Convert simple MFC CView/CDocument/CSingleDocTemplate app to ActiveX control - c++

I have a fairly simple MFC app that just defines its own sub-classes of CDocument, CView and CFrameWnd and uses them via a CSingleDocTemplate to display the read-only contents of the document in a tree on the view. All very standard MFC MVC.
I now need to convert this app so that it works as an ActiveX control that I can then embed it within a larger application.
How should I go about this?
Is it possible to use the COleControl sub-class in place of the CFrameWnd sub-class in the CSingleDocTemplate? Or do I need to place the CFrameWnd sub-class within the COleControl some how?
Failing that, how can I use my existing CDocument\CView sub-classes within an ActiveX control?

Answering my own question: I found quite a few references to an old article about this, which used to be at http://www.microsoft.com/mind/0497/mfc.asp but has long since disappeared. :(
Fortunately though, the Wayback Machine still has a complete copy of it:
"Designing ActiveX Components with the MFC Document/View Model" by Steve Zimmerman, Microsoft Interactive Developer (April 1997)
Steve presents source code for two new classes:
CActiveXDocTemplate : a sub-class of CSingleDocTemplate
CActiveXDocControl : a sub-class of COleControl
which allowed me to use my existing CView and CDocument sub-classes in an ActiveX control.
(Thanks Steve wherever you are now)

Related

Should use CDialog or CFramewnd to build drawing application?

I'm reading Chapter "Drawing with GDI" in book "Programming Windows with MFC".
I saw that CFramewnd or Document/View are used in all examples of this chapter.
I think that maybe CDialog is not proper way to build drawing application.
So, my question is: should I use CDialog or CFramewnd or Docuemnt/View to build drawing application?
And could you give me some difference between CDialog and CFramewnd?
CDialog is intended to be used as the base class for dialogs - relatively shortlived windows to communicate relatively simple bits of information. There are a bunch of standard dialogs (e.g. File Open dialog) but for most information, you'd write your own and base that on CDialog.
So it's not intended as the main window for a normal application. Yet, if your application is a simple tool - say switch a single registry value from 0 to 1 - it may make sense to implement it as just a dialog. But a drawing application? That's not a dialog.

How to use MFC ListCtrl in SDI

I am really a beginner with MFC. I just want a few guidelines on how to use a ListCtrl in an SDI application. For example, getting input from the user and displaying it in the listctrl when a button is clicked. Please guide me.
In SDI application I would use CListView-derived class for main view. This class has been designed to be used in SDI/MDI apps and supports standard MFC document-view architecture. The CListView class internally uses CListCtrl, but it does automatic resizing and other handy things, you can also get direct access to embedded list ctrl by calling CListView::GetListCtrl() method that returns CListCtrl*.

MFC without document/view architecture

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.

Choosing between a Dialog Based Vs SDI Projects

I am new to MFC well not entirely new but wanted to ask experts on this forum as why one would choose one project over the other. I hope this is not a stupid question as I am relatively new to MFC.
Thanks so much
Chose based on what template your application fits best into:
Single Document Interface (SDI) - if your application needs to work with only 1 document or data object or data set at a time
Example: notepad.exe
Multiple Document Interface (MDI) - if your applicaiton needs to work with multiple documents or data objects or data set at a time
Example: Visual Studio
Dialog Based - for anything else.
Example: Calculator
No matter what you chose, you still have the same functionality available to you in the end and you can cusotmize it in any way. So you aren't limiting yourself to anything you start with.
All variants come with CWinApp which is the base class for which you derive your MFC applications.
With a dialog based application you start with a CDialog as well. With an SDI application you start with CMainFrame, CDocument, and CView as well.
If you select an SDI project you get a whole Model-View-Controller framework included.
You get a document class (inheriting from CDocument) which ideally should hold all of the data, and a view class (inheriting from CView) to do with the display.
You get given a hosting frame with a menu already attached, and there are functions you can override to save and load to file.
If you have a dialog based application, then you get one dialog. That's it. Of course, this dialog can spawn off others, but the application essentially consists of a dialog.
If you're developing a small application that just does one task, a dialog application is appropriate, because you don't need the overhead.
If you are developing an application where the user will be loading, editing and saving data, then the SDI path would be more appropriate.
Having answered your question, I'd politely ask if there was a compelling reason why you were choosing MFC over Windows Forms. I believe that MFC was an excellent technology for its day, but the Visual Studio suite offers more advanced tools (if you're prepared to go down the .NET path).
If a "document" is the right metaphor for your application, use SDI or MDI. (Single of only one document can be open at a time, Multiple if more than one.) When you think about it, the document metaphor really isn't appropriate for most applications.

How can I place a MFC CFormView inside a CDockablePane?

How can I place a MFC CFormView inside a CDockablePane which was introduced in the VS 2008 MFC Feature Pack?
Check the BCGSoft Samples for doing this with a cview. The class names are a little different but its more or less the same stuff since they provided CDockablePane to Microsoft.
I couldn't find such samples in MFC Feature Pack samples.
All projects containing CFormView are :
TasksPane
TabControl
TabbedView
StatusBarDemo
SetPaneSize
MenuSubSet
But in any of the projects, CFormView is not embedded in CDockablePane.
There is a sample of the feature pack that does this.
However, what I do is the following: I made a CDialog-derived class that I put in the DockablePane. Then I make a CFormView-derived class and make an instance of that a member variable of the dockable pane. Every function that I'm interested in (most likely UpdateView() or whatever it's called), I forward to the CDialog-derived class. That way I can sidestep the difficulties of shoehorning the doc/view structure into my application and still get the benefits.
Actually there are a few ways of doing this.
If you derive your own CFameWnd class and then put an instance of that class in the CDockable pane you now can put whatever type of framework that you want inside of that CFrameWnd derived class.
The trick is to make sure that you are doing the creation in the correct order. If you try to call it to early then your internal views will never be created.
Probably this cab be a clue.
http://www.codeproject.com/KB/toolbars/sizecbar.aspx
Although it doesn't use CDockablePane, concept behind it is same.
I didn't try CDockablePane and CFormView work like the one explained in the page yet, but by taking a glance at it, I feel that things are similar.