FAQs about VC and MFC
Select from http://www.microsoft.com/china/MSDN/library/archives/technic/faq/MFCfaq01.asp
Microsoft Corporation
Version 5.0, January May 15
How to throw an exception derived from cuserexception?
When I try to catch an exception in a derived class, I get the following error "error c2039: 'classcmyexception': is not a member of 'cmyexception' 'classcmyexception ': undeclared identifier 'iskindof': cannot convert parameter 1 from 'int * 'to 'const struct cruntimeclass *"
You must use the declare_dynamic () and implement_dynamic () macros to dynamically create your cmyexception class. The catch macro wants to get the runtime information about the thrown class.
Must the exception class be derived from cuserexception?
No, "user" in cuserexception only refers to the user-generated exception. It is a common misunderstanding to regard it as the only exception you can derive.
How to Create a CDC class from HDC?
Sometimes Windows API will give you a DC handle, and you can create a CDC class through it. For example, drop-down list, combo box, And button. With HDC, you will receive the draw message. The following describes how to convert HDC to a more familiar CDC.Program. You can also use this technique to convert any other MFC class and Windows handle.
Void mydlist: drawitem (lpdrawitemstruct lpdrawitem) {CDC mydc; mydc. Attach (lpdrawitem-> HDC); // insert other requiredCode. // If you do not separate the handle, it will be deleted, leading to problems. Mydc. Detach ();}
Another method is to call the fromhandle method of the CDC class: CDC * PDC = CDC: fromhandle (lpdrawitem-> HDC );
It is not clear which method is better-fromhandle () may have fewer errors, because it does not require you to detach the handle.
How can I read a 256-color bitmap file from a disk?
Currently, MFC does not support directly reading and displaying Dib files and BMP files. However, there are a variety of applications that can illustrate how to complete the task. The first example is the MFC sample program diblook. Sample multdocs provides the sameSource codeTo read and display the DiB and BMP files. The other two examples included in VC ++ are the dibview program and showdib program in the SDK package.
How can I change the size of a view?
Generally, you can call the movewindow () function to change the window size. In an application developed using the MFC Library, the view is a subwindow surrounded by the Framework Window. To change the size of a view, you can call the getparentframe () function to obtain the pointer to the frame window, and then call the movewindow () function to change the size of the parent window. When the size of the parent frame window changes, the view automatically changes the size to adapt to the parent window.
How can I change the size of a cformview?
For more information, see the basic knowledge about visual C ++.ArticleQ98598 using cformview in SDI and MDI applications. Basically, in the class derived from the cformview class, you must override the oninitialupdate () function (). Other questions about how to create cformview can be found in this article.
Declare the following function in clikethisview: Virtual void oninitialupdate (); In clikethisview code, the function is as follows: void clikethisview: oninitialupdate () {// make the window the same size as the Main Dialog Box cformview: oninitialupdate (); getparentframe ()-> recalclayout (); resizeparenttofit (/* false */);}
How to use a new view of a document template?
In the application created with Appwizard, you have two options: change the derivation relationship of the current view or create a new view and use both the New View and the original view in your MDI program.
To create a new view, you can use classwizard to derive a new class from cview. After a new class is created, use the new view or modify the view provided by Appwizard. The steps are the same.
Modify the header file of the View class to rename all references to the cview class to the name you want. The classes in this example are derived from cscrollview. Generally, this step includes changes to the class. The class will be derived from the following method:
Class cmyview: Public cscrollview
Modify the implementation file of the class to rename all references to the cview as your desired name. This includes changing the statements in the implement_dyncreate row:
Implement_dyncreate (cmyview, cscrollview)
Change the Statement of the in_message_map row:
Begin_message_map (cmyview, cscrollview)
Change all other cviews to cscrollview.
If the view you modified is generated by Appwizard, no more modifications are required. If you are creating a new view, find the call to the adddoctemplate () function in the cwinapp: initinstance () function. The third parameter of adddoctemplate () function is runtime_class (csomeview). Instead of csomeview, you can change the current view to a new view. In the MDI application, you can add the second adddoctemplate () function call to use the multi-view type and change runtime_class (csomeview) to runtime_class (cmyview ).
For more information, see the related article switching views in a single document interface program in q996.
How can I change the background color of a view?
You can modify the background color of a cview, cframewnd, or cwnd object by processing the wm_erasebkgnd message. See the following section:
Bool csampleview: onerasebkgnd (CDC * PDC) {// set the required background color brush cbrush backbrush (RGB (255,128,128 )); // save the old brush cbrush * poldbrush = PDC-> SelectObject (& backbrush); crect rect; PDC-> getclipbox (& rect ); // erase the required region PDC-> patblt (rect. left, rect. top, rect. width (), rect. height (), patcopy); PDC-> SelectObject (poldbrush); Return true ;}
The following method is used to solve the problem:
Hbrush dlgtest: onctlcolor (CDC * PDC, cwnd * pwnd, uint nctlcolor) {Switch (nctlcolor) {Case ctlcolor_btn: Case ctlcolor_static: {PDC-> setbkmode (transparent );} case ctlcolor_dlg: {cbrush * back_brush; colorref color; color = (colorref) getsyscolor (color_btnface); back_brush = new cbrush (color); Return (hbrush) (back_brush-> m_hobject) ;}} return (cformview: onctlcolor (PDC, pwnd, nctlcolor ));}
How to get the current view?
The best way is to pass the view as a parameter. If you cannot do this, but you are sure that it is the current active document and current active view, you can also get this view. For details, see the Visual C ++ Article q108587 "get current cdocument or cview from anywhere".
Simply put, use: (cframewnd *) afxgetapp ()-> m_pmainwnd)-> getactivedocument () and: (cframewnd *) (afxgetapp ()-> m_pmainwnd )) -> getactiveview ()
To get the document and view. A good method is to encapsulate them in static functions of your cmydoc and cmyview classes and check whether they belong to the correct runtime_class. However, if this view is not currently activated or you are running OLE to activate it locally, it will fail.
How to create multiple views in a document?
Cdoctemplate: createnewframe () function to create an additional view of the document in the mfc mdi application. To call this function, you must specify a pointer to the cdocument object (the document for which a view will be created) and a pointer to the frame window from which properties can be copied. Generally, the second parameter of the function is null.
When the application calls the createnewframe () function, the function creates a framework window and a view in the window. The Framework Window and its view types are determined by the Document Template (cdoctemplate) associated with the document specified by the createnewframe () function call.
The chkbook MFC sample program in Visual C ++ also demonstrates how to create additional frameworks and views for the document. Check the cchkbookapp: opendocumentfile () function in the chkbook. cpp file.
Another example using the createnewframe () function is the multview sample program.
The createnewframe () function creates a framework and a view, not just a view. If the createnewframe () function does not fully meet your needs, you can refer to the source program of the createnewframe () function to learn the steps required to create a structure and view.
How to get all views in the MDI program?
You must use some functions not recorded in the document:
Cdocument: getfirstviewposition (); // doccore. CPP cdocument: getnextview (); // doccore. CPP cmultidoctemplate: getfirstdocposition (); // docmulti. CPP cmultidoctemplate: getnextdoc (); // docmulti. CPP
You also need to deal with the cwinapp member m_templatelist.
Note: The version 4.0 has changed. Now there is a class named cdocmanager that can help you display all views and documents. For more information, see MFC internals.
How to Create a cscrollview class with mouse pull
Download autosv. lzh from the msmfc library on CIS. This program tells you how to implement an auxiliary message loop to manage the mouse activity, and provides hooks to customize the code. This is a free software.
Must I use the view/document structure?
MFC does not necessarily require you to use the document/view structure. View hello, MDI, and helloapp examples-they do not use that structure. Most MFC features can be used in non-document/view applications. However, when you do not need a document/view structure, you do lose some features, such as print preview and many OLE features.
How do I get the current document?
For details, see "how to get the current view? "Chapter.
When is a document destructed?
In the SDI Program, the document is deleted after the program exits. In the MDI program, the document is deleted when the last view related to the document is closed. To use this document in SDI and MDI at the same time, you should delete the data of this document in the deletecontents () function of the virtual function, instead of in the destructor.
How to create multiple documents?
To support additional document types, you can create and register additional cmultidoctemplate objects in the cwinapp derived class. This method has been described in the multdocs sample program. The general steps for adding an additional document type to the MFC program are as follows:
Use Appwizard to create a new document class and View class.
Add a new resource string in the resource editor to support the new document class. For more information about the document sample string format, see "How to understand document sample strings ".
Use the resource editor to add additional application icons and menu resources. Note that each ID of these resources must be the same as the document template string ID created in step 2. This ID is used by the cmultidoctemplate class to identify resources related to the additional document type.
In the initinstance () function of the application, another cmultidoctemplate object is created and registered using the cwinapp: adddoctemplate () function. For example:
Cmultidoctemplate * pdoctemplate2 = new cmultidoctemplate (idr_doc2type, runtime_class (cdoc2), runtime_class (cmdichildwnd), runtime_class (cview2); adddoctemplate (pdoctemplate2 );
Finally, add the custom serialization and drawing code to your new document and View class.
How do I get a list of open documents?
The following section describes how to obtain a pointer list for all documents created using the cdoctemplate object.
In the following section, cmyapp is derived from cwinapp. The m_templatelist variable is a cptrlist object. It is a member variable of cwinapp and contains a list of all document template pointers. The document template functions getfirstdocposition () and getnextdoc () are used to iterate in the Document Template list to obtain each document template.
Void cmyapp: getdocumentlist (coblist * pdoclist) {assert (pdoclist-> isempty (); position Pos = m_templatelist.getheadposition (); While (POS) {cdoctemplate * ptemplate = (cdoctemplate *) m_templatelist.getnext (POS); position pos2 = ptemplate-> getfirstdocposition (); While (pos2) {cdocument * pdocument; if (pdocument = ptemplate-> getnextdoc (pos2 ))! = NULL) pdoclist-> addhead (pdocument );}}}
Two common member functions of the cdoctemplate class are not described in the reference manual or online help. However, these common member functions are defined in the cdoctemplate class and provide simple support for searching before and after opening the document list.
These functions are as follows:
Function virtual position getfirstdocposition () const;
Call this function to obtain the location of the first document associated with the template in the open document list. The returned position value can be used repeatedly by the getnextdoc member function.
Function virtual cdocument * getnextdoc (Position & rposition) const;
Rpostion is the position value returned by calling the getnextdoc or getfirstdocposition function. The value cannot be null. Call this function to iterate in all open documents. This function returns the document identified by rposition and sets rposition to the position value of the next document in the list. If the last document in the list is retrieved, rposition is set to null.
Note that this is only valid for mfc3.2 or earlier versions. For mfc4.0 versions, see the following:
Void cmyapp: dosomethingtoalldocs () {coblist pdoclist; position Pos = getfirstdoctemplateposition (); While (POS) {cdoctemplate * ptemplate = getnextdoctemplate (POS ); position pos2 = ptemplate-> getfirstdocposition (); While (pos2) {cdocument * pdocument; If (pdocument = ptemplate-> getnextdoc (pos2) pdoclist. addhead (pdocument) ;}} if (! Pdoclist. isempty () {pos = pdoclist. getheadposition (); While (POS) {// call the cdocument function (cdocument *) pdoclist for each document. getnext (POS)-> updateallviews (null );}}
How can I prevent my program from creating a new document at startup?
Before the processshellcommand function in the initinstance of the program, add: cmdinfo. m_nshellcommand = ccommandlineinfo: filenothing.