Just wondering where is best to put functionality in an MFC application that is triggered when the whole window is resized. I was thinking mainfrm but I couldn't seem to capture any OnSize messages...
Can someone tell me what I am doing wrong?
Can someone tell me what I am doing wrong?
You didn't include any interesting details, so here are a few guesses (because of course the mainframe normally gets sent WM_SIZE messages...):
You didn't set up your message handler properly. Perhaps you forgot the message map entry?
You have an existing handler in place for WM_WINDOWPOSCHANGED that fails to call the default window procedure, thereby preventing WM_SIZE messages from being sent.
I am guessing that you are using the Multiple Document Interface ( MDI ) application type. In this case, you should capture the WM_SIZE message in each of your views - the classes you have derived from CView.
Related
I'm using and improving on an open source MFC work-alike library called FFC. Sometimes the library associates the wrong window handle to a dialog object, which means the C++ object can't be found later when the correct handle is looked up. In particular, this is happening when the application opens its root window, which is a dialog that it opens with a call to DoModal.
In its DoModal function, the FFC library uses a... "surprising" way to attach the handle to the dialog object. It stashes the "this" pointer in a global variable and hooks a function to be called on all window messages before calling the DialogBox function. This hook function it registered in term assumes the handle from the first message it receives is the handle for the window in the global variable, and attaches that handle to it.
Sometimes, this works. Often - and I don't know if it's because of intrusive things done by the McAfee scanner on my work computer, or because my program starts from a console window, or something else - many unrelated messages will be captured before a message actually meant for the modal dialog comes through.
At first I thought it was because FFC wasn't making sure the message it looks for is "WM_CREATE". I added this check, but it didn't fix the problem. Turns out one or more of the spurious messages are also WM_CREATE messages! Before it gets the one for the real dialog, the first WM_CREATE it receives is a handle for a window with blank window text and rectangle 0,0-0,0.
So is this really the correct or canonical way to get the handle for a modal dialog? It seems unreliable. (Note that because the dialog is modal, you can't use the return value from CreateWindowEx because the DialogBox function doesn't return until the modal dialog is closed.) Is this really how MFC does it? Is there a better way? Could I associate some data with the dialog or look for data that should be associated with it to make sure I have the right window handle? (For instance checking the template parameter passed to the dialog box call, if I can get that back from the handle somehow.)
I am sure this is published in books, but MFC sets a windows hook (WH_CBT) and then looks for the HCBT_CREATEWND code in the hook to marry the C++ object to the HWND.
I have derived the CHtmlEditCtrl, and want to be able to react when the control gets or looses its focus. However the standard MFC OnSetFocus and OnKillFocus handling routines are not being called.
I presume it has something to do with the control actualy being a wrapped ActiveX control.
I have tried giving it the WS_EX_CONTROLPARENT and WS_TABSTOP styles on creation as suggested here, but it did not help.
I found somewhere that I should make my control the event sink for HTMLDocumentEvents2, but I would rather avoid that if possible.
EDIT: Spy++ says I should be getting WM_PARENTNOTIFY and WM_MOUSEACTIVATE messages. However, my Derived Class receives absolutely no messages. I tried it with OnSize and OnCreate too. No message whatsoever is being sent. Any idea?
I am working on a MFC C++ application. I was working on a dialog that has SystemMenu property set to FALSE, so it does not have the ability to maximize. I want to handle the double-click message on the title bar. How can I do that?
EDIT:
I hope this time it will be clear for everybody. I have a dialog that does not have system menu (and system buttons or icon). When the user double-clicks the titlebar of that dialog, I want the program to call function x();.
Technically, you would have to handle WM_NCLBUTTONDBLCLK and check if the double click occurred in the caption area of the window, possibly by sending it WM_NCHITTEST and testing that the return value is HTCAPTION.
(Update: As JohnCz rightfully points out, sending WM_NCHITTESTis not actually necessary, since WM_NCLBUTTONDBLCLK already carries its result in wParam.)
Then you would only have to send WM_SYSCOMMAND with SC_MAXIMIZE in wParam to the window to maximize it.
In practice, however, it will not achieve much if your dialog box is not ready to handle size changes and layout its controls accordingly. This feature did not come out of the box in MFC last time I checked.
I think there is some kind of confusion here:
Frédéric Hamidi
You are correct, handling WM_NCLBUTTONDBLCLK message is the right way to go, however it is no necessary to call HitTest, since WM_NCLBUTTONDBLCLK message delivers hit information that MFC framework translates in the WM_NCLBUTTONDBLCLK handler.
Victor,
What is exactly that you are trying to achieve by handling WM_NCLBUTTONDBLCLK message?
Maybe there is some other way to fulfill your requirement once you make it clear to us.
The fact that you do not have system menu, does not prevent your app from receiving non-client area messages.
I am writing a fairly simple wrapper around Win32 controls/dialogs/windows.
The issue I have is that ListBox's and ComboBox's seem to behave rather differently.
In the base Widget class that I am inheriting from, I override the existing WNDPROC for the control and then handle messages in the new WNDPROC, primarily promoting them to boost::signal events.
The issue is that, while ComboBox's WndProc receives the CBN_SELCHANGE - as expected - ListBox's WndProc does not receive the LBN_SELCHANGE command.
I realize that the dialog/window that owns the control will likely receive this, but I've kind of gone down this rabbit hole already and it feels like a pretty neat solution. Need I back out and have the owners of the controls handle the WM_COMMAND messages (and from there promote it to an event on the control itself).
This is a learning exercise, so please don't remind me about MFC or comment on the value of doing this.
Notification messages are typically sent to a control's parent. Presumably all the windows (i.e. both parent windows and controls) are using the same window procedure? In this case the usual solution is: in the notification handler in your window procedure check if the notification came from the current window. If it did, raise an event; if it didn't resend the message back to the control it came from (where it will be raised as an event).
In .Net there is a feature called KeyPreview. How can I do this in WinApi. Maybe I don't necessarily need this but my hWnd has WM_KEYDOWN, but it does not receive it when my Text Box has focus. How can I achieve this?
Thanks
*Using pure Win32API...
is there an alternative, how could I handle the Text Box's WM_KEYDOWN?
You can try subclassing the edit control. Either "instance subclassing", to trap messages for only one window, or "global subclassing" to trap messages for all windows of that class (in your application, not system-wide).
The example here (http://msdn.microsoft.com/en-us/library/ms997565.aspx) shows how to subclass an edit control and trap the WM_GETDLGCODE message -it wouldn't be that difficult to change it to WM_KEYDOWN.
You may have problems previewing the keys used for dialog commands, e.g. TAB or RETURN, as they may be trapped higher up the food chain. You may need to look at changing WM_GETDLGCODE as well.
If you use MFC you can look at PreTranslateMessage (I am not sure regarding to PreTranslateMessage, but you can easily to verify whether to enough to override the function).
You can set keyboard hook.
There is no such a possibility in WinAPI to catch the messages belonging to controls in window procedure of parent window (although some exceptions exist).
What .NET basically does is that it routes all messages of all controls including their parent window to a single window procedure. Then it's easy to catch all the messages in one place.
This is your way to go - to set window procedures of all the controls into single procedure and there to catch all the messages
As window procedure also receives hwnd parameter, it's then also easy to determine the control to which the message belongs.