当前位置:网站首页>MFC basic knowledge and course design ideas

MFC basic knowledge and course design ideas

2022-06-10 16:55:00 Liu, come down and bang me

introduction

         This article is dedicated to providing MFC Knowledge about , So that we can better understand MFC How to use . The introduction will be divided into the following sections :MFC Understanding of initial documents 、MFC The framework we use understands 、MFC Advanced use of 、MFC Problems and solutions I encountered in the process of using .

MFC Understanding of initial documents

        MFC There are two files that we often need to use in the initial file of , Other files can be ignored for the time being , We hardly use . One is MFCApplicationView, For short View class , One is MFCApplicationDoc, For short Doc class .

        Doc Class is Document Abbreviation , It is used to deal with the relationship between programs and computer files , We read 、 This class is used to save files , If we want to get the read image information , It's all through Doc Class to read . For example, the following code snippet we often use .

	CMFCApplication1Doc* pDoc = GetDocument();//  Get document 		//
	long	lSrcLineBytes;		// Number of bytes per line of image 
	long	lSrcWidth;      // The width and height of the image 
	long	lSrcHeight;
	int     lpSrcBitCount;       // Bit depth of image 
	LPSTR	lpSrcDib;		// Pointer to the source image 	
	LPSTR	lpSrcStartBits;	// Pointer to the source pixel 
	lpSrcDib = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHObject());//  lock DIB
	if (!lpSrcDib) return;
	/*
	if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)//  Judge whether it is 8-bpp Bitmap 
	{
		   AfxMessageBox(L" I'm sorry , No 256 color bitmap !");//  Warning 
		   ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());//  Unlock 
		   return;									// return 
	 }										// Judge whether it is 8-bpp Bitmap , If not, return to 
	 */
	lpSrcStartBits = pDoc->m_dib.GetBits(lpSrcDib);			//  find DIB Starting position of image pixel 	
	lSrcWidth = pDoc->m_dib.GetWidth(lpSrcDib);					//  Get the width of the image 		
	lSrcHeight = pDoc->m_dib.GetHeight(lpSrcDib);					//  Get the height of the image 	
	lpSrcBitCount = pDoc->m_dib.GetBitCount(lpSrcDib);                    // Get image bit depth 
	lSrcLineBytes = pDoc->m_dib.GetReqByteWidth(lSrcWidth * lpSrcBitCount);		//  Calculate the number of bytes per line of the image 
///

         among GetDocument() The function is View Class , Its function is to extract the previous Doc Class has already read the good content ( Read directly through the pointer Doc Class ) And then pDoc->m_dib yes CDib class ,CDib Its function is to store image information .

         Why is information stored in CDib Instead of being stored directly in Doc Class , This is a question worth thinking about , You can view the functions defined in the two classes , Feel the functional differences between the two classes , This difference is difficult to describe accurately .

        View Class is a class used to interact with users , It has a wide range of functions , For example, what function operations should be performed after a user presses an option ( It's actually part of what we do )、 Popup 、 The shape of the mouse changes .

        If you want to make a more vivid metaphor ,View Class is the front end ,Doc Class is the back end .

MFC The framework we use understands

        What we use MFC The basic process of the framework is as follows :

        On the menu MENU in ( You can understand it as View Class ), We can define tabs , Name it ID_ name . We are View Class events COMMAND, You can add this ID Of On function , And write their own change function . The body of the function we wrote will be executed after this tab is clicked . The content to be executed can be to directly perform a certain operation , For example, pop-up dialog box , You can also call the specified dialog function ( You don't have to call ).

        In fact, after understanding the above part, we can implement many functions , Just to make our interaction with users stronger , We need to define the dialog class to collect the information that the user wants to input .( In general , The dialog class is only responsible for collecting information , After collecting the information , We still need to View Class to process the results corresponding to this input )

        When building dialog classes , We need to be in Dialog Create a IDD_ name , This is our design page .

         In the process of page design , It is best to generate... In sequence for the same group of objects , If I want to create three radio boxes , I just create them in order IDC_RADIO1、IDC_RADIO2、IDC_RADIO3, Instead of creating IDC_RADIO1 Create a text box , To create a IDC_RADIO2, Or create IDC_RADIO1、IDC_RADIO2 after , Delete IDC_RADIO2 Create another . When designing a page, it's best to think about it in advance , Make fewer changes , Because all the controls we create will have a number in the background ID, for example IDC_RADIO1 It may correspond to 1001, that IDC_RADIO2 It will correspond to 1002, Used to make the computer recognize , Creating them out of order may disrupt this ID, Affect future operations .

        After designing the page , We need to create the class first , Right click the dialog box to directly create a CDlg Name class is OK . After creation , We can go straight to IDD Add member variables to the page , stay CDlg Class to add dialog functions and control functions , You can also use the class wizard to build . The class wizard builds faster , It will be very convenient to use after getting started .

        The following figure shows the class wizard page , We can observe whether the resources here are what we want IDD name , If it is ABOUTBOX, That means you haven't added a class yet , You must add a class to use the class wizard . The class wizard consists of five parts , command 、 news 、 Virtual functions 、 Member variables 、 Method . Methods are generally not used , I don't explain .

         among , The command is used to add control functions , It contains all of ID, Many of them don't need our care , I don't know why he didn't do a screening . We can look through it manually IDC All of the beginning ID, If the message function of an object does not only have the two messages shown in the above figure , That's it ID It is our IDD Controls in the page , You can add functions with confidence .

         The message contains the message functions of all dialog boxes , For example, when you press the mouse (OnLButtonDown)、 When you raise the mouse (OnLButtonUp), The corresponding function when moving the mouse .(OnMouseMove). Virtual functions are defined by the system , Functions that we can rewrite , such as OnInitDialog( Initialization function )、OnOK( What happens after pressing the OK button ). The difference between a message and a virtual function is , Message functions are optional functions , I can move the mouse to have functions , There can be no . Virtual functions are all necessary functions , You didn't write , The system will use its default set .

        There is no need to elaborate on member variables , Each control can add a value and a CButton The control of a class .CButton Class can control the state of this control . Visible in the box below , Ban , Read only things should be controllable . Value is value , Is the content of the control , Is the value of the edit box , Is the serial number of the radio box .

 

          For radio boxes , There's a place to pay attention to . Radio boxes have a set of options , We can set the group of the first radio box to TRUE, The first N+1 A for TRUE, Let's go from first to N Radio boxes form a group . If there is no need to divide into groups , Just make the group of the first radio box TRUE, The rest are all FALSE that will do . The premise of all this is your RADIO Of ID It's in order , There is no confusion , Otherwise the computer will not be able to recognize them as a group .

        In the class wizard , Only the first radio box in a group can set member variables and functions , I don't know why? , But you can add functions manually , stay CDlg Class . For radio boxes , The value is their serial number , When you press the first radio box , Value will be 0, Press the second , Value will be 1, Press next N individual , Value will be N-1.

          After creating the dialog class , After adding dialog class functions 、 After each control's variables and functions , We need to add the dialog class to View Class . We need to be in View Class to import dialog class , Then call... Through a function , The general functions are as follows :

	CDIG name  dlgPara;//  Create dialog 		
	dlgPara. Variable = View Variables in ;// Import some variables required by the dialog box , Such as image data 

	if (dlgPara.DoModal() != IDOK)//  Show dialog , 
	{
		return;
	}

    View Variables in  = dlgPara. Variable ;// Export the variables of the dialog box , We can know what the user has entered through this , And carry out the corresponding operation 
    // There is a handler 
    pDoc->SetModifiedFlag(true);
	pDoc->UpdateAllViews(NULL);// Whether to save the changed image 

        among if(dlgPara.DoModal()!=IDOK){return;} The role of is , Open the dialog box , And end the statement after closing the dialog .

        in summary , In fact, the process of the whole framework is :View Class control Doc Class to read the contents of the file , Click on the tab ,(View Class call dialog , People enter information ),View Class handles related operations .

MFC Advanced use of

        Some routine operations use MFC It is difficult to implement the basic framework of , I share some of the things I use 、 We often see but do not know what functions and operations are used .
        1、UpdateData()

        This function often appears in dialog classes ,UpdateData It is actually used to control the value displayed on the control ( Such as the value entered by the user in the edit box ) And the value stored in the background .UpdateData(TRUE) All the values in the edit box will be copied to the values stored in the background ( In fact, it is the value variable you added to this control );UpdateData(FALSE) The value stored in the background will be copied into the edit box , Form an interaction .

        2、BeginWaitCursor()

        This function is View Functions in class , It is used to turn the mouse into a waiting state , It can be used EndWaitCursor() Cancel waiting state . If some functions have high time complexity , You can consider before the function BeginWaitCursor(), After the end EndWaitCursor().

        3、 Preview image

        The operation of preview image is difficult to realize in the traditional framework . Because according to the logic of our previous framework , We will not process the image until we finish the dialog box , Because our dialog just collects data . If we want to modify the data in the dialog , We must face a problem : If... Will be called in the dialog box pDoc Function of , After all, we must at least use

    pDoc->SetModifiedFlag(true);
    pDoc->UpdateAllViews(NULL);// Whether to save the changed image

These two functions can .

        It's easy , Is to pass on . We are in the dialog .h Add... To the header file #include "MFCApplication1Doc.h", And in the dialog class public Add     CMFCApplication1Doc* m_pDoc; Member variables , In the end, it just needs to be View Class     dlgPara.m_pDoc = pDoc; that will do . The following is a View Class :

void CMFCApplication1View::OnStylize()
{
	CMFCApplication1Doc* pDoc = GetDocument();//  Get document 	
	CDlgStylize dlgPara;//  Create dialog 	
	dlgPara.m_pDoc = pDoc;
	if (dlgPara.DoModal() != IDOK)//  Show dialog  
	{
		return;
	}
}

        The rest of us just need to preview the image button in the dialog class OnClickButton Add our processing function to the function . To cancel preview, you only need to exchange background data .( We need to rewrite OnOK function ,OnOK Function only needs to call our preview image function )

        The above method is a preview image realized through small changes , The effect is not very good . Join us to process this image by panning , Then preview the oil painting effect of this image , At this time, we click Cancel preview , As a result, there is no translation effect . Is there any way to solve this problem ? yes , we have , The theory works , I didn't realize , The method is as follows :

        Number each operation , Use the stack to store the user input operation , Preview and confirm are put on the stack , Cancel previewing and canceling , Every time we update the view , Exchange images with the background , And operate from the bottom of the stack to the top of the stack according to the operation number .

        4、 Store and read the data in the dialog box

        

#include <fstream>
// Storage 
CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, _T("*.txt|All Files (*.*) |*.*|"), this);
fileDlg.DoModal();
CString strFilePath = fileDlg.GetPathName();		// File path 
ofstream fout;
fout.open(strFilePath, ios::out);
if (!fout.is_open())
{
	AfxMessageBox(L" Can't open file ");
	return;
}
char buff[1024] = { 0 };
fout <<  data <<" ";

fout.close();

// Read 
CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, _T("*.txt|All Files (*.*) |*.*|"), this);
fileDlg.DoModal();
CString strFilePath = fileDlg.GetPathName();		// File path 
ifstream fin;
fin.open(strFilePath, ios::in);
if (!fin.is_open())
{
	AfxMessageBox(L" Can't open file ");
	return;
}
fin >>  data ;

fin.close();
UpdateData(FALSE);

MFC Problems encountered in the process

        For the time being, I encountered a serious problem : When you are in CDlg Class also contains Doc Class and function Class time , because View There are function class , Will redefine . Modify all function Functions in class , add to static that will do .

        Other memory read conflicts may be null pointers

原网站

版权声明
本文为[Liu, come down and bang me]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/161/202206101557029782.html