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.
Related
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.
Qt is cross platform c++ Gui Library.Code once and compile for different Platform. Let's for instance, I have compiled a Project(decent text editor with few tool bar) or any such program for Windows(x86).
Statement 1: The Program.exe entry point will be WinMain.
Statement 2: The Text editor and tool bar will created using "CreateWindow" win32 api. Qt have its own class to implement but to ask OS(Windows) for creating a tool bar or text editor, Program exe interface with OS(Windows). OS understand what it know it does not know anything about Qt class,so to create tool bar or text editor program have to use win32 api.
Statement 3: All event processing( button click, mouse click) will handles using windows messeging system.
Note: It may seem i am viewing every thing with win32 api glass on my understanding.
Correct. The WinMain implementation is provided by the Qt library.
Half correct. The top-level windows are created using CreateWindow. Child widgets, such as a non-toplevel toolbar are Qt's own widgets and are opaque outside of your application. They are exposed only via the accessibility APIs. This allows you to create more widgets than Windows would be able to deal with. A million child widgets is doable, if not particularly fast.
Correct - there's no other way. Of course Qt immediately translates native messages into QEvent instances and dispatches them internally to various QObject instances. In Qt-land, all events must be received by a QObject instance.
You're incorrect in your assertion that winapi has anything to do with the kernel. Winapi is implemented by a bunch of user-space DLLs. You could implement those DLLs yourself. Those DLLs themselves call into the kernel using the native api. That's the API actually exposed by the kernel to the user space.
In Win32 API we have 2 functions called 'SetProp' and 'GetProp' to set and get the property of a window identified by HWND
SetProp:
http://msdn.microsoft.com/en-us/library/ms633568%28VS.85%29.aspx
I have 2 applications, one coded with Qt, the other coded with Win32 API. I need some kind of flag so the application in Win32 can recognise the application in Qt.
Are there any equivalent functions in Qt to set and get the properties for QMainWindow?
I would just use the HWND of the QMainWindow returned by QWidget::winId() in use with the two Windows functions that you mentioned in your question.
Somewhat related... here are ways to access other properties that are associated with a HWND of a QMainWindow:
Most are covered by the Window Flags
Window Flags Example
Qt::WindowFlags
QWidget::setWindowFlags()
and Widget Attributes...
QWidget::setAttribute()
Qt::WidgetAttribute
This should yield your answer:
About using an undocumented class in Qt
(Using setProperty or the undocumented class if you like being risky).
http://doc.qt.digia.com/qt/qobject.html#setProperty
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)
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.