Glenn W Munroe wrote:
The problem I was having with the KeyUp/KeyDown events was, as you
indicated, caused by the -dialogui option. Neither the 'KeyDown' nor the
'Char' event gets fired when -dialogui is used,

That depends on the control and what it returns from the WM_GETDLGCODE message sent to it when it has focus by the IsDialogMessage() call in the message pump. For example WM_CHAR messages are sent to Textfields.

nor do they when an
accelerator table is defined.

With -dialogui => 1 all KeyUp/Char/KeyDown messages should be sent to a control, except for ones corresponing to the defined accelerators in the accelerator table, as they have been processed as accelerators.

[snip]

The only thing that bugs me a little is the need for the
Hook call to WM_SETFOCUS. I'll have a play to see if that is necessary for
my purpose.

You'll need it if you need any accelerators processing when no other control has the focus. It wouldn't be difficult to add an onGotFocus event to the Win32::GUI::Window class

As for the RFE, I think that this functionality is definitely needed, but
I'm still not 100% sure that accelerators are the best way to achieve it. It
looks like they'll do the job, but I'm a bit uncomfortable changing the way
the Windows GUI is supposed to work, if, in fact, they were only designed to
work for top-level windows (I had a hunt on MSDN, but couldn't find the
relevant bit). I'll have a play with these new techniques and think about
that later.

I think we may be talking a little at cross purposes: I did not mean that MS think accelerators should only be used for top level windows; I meant that Win32::GUI::Dialog() was coded to only use accelerators from top level windows.

MSDN doen't say a lot about accelerators (that I've found) - they are processed with in a message pump by the TranslateAccelerator() function.

A typical message pump looks like (pseudocode)

while msg=GetMessage() {
        if TranslateAccelerator(hwnd, acc, msg)
                continue;

        TranslateMessage(msg);
        DispatchMessage(msg);
}

TranslateAccelerator() takes a set of accelerator definitions (acc) and a message from the thread's message queue, and if the message is a key message for the accelerator definition TranslateMessage send a WM_COMMAND message to the window passed to it (hwnd) and returns non-zero to indicate that the message has been processed and should not be passed on to TranslateMessage/DispatchMessage.

Win32::GUI::Dialog() get hwnd and acc for TranslateAccelerator by traversing the window hierarchy from the window to which the event is being sent, up until it finds the parent top-level window.

It would be relatively easy to stop at each level, see if there was an accelerator Table object associated with each window and if so try to ue it, bailing out the first time TranslateAccelerator returns non-zero.

Regards,
Rob.

Reply via email to