Vollständige Version anzeigen : [C/C++] Win32 API: Fenster


terraNova
09.06.2008, 22:57

Win32 API - Fenster erstellung

Um ein Fenster zu erstellen benötigt man nicht viel,
und man wird es nach einiger Zeit auch flüssig von der Hand schreiben können,
sodass man nicht jedesmal nachlesen muss.

Vorerst einmal will ich euch die zu verwendenden Funktionen und Strukturen vorstellen:

Die WNDCLAS;-Struktur ( Window Class Extended ):

Diese Struktur ist wie folgt definiert:


typedef struct {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbCl;tra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLAS;, *PWNDCLAS;;


cbSize: gibt an wie groß die Struktur ist, mit der wir gerade arbeiten.
style: Wie soll unser Fenster hinterher genau aussehen?
lpfnWndProc: (lpfn: (ungarische Notation) long pointer function ) Hier wird ein Zeiger zu der Funktion angegeben, die unsere Nachrichten empfängt und abarbeitet.
cbCl;tra: Unnötig, daher auf 0 setzen. Wir brauchen keinen zusätzlichen Speicher für unsere Struktur
cbWndExtra: s;o.
hInstance: Eine Instanz zu unserem Programm, wo sich unsere "Nachrichtenverwaltung" befindet.
hIcon: Ein Handle zu einem Bild für unser Programm ( Titelleiste )
hCursor: Ein Handle zu einem Bild für unseren Mauszeiger, entweder aus der Resource-Datei unseres Programmes, oder die Windowseigene ( IDC_ARROW )
hbrBrackground: Ein Handle zu einem Brush, mit dem unserer Fensterhintergrund gefüllt wird.
lpszMenuName: Für ein Menu wird hier ein Nullterminierter-String benötigt, der ebenfalls in unserer Resource-Datei befindet.
lpszClassName: Der Name unserer Fenster Klasse.
hIconSm: Siehe hIcon, nur für die kleinen Icons ;).



Die MSG-Struktur:


typedef struct {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;


hwnd: Ein Handle vom Fenster, das die Nachricht empfangen hat.
message: Die Nachricht.
wParam: Zusätliche Informationen.
lParam: s;o.
time: Gibt an, wann die Nachricht versendet wurde.
pt: Gibt an, wo sich der Mauszeiger gerade befindet.



Die Funktion RegisterClas; ( Register Class Extended ) ist wie folgt definiert:


ATOM RegisterClas;( WNDCLAS;* wnd );

Diese Funktion registriert unsere Fensterklasse, bei einem Fehlschlag
wird 0 zurückgegeben, die wahrscheinlichkeit ist ziehmlich gering, dass das passiert.



Die Funktion CreateWindow:


HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);

Die Funktion gibt ein Handle zu unserem erstellten Fenster zurück,
um zu Prüfen ob ein Fehler existiert, gilt das Handle mit dem Makro FAILED(x) zu überprüfen,
oder auf NULL zu checken.


lpClassName: String der Klasse, die wir auch bei der Struktur WNDCLAS; angegeben haben
lpWindowName: Text der auf der Titelleiste des Fensters erscheinen soll.
dwStyle: Fenstereigenschaften, wie z;b. ein Rahmen.
x, y: Koordinaten des Fensters.
nWidth, nHeight: Größe und Breite des Fensters.
hWndParent: Gibt es ein Fenster, zu dem dieses hier gehören soll( Also Eltern? ).
hMenu: Ein Handle zu einem Menu.
hInstance: Ein Handle zu der Instanz der Applikation.
lParam: Angabe nicht nötig.



Die Funktionen ShowWindow und UpdateWindow:


BOOL ShowWindow(
HWND hWnd,
int nCmdShow
);

BOOL UpdateWindow(
HWND hWnd
);

Bei beiden Funktionen muss ein Handle zum Fenster angegeben werden,
mit einem unterschied bei der Funktion ShowWindow, nämlich wird hier noch
beim zweiten Parameter nCmdShow angegeben, ob man das Fenster zeigen
oder nicht zeigen will( SW_SHOW, SW_HIDE ).

Mit ShowWindow gebt ihr an ob ihr das Fenster zeigen wollt, oder eben nicht,
und mit UpdateWindow wird das Fenster dann gezeichnet.



Die Funktion PeekMessage:


BOOL PeekMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);


lpMsg: Ein Zeiger zu einer MSG-Struktur.
hWnd: Von welchem Fenster sollen die Nachrichten empfangen werden. NULL wird übergeben, um von jedem Thread dieses Programmes die Nachricht zu bekommen.
wMsgFilterMin: Jede Nachricht ist ein Konstanter Wert, hier wird angegeben welcher Wert der minimalste Wert ist, den wir empfangen wollen.
wMsgFilterMax: s;o.
wRemoveMsg: Hier gibt man an, ob man nach dem erhalten der Nachricht, die Nachricht löschen will, damit diese nicht mehr für andere Threads erhältlich ist.


DispatchMessage und TranslateMessage:

DispatchMessage und TranslateMessage erwarten beide nur einen Parameter:
einen Zeiger zu einer MSG-Struktur.

TranslateMessage bereitet die Struktur vor und DispatchMessage schickt diese dann an unsere
"Nachrichtenverwaltung" um bearbeitet zu werden.

So. Soviel zur Theorie. Klingt beim ersten durchlesen nach viel Information, was es eigentlich garnicht ist.
Es ist mehr oder weniger sehr einfach zu merken, weil es eben auch logisch ist.

Ich schreibe nun einmal ein stück Quellcode, und erläutere die Schritte, etc. mit Kommentaren.

#define WIN32_LEAN_AND_MEAN
// Nachdem WIN32_LEAN_AND_MEAN per Präprozessor definiert wurde,
// werden unnötige Teile einfach ausgelassen, was unsere Anwendug natürlich kleiner
// macht.
//
#include <windows;h>

// Hier definieren wir unsere Funktion, die die Nachrichten bearbeitet.
//
LRESULT CALLBACK WindowProc ( HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam );

#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdline, int nshowcmd )
{
const char c_acWindowClass[] = "Fenster";
HWND hWindow = NULL;
MSG sMessage;
WNDCLAS; wnd;

ZeroMemory( &wnd, sizeof( WNDCLAS; ) );
ZeroMemory( &sMessage, sizeof( MSG ) );

wnd;cbCl;tra = 0; // Wir brauchen keinen zusätzlichen Speicher
wnd;cbWndExtra = 0; // S;o.
wnd;cbSize = sizeof( WNDCLAS; ); // Die größe dieser Struktur
wnd;hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); // Ein Brush mit dem unserer Hintergrund gefüllt wird
wnd;hCursor = (HCURSOR)LoadCursor( NULL, IDC_ARROW ); // Ein Icon für unseren Mauszeiger
wnd;hIcon = 0; // Wir verwenden den standard Icon für unsere Titelleiste
wnd;hIconSm = 0; // S;o.
wnd;hInstance = hInstance; // Eine Instanz zu diesem Programm
wnd;lpfnWndProc = WindowProc; // Unsere Nachrichtenfunktion
wnd;lpszClassName = c_acWindowClass; // Der Klassenname
wnd;lpszMenuName = NULL; // Wir verwenden hier kein Menü
wnd;style = CS_HREDRAW|CS_VREDRAW; // Zeichnet das Fenster nochmal komplett neu, bei veränderung/vergrößerung

if( FAILED( RegisterClas;( &wnd ) ) ) // Unsere Fensterklasse registrieren
{
MessageBoxA( 0, "Failed to register windowclass;", "Error", 0 );
return -1;
}

hWindow = CreateWindowA( c_acWindowClass, c_acWindowClass, // Klassenname, Titelleiste
WS_OVERLAPPEDWINDOW, // Rahmen, etc.
50, 50, WINDOW_WIDTH, WINDOW_HEIGHT, // x-, y Koordinaten, Breite, Höhe
0, 0, hInstance, 0 ); // Parent, Menu, Instanz, lParam

if( FAILED( hWindow ) ) // Wurde das Fenster erstellt?
{
MessageBoxA( 0, "Failed to create window;", "Error", 0 );
return -1;
}

ShowWindow( hWindow, SW_SHOW ); // Fenster zeigen
UpdateWindow( hWindow ); // und zeichnen

while( WM_QUIT != sMessage;message ) // Solange Nachrichten empfangen, bis das Fenster die Nachricht zum schließen bekommt.
{
if( TRUE == PeekMessageA( &sMessage, 0, 0, 0, PM_REMOVE ) ) // Nachricht bekommen, keine Filterangabe, Nachricht löschen
{
TranslateMessage( &sMessage );
DispatchMessage( &sMessage );
}
}

return sMessage;wParam;
}

LRESULT CALLBACK WindowProc ( HWND hWindow, UINT uiMessage, WPARAM wParam, LPARAM lParam )
{
switch( uiMessage ) // Überprüfen welche Konstante, bzw. Nachricht wir empfangen haben
{
case WM_DESTROY: // Ist es WM_DESTROY( Bei beendigung eines Programmes, z;b. )?
{
PostQuitMessage(0); // Alles zum aufräumen vorbereiten

return 0;
}
}

return DefWindowProc( hWindow, uiMessage, wParam, lParam ); // Nachricht konnte nicht bearbeitet werden -> von "Windows" bearbeiten lassen.
}


So das war's!
Wie gesagt, je öfter ihr ein Fenster erstellt, desto einfacher wird euch das
erstellen des Codes fallen.

Es wird lediglich eine Klasse für unser Fenster erstellt, welche die Informationen von unserem Fenster hat, danach wird diese registriert. Jetzt wird unser Fenster erstellt und es werden die ganze Zeit über die Nachrichten, die das Fenster erhält, bearbeitet.

Falls es Fragen gibt, können diese mir gerne geschickt werden, und jenachdem
wie sinnvoll diese Frage ist werde ich diese hier nochmal hineineditieren.

Hardware Preisvergleich | Amazon Blitzangebote!

Videos zum Thema
Video Loading...
Ähnliche Themen zu [C/C++] Win32 API: Fenster
  • Win32.Brontok
    Hi, Leute hatte mir vorhin ein Video online anschaun wollen, wo irgend eine Nachricht von wegen Adobe und Java kam(kann mich nicht mehr genau entsinnen). Dann startete der Pc neu und nun kommt alle 15 Min folgende Meldung: ;;;xup~in/pic,21043548/fuck;JPG Ich hab dann erstmal, Spybot - Search & De [...]

  • [XP] Geister Fenster - klicke durch Fenster durch
    Hi Leute, ich hab seit einigen Tagen das problem, dass wenn ich z;B. im Explorer grad fröhlich mich durch die Ordner klicke und plötzliche alle klicks auf das Fenster das unter dem des Exploreres liegt gehen bzw wenn kein weiteres Fenster drunter ist ich auf den desktop klicke.. Es ist so also [...]

  • [JavaScript] Fenster steuert anderes Fenster
    Hey Rushler, ich habe quasi 2 Fenster (Hauptfenster + Steuerfenster). Nun möchte ich dass das Hauptfenster am Beamer ausgegeben wird und mein Steuerfenster am PC/Notebook. Alles kein Problem! Nun will ich den Inhalt vom Hauptfenster mit dem Steuerfenster beinflussen können z;B: habe ich [...]

  • Kann kein Video im großen Fenster abspielen. Geht nur im kleinen Fenster?!
    hi, ich kann aus welchen gründen auch immer kein video in einem großen fenster abspielen. habe auch alle videoprogramme neuinstalliert und geupdatet aber es hat nichts gebracht. benutze vlc mediaplayer aber seit n paar tagen funzt der nicht mehr. weiß wer woran das liegen kann?? jede sinnvolle [...]



raid-rush.ws | Imprint & Contact pr