Callback-Funktion WndProc Problem
-
Hallo!
Ich möchte in meinem Programm mehrere Fenster verwenden. Deshab muss ich in der Callback-Routine WndProc erst mal herausfinden, von welchem Fenster die Nachrichten kommen. Deshalb habe ich für jedes Fenster eine Extra Callback-Routine geschrieben, die dann von der WndProc aufgerufen wird: in diesem Beispiel nur mal für ein Fenster:LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (hwnd == hwndMain) return WndProc_Main (hwnd, msg, wParam, lParam); //Callback Routine für das Hauptfenster } LRESULT CALLBACK WndProc_Main (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: { HWND hwndButton1 = CreateWindow (TEXT("button"), //Button erzeugen TEXT("up"), WS_CHILD | BS_PUSHBUTTON |WS_VISIBLE, 0,200, 100,20, hwnd, (HMENU) 1, GetModuleHandle(NULL), NULL); } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: capPreview(hwndVideo,FALSE); capDriverDisconnect(hwndVideo); PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }Die untere ist die eigentliche Callback Funktion. Leider bekomme ich den Button nicht gezeichnet. Wenn ich die if Abfrage weglasse und einfach return WndProc_Main (hwnd, msg, wParam, lParam); stehen lasse, dann bekomme ich meinen Button. Das lässt vermuten, dass die if Bedingung nicht erfüllt ist, aber wenn ich das alles komplett weg lasse, dann bekomme ich erst gar kein fenster! also muss die callback-Routine aufgerufen werden
-
Welche WndProc hast du denn für deine WindowClass angegeben?
Meiner Erfahrung nach braucht man nicht für jeden Button und jede Scrollbar eine eigene WndProc. Wofür denn? Die Ereignisse wie Buttonklick u.ä. kann (sollte) man in der Haupt-WndProc abarbeiten.
Z.B kannst du mit
*EDIT*Fehler, unten korrigiert
*EDIT
steuern, was bei einem Klick auf den Button passiert.gruß
Martin
-
Ich glaube, ich habe da was falsch verstanden. Der Handle, der in die WndProc übergeben wird, stammt nicht vom Parent-Window der Buttons, etc., sondern von dem jeweiligen Steuerelement selbst?
Also hieße das, wenn ich 2 Fenster habe, diese über das selbe WndProc laufen.
Dann müsste aber nach "case WM_CREATE:" abgefragt werden, von welchem Fenster die Nachricht stammt, oder?
das würde bedeuten:case WM_Create:
if (hwnd == hFenster1)
{
Erzeuge Steuerelemente für erstes Fenster
}if (hwnd == hFenster2)
{
Erzeuge Steuerelemente für zweites Fenster
}ist das richtig so?
-
case WM_COMMAND: if (lParam == (LPARAM)hWndButton){ if (LOWORD(wParam) == BN_CLICKED){ // do something } }Hi, wie du siehst, hab ich etwas wichtiges vergessen. Man prüft bei WM_COMMAND mit lParam == (LPARAM)hWndButton, welches Steuerelement die Msg geschickt hat.
Scheinbar hab ich dich falsch verstanden. Das Handle hWnd in der WndProc ist schon das Handle des Windows selbst. Du hast ja 2 Fensterklassen wndclass1 und wndclass2. Bei jeder gibst du ja eine WndProc an. Wenn du nun 2x die gleiche angibst, solltest du theoretisch mit hwnd == hWindow1 und hwnd == hWindow2 abfragen können, welches Window die Nachricht bekommen hat und dementsprechend reagieren.
Nur wenn du in deinem Beispielcode für das MainWindow als WindowProc WndProc_Main() angegeben hast und für das 2. Fenster WndProc, dann wird in der kurzen WndProc die If-Abfrage nie true werden, da hier das übergebene Handle immer das vom 2. Fenster ist, und nie das vom 1.
Sorry für den Fehler. Probiers mal einfach aus, beide in eine WndProc zu packen.
gruß
Martin
-
Es ist wohl sinnvoll, für jedes Fenster (also das Fenster im eigentlichen Sinne) eine eigene WindowClass zu erstellen, aber so funktioniert's jetzt auch:
case WMCreate:
if (wParam == hFenster1)
{
Erzeuge Steuerelemente für erstes Fenster
}das Verwunderliche ist, dass der Handle in wParam steht.
-
Nee, vergesst das Bitte! war falsch!