PDA

View Full Version : Capturing keystrokes


johnman
25th June 2005, 00:31
Im working with winAPI or whatever it is called and c.
I have searched a little (actualy a lot) but i havent found any non hackish like solution. I want to make a dialog, and capture the keystrokes which are send to the dialog. I know how to do this with a normal window (using TranslateAccelerator) but with a dialog there is no mesage loop. Its also possible to use hooks, but thats something i like to avoid. There is also a MFC solution, but i dont use mfc.

Is it me or are the microsoft developpers totaly nuts. This is even worse then capturing some simple commandline output from a program, which is also awfull to do :mad:. You would expect that something basic like using a keyboard in a dialog wouldnt involve some rocket science level coding to work.

mpucoder
25th June 2005, 01:51
The designers aren't nuts. You just surrendered all control by using the library routine to handle your dialog box. Use CreateDialog() if you want more control. But you will have to supply the window procedure.
But - there is only one message loop per instance of an application (not one per window, and a dialog box is another window with a procedure to handle its messages) You will still need to determine, in the main message loop, what window the message is for before it is translated and dispatched. see the MSG structure. If you want to handle the keystrokes in the dialog procedure then you must disable translation of messages for that window (hdlg is the handle of the dialog window):
if (msg.hwnd != hdlg) {
if (!TranslateAccelerator( hWnd, ghAccel, &msg ))
{
TranslateMessage( &msg ) ;
DispatchMessage( &msg ) ;
}
}else{
DispatchMessage( &msg ) ;
}

edit: Also, if you are trying to capture keystrokes to a control in the dialog, remember that every control is also a window, with its own procedure. To trap those you will need to know the handle for the control - GetDlgItem() - and trap messages for that window in the message loop. Once the message is handed to DispatchMessage it will go directly to the control's procedure, not the dialog procedure.
You might want to write your own function to trap/process these in the same manner as TranslateAccelerator - ie return TRUE if the message was intercepted. Then call the function from the message loop.
if (!KeystrokeIntercept( &msg) {
if (!TranslateAccelerator( hWnd, ghAccel, &msg ))
{
TranslateMessage( &msg ) ;
DispatchMessage( &msg ) ;
}
}

johnman
25th June 2005, 02:44
You just edited intime :)

I also thought about changing the msg loop, but then i have to test for every msg if its one that i wanted to intercept. This is not the most elegeant way IMO. Every msg gets compared like 10 times when the dialog is active :(.

EDIT Maybe its not such a bad idea after all, im thinking about checking the parent hwnd and the hwnd itself and if it matches the dlg's hwnd ill check if its a keystroke. Thanks for the tip :goodpost:

stax76
25th June 2005, 03:48
But - there is only one message loop per instance of an application (not one per window, and a dialog box is another window with a procedure to handle its messages)

I believe there can be more loops in a multi threaded environment.

mpucoder
25th June 2005, 04:07
That is true, every thread has its own message queue.

johnman
25th June 2005, 15:34
I think i sort of solved it. Thx for the help :)

mpucoder
2nd July 2005, 17:31
I don't know if you're still working on this, but I came across something while looking for something else (as usual). It seems the dialog procedure, at least if modal, will process all messages for the thread. This is how it prevents the other windows from doing anything. But there is a way to hook it with SetWindowsHookEx

johnman
3rd July 2005, 01:54
I also often find solutions to old problems when im not looking for them anymore :)

I solved it by using CreateDialog insted of dialogbox. The problem is that i now have to disable the mainwindow when the dialog is showed (just like when dialogbox is used).

But what you said about using hooks is also possible, but in my first post i already indicated i rather not use any hooks.

I still find it weird that keystrokes arent supported normally with modal dialogboxes.