Some common problems in VC and MFC
Microsoft Corporation Version 5.0, May 15, 97 How to throw (THROW) Abnormally derived from CuthException? When an exception I try to capture (catch) a derived class, I get the following error "error C2039: 'classCMyException': is not a member of 'CMyException' 'classCMyException': undeclared identifier 'IsKindOf': can not parameter from 1 convert 'int * 'to' const struct cruntimeclass * "You must make your CMYEXCEPTION class dynamically by using declare_dynamic () and import_dynamic () macro to make your CMYException class dynamically. The Catch Macro hopes to obtain runtime information about being thrown. Is an exception class be derived from CUSEREXCEPTION? No, "User" in CUSEREXCEPTION refers only to the exception generated by the user. The only anomalies you can derive are common misunderstandings. How to build a CDC class from HDC? Sometimes the Windows API will give you a DC handle, you can build a CDC class through it. For example: a drop-down list, a combo box, and a button. You will receive a drawing message via HDC. Below is a block that converts HDC to your more familiar CDC. You can also use this trick to use any other MFC class and Windows handle. Void myodlist :: DrawItem (LPDrawItemstruct LPDrawItem)
{
CDC MYDC;
Mydc.attach (LPDrawItem-> HDC);
// Insert this other required code here.
// If you don't separate your handle, it will be deleted, resulting in a problem.
mydc.detach ();
}
Another way is to call the fromHandle method of the CDC class:
CDC * PDC = CDC: fromHandle (LPDRAWITEM-> HDC);
It is not clear which method is more superior - using fromHandle () errors may be less because it does not require you to separate (DETACH) handles. How to read 256 color bitmap files from disk? Currently, MFC does not support direct reading and display DIB files and BMP files. However, there are many sample applications to explain how to complete this task. The first example is the MFC sample program DIBlook. Sample MultDocs reads and displays DIB files and BMP files with the same source code provided by Diblook. Examples included in the other two VC are DibView programs and showDIB programs in the SDK package. How to change the size of a view? Typically, you can call function moveWindow () to change the size of the window. In applications developed with MFC libraries, the view is a sub-window surrounded by the frame window. To change the size of a view, you can get the pointer of the Frame Window by calling the function getParentFrame (), then call the function moveWindow () to change the size of the parent window. When the parent frame window changes the size, the view will automatically change the size to adapt to the parent window. How to change the size of a CFormView? To learn more about, you can see the article about Visual C basics Q98598 "Using CFormView In SDI and MDI Applications". Basically, in the class derived from the CFormView class, you must overwrite the function onInitialupdate (). Other details of CFORMVIEW can be obtained from this article. Declare the following functions in class CLIKETHISVIEW: Virtual void OnInitialupdate ();
In the code of the CLIKETHISVIEW, the function is as follows:
Void CLIKETHISVIEW :: OnIitialupdate ()
{
/ / Make the window as the main dialog
CFORMVIEW :: OnInitialupdate ();
GetParentFrame () -> RecalcLayout ();
ResizeParentTofit (/ * false * /);
}
How to use a new view of a document template? In applications created with AppWizard, you have two options: changing the derived relationship of the current view or create a new view and use a new view and the original view at the same time in your MDI program. In order to create a new view, you can derive a new class with ClassWizard by CVIEW. When the new class is created, the steps of the two are the same as the view provided by AppWizard after the new class or modified. Modify the header file of the view class to rename all references to the CView class for the name you want. The class in this example is derived from CScrollView. Typically, this step includes changes to the class, and the view class will be derived from the following: Class CMYVIEW: PUBLIC CSCROLLVIEW Modify the implementation file for the view class to change all the reference to CVIEW to the name you want. This includes statements IMPLEMENT_DYNCREATE that line changed: IMPLEMENT_DYNCREATE (CMyView, CScrollView) will BEGIN_MESSAGE_MAP the line of the statement read:. BEGIN_MESSAGE_MAP (CMyView, CScrollView) and all other CView into CScrollView if you change the view by AppWizard Generated, then there is no need to modify it. And if you create a new view, first find the call to the AddDDOCTemplate () function in the cwinapp :: initInstance () function. The third parameter of the addDoCtemplate () function is Runtime_Class (CsomeView), with CMYVIEW instead of CsomeView, can change the current view to a new view. In the MDI application, you can increase the second addDoctemplate () function call to use the multi-view type to change the runtime_class (cmyView). To get more information, please refer to Q99562 Related Articles "Switch Views In A Single Document Interface Program". How to change the background color of the view? You can change the background color of CView, CFrameWnd, or CWND object by handling WM_ERASEBKGND messages. Please see the following block: BOOL CSAMPLEVIEW :: OneRaseBkGnd (CDC * PDC) {
/ / Set the brush of the desired background color
Cbrush backbrush (RGB (255, 128, 128);
/ / Save the old brush
CBRUSH * POLDBRUSH = PDC-> SelectObject (& BACKBRUSH);
CRECT RECT;
PDC-> getClipbox (& Rect); // Erase the required area
PDC-> Patblt (Rect. Wid, Rect.top, Rect.width (), Rect.Height (), PATCopy;
PDC-> SELECTOBJECT (POLDBRUSH);
Return True;
}
And I use the following method to solve this 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 can't do this, you are confident that it is currently activating the document and the current activation view, you can also get this view. For details, see Visual C Articles Q108587 "Get Current Cdocument Or CView from Anywhere". Simply mention, use:
((Cframewnd *) AFXGETAPP () -> m_pmainwnd) -> getActiveDocument ()
with:
((CframeWnd *) (AFXGetApp () -> m_pmainwnd) -> getActiveView ()
Come get documents and views. A good way is to package them in the static function of your CMYDoc and CMYVIEW class, and check if they belong to the correct russime_class. However, if this view is not the current activation view or you activate the OLE locally, this will not succeed. How to build multiple views in a document? CDOCTemplate :: CreateNewFrame () Function Creates an additional view of the document in the MFC MDI application. In order to call this function, you want to specify a pointer to the CDocument object (a document that will be established to establish a view) and a pointer to the frame window that can be copied from it. In general, the second parameter of the function is NULL. When the application calls the function creageNewFrame (), the function creates a frame window and the view within the window. The type of frame window and its view is determined by the document tangent (CDOCTemplate) associated with the CreateNewFrame () function calls the specified document. The CHKBOOK MFC sample program in Visual C also demonstrates how to establish an additional framework and view for documents. Check the cchkbookapp :: OpenDocumentFile () function in the chkbook.cpp file. Another example of using a function createNewFrame () is a MultView sample program. The CreateNewWFrame () 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 steps necessary to establish a structure and view for the source engine of the CreateNewWFrame () function. How do I get all the views in the MDI program? You must use a function in some documents: cdocument :: getFirstViewPosition (); // doccore.cpp
CDocument :: getNextView (); // doccore.cpp
CMULTIDEMPLATE :: getFirstDocPosition (); // docmulti.cpp
CMULTIDEMPLATE :: getNextdoc (); // DOCMULTI.CPP
You also need to deal with CWINAPP members M_TemplateList. Note: Changes in MFC version 4.0. There is now a class called CDOCManager to help you show all views and documents. Please refer to "MFC INTERNALS" to get more detailed information. How to build a CScrollView class that can be pulled with a mouse to 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 provide hook to customize the code. This is a free software. Do you have to use a view / document structure? The MFC does not necessarily require you to use the document / view structure. View Hello, MDI and HelloApp examples - they have no use of that structure. Most MFC features can be applied in non-document / view applications. But when you don't have to use a document / view structure, you really lose some features, such as printing previews and many OLE features. How to get the current document? Please refer to "How to get the current view?" Chapter. When is the documentation? In the SDI program, the program is deleted after the program exits. In the MDI program, the document is deleted when the last view associated with this document is turned off. In order to use this document simultaneously in SDI and MDI, you should delete the data of the document in the virtual function deleteContents () function, not in the destructor. How to build multi-document? To join the support of the additional document type, you can create and register additional CMULTIDECTEMPLATE objects in the CWINAPP derived class. This method has been explained in the MultDocs sample program. The general steps to add an additional document type to the MFC program: Use AppWizard to create a new document class and view class. Add new resource strings to support new document classes with resource editor. To know more about the document model string format, see "How to understand the document sample string". Add additional application icons and menu resources with resource editing. Note that each of these resources must be the same as the ID of the document template string created in step 2. This ID is used by the CMULTIDEMPLATE class to identify resources related to the attached document type. In the initInstance () function of the application, another CMULTIDEMPLATE object is created and registered with the cwinapp :: adddhemplate () function. For example: cmultidoCtemplate * pdoctemplate2 = new cmultidoCTemplate (idR_doc2type, runtime_class (cdoc2),
Runtime_class (cmdichildwnd), runtime_class (cView2));
AddDDOCTemplate (pdoctemplate2);
Finally, add customized serialization and drawing code to your new document and view class. How to get a list of open documents? The following program segment indicates how to get the pointer list of all documents established with the CDOCTemplate object. In the following block, CMYAPP is derived from CWINAPP. Variable M_TemplateList is a cptrlist object that is a member variable of CWINAPP, which contains a list of all document template pointers. Document Template Functions getFirstDocPosition () and getNextdoc () are used to get iteratively to get every document template in the document template list. 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 = ptembly-> getnextdoc (pOS2))! = null)
PDOCLIST-> Addhead (pdocument);
}
}
}
In the reference manual or online help, there is no explanation of the public member functions of two CDOCTemplate classes. However, these public member functions are defined in the CDOCTemplate class and provide simple support for the front and rear searches before and after opening the document. These functions are as follows: Function Virtual Position getFirstDocPosition () const; calling this function to get the location of the first document associated with the template in the open document list. The value returned Position can be repeatedly used by the GetNextDoc member function. Function Virtual CDocument * getnextdoc (position & rposition) const; rpost is the position value returned by the getNextDoc or getFirstDocPosition member function. This value cannot be NULL. This function is called to be iterated in all open documents. This function returns the position value of the document identified by the RPosition and sets the rposition to the next document in the list. If the retrieved is the last document in the list, rposition will be set to null. Note that this is only valid for the MFC3.2 or lower version, please refer to the MFC4.0 version: void cmyapp :: DOSMETHINGTOALLDOCS ()
{
Coblist pdoclist;
Position POS = getFirstDonommentemplatePosition ();
While (POS)
{
CDOCTemplate * Ptemplate = getNextDocTemplate (POS);
Position POS2 = PTEMPLATE-> getFirstDocPosition ();
While (POS2)
{
CDocument * pdocument;
IF (pDocument = ptembly-> getnextdoc (POS2))
PDOCList.Addhead (pdocument);
}
}
IF (! pdoclist.isempty ()) {
POS = pdoclist.getheadposition ();
While (POS)
{
/ / Call the cDocument function for each document
(CDocument *) PDOCLIST.GETNEXT (POS))
-> UpdateAllViews (NULL);
}
}
How to make my program do not create a new document when starting? Add: cmdinfo.m_nshellcommand = ccommandlineinfo :: filenothing