zurück zur Startseite

API-Windows-Programmierung (ohne MFC)

Inhalt

1. WinMain(...) und windows.h
2. Eigene Fenster erzeugen
3. Zwei Fenster auf Basis einer WNDCLASS-Struktur erzeugen
4. Nachrichtenverarbeitung
5. Interaktionen mit Kindfenstern
6. DLL-Programmierung
 

5. Interaktionen mit Kindfenstern

Die Darstellung von Fenstern und die Verarbeitung von Nachrichten ist die Grundlage von Windows. Im nächsten Schritt betrachten wir die Zusammenarbeit mehrerer Fenster zur Interaktion mit dem Benutzer. Hierbei ist es wichtig, daß man versteht, daß Buttons, Edit-Felder usw. auch nur Fenster sind, die über den Austausch von Nachrichten mit einem Elternfenster Aktionen einleiten. Beginnen wir mit einem Button.

Als Ausgangspunkt verwenden wir folgendes Programm, das einen Button als Kindfenster darstellt. Die entsprechenden notwendigen Ergänzungen im Programmcode sind rot hervorgehoben: 



#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
{
 char szName[] = "Fensterklasse";
 HBRUSH MyBrush = CreateSolidBrush( RGB( 0, 150, 255 ) );
 WNDCLASS wc;

 wc.style         = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc   = WndProc;
 wc.cbClsExtra    = 0;
 wc.cbWndExtra    = 0;
 wc.hInstance     = hI;
 wc.hIcon         = LoadIcon (NULL, IDI_WINLOGO);
 wc.hCursor       = 0;
 wc.hbrBackground = MyBrush;
 wc.lpszMenuName  = NULL;
 wc.lpszClassName = szName;

 RegisterClass (&wc);

 HWND hwnd = CreateWindow (szName, "Interaktives Fenster", WS_OVERLAPPEDWINDOW,
                            0, 0, 400, 100, NULL, NULL, hI, NULL);
 ShowWindow   (hwnd, iCmdShow);
 UpdateWindow (hwnd);

//-----------------------------------------------------------------------------------

  MSG msg;

  while (GetMessage (&msg, NULL, 0, 0))
  {
    TranslateMessage (&msg);
    DispatchMessage  (&msg);
  }
  return msg.wParam;
}

//-----------------------------------------------------------------------------------

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 HWND hwndButton;

 switch (message)
 {

  case WM_PAINT:
    hdc = BeginPaint (hwnd, &ps);
      SetTextColor(hdc, RGB(255,0,0) );
      SetBkColor(hdc, RGB(255,255,0) );
      TextOut (hdc, 20, 20, "Ich bin ein Fenster.", 20);
      EndPaint (hwnd, &ps);
  return 0;

case WM_CREATE :

  hwndButton = CreateWindow ( "button", "Knopf",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   200, 20, 100, 40,
                                   hwnd, NULL,((LPCREATESTRUCT) lParam)->hInstance, NULL);
  return 0 ;

  case WM_DESTROY:
    PostQuitMessage (0);
  return 0;
 }

 return DefWindowProc (hwnd, message, wParam, lParam);
}


Nach dem Kompilieren erhält man folgendes Ergebnis:

An der Stelle x=200 / y=20 (linke obere Ecke des Buttons) findet man jetzt ein mit CreateWindow(...) erzeugtes Kindfenster vom Typ "button" / BS_PUSHBUTTON mit der Höhe=40 und der Breite=100.

Etwas kompliziert wirkt zunächst der Ausdruck für den Parameter "instance handle":

((LPCREATESTRUCT)lParam)->hInstance.

Die WM_CREATE Nachricht liefert als lParam einen Zeiger auf eine Struktur vom Typ CREATESTRUCT.
Diese Struktur enthält folgende Elemente, die denen der Funktion CreateWindow(...) entsprechen:

       LPVOID         lpCreateParams
    HINSTANCE      hInstance
    HMENU          hMenu
    HWND           hwndParent
    int            cy
    int            cx
    int            y
    int            x
    LONG           style
    LPCTSTR        lpszName
    LPCTSTR        lpszClass
    DWORD          dwExStyle

Ein Element dieser Struktur ist hInstance. Daher wird lParam in einen Zeiger auf diese  CREATESTRUCT-Struktur umgewandelt. Mit dem Pfeiloperator erhalten wir daraus das Element hInstance.

Eine weitere Methode besteht im Einsatz der Funktion GetWindowLong(...) und cast von LONG nach HINSTANCE wie folgt:

(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE)


...
    case WM_CREATE :
        hwndButton = CreateWindow ( "button", "Knopf",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   200, 20, 100, 40,
                                   hwnd, NULL,
                            (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),
                                   NULL);
    return 0;
...

Als weitere Alternative kann man außerhalb der Funktionen WinMain(...) und WndProc(...) eine globale Variable hInst deklarieren, die man in WinMain(...) vor Erstellen des Hauptfensters einfach mit hInst = hI initialisiert. Dann kann man wie folgt vorgehen:



#include <windows.h>
HINSTANCE hInst;
...
int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
{
...
 hInst = hI;
...
}

LRESULT CALLBACK WndProc (...)
{
...
case WM_CREATE :
     hwndButton = CreateWindow ( "button", "Knopf",
                                 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                 200, 20, 100, 40,
                                hwnd, NULL, hInst, NULL);
return 0 ;
...
}


Diese Variante sieht zumindest weniger kompliziert aus als die ersten beiden. Man erkauft diesen Vorteil durch eine zusätzliche globale Variable.

Probieren Sie einfach alle drei Varianten aus, um an hInstance zu gelangen.

Mir persönlich gefällt die Methode mit GetWindowLong(...) am besten.
Daher ändern Sie den Code für die weiteren Betrachtungen bitte auf diese Methode ab.

Das Fenster mit seinem Button sieht zwar hübsch aus, aber eine Funktion ist noch nicht zu erkennen.
Was passiert, wenn man mit der Maus auf den Knopf klickt? Hierbei erzeugt man eine Nachricht WM_COMMAND.
Diese Nachricht kann man abfangen und auswerten. Der Aufbau der Nachricht ist wie folgt:
 
 LOWORD (wParam)   Kindfenster ID
 HIWORD (wParam)   Notification code
 HWND   (lParam)  Kindfenster handle 

Diese Parameter sind im Moment nicht wesentlich. Wir probieren zunächst das Abfangen der Nachricht. Ergänzen Sie die switch-Kontrollstruktur zur Auswertung der Nachrichten bitte wie folgt:



switch (message)
{
...
  case WM_COMMAND:
      MessageBox(hwnd,"Click", "Die Nachricht WM_COMMAND wurde erzeugt", MB_OK);
  return 0;
...
}

Beim Mausklick auf den Button erhält man folgende Antwort:

Sie haben es nun geschafft, ein Kindfenster als Button in unser Elternfenster zu integrieren und diesem Button eine Funktion zuzuordnen.
Im nächsten Schritt werden wir zwei Buttons einbauen. Zur Sicherheit hier noch einmal der komplette Code:


#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
{
 char szName[] = "Fensterklasse";
 HBRUSH MyBrush = CreateSolidBrush( RGB( 0, 150, 255 ) );
 WNDCLASS wc;

 wc.style         = CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc   = WndProc;
 wc.cbClsExtra    = 0;
 wc.cbWndExtra    = 0;
 wc.hInstance     = hI;
 wc.hIcon         = LoadIcon (NULL, IDI_WINLOGO);
 wc.hCursor       = 0;
 wc.hbrBackground = MyBrush;
 wc.lpszMenuName  = NULL;
 wc.lpszClassName = szName;

 RegisterClass (&wc);

 HWND hwnd = CreateWindow (szName, "Interaktives Fenster", WS_OVERLAPPEDWINDOW,
                            0, 0, 400, 100, NULL, NULL, hI, NULL);
 ShowWindow   (hwnd, iCmdShow);
 UpdateWindow (hwnd);

//-----------------------------------------------------------------------------------

  MSG msg;

  while (GetMessage (&msg, NULL, 0, 0))
  {
    TranslateMessage (&msg);
    DispatchMessage  (&msg);
  }
  return msg.wParam;
}

//-----------------------------------------------------------------------------------

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 HWND hwndButton1, hwndButton2;

 switch (message)
 {
  case WM_PAINT:
      hdc = BeginPaint (hwnd, &ps);
      SetTextColor(hdc, RGB(255,0,0) );
      SetBkColor(hdc, RGB(255,255,0) );
      TextOut (hdc, 20, 20, "Ich bin ein Fenster.", 20);
      EndPaint (hwnd, &ps);
  return 0;

  case WM_CREATE :
      hwndButton1 = CreateWindow ( "button", "Knopf 1",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   150, 20, 100, 40, hwnd, NULL,
                                   (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);

      hwndButton2 = CreateWindow ( "button", "Knopf 2",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   251, 20, 100, 40, hwnd, NULL,
                                   (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
  return 0;

  case WM_COMMAND:
      MessageBox(hwnd,"Click", "Die Nachricht WM_COMMAND wurde erzeugt", MB_OK);
  return 0;

  case WM_DESTROY:
      PostQuitMessage (0);
  return 0;
 }

 return DefWindowProc (hwnd, message, wParam, lParam);
}


Das Ergebnis zeigt ein Fenster mit zwei Kindfenstern vom Typ Button.

Jetzt gibt es aber ein Problem. Egal, ob ich auf Knopf 1 oder Knopf 2 drücke, immer erscheint die gleiche Messagebox.
Wie kann man hier unterschiedliche Reaktionen erzeugen?

Verändern/Ergänzen Sie den Code bitte wie folgt:



case WM_CREATE :
      hwndButton1 = CreateWindow ( "button", "Knopf 1",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   150, 20, 100, 40, hwnd, (HMENU)1,
                                   (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);

      hwndButton2 = CreateWindow ( "button", "Knopf 2",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   251, 20, 100, 40, hwnd, (HMENU)2,
                                   (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
  return 0;

  case WM_COMMAND:
  if(LOWORD(wParam) == 1)
   {
      MessageBox(hwnd,"Click auf Knopf 1", "Die Nachricht WM_COMMAND wurde erzeugt", MB_OK);
   }
   if(LOWORD(wParam) == 2)
   {
      MessageBox(hwnd,"Click auf Knopf 2", "Die Nachricht WM_COMMAND wurde erzeugt", MB_OK);
   }
  return 0;


Jetzt funktioniert die Unterscheidung der beiden Buttons.  Was haben wir genau unternommen? Ganz einfach: Wir haben den beiden Kindfenstern verschiedene Namen gegeben: 1 und 2. Die ID (ID=Identifikation; das ist der Name - in Windows natürlich eine Zahl - des Kindfensters) wird im switch-Zweig mit der Nachricht WM_COMMAND abgefragt. Auf diese Weise - also unter Verwendung der ID - kann man die Kindfenster in einem Elternfenster sicher unterscheiden. Nachfolgend finden Sie zur Übung die entsprechende switch-Variante, falls Ihnen diese Kontrollstruktur hier besser gefällt:



case WM_COMMAND:
   switch(LOWORD(wParam))
   {
    case 1:
      MessageBox(hwnd,"Click auf Knopf 1", "Die Nachricht WM_COMMAND wurde erzeugt", MB_OK);
    break;
    case 2:
      MessageBox(hwnd,"Click auf Knopf 2", "Die Nachricht WM_COMMAND wurde erzeugt", MB_OK);
    break;
   }
return 0;

Hier können Sie übrigens auch wParam anstelle LOWORD(wParam) verwenden, da dies hier identisch ist. Zur Erinnerung der Aufbau der Message WM_COMMAND:
 
 LOWORD (wParam)   Kindfenster ID
 HIWORD (wParam)   Aktions-Code
 HWND   (lParam)  Kindfenster-Handle 

Übrigens: Wenn Sie den "Kindern" gleiche Namen geben, also z.B. beide (HMENU) 1, dann kommen eben beide, wenn Sie rufen. Probieren Sie es aus.

Den Code in WndProc(...) ändern wir nun wie folgt ab, um zusätzlich zur Button-Schaltfläche das Edit-Feld kennenzulernen:



LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static HWND hwndButton1, hwndEdit2;

 switch (message)
 {
  case WM_PAINT:
      hdc = BeginPaint (hwnd, &ps);
      SetTextColor(hdc, RGB(255,0,0) );
      SetBkColor(hdc, RGB(255,255,0) );
      TextOut (hdc, 20, 20, "Ich bin ein Fenster.", 20);
      EndPaint (hwnd, &ps);
  return 0;

  case WM_CREATE :
      hwndButton1 = CreateWindow ( "button", "Knopf 1",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   150, 20, 100, 40, hwnd, (HMENU)1,
                                   (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);

  hwndEdit2   = CreateWindow ( "edit", "Edit-Feld",
                                   WS_CHILD | WS_VISIBLE,
                                   251, 20, 100, 40, hwnd, (HMENU)2,
                                   (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL);
  return 0;

  case WM_COMMAND:
      switch(LOWORD(wParam))
      {
  case 1:
           SetWindowText(hwndEdit2,"");
           SendMessage(hwndEdit2, EM_SETREADONLY, TRUE, 0);
      break;
      case 2:
           SendMessage(hwndEdit2, EM_SETREADONLY, FALSE, 0);
      break;
      }
  return 0;

  case WM_DESTROY:
      PostQuitMessage (0);
  return 0;
 }

 return DefWindowProc (hwnd, message, wParam, lParam);
}


Wichtig ist, daß wir die HWND-Variablen für unsere Kindfenster auf static setzen, damit der Inhalt dieser Variablen nicht verloren geht.
Für das Edit-Feld setzt man in CreateWindow(...) den Parameter lpClassName einfach auf das vorgefertigte "edit".

Nach dem Kompilieren findet man nun folgendes Bild:

Mit den ersten beiden Parametern der Funktion CreateWindow ( "edit", "Edit-Feld", ...) haben wir also den Fenster-Typ Edit-Feld und den Text im Feld festgelegt.

Die Reaktionen auf das Klicken mit der Maus in das Kindfenster wird über die Nachricht WM_COMMAND festgelegt. Daher haben wir dort einige Funktionen eingebaut.

Ein Klick auf den Button bewirkt folgende Funktionen:

SetWindowText(hwndEdit2,"");
SendMessage(hwndEdit2, EM_SETREADONLY, TRUE, 0);

Die erste Funktion verändert einfach den Text im Fenster. Ersetzen Sie hwndEdit2 versuchsweise durch hwnd und hwndButton1. Damit können Sie also die Texte "Interaktives Fenster", "Knopf1" und "Edit-Feld" beeinflussen.

Eine sehr breit einsetzbare Funktion ist SendMessage(...). Die allgemeine Syntax ist:

LRESULT SendMessage (  HWND hWnd,  UINT Msg,  WPARAM wParam,   LPARAM lParam );

Der erste Parameter legt das Fenster fest, an das die Nachricht gesendet werden soll. Dann folgt die Nachricht und ihre beiden Parameter.
Wir senden also die Nachricht EM_SETREADONLY mit den Parametern wParam = TRUE und lParam = 0. In MSDN finden Sie die betreffenden Informationen:

EM_SETREADONLY
wParam = (WPARAM) (BOOL) fReadOnly; // read-only flag
lParam = 0;                       // not used; must be zero

Dort erfahren Sie, daß das read-only flag auf TRUE gesetzt werden muß, wenn das Edit-Feld schreibgeschützt sein soll. Dann wird das Eingabefeld zum Ausgabefeld, gekennzeichnet durch die graue Farbe. Mit FALSE kann man das Flag zurücksetzen.

Auf Knopfdruck haben wir jetzt das Edit-Feld gelöscht (string "") und auf READ-ONLY gesetzt.

Ein Klick in das Edit-Feld aktiviert das Feld durch folgende Funktion:

SendMessage(hwndEdit2, EM_SETREADONLY, FALSE, 0);

Die Bedeutung kennen Sie ja bereits. Schauen Sie sich einmal in MSDN alle Nachrichten an, die mit EM_SET... beginnen.
Dort finden Sie 27 Nachrichten, die Ihnen eine Manipulation des Edit-Feldes erlauben. Testen Sie nach Belieben.

In der Funktion CreateWindow haben wir bisher nur die Parameter WS_CHILD | WS_VISIBLE gesetzt. Damit haben wir ein Standard-Edit-Feld als sichtbares Kindfenster installiert. Weitere Eigenschaften kann man über Styles ES_... setzen.

Ändern Sie z.B. auf WS_CHILD | WS_VISIBLE | ES_MULTILINE ab. Dann können Sie z.B. mehr als eine Zeile im Edit-Feld nutzen:

Unser Edit-Feld ist natürlich zu klein, um größere Eingaben zuzulassen. Zwei Zeilen sind momentan das Maximum.
Mittels WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL kann man mehr als zwei Zeilen eingeben, da das Feld automatisch weiterscrollt. Mit den Pfeiltasten können Sie den Inhalt entsprechend scrollen.
Informieren Sie sich in MSDN unter edit styles.

Bisher haben Sie die vordefinierten Fenster-Typen "button" und "edit" kennengelernt.
Nachfolgend noch einige andere vordefinierte Fenster-Typen:
 
Fenster-Typ Nachricht (message) Stil (style)
"button" BM_ BS_
"edit" EM_ ES_
"listbox" LB_ LBS_
"combobox" CB_ CBS_
"static" STM_ SS_

Dieses Handwerkzeug müssen Sie nun vertiefen. Nachfolgend finden Sie ein einfaches Übungsbeispiel mit einer ListBox.
Konzentrieren Sie sich vor allem auf das Zusammenspiel zwischen Eltern- und Kindfenster:
 
#define WIN32_LEAN_AND_MEAN

#include <windows.h> 
#include <stdio.h> 
#include <string.h> 

const  UINT ID_LISTBOX = 1; 
static HWND hwndListBox; 

static char g_szClassName[] = "MyWindowClass"; 
static HINSTANCE g_hInst    = NULL; 

UINT  limit = 20; //Notwendiger freier Speicherplatz in MB 
BOOL  LaufwerkIsTrue[30]; 
DWORD LaufwerkFreierSpeicher[30]; 
short LaufWerkListBoxIndex[30]; 

void  GetLaufwerkInfo(); 
 

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) 

 int x; 
 char str[256]; 
 unsigned short index; 

 switch(Message)
 { 
 case WM_CREATE: 
  for( x=0; x<30; x++ ) {LaufWerkListBoxIndex[x] = 1000;} 
  hwndListBox   = CreateWindowEx ( WS_EX_CLIENTEDGE,"listbox", "", 
                                   WS_CHILD|WS_VISIBLE|LBS_STANDARD, 
                                   10, 10, 200, 400, 
                                   hwnd, (HMENU)ID_LISTBOX, g_hInst, NULL); 
  return 0;

 case WM_COMMAND: 
  switch(LOWORD(wParam)) 
  { 
   case ID_LISTBOX: 
     if (HIWORD(wParam) == LBN_SELCHANGE ) 
     { 
      index = SendMessage(hwndListBox, LB_GETCURSEL, 0, 0 ); 
      for(int i=0; i<26; i++) 
      { 
       if(LaufWerkListBoxIndex[i] == index) 
       { 
        sprintf( str,"Index %d   Freier Speicher (MB) %d",
                                      index, LaufwerkFreierSpeicher[i] ); 
        MessageBox(hwnd,str,"",MB_OK | MB_ICONINFORMATION ); 
       } 
      }/*for*/ 
     }/*if*/
    break;
   } 
   return 0; 

   case WM_CLOSE: 
     DestroyWindow(hwnd); 
   return 0; 

  case WM_DESTROY: 
    PostQuitMessage(0); 
  return 0; 
 } 
    return DefWindowProc(hwnd, Message, wParam, lParam); 
}//WndProc 
 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                   LPSTR lpCmdLine, int nCmdShow ) 

 if( FindWindow("MyWindowClass","HardDisk") ) //verhindert, daß das Programm mehrfach gestartet wird 
 { 
  PostQuitMessage(0); 
  return 0; 
 } 
   WNDCLASSEX WndClass;   HWND hwnd;   MSG msg;   g_hInst = hInstance; 

   WndClass.cbSize        = sizeof(WNDCLASSEX); 
   WndClass.style         = CS_VREDRAW | CS_HREDRAW; 
   WndClass.lpfnWndProc   = WndProc; 
   WndClass.cbClsExtra    = 0; 
   WndClass.cbWndExtra    = 0; 
   WndClass.hInstance     = g_hInst; 
   WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION); 
   WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW); 
   WndClass.hbrBackground = (HBRUSH)(LTGRAY_BRUSH); 
   WndClass.lpszMenuName  = NULL; 
   WndClass.lpszClassName = g_szClassName;
   WndClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); 

   RegisterClassEx(&WndClass); 
   hwnd = CreateWindowEx( WS_EX_TOOLWINDOW , g_szClassName, "HardDisk", 
          WS_SYSMENU|WS_CAPTION, 100, 100, 400, 500, NULL, NULL, g_hInst, NULL); 

   GetLaufwerkInfo(); 

   ShowWindow(hwnd, nCmdShow); 
   UpdateWindow(hwnd); 

   while ( GetMessage( &msg,NULL,0,0 ) ) 
   { 
    TranslateMessage ( &msg ); 
    DispatchMessage  ( &msg ); 
   } 
   return msg.wParam; 
}//WinMain 
 

void GetLaufwerkInfo() 

 ULARGE_INTEGER FreeBytes; 
 ULARGE_INTEGER TotalBytes; 
 int ListBoxIndex = -1; 

 int Drive = 1;      // Laufwerktyp (1-6)
 char str[] ="   ";  // für A: bis Z: 

 for( int zaehler = 0; zaehler<26; zaehler++ ) 
 { 
   switch(zaehler) 
   { 
   case 0:     strcpy(str,"A:");break; 
   case 1:     strcpy(str,"B:");break; 
   case 2:     strcpy(str,"C:");break; 
   case 3:     strcpy(str,"D:");break; 
   case 4:     strcpy(str,"E:");break; 
   case 5:     strcpy(str,"F:");break; 
   case 6:     strcpy(str,"G:");break; 
   case 7:     strcpy(str,"H:");break; 
   case 8:     strcpy(str,"I:");break; 
   case 9:     strcpy(str,"J:");break; 
   case 10:    strcpy(str,"K:");break; 
   case 11:    strcpy(str,"L:");break; 
   case 12:    strcpy(str,"M:");break; 
   case 13:    strcpy(str,"N:");break; 
   case 14:    strcpy(str,"O:");break; 
   case 15:    strcpy(str,"P:");break; 
   case 16:    strcpy(str,"Q:");break; 
   case 17:    strcpy(str,"R:");break; 
   case 18:    strcpy(str,"S:");break; 
   case 19:    strcpy(str,"T:");break; 
   case 20:    strcpy(str,"U:");break; 
   case 21:    strcpy(str,"V:");break; 
   case 22:    strcpy(str,"W:");break; 
   case 23:    strcpy(str,"X:");break; 
   case 24:    strcpy(str,"Y:");break; 
   case 25:    strcpy(str,"Z:");break; 
   } 

   Drive = GetDriveType( str );   // Laufwerk-Typ abfragen 
   if( Drive == 3)             // 3 entspricht Festplatte
   { 
    GetDiskFreeSpaceEx( str, &FreeBytes, &TotalBytes, NULL ); 

    if( FreeBytes.QuadPart /(1024*1024) >= limit ) 
 
     LaufwerkIsTrue[zaehler] = TRUE; 
     LaufwerkFreierSpeicher[zaehler] =  (UINT) (FreeBytes.QuadPart /(1024*1024)); 
    }

    if( LaufwerkIsTrue[zaehler] ) 
    { 
     char ausgabe[20]; 
     sprintf( ausgabe,"%s %u MB",str,LaufwerkFreierSpeicher[zaehler] ); 
     SendMessage(hwndListBox,LB_ADDSTRING,0        , (LPARAM)ausgabe ); 
     ListBoxIndex++; 
     LaufWerkListBoxIndex[zaehler] = ListBoxIndex; 
     SendMessage(hwndListBox,LB_SETCURSEL,(WPARAM)0, 0               ); 
    } 
   }/*if*/
 }/*for-Schleife*/


weiter zu Teil 6: DLL-Programmierung

zurück zur Startseite