Where can I put my MFC Control initialization code - c++

I'm writing an MFC CEdit derived control, and I need to add initialization code once the control's m_hwnd is filled.
Which function can I override or which message can I handle to achieve this?
I tried with OnCreate, but It seems to work only for dialogs
EDIT:
The thing I'm initializing is the edit's cue banner
Thanks

Following Mark Ransom's hint, I finally found a better function to implement my intitialization. While overloading CWnd::SubclassWindow is a good idea, this function is not virtual and it would require a call from the subclass pointer. Calling SubclassWindow from a CWnd* would not work.
I found the function CWnd::PreSubclassWindow. It's virtual and is called just before SubclassWindow. Since m_hwnd is valid there, it is a good place to write the code I need.
In addition, the function is virtual and is called automatically by the framework so I don't need to worry about having the good pointer type

OnCreate doesn't work if the control is on a dialog, because the control is created before it can be subclassed to your window class - that happens in the dialog's DoDataExchange.
You can override CWnd::SubclassWindow and call the base method before your own code.

Depending what exactly you are initializing, you can override OnPaint(), or you can add your initialization code into the OnInitDialog() in the Dialog class that the control is contained in.

Related

Is there a message handler like 'OnPostCreate' for the MFC CWnd class?

I need to know how I can access to GetClientArea() when my CWnd is created. Obviously, you can't call it before it is created in the constructor and I just want to let the framework handle OnCreate() so when should I call it? Is there a OnPostCreate() handler or something similar I can use?
I assume you mean GetClientRect(), not ...Area().
You would need to get that rectangle every time the size of your window changes, right? Then the most appropriate place to do it is in
CWnd::OnSize

MFC: Notification after a control is created

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.

Client Area CMDIFrameWndEx

Good afternoon!
I'm updating my application from CMDIFrameWnd to CMDIFrameWndEx, and faced with the problem of client area of MainFrame.Before I had m_hWndMDIClient, and Subclass to it with my class. Now I have m_wndClientArea, and it brings me only headache! Now I can't Subclass. That's why I tried to do this:
mdiCliWnd_.Attach(m_wndClientArea.Detach());
mdiCliWnd_.Invalidate();
mdiCliWnd_.UpdateWindow();
m_wndClientArea.Attach(mdiCliWnd_.Detach());
But I can't even check how it work,because now I have a problem, that I should give CWnd of my client area to another functions, but m_wndClientArea is protected.
So my questions are : Can I subclass my own class in another way? If I can't, how I should use m_wndClientArea to give it to another functions?
What is the reason for that subclassing?
If it is just about drawing the background, use the new virtual function:
OnEraseMDIClientArea
Otherwise it is no problem to use the standard subclassing.
Because the HWND handle of the mdi client window is already attached to a MFC CWnd class object you can't use the MFC subclassing again.

CDockablePane prevent from closing

Can I hide close button from CDockablePane and prevent it from closing?
I cannot find CanBeClosed method in the headers that I've just googled.
I suppose I can use PreTranslateMessage to filter WM_CLOSE event. But I am not sure that this is correct solution.
I am not sure that the dockable pane is really closed, AFAIK it is only hidden when the close button is pressed.
Note: WM_CLOSE is not send via a a PostMessage, it is directly delivered to the window.
There are several ways.
Handle OnClose (WM_CLOSE) yourself in your derived CDockablePane
The virtual function OnPressCloseButton is called. You migh overwrite it.
In your parent frame class (usually your CMainFrame) handle AFX_WM_ON_PRESS_CLOSE_BUTTON, you receive this message with the lParam set with the pointer to the CDockablePane. Return non zero to prevent closing.
I think method 3. is the one you should use...
I'm not sure what version of Visual Studio you have, but, that method is defined and implemented in AfxBasePane.h. Since it's virtual, you need to override it to remove the button. Details are here on how to work with that method.

Call function automatically whenever I open a Dialog

I've got some code in my CMyView class. There I open a dialog with DoModal():
AnotherDialog dlg;
dlg.DoModal();
Now I want to automatically run a function. The poblem is, whenever I call dlg.DoModal(), the compiler waits till I close the Dialog window again, to continue running my code into the CMyView class. The function can also automatically be called into my AnotherDialog class.
Can anyone tell me, how I can automatically run a function whenever I open another Dialog?
AnotherDialog has a constructor, AnotherDialog::AnotherDialog(). Any function called from there will be called every time a dialog is created without providing arguments. If you add constructor overloads, each constructor can have different behavior, and it's up to you to make your code not confusing. (I.e. just be consistent)
If AnotherDialog is not your class, you may want to derive from it instead: class MyOtherDialog : public AnotherDialog. You can now have a MyOtherDialog::MyOtherDialog constructor which is called after AnotherDialog::AnotherDialog().
You could also add code to DoModal(), again in the existing class or a derived class.
The code in your view class is waiting because you are using the DoModal () method. By definition, DoModal is synchronous so it will wait for the dialog to close before continuing. Without knowing too much about your design, I would guess that you should use a "modeless" dialog invocation instead.