?
Moin,
Ich schreibe gerade an einer Excel-Erweiterung, die per VBA in Excel eine Funktion registriert, die aus einer DLL einen nichtmodalen Dialog öffnet. Da ein nichtmodaler Dialog keine eigene Nachrichtenpumpe hat, muss ich mich, um Keyboard-Events behandeln zu können, per Windows-Hook in Excels Nachrichtenpumpe einhaken:
// In OnInitDialog()
m_hMessageHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, AfxGetInstanceHandle(), GetCurrentThreadId());
und
// In OnDestroy()
UnhookWindowsHookEx(m_hMessageHook);
GetMsgProc liest sich wie folgt:
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 ist. Glücklicherweise gibt es nur den einen Dialog, so dass Buchführung über mehrere Hooks nicht notwendig ist. Das Verfahren stammt hierher.
Das funktioniert auch annähernd - Tasten werden verarbeitet, ich kann mit Tab zwischen Knöpfen hin und her und sie auch mit der Leertaste drücken, aber wenn ich einen Knopf mit der Tastatur drücke, werden Mausevents von der gesamten Anwendung nicht mehr verarbeitet, bis ich einmal klicke. Das äußert sich darin, dass der Mauszeiger sich nicht mehr entsprechend der Window-Class und SetCursor-Aufrufe in WM_MOUSEMOVE-Handlern ändert (diese Events bekomme ich nicht mehr, dementsprechend werden die Handler nicht ausgeführt) und der erste Klick ignoriert wird, es sei denn, er ist genau auf den Knopf, den ich gerade per Leertaste gedrückt habe (allerdings ändert sich der Mauszeiger auch nicht entsprechend der Window-Class des Buttons, wenn er darüber schwebt). Das ist auch nicht auf mein Dialogfenster beschränkt; Excel kann seinen Schweizer-Kreuz-Zeiger auch nicht mehr setzen. Erst, wenn ich den Mauszeiger außerhalb aller mit der Anwendung verbundenen Fenster halte, verhält er sich wieder normal.
Ich bin da mit meinem Latein echt am Ende. Hat jemand von euch eine Idee, woran das liegen und wie man es beheben kann?