MessageBox mit Mauscursor auf default button

By dose | January 16, 2007
Under: technical stuff, Uncategorized

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

Leave a Comment

Name:

E-Mail :

Subscribe :
Website :

Comments :