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.
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.
I just started looking at an MFC code of new project, I am assigened to and didn't had much coding done before in MFC. I can see that MFC document view architecture basically assigns all
display related tasks to view, Frame handles communication with windows, and document holds
all application related data.
But then I am wondering why MFC has SetTitle method in CDocument class and not in CFrameWnd class? On the other hand to set text in status bar you got method SetMessageText in CFrameWnd ?
Thanks In advance.
It is already said, that CFrameWnd has a SetTitle method.
But beside that: The reason is simple. A CFrameWnd can contain and serve more than one Document. Depending on the active docucment it should show the title of this determined CDoucment.
And each CDocument can have its own title.
CFrameWnd does have a SetTitle method.
Background
I am woefully inexperienced with MFC and C++.
I have a set of dialogs that all have a small section with the same set of controls and extremely similar code.
I would like to separate that small section of controls from all dialogs move the code from all the dialog classes into a single class.
Problem
I'm not sure how to go about it. All my ideas all seem to have their own problems because I am so inexperienced.
Could I make a super class these dialogs inherit from that creates the controls dynamically given an (x, y) and that hooks up all the connections and communicates the few specifics through virtual methods?
The problem is I don't know the specifics:
Where would the super class inherit from? (CWnd? CDialog?)
Where would I create the controls in the super class? (OnInit? Constructor?)
Where would I initialize the super class in its subclasses? (OnInit? Constructor?)
Would I just have two message maps? One for the super class and one for the sub class?
Are there any other pitfalls I should watch out for?
The small section that you want to reuse can be an ordinary modeless dialog, derived from CDialog. You can create its controls with the resource editor - just like any other dialog - so they won't have to be created dynamically. The trick is to turn off the dialog's titlebar style (in the resource editor) so it will not be visually apparent that this section is a separate dialog. It will blend right in with the parent dialog.
For each place you want to reuse this dialog just create it and place it on the parent dialog with (x, y) coordinates using SetWindowPos.
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.
I'd like some help on using MFC without the document/view architecture.
I created a project without doc/view support, Visual C++ created a CFrameWnd and a view that inherits from CWnd. I replaced the view inheriting from CWnd with a new view that inherits from CFormView.
However, when I run my program, after I close the window I get a heap corruption error.
If inside where the frame window handles WM_CREATE, you change the code to create the instance of CFormView with the "magic" id of AFX_IDW_PANE_FIRST, you'll find it becomes the view for the frame window. This is due to the behaviour of CFrameWnd::InitialUpdateFrame(), which will be called from within MFC. The MSDN page comments on this helpful little feature:
http://msdn.microsoft.com/en-us/library/ch3t7308.aspx
Since you want to use the dialog editor and you don't want the document/view architecture, then maybe a "Dialog based" application is what you need.
The problem is MFC's lifecycle management. The view declaration (created by Visual C++ wizard) is:
CChildView m_wndView;
I replaced the above code with:
CChildFormView m_wndView;
CChildView inherits from CWnd, CChildFormView inherits from CFormView. Both views were created by the wizard, but only CChildFormView uses the DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE macros.
Since m_wndView is being created in the stack, when MFC automagically calls delete I get the error.