SetWindowLong() schlägt fehl
-
Zeig doch mal den Code. :p
-
Der Code sieht in etwa folgendermaßen aus (hab ihn gerade nicht parat):
LRESULT CALLBACK EditorShortcutProc(HWND Hwnd, UINT nMessage, WPARAM WParam, LPARAM LParam) { switch (nMessage) { case WM_NOTIFY: { LPPNHNOTIFY stNotify = (LPPNHNOTIFY) LParam; if (stNotify.hdr.code == PSN_KILLACTIVE) { SetWindowLong(Hwnd, DWL_MSGRESULT, TRUE); } } } }
Ich weiß nicht mehr genau den Typnamen (ich glaub LPPNHNOTIFY oder so ähnlich), aber die Nachricht PSN_KILLACTIVE kommt richtig an (genau dann, wenn OK oder Übernehmen geklickt wurde).
SetWindowLong() schlägt fehl (Return-Wert 0), und als Begründung liefert mir FormatMessage(), dass das Fensterhandle ungütlig ist.
Sagt mir bitte, dass ich etwas ganz schön falsch gemacht habe!
-
1.) Es sollte LPPSHNOTIFY stNotify = (LPPSHNOTIFY)lParam; heißen
2.) stNotify ist dann ein Pointer. Deswegen brauchst du den -> Operator: stNotify->hdr.code
3.) Hast du es mal mit stNotify->hdr.hwndFrom anstelle von Hwnd versucht (Vorschlag von WebFritzi)
-
- Ja genau.
- Ja das hab ich übersehen, danke. War aber natürlich nicht der Fehler.
- Das habe ich auch probiert: Dasselbe Ergebnis.
-
Setz vor Aufruf von SetWindowLong noch SetLastError(0); sonst stimmt der Fehler.
Nur weil SetWindowLong 0 zurückgibt, heißt das noch lange nicht das die Funktion fehlgeschlafen ist. Die gibt nämlich nur den alten Wert zurück. Und der kann auch 0 sein.
-
If the previous value of the specified 32-bit integer is zero, and the function succeeds, the return value is zero, but the function does not clear the last error information. This makes it difficult to determine success or failure. To deal with this, you should clear the last error information by calling SetLastError(0) before calling SetWindowLong. Then, function failure will be indicated by a return value of zero and a GetLastError result that is nonzero.
-
Hab ich bereits probiert, der Fehler tritt meiner Ansicht nach dennoch auf.
Denn: Wenn man bei PSN_KILLACTIVE SetWindowLong(Hwnd, DWL_MSGRESULT, TRUE) aufruft, sendet Windows (laut MSDN) die Nachricht PSN_APPLY, die ich aber leider nie kriege!
-
Nein! Gerade andersrum!
To receive this notification, a page must set the DWL_MSGRESULT value to FALSE in response to the PSN_KILLACTIVE notification message.
-
Sorry, es ist dabei immer egal gewesen, ob ich TRUE oder FALSE setze. Schon klar, dass man die Funktion mit FALSE aufrufen muss, um PSN_APPLY zu kriegen.
Nur ich bin mir ziemlich sicher, dass die Message auch bei einem Parameterwert FALSE nicht kam.
-
Auch mit FALSE wird PSN_APPLY nicht versendet, hier der korrekte Code, der nicht funzt:
LRESULT CALLBACK EditorShortcutProc(HWND Hwnd, UINT nMessage, WPARAM Wparam, LPARAM LParam) { switch (nMessage) { case WM_NOTIFY: { LPPSHNOTIFY pstNotify = (LPPSHNOTIFY) LParam; if (pstNotify->hdr.code == PSN_KILLACTIVE) { fprintf(Protokoll, "Killactive\n"); SetLastError(0); if (!SetWindowLong(Hwnd, DWL_MSGRESULT, FALSE)) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); MessageBox(NULL, (LPCTSTR) lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); LocalFree(lpMsgBuf); } } if (pstNotify->hdr.code == PSN_APPLY) { fprintf(Protokoll, "Apply\n"); return PSNRET_INVALID_NOCHANGEPAGE; } } } return true; }
SetWindowLong() gibt 0 zurück, Format Message sagt mir "Der Vorgang wurde bearbeitet"!
PSN_APPLY krieg ich dennoch nicht, dass heißt im Protokoll les ich nur "Killactive".
Wäre dankbar für Vorschläge!
-
Und wo returnst du TRUE?
To set a return value, the dialog box procedure for the page must call the SetWindowLong function with a DWL_MSGRESULT value set to the return value. The dialog box procedure must return TRUE.
-
Ich gebe am Ende der Funktion true zurück, das habe ich im Quellcode vergessen, sorry.
Das Problem besteht also immernoch!