MessageBox mit Mauscursor auf default button
Ich bin unlängst vor dem Problem gestanden, dass ich eine Software, welche sich über ein Diktiergerät
steuern lässt (im Prinzip ein USB HID mit Zusatzknöpfen), entsprechend erweitern sollte, sodass der
Mauscursor auch in Dialogen entsprechend immer auf dem Default-Knopf platziert wird.
Das bietet den Vorteil, dass man beim schnellen Arbeiten z.B. bei der Frage, ob man ein Diktat speichern will,
nur noch die linke Maustaste drücken muss, um zu bestätigen, und nicht jedesmal mit der Trackpad-Kugel
hinfahren muss.
In selbst definierten Dialogen geht das ja relativ einfach mit SetCursorPos
. Was aber macht man bei Standard Windows-Dialoge, welche man mit MessageBox
generiert? Hier hat man ja normalerweise keinen Einfluss auf die Gestaltung des Dialogs. Aufmerksame Leser meines Blogs werden sich an meinen Artikel zur Anpassung von Standarddialogen erinnern, wo diese Problematik ja schon einmal besprochen wurde. Windows bietet ja glücklicherweise die Möglichkeit, mittels SetWindowsHookEx
und einer CBTProc-Funktion
die Erstellung von Messageboxes zu hooken und damit auch zu beeinflussen.
Konstruiert man also nun so einen Hook, kann man die HCBT_ACTIVATE
Notification abfangen. Zu diesem Zeitpunkt sind bereits alle Controls positioniert und gesetzt. Daher kann man dann mittels GetWindowLong
mit dem GWL_STYLE
Parameter abfragen, welcher Button default ist. Um das Ganze für alle möglichen Buttons in einer Schleife realisieren zu können, muss man die IDs der einzelnen Buttons wissen:
#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
Es reicht also, zwischen IDOK
und IDNO
zu loopen.
Interessanterweise kann sich die Position des MessageBox-Fensters auch nach HCBT_ACTIVATE
noch ändern, sodass man mittels SetWindowPos
die Fensterposition auf eine marginal andere Position als die aktuelle ändern muss, damit das Fenster dort bleibt, wo es ist.
Dann einfach mit SetCursorPos
den Mauscursor auf das Default-Button platzieren und fertig.
Das Sourcecode dafür gibt es hier