c - Brugerdefinerede kontroller og Windows-meddelelser

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg lavede en brugerdefineret Splitter kontrol i ren Windows API. Det er lavet af 4 kontroller: hovedbeholderen, splitteren og de 2 ruder.


Nu var jeg nødt til at kigge ind i Windows-proceduren for at finde ud af, hvornår et af dets barnkontroller flyttede eller ændrede størrelsen, så jeg brugte SetWindowsHookEx . Jeg får de WM\_SIZE -meddelelser i min krogprocedure fint, men ingen WM\_MOVE -meddelelser bliver nogensinde fanget fra mine Splitters barnevinduer.


Jeg forsøgte at tilføje et børnevindue til en Groupbox (som jeg ved, er ikke den måde de skal bruges på) for at se om meddelelserne WM\_MOVE blev fanget af hookproceduren, og de var .


Så hvad mangler jeg her? Hvad skal jeg tilføje til min Splitter-vindueprocedure, så de WM\_MOVE s bliver sendt? Eller var min fejl et andet sted?


PS: SetWindowPos virker på disse børnevinduer, det er bare ikke at fange WM\_MOVE .


EDIT: Som anmodet her er den fulde kode i Splitter vinduesklasse: http://pastebin.com/Lgvb0Vfv[3]


Her er den del af koden, der betyder noget:


LRESULT WINAPI AnchorProc(int nCode, WPARAM wParam, LPARAM lParam) {
    CWPRETSTRUCT* theMessage = (CWPRETSTRUCT*)lParam;

    if (theMessage->message == WM\_MOVE) printf ("!");
}    


Nogle gange efter hovedvinduet 's WM\_CREATE :


SetWindowsHookEx(WH\_CALLWNDPROCRET,AnchorProc,NULL,GetCurrentThreadId());

// groupbox

HWND gb = CreateWindowEx(0,"button",NULL,BS\_GROUPBOX|WS\_CHILD,0,0,200,200,hwndMain,0,hInst,NULL);
HWND but = CreateWindowEx(0,"button",NULL,BS\_PUSHBUTTON|WS\_CHILD,0,0,40,40,gb,0,hInst,NULL);

// custom control

HWND split = CreateWindowEx(0,"FSplitterClass",NULL,WS\_CHILD,200,0,200,200,hwndMain,0,hInst,NULL);
HWND pane1 = (HWND)SendMessage(split,WM\_SPGETPANE,0,0);
HWND but1 = CreateWindowEx(0,"button",NULL,BS\_PUSHBUTTON|WS\_CHILD,0,0,40,40,pane1,0,hInst,NULL);

SetWindowPos(but, NULL, 1,1,0,0,SWP\_NOSIZE|SWP\_NOZORDER); // triggers WM\_MOVE
SetWindowPos(but1, NULL, 1,1,0,0,SWP\_NOSIZE|SWP\_NOZORDER); // doesn't

Bedste reference



  1. En vinduekrog er overkill her. Subclassing er meget mere effektiv.

  2. WM\_MOVE er kun genereret [4], hvis vinduet proceduren sender WM\_WINDOWPOSCHANGED beskeden til DefWindowProc. Hvis du ikke kan garantere det, er du ikke garanteret en WM\_MOVE besked. Lyt efter WM\_WINDOWPOSCHANGED.