15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


PreTranslateMessage(): WM_KEYDOWN by window?

David Morgenlender -- 75206.1070@CompuServe.COM
Tuesday, November 05, 1996

Environment:  VC++ 1.52, Win 95

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



Carl Gunther -- cgunther@ix.netcom.com
Thursday, November 07, 1996

David,

There may be two problems, rather than just one.

PreTranslateMessage() is not invoked when a modal dialog is
active, because such a dialog has its own message loop.
I discovered this while solving a similar problem in which I wanted to
trap a WM_KEYDOWN message while a modal dialog was active.
I solved this problem by overriding ProcessMessageFilter() in my
CWinApp-derived class.  This function gets called for all
messages when a modal dialog box exists.

As far as the problem of determining whether the message
comes from a control that is descended from you CFormView is concerned,
it seems to me that you could just search up the
chain of parent links from pMsg->hwnd to determine if the
CFormView object is an *ancestor* of the control window
(as opposed to only looking at the parent).

If for some reason there is not a direct chain of parent
links leading from the dialog control to the CFormView
instance, then perhaps you could maintain a list of
all dialogs spawned by the CFormView that you wish to
have considered as being related to it for purposes of your
message processing.  You could then check to see if
any of these is an ancestor of the pMsg->hwnd
passed to PreTranslateMessage().

For further information on the interaction between 
PreTranslateMessage(), ProcessMessageFilter(), and modal dialogs,
check out article Q126874 in the VC++ Knowledge Base (available
on the MSDN CD).

Carl

David Morgenlender wrote:
> 
> Environment:  VC++ 1.52, Win 95
> 
> 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

-- 
Check out the extensive Website of the Labor/Community Strategy Center
at http://www.igc.apc.org/lctr/

Check out the Website of Songs for Social Change
at http://globalvisions.org/cl/sfsc/

Copyright 1996 Carl E. Gunther.  Permission to reproduce this message
in text form for not-for-profit purposes freely granted provided that 
the preceeding copyright notice is retained.






| Вернуться в корень Архива |