Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PreTranslateMessage(): WM_KEYDOWN by window?

958 views
Skip to first unread message

David Morgenlender

unread,
Nov 5, 1996, 3:00:00 AM11/5/96
to

I want to use CWinApp::PreTranslateMessage() to test for all
occurrences of WM_KEYDOWN; it should discard the message, unless a
control in the main CFormView has the focus. The problem is that I
can't figure out any way to determine if the CFormView has the focus!
This app implements nested sub-dialogs. If the focus is on a control
within a nested sub-dialog, the message must be discarded.

pMsg->hwnd does not have the hwnd of the CFormView of CFrameWnd. I
assume it has the hwnd of the control with the focus.

I considered setting a flag in my CFormView::PreTranslateMessage();
but this is called AFTER CWinApp::PreTranslateMessage().

GetActiveWindow() doesn't help, because of the nested sub-dialogs; if
the focus is in a nested sub-dialog, GetActiveWindow() returns the
CFormView. I need to determine that the nested sub-dialog is in
control.

GetFocus() returns the control itself, not the parent dialog. This is

presumably essentially the same as using the pMsg->hwnd as described
above.


So how can I do this?

I've considered looking for the parent of pMsg->hwnd. But this would
need some special case code, because in some cases there's an
invisible window between the control & it's logical parent. (There
are good technical reasons for this.)

I could put PreTranslateMessage() code in each window for which I want
the message discarded & not in CWinApp::PreTranslateMessage(), i.e.
I'd distribute the special processing, instead of having it in one
central place. As far as I can see this should work; but it's UGLY!

[ BTW, in case anybody is interested, here's why I need to deal with
this ... this is a 16-bit app written using VC++ 1.52c. The app
implements Win95-style help when running under Win95. I see no reason
these problems wouldn't exist for a 32-bit app though. I specify the
WS_EX_CONTEXTHELP style for all windows except the main frame window;
I can't specify it for the main frame window, since the
WS_EX_CONTEXTHELP style disables the ability of the window to be
minimized! Don't ask me why, but the MSDN CD says this is by
design!!! There's a bug in MFC where the F1 key with Win95-style help
enabled generates double-help, once for the F1 keyboard accelerator
handler via MFC, the other by Win95. The MSDN CD suggests discarding
the F1 keydown in CWinApp::PreTranslateMessage(); but if I do this, I
don't get any help for the CFormView window, because it doesn't get
Win95-style help!!! ]

Any suggestions???

Dave


S. McAdams

unread,
Nov 5, 1996, 3:00:00 AM11/5/96
to

David Morgenlender wrote:
>
> I want to use CWinApp::PreTranslateMessage() to test for all
> occurrences of WM_KEYDOWN; it should discard the message, unless a
> control in the main CFormView has the focus. The problem is that I
> can't figure out any way to determine if the CFormView has the focus!
...
> GetFocus() returns the control itself, not the parent dialog. This is
>

You should be using GetFocus() to determine if the desired control has
input focus. Your only problem is communicating it to your
CWinApp-derived class. This can be solved by adding a CWnd* member that
is initialized to 0 by the CWinApp-derived class' ctor. When the
FormView is created, it can store the control's CWnd* in the new member,
then when PreTranslateMessage() is called it can GetFocus() and compare.

You'll probably want to reset the member when the FormView loses focus
and set it when it gains focus, this way dialogs etc will continue to
work, but this depends on what your app really needs. -steve

Jussi Jumppanen

unread,
Nov 5, 1996, 3:00:00 AM11/5/96
to

David Morgenlender (75206...@compuserve.com) wrote:
> I want to use CWinApp::PreTranslateMessage() to test for all
> occurrences of WM_KEYDOWN; it should discard the message, unless a
> control in the main CFormView has the focus. The problem is that I
> can't figure out any way to determine if the CFormView has the focus!
> This app implements nested sub-dialogs. If the focus is on a control
> within a nested sub-dialog, the message must be discarded.
[Snip..]

> GetFocus() returns the control itself, not the parent dialog. This is

> presumably essentially the same as using the pMsg->hwnd as described
> above.

Once you have the hwnd of the control use the GetWindowWord API call to
get the parent window of the control.

Jussi Jumppanen (jus...@ca.com.au)
Author of: Hardware Digital Logic Analyers for Windows
Zeus for Windows, Win32 (Brief, WordStar, Emacs) Text Editor
"The C/C++, Java, Pacal, Fortran and integrated development environment"
Home Page: http://ourworld.compuserve.com/homepages/jussi/


pazi

unread,
Nov 6, 1996, 3:00:00 AM11/6/96
to

ju...@sydney.DIALix.oz.au wrote:
>Once you have the hwnd of the control use the GetWindowWord API call to
>get the parent window of the control.

Or just hWndParent = GetParent(hWnd). Looks nicer :)

-zi


David Morgenlender

unread,
Nov 6, 1996, 3:00:00 AM11/6/96
to

"S. McAdams" <smca...@mhss.com> wrote:

>David Morgenlender wrote:
>>
>> I want to use CWinApp::PreTranslateMessage() to test for all
>> occurrences of WM_KEYDOWN; it should discard the message, unless a
>> control in the main CFormView has the focus. The problem is that I
>> can't figure out any way to determine if the CFormView has the focus!

>...

>> GetFocus() returns the control itself, not the parent dialog. This is
>>
>

>You should be using GetFocus() to determine if the desired control has
>input focus. Your only problem is communicating it to your
>CWinApp-derived class. This can be solved by adding a CWnd* member that
>is initialized to 0 by the CWinApp-derived class' ctor. When the
>FormView is created, it can store the control's CWnd* in the new member,
>then when PreTranslateMessage() is called it can GetFocus() and compare.
>
>You'll probably want to reset the member when the FormView loses focus
>and set it when it gains focus, this way dialogs etc will continue to
>work, but this depends on what your app really needs. -steve

I ended up using the MFC GetFocus() & GetParent() functions in
PreTranslateMessage(). I had thought this wouldn't work for me,
because I have some nested windows, so the immediate parent wasn't
always the window I needed to test against; but in fact, the nested
windows aren't relevant here, so this works ok.

But I do have another problem ... PreTranslateMessage() is not called
for modal dialogs. I'm well aware of the fact that modal dialogs have
their own message loops; but I didn't make the connection until it
bit me here. So now I have to implement a workaround. This is made
tougher by the fact that in some cases modal dialogs are nested. I've
got to either hook into ProcessMessageFilter() or use modeless dialogs
acting like modal dialogs. I actually have a class to implement these
"pseudo-modal" dialogs; but my gut feel is to not use this approach;
for one thing it means changing MANY dialogs; secondly, there were
some cases where the inactivation of the parent window did not cause a
full simulation of a modal dialog, i.e. some grandparent windows could
be activated. I never chased down the cause of this, because the UI
changed and these symptoms no longer appeared. But I'm still leary of
this approach.

So I'm thinking of hooking into ProcessMessageFilter(). All my modal
dialogs use a common base class, which is derived from CDialog. I'm
thinking of having this class maintain a pointer to the deepest modal
dialog in my class which is derived from CWinApp. My
ProcessMessageFilter() will be able to invoke the "current" modal
dialog. The CDialog-derived class will maintain a list of previous
dialog pointers, so they can be unwound as modal dialogs are
destroyed.

Dave

David Morgenlender

unread,
Nov 6, 1996, 3:00:00 AM11/6/96
to

ju...@sydney.DIALix.oz.au (Jussi Jumppanen) wrote:

>David Morgenlender (75206...@compuserve.com) wrote:
>> I want to use CWinApp::PreTranslateMessage() to test for all
>> occurrences of WM_KEYDOWN; it should discard the message, unless a
>> control in the main CFormView has the focus. The problem is that I
>> can't figure out any way to determine if the CFormView has the focus!

>> This app implements nested sub-dialogs. If the focus is on a control
>> within a nested sub-dialog, the message must be discarded.
>[Snip..]
>

>> GetFocus() returns the control itself, not the parent dialog. This is

>> presumably essentially the same as using the pMsg->hwnd as described
>> above.
>

>Once you have the hwnd of the control use the GetWindowWord API call to
>get the parent window of the control.
>

>Jussi Jumppanen (jus...@ca.com.au)
>Author of: Hardware Digital Logic Analyers for Windows
> Zeus for Windows, Win32 (Brief, WordStar, Emacs) Text Editor
>"The C/C++, Java, Pacal, Fortran and integrated development environment"
>Home Page: http://ourworld.compuserve.com/homepages/jussi/
>

Actually, I ended up using the MFC GetParent() function, since I
already had a CWnd*; but this is essentially the same as what you
suggested. I had thought this wouldn't work for me, because I have

S. McAdams

unread,
Nov 6, 1996, 3:00:00 AM11/6/96
to

David Morgenlender wrote:

>> All my modal dialogs use a common base class,
>> which is derived from CDialog.

Suggest you add a PreTranslateMessage() to your base class. There are
two PreTranslateMessage() members, one in CWinApp and the other is a
virtual in CWnd. No guarantees but this ought to catch it. -steve

David Morgenlender

unread,
Nov 7, 1996, 3:00:00 AM11/7/96
to

"S. McAdams" <smca...@mhss.com> wrote:

I've implemented a ProcessMessageFilter() which processes the messages
for modal dialogs. My CDialog-derived class maintains a chain of
modal dialogs, so nested modal dialogs can be handled. This seems to
be working. Actually, all help functionality on both Win 3.1 & Win95
seems to be working!!! Hopefully, it will stay this way!

Dave


0 new messages