Windows-Programmierung: das Grundgerüst |
Und wieder einmal ein Rahmenprogramm für ein einfaches Windowsprogramm. Diesmal ist es mit Hyperlinks ausgestattet, so daß man zwischen Erklärung und Source hin- und herspringen kann. Vielleicht veranschaulicht das etwas, zumindest macht es Spaß.
Die Instanz
Per Parameter erhält MainWin die Instanz von Windows.
Diese Variable wird
bei Aufrufen von diversen Funktionen benötigt, die an Windows gehen. An
dieser Variablen erkennt Windows die Applikation wieder, auch dann, wenn sie
kein Fenster geöffnet hat. Aus diesem Grund wird sie von den meisten
Windowsprogrammen in einer globalen Variable gespeichert und direkt
zugegriffen.
MyRegisterClass
Das Hauptfenster wird registriert und bei Windows angemeldet.
Die Registrierung ist die Anmeldung einer Fensterklasse.
Es können also
auch mehrere Fenster der gleichen Klasse angemeldet werden.
Der RegisterClass-String
Welches Fenster zu welcher Klasse gehört, wird nicht durch ein Handle,
sondern durch eine Zeichenkette beschrieben. Da diese Zeichenkette exakt
identisch sein muß, wird dieser String zu Anfang in einem
define-Statement festgelegt oder sogar in den
Ressourcen abgelegt. Wichtig ist, daß er das Fenster im laufenden
System eindeutig bezeichnet. Er wird einmal bei der Registrierung der
Klasse und dann noch einmal beim Erzeugen des Fensters verwendet.
Das Fenster wird durch den RegisterClass-String als zu der registrierten Klasse gehöriges Fenster erzeugt.
Als zweiten String hat das Fenster szTitle.
Das ist der Text, der im blauen Balken
zu sehen ist. Er hat nur informellen Charakter und könnte auch leer sein.
Da dieser String oft sprachenabhängig ist, würde es Sinn machen, ihn in der
Ressource abzulegen.
Windows liefert vier Parameter mit. Der erste ist das Handle (HWND) des Fensters
Dies ist besonders wichtig, wenn es mehrere Fenster gleichen Typs gibt.
Der zweite Parameter ist der Typ der Message. Typischerweise besteht eine
Fensterfunktion in erster Linie aus einer großend Fallunterscheidung
über diese Variable.
Die beiden restlichen Variablen sind Parameter des Typs. So liefert
die WM_SIZE in diesen Parametern die neue Ausdehnung des Fensters.
Die Fensterfunktion
Die Fensterfunktion behandelt diejenigen Ereignisse,
die auf das Fenster einstürmen.
Die Funktion wird von Windows gerufen, wenn immer ein Ereignis für dieses
Fenster vorliegt.
Die Default-Fensterfunktion DefWindowProc
Werden Nachrichten nicht behandelt oder werden nur Teilaspekte des Ereignisses
verarbeitet, so ruft die Fensterfunktion die Funktion DefWindowProc
und übergibt ihr die Parameter, die sie von Windows erhalten hat.
DefWindowProc ist die Default-Fensterfunktion und behandelt alle
Ereignisse mit der Standardreaktion. So wird beispielsweise das Fenster
vergrößert oder mit der Hintergrundfarbe weiß versehen.
Das Menü
Die Quit-Nachricht wird nicht in der Fensterfunktion bearbeitet, sondern bewirkt ein Unterbrechen der Main-Loop und führt so zum Ende der Applikation.
Der scheinbare Umweg über das Nachrichtensystem führt dazu, daß alle beteiligten Komponenten informiert sind, daß dieses Programm sich abbaut.
#include <windows.h> #include "resource.h" HINSTANCE hInst; #define szTitle "Fenstertitel" #define szWindowClass "MyWindowClass" LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_EXIT: DestroyWindow(hWnd); break; } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // do the painting of the window EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hWnd, message, wParam, lParam); } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex = {0}; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_RAHMEN); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_RAHMEN; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } BOOL InitMainWindow(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; HACCEL hAccelTable; MyRegisterClass(hInstance); hInst = hInstance; if (!InitMainWindow (hInstance, nCmdShow)) return FALSE; hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_RAHMEN); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } |
#include "resource.h" #include "windows.h" // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_RAHMEN ICON DISCARDABLE "Rahmen.ICO" IDI_SMALL ICON DISCARDABLE "SMALL.ICO" IDC_RAHMEN MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "E&xit", IDM_EXIT END POPUP "&Help" BEGIN MENUITEM "&About ...", IDM_ABOUT END END IDC_RAHMEN ACCELERATORS MOVEABLE PURE BEGIN "?", IDM_ABOUT, ASCII, ALT "/", IDM_ABOUT, ASCII, ALT END STRINGTABLE DISCARDABLE BEGIN IDC_RAHMEN "RAHMEN" IDS_APP_TITLE "Rahmen" IDS_HELLO "Hello World!" END |
#define IDR_MAINFRAME 128 #define IDD_RAHMEN_DIALOG 102 #define IDS_APP_TITLE 103 #define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDS_HELLO 106 #define IDI_RAHMEN 107 #define IDI_SMALL 108 #define IDC_RAHMEN 109 #define IDC_MYICON 2 #define IDC_STATIC -1 |
Homepage - Windows-API-Programmierung | (C) Copyright 1999 Arnold Willemer |