I am facing a problem where I am getting the device context as NULL in OnEraseBkgnd fucntion handler.
I have OnEraseBkgnd handler in my custom Tab control class which is inherited from CTabCtrl, I am also getting the same problem in DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) of another custom button control class which is inherited from CButton.
Device Context is getting NULL sporadically and not always. Please let me know if any idea why this device context would have become NULL.
Related
I'm new to MFC. I chose to create an office style MFC app through the wizard in VS2017. I now want to extend CMFCShellTreeCtrl so I created another class with that as the base class. The basics are fine. My issue is that I want to do something like:
whatever MyClass::FuncitonCalledAfterControlCreated(...)
{
SetFlags(GetFlags() | SHCONTF_NONFOLDERS);
ModifyStyle(0x0, TVS_CHECKBOXES);
}
But I'm having trouble figuring out what virtual function to override or am I supposed to do one of those message mapping things? I would guess that whatever it is, it would be common to all controls? Anyway, what would be the appropriate function?
TIA!!
If control is derived from CWnd a WM_CREATE is issued which can be directed to the control via a message map of:
ON_WM_CREATE()
And member function:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
If on a dialog resource the WM_CREATE won't occur. Some say you can use PreSubClassWindow but on a case of testing Create(), that call comes BEFORE the CreateWindowEx call so won't work for setting the TVS_CHECKBOX style. I didn't try a CDialog with a tree control and check the call stack.
In my CTreeCtrl derived class, I am acting on TVN_ITEMEXPANDED:
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, &OnTVNItemExpanded)
In the control's parent dialog, I also want to act upon the same notification, TVN_ITEMEXPANDED,
ON_NOTIFY(TVN_ITEMEXPANDED, IDC_ELEMENT_TREE, &OnTVNItemExpanded)
However, only the control class's OnTVNItemExpanded method is getting called, never my dialog's. I am using both breakpoints and seeing the desired behavior (or lack of desired behavior) in both methods to verify that only the control class's method is being called, not my dialog's method.
BUT, if I comment out the ON_NOTIFY_REFLECT from my CTreeCtrl-derived BEGIN_MESSAGE_MAP, then my dialog's method gets called!?!
Why can't the notification go both to my control and to my dialog?!?
ON_NOTIFY_REFLECT overrides ON_NOTIFY, but you can use ON_NOTIFY_REFLECT_EX instead which lets your callback decide if the message should go through to the parent or not.
See Message Reflection for Windows Controls for a more detailed explanation:
If, in your parent window class, you supply a handler for a specific
WM_NOTIFY message or a range of WM_NOTIFY messages, your handler will
be called only if the child control sending those messages does not
have a reflected message handler through ON_NOTIFY_REFLECT(). If you
use ON_NOTIFY_REFLECT_EX() in your message map, your message handler
may or may not allow the parent window to handle the message. If the
handler returns FALSE, the message will be handled by the parent as
well, while a call that returns TRUE does not allow the parent to
handle it. Note that the reflected message is handled before the
notification message.
I am developing an application using the MFC library and I am currently trying to prevent the user accidentally changing one of the combo box controls when they are scrolling the mouse wheel.
I am looking for a solution without deriving a new class from the CComboBox class and preventing the mouse scrolling there.
My understanding of the system is that Windows passes the WM_MOUSEWHEEL message to the Combo box control which handles it (scrolling the combo box) and then this is propagated up the chain of parent controls (so them to my CFormView etc.), which means I cannot prevent the scrolling by capturing the event in my form view.
Does anyone have a solution to this problem? Thanks in advance!
You can always derive a control from CComboBox and trap the WM_MOUSEWHEEL message in the control itself. Then simply use your new derived combo box in your form view.
If you don't want to create a derived class (perhaps it's too big a change for your project), you can subclass the combo box and trap the WM_MOUSEWHEEL there.
Override the PreTranslateMessage handler in the main window class and look for WM_MOUSEWHEEL messages. Compare the pMsg->hwnd handle in PreTranslateMessage handler with the combobox handle, if found, filter the messages away.
I'm writing a custom control derived from CWnd. I want to initialize a member variable (e.g: a memory dc) of my custom control class using its device context. Which is the correct way to do it? I guess device context won't be ready in the constructor. So what is the next option. Is it safe using the dc the OnCreate event? I'm probably in search of something like OnInitDialog, but its a custom control, not a dialog.
Update: I added the custom control to the parent dialog via resource editor. So there is no chance for getting WM_CREATE event as it has already been created before subclassing.
Device context can be created in OnCreate (WM_CREATE), after you call the base class' OnCreate method.
http://msdn.microsoft.com/en-us/library/dd318297(v=vs.85).aspx
From Programming Windows
I have a class derived from CDockablePane. I need to do something when the view is focused, so I handle WM_SETFOCUS and it all works nicely most of the time.
But when the pane is docked in Tabbed Document mode (TDI), and the user activates it, the WM_SETFOCUS is not called.
I used Spy and noticed the WM_MDIACTIVATE message is sent to the pane's parent window.
However if I handle WM_MDIACTIVATE inside the pane or inside the mainframe, it does not get called either.
Any ideas what I need to handle?
You may need to inherit the frame class and trigger the sending of a custom message to your views when WM_MDIACTIVATE is received by the frame.