000
02.08.2010, 23:10 Uhr
0xdeadbeef
Gott (Operator)
|
Moin,
Ich bin mir bewusst, dass der Titel etwas verwirrend ist, aber das Problem lässt sich nicht in einer Zeile umschreiben. Es geht um Folgendes:
Ich schreibe an einer Excel-Erweiterung, die einen nichtmodalen Dialog vorhält und auf Anfrage anzeigt (i.e., Knopfdruck im Excel-Sheet). Da nichtmodale Dialoge keine eigene Nachrichtenpumpe haben, muss ich mich, um Tastaturereignisse abzufangen, in Excels Pumpe einhooken (bzw. in GetMessage/PeekMessage):
C++: |
// In OnInitDialog()
m_hMessageHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, AfxGetInstanceHandle(), GetCurrentThreadId());
|
in OnDestroy entferne ich den Hook wieder. Es gibt in der DLL nur einen Dialog, daher ist Buchführung über verschiedene Hooks glücklicherweise nicht nötig. GetMsgProc verhindert die Weiterleitung für den Dialog bestimmter Nachrichten:
C++: |
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { LPMSG lpMsg = (LPMSG) lParam;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(nCode >= 0 && wParam == PM_REMOVE && lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST && theApp.m_dDialog->IsDialogMessage(lpMsg)) { lpMsg->message = WM_NULL; lpMsg->lParam = 0; lpMsg->wParam = 0; }
return CallNextHookEx(theApp.m_dDialog->m_hMessageHook, nCode, wParam, lParam); }
|
Wobei theApp das örtliche von CWinApp abgeleitete Objekt und theApp.m_dDialog ein Zeiger auf den Dialog ist. Das funktioniert auch annähernd korrekt - ich komme mit Tab zwischen den Unterfenstern hin- und her, Leertaste drückt Buttons etc., aber es gibt einen Haken: Nachdem ein Button per Tastatur gedrückt wurde (per Maus ist unproblematisch), kriege ich bestimmte Events nicht mehr. So hat etwa ein Unterfenster des Dialogs einen besonderen Mauszeiger in der Window-Class, der nicht mehr gesetzt wird, wenn der Mauszeiger über dieses Unterfenster (oder daraus weg) geht. Auch Excel setzt seinen Schweizer-Kreuz-Zeiger nicht mehr, wenn der Mauszeiger über einer Tabelle schwebt - es kommt scheinbar kein WM_SETCURSOR-Event. Tooltips tauchen nicht mehr auf (ich kriege kein WM_MOUSEMOVE-Event).
Das richtig Verrückte aber ist, dass diese Symptome nur bis zum ersten Mausklick anhalten. Klicke ich irgendwohin, tut der erste Klick nichts - keine Buttons werden ausgelöst, keine Comboboxen ausgeklappt, nichts - aber danach funktioniert alles, wie es soll.
Ich helfe mir jetzt, indem ich per SendInput einen Mausklick sende, sobald ein Button gedrückt wurde. Das funktioniert, aber der Hack ist mir entschieden zu dreckig für eine Produktionsversion. Kennt jemand von euch das Problem oder hat eine Idee, woran es liegen könnte?
Ich stehe da echt auf dem Schlauch, und Google ist nicht sonderlich hilfsbereit. -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra Dieser Post wurde am 02.08.2010 um 23:12 Uhr von 0xdeadbeef editiert. |