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
 

Bevor wir zur Nachrichtenverarbeitung, dem Kernstück der Windows-Programmierung, kommen,
werden wir zunächst zwei Fenster mittels CreateWindow(...) auf Basis einer gemeinsamen WNDCLASS-Struktur
in einem Programm aufrufen.
 

3. Zwei Fenster auf Basis einer WNDCLASS-Struktur erzeugen

Mit CreateWindow(...) kann man auf Basis einer registrierten WNDCLASS-Struktur in einem einzigen Programm
auch mehrere Fenster erzeugen. Damit Sie hierfür eine experimentelle Basis haben, ändern Sie bitte auf folgenden Code ab:
 
#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
{
char szName[] = "Fensterklasse";
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 = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szName;
RegisterClass (&wc);

HWND hwnd = CreateWindow          // Fenster 1
(
    szName,
    "Dies ist unser erstes kleines Fenster",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    NULL, // Handle des Elternfensters nicht vorhanden
    NULL,
    hI,
    NULL
);

ShowWindow   (hwnd, iCmdShow);
UpdateWindow (hwnd);

HWND hwnd2 = CreateWindow        // Fenster 2
(
    szName,
    "Dies ist unser zweites kleines Fenster",
    WS_OVERLAPPEDWINDOW,
    200, 200, 200, 50,
    hwnd, // Handle des Elternfensters
    NULL,
    NULL,
    NULL
);

ShowWindow   (hwnd2, SW_SHOWNORMAL);
UpdateWindow (hwnd2);

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

  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;

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

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

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

Nach dem Kompilieren verfügt unser Programm über zwei Fenster mit jeweils eigener Titelzeile und Systemmenü:

Dies liegt daran, dass für beide Fenster der Stil WS_OVERLAPPEDWINDOW festgelegt wurde.
Sie können das zweite Fenster auch außerhalb des Bereichs des ersten Fensters bewegen:

Anders verhält sich dies, wenn Sie beim zweiten Fenster anstelle des Stils WS_OVERLAPPEDWINDOW
den Stil WS_CHILD | WS_THICKFRAME verwenden.

Jetzt ist das zweite Fenster "gefangenes Kind" des ersten Fensters und darf sich nur in dessen Anwendungsbereich (client area) bewegen.
Da wir zusätzlich WS_THICKFRAME angegeben haben, kann man den Rahmen des zweiten Fensters mit der Maus anpacken
und damit dessen Größe verändern. Der Code im zweiten CreateWindow(...) sieht nun folgendermaßen aus:

HWND hwnd2 = CreateWindow
(
    szName,
    "Dies ist unser zweites kleines Fenster",
    WS_CHILD | WS_THICKFRAME,
    200, 200, 200, 50,
    hwnd,
    NULL,
    NULL,
    NULL
);

ShowWindow   (hwnd2, SW_SHOWNORMAL);
UpdateWindow (hwnd2);

Nach dem Kompilieren / Starten bietet sich folgendes Bild:

Systemmenü und Titelzeile des zweiten Fensters sind verschwunden,
und das zweite Fenster hat klare Grenzen innerhalb des ersten Fensters.
 
 



weiter zu Teil 4: Nachrichtenverarbeitung
 
zurück zur Startseite