Recently this question came up in the Microsoft MFC Newsgroup, where someone was porting an MFC app to pure-API, and wanted to know what the PreTranslateMessage equivalent was for the pure-API application. Essentially all you need to do is to put your code just before the TranslateMessage call, as shown in the code snippet below :-
// Main message loop
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(
msg.hwnd, hAccelTable, &msg))
{
//Put your PreTranslateMessage stuff here
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Or if you don’t want to do that, you could do this as well, though it seems less elegant :-
LRESULT CALLBACK WndProc(HWND hWnd,
UINT message, WPARAM wParam, LPARAM lParam)
{
//Put your PreTranslateMessage stuff here
switch (message)
{
case WM_COMMAND:
//...
case WM_PAINT:
//... etc.
default:
return DefWindowProc(hWnd,
message, wParam, lParam);
}
return 0;
}
The basic thing to remember is that, there is no message called PreTranslateMessage in Win32. PreTranslateMessage is something the MFC developers added so that we have an option to do something before a call is made to TranslateMessage/DispatchMessage; and incidentally, some Win32 Gurus like Joe Newcomer for instance, are quite vocal about their opinion that using PreTranslateMessage is bad style.
For interested people, here’s a legal (IMHO) usage for
PreTranslateMessagein MFC apps :-Keyboard messages/accelerators handling in MFC dialog based applications
Nish..
I am creating an ATL Composite control.There in the control class i couldn’t find any PreTranslateMessage.Can i use the same code there?I have a webbrowser control in that, and i am handling its events in Invoke method.
Hi Dreamz
Uhm, if you want to handle the keyboard, override
PreTranslateAccelerator.For the ATL control, you don’t really have direct access to the message handling loop. So you cannot use the technique I’ve mentioned in the blog entry [as far as I know, but I am not much of an ATL guy, so better double check this elsewhere].
Hi again Dreamz
In my previous reply, I assumed that your ATL control was in a DLL. If it is in an EXE, then you can override
PreMessageLoop.BTW I assume that you are using VC++ 7.1 🙂
Thanks Nish..
Mine is a DLL in VC++ 6.0 😦
Hi Nish,
I agree with first implementation of PreTranslateMessage pure WIN32 programming. I have a doubt on second implementation of PreTranslateMessage in WndProc. As of my knowledge WndProc procedure is called by DispatchMessage API. Before this usally TranslateMessage is called. Greatly appriciated if you clarify this.
Thanks
Choudam
Hi Choudam
Your interpretation is very correct. The second alternative is not really a pre-translate-handler, but basically for all purposes it serves a similar purpose, in the sense that we still have the option of preventing any specific-message handler from being called, prevent the default window procedure from being called and we can modify WPARAM and LPARAM if we chose to etc. I hope I’ve made myself clear?
Hi nish…
I’m using a MFC control in managed wrapper ( usercontrol ), the MFC control has keyboard accelrator handled in PreTranslateMessage(over written function ) .. but in .net this function is not at all called … what might be the problem ???
can u pls tell me ??
bye
Chetan.M
hi nish i use a ActiveX control of flash macromedia in a MFC Dialge i try hard to recive
WM_RBUTTONDOWN message from this control but i fail , what i want is to prevent only
the right click menu and replace it with any thing menu, messagebox,any thing
1- i use subclass ,but how to subclass a non MFC control ?
2- i try to use SetWindowLong with callback dosn’t work
please can you help but in details or example
In WTL world the Pretranslate is a virtual function in a Class called CMessageFilter
///////////////////////////////////////////////////////////////////////////////
// CMessageFilter – Interface for message filter support
class CMessageFilter
{
public:
virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
};
Which is then fired in the CMessageLoop class that creates the message pump of ATL/WTL apps like so.
// message loop
int Run()
{
BOOL bDoIdle = TRUE;
int nIdleCount = 0;
BOOL bRet;
for(;;)
{
while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!OnIdle(nIdleCount++))
bDoIdle = FALSE;
}
bRet = ::GetMessage(&m_msg, NULL, 0, 0);
if(bRet == -1)
{
ATLTRACE2(atlTraceUI, 0, _T(“::GetMessage returned -1 (error)\n”));
continue; // error, don’t process
}
else if(!bRet)
{
ATLTRACE2(atlTraceUI, 0, _T(“CMessageLoop::Run – exiting\n”));
break; // WM_QUIT, exit message loop
}
if(!PreTranslateMessage(&m_msg))
{
::TranslateMessage(&m_msg);
::DispatchMessage(&m_msg);
}
if(IsIdleMessage(&m_msg))
{
bDoIdle = TRUE;
nIdleCount = 0;
}
}
return (int)m_msg.wParam;
}
Modifying the main message loop does not help to monitor messages in a modal dialog box. The main message loop is never called. Somehow in MFC apps the PreTranslateMessage gives you access to modal dialog box messages, but I see no equivalent way to do it in API apps? Does anyone know how to get to the message loop for modal dialog boxes in an API app? You can see how to do it for MFC apps here:
http://support.microsoft.com/kb/100770
but how to do it for API apps, as the main message loop is never called.
Good afternoon, I was just on your website and filled out your contact form. The contact page on your site sends you these messages to your email account which is why you’re reading through my message right now correct? This is the most important accomplishment with any kind of online ad, making people actually READ your ad and that’s exactly what I just accomplished with you! If you have an advertisement you would like to blast out to thousands of websites via their contact forms in the U.S. or to any country worldwide send me a quick note now, I can even focus on specific niches and my pricing is very reasonable. Send a reply to: Phungcorsi@gmail.com