First knowledge MFC window class

xiaoxiao2021-03-06  17

The relationship between frame, view, document is very important, which is indeed isolated, but interconnected.

If it is an SDI program, CMAINFRAME calls getActiveView to get CView, and CView can call GetDocument to get CDocument. If CDocument is known, you can use GetFirstViewPosition to get the first related CView, then use GetNextView to get the next CView. The reason why this is because the MFC allows a cdocument to have multiple CVIEWs.

If it is an MDI program, it is slightly more complicated. You can't call getActiveView directly, but you need to call CMAINFRAME :: MDiGetActive to get the current cmdichildwnd, and this cmdichildwnd is equivalent to CMAINFRAME in SDI.

1, frame window

The frame window provides a structural frame for the application's user interface. It is the main window of the application. It is responsible for managing its tolerant windows. The top-level frame window of an application is the first window created when the application is started.

MFC offers three types of frames: Single Document Window, Multi-Document Window (MDI), dialog. In the first dialog of AppWizard, options are provided to allow the user to select an application based on a single document, a multi-document or dialog. The MFC single document window can only open a document frame window at a time, while the MDI application runs, opens multiple document frame windows in one instance of the application, which is called a child window. These documents can be the same type or may be different types. For example, Visual Studio opens different types of windows such as resource file windows and source windows. At this point, activate different types of MDI sub-windows, and the menu will also change accordingly.

The MFC provides three class CFrameWnd, CMDIFrameWnd, CmdichildWnd, and CDialogs to support a single document window, multi-document window, and dialogs, respectively.

CFrameWnd is used in the SDI frame window to form a single document and a border therefor. The frame window is both the main frame window of the application and a border of the view corresponding to the current document.

CmdiframeWnd is used for the main frame window of the MDI application. The main frame window is a container of all MDI document windows and sharess menu bars with them. The MDI frame window is a top-level window that appears in the desktop.

CMDICHildWnd is used to display all documents opened in the MDI main frame window. Each document has an MDI sub-frame window, and the subframe window is included in the MDI main frame window. The sub-frame window looks similar to a general frame border window, but it is included in the main frame window, not at the desktop, and cuts the main window. And the MDI child window does not have its own menu, which shares the menu with the main MDI Frame window window.

The CDialog dialog is a special type of window, which is generally not adjustable, and the internal contains some control windows. The technical report as the main window can see the next chapter.

To generate a single document window, the main window must be derived from the CFraMewnd; to generate a multi-document window, the main window must derive from the cmdiframewnd, and the sub-window must be derived from cmdichildwnd; and the dialog-based window program is Derived from CDIALOG to the main window class.

Child window

The child window is a window with a WS_CHILD style, and there must be a parent window. All controls are sub-windows. The sub-window can have no border. The sub-window is fully limited inside the parent window.

Parent window

The parent window is a window with a child window.

Pop-up window

Has a WS_POPUP style, it can have no parent window. This window is almost all, it can be seen as a rectangular area. 2, the creation of the window

The creation of the window is divided into two steps: The first step is to create a C window object with NEW, but this is only the data member of the initialization window, and does not really create a window (this is different from the general object).

2.1, step: Create a C object, where CMAINFRAME is a target derived from the CFrameWnd.

CMAINFRAME * PMYFRAME = New cmainframe (); // Create a window object with a New operator

or

CMAINFRAME MyFrame; / / Define a window object and automatically call its constructor

2.2, the second step is to create a window. The CFrameWnd's Create member function is made, and the HWND is saved in the public data member m_hwnd of the C object.

// Step 2: Create a window

PMYFRAME-> CREATE (NULL, "My Frame Window);

or

Myframe.create (NULL, "My Frame Window);

The original shape of the CREATE function is as follows:

BOOL Create (LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT & rect = rectDefault, CWnd * pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext * pContext = NULL);

The CREATE function first parameter is a window registration class name, which specifies the icon and type of the window. Here we use null as its value, indicating the use of default attributes. The second parameter is a window title. The remaining parameters specify the style, size, parent window, menu name, etc. of the window.

This function looks more complicated. For the window derived for CFrameWnd, we can use LoadFrame to create a window from the resource file, which only needs a parameter.

PMYFRAME-> LoadFrame (iDR_frame);

LoadFrame uses this parameter to get many defaults from the resource, including the title, icon, menu, acceleration key, etc. of the main border window. However, when using LoadFrame, you must ensure that resources such as header strings, icons, menus, acceleration keys are used to use the same ID identifier (in this case, we use idR_frame).

Tip: We can't see the process of creating a window in InitInstance in the Hello program. In fact,

PDOCTEMPLATE = New CSINGEDOCTEMPLATE (iDR_Mainframe, Runtime_Class (CHELLODOC), Runtime_Class (CMAINFRAME), // Main SDI Frame Window

Runtime_class (chelloview);

AddDDDEMPLATE (PDOCTemplate); In the segment, we see that the second parameter of the CSINGLEDEMPLATE constructor is IDR_MAINFRAME. Inside the constructor, the creation process of the application main window has been completed by calling m_pmainwnd-> loadingframe (idR_mainframe).

In InIntInstance, after the window is created, the window calls the showWindow member function to display the window. ShowWindow with a parameter, indicating what is displayed in the window (maximize, minimize or general). The default mode is SW_SHOW, but in fact, we often want the application to maximize the window when the application starts, and this parameter can be sw_showmaxmized, that is, call m_pmainwnd-> showWindow (sw_showmaximized);

In Mainfrm.cpp, we also see that the CMAINFRAME class has an OnCreate method. The oncreate member function is defined as Listing 3.3. When CREATE or CREATEEX is called, the operating system sends a WM_CREATE message to the window. This function is used to respond to WM_CREATE messages.

Listing 3.3 Oncreate Member Function Definition

INT CMAINFRAME :: OnCreate (lpcreatestruct lpcreatestruct)

{IF (cframeWnd :: oncreate (lpcreateStructure) == -1) Return -1;

IF (! m_wndtoolbar.create (this) ||! m_wndtoolbar.loadtoolbar (iDR_mainframe))

{

Trace0 ("Failed to Create Toolbar / N);

Return -1; // fail to create

}

IF (! m_wndstatusbar.create (this) ||! m_wndstatusbar.setindicators (INDICATORS, SIZEOF (INDCATORS) / SIZEOF (UINT)) {

Trace0 ("Failed to Create Status Bar / N);

Return -1; // fail to create

}

// Todo: Remove this if you don't want Tips or a Resizeable Toolbar

M_WndToolBar.setbarstyle (m_wndtoolbar.getbarstyle () | CBRS_Tooltips | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

// Todo: Delete these Three Lines if you don't wantbar to

// be Dockable

m_wndtoolbar.enabledocking (CBRS_ALIGN_ANY);

Enabledocking (CBRS_ALIGN_ANY);

DockControlbar (& M_WndToolbar);

Return 0;

}

In the oncreate function, first call the CFRAMEWND's default processing method onCreate complete the window creation work. Behind the specific work of the application main window, in the above program, create a toolbar and status bar (see the toolbar and status bar programming to see the following chapter). Some initialization works can be added here, such as load settings from the INI file, display the SPLASH WINDOW, and the like.

3, registration window

In the traditional Windows C program, all messages given to a window are processed in its window function. The process of linking a window with its window function is called a registration window class. The registration window includes specifying a window function (a pointer to the window function) and the cursor, background brush, etc. of the setting window. A registration window class can be shared by multiple windows. The registration window is done by calling the API function registerclass.

Under the MFC, the framework provides the default auto window registration process. The framework still uses traditional registration classes, and provides several standard registration classes, which are registered in the standard application initialization function. Call the AFXREGISTERWNDCLASS global function to register additional window classes, then pass the registered class to the CREATE member function of CWnd. Users can customize their own registration procedures to provide some additional features. For example, icon, background, cursor, etc. set up window. Below is an example of a registered window. Bool CMAINFRAME :: PrecreateWindow (CreateStruct & Cs)

{

// Todo: modify the window class or styles here by modifying

// The createStruct CS

UINT ClassStyle = CS_VREDRAW | CS_HREDRAW;

CS.Style = CS.Style & (~ fws_addtotitle);

cs.lpszclass = AFXREGISTERWNDCLASS (ClassStyle,

AFXGetApp () -> LoadStandardCursor (IDC_ARROW), (Hbrush) (Color_Window 1), // for brush

AFXGetApp () -> loadicon (idR_mainframe);

Return True;

}

The registration window is done in the PrecreateWnd method of the cframewnd. From the member function name PrecreateWindow, you can see that the work of the registration window must be done before calling the CREATE function creation window. Where cs.style = cs.style & (~ fws_addtotitle) Specifies the window title style, close the function of the automatic adding document title. AFXREGISTERWNDCLASS Specifies the window using an arrow cursor, a background brush uses the color of the window color label, the icon uses the icon specified by the idR_mainframe identifier (of course, other icons). Replace the PrecreateWindow member function definition in the Hello program mainfrm.cpp with the above program segment, and recompile and run the program. At this point, the window title becomes Hello, which is an annoying "Untitled-", because the window style is turned off automatically to add the current file name.

4, close and destroy window

The frame window not only maintains the creation of the window, but also manages the shutdown and destruction process of the window. When the window is turned off, the operating system sends WM_Close and WM_DESTROY messages in turn. The default processing function on the WM_Close message calls DestroyWindow to destroy the window;

Do not use the C Delete operator to destroy the frame window, and the CWnd's DestroyWindow member function should be used to destroy. DESTROYWINDOW first deletes sub-windows, then delete the window itself. If the window is generated in a variable mode (ie, allocated on the stack), the window object will be automatically cleared. If the object is created with a New operator (that is, allocating memory on the heap), you need to handle it yourself. Further explanations are also further explained in Chapter 5 dialog in Chapter V.

OnClose () Common features: Save some status of the window, the toolbar status, prompt to save unsaved data, etc.

Void cmainframe :: onClose ()

{

Savebarstate ("MyDockState"); // Save the tool strip status

CframeWnd :: onClose ();

}

5, window activation

Activity window must be a top window without a parent window, including the Frame Window, and dialog. When the top window is activated, Windows sends a WM_ACTIVATE message to the window, and the default processing of this message is to set the moving window to have input focus. Input focus is used to indicate which window is eligible to receive the keyboard input message. A window with an input focus or an active window, or a sub-window of the active window. When a top window gets the input focus, Windows sends a WM_SETFOCUS message to the window, which relocates the input focus to its sub-window. The sub-window does not automatically get the input focus. The window that lost the focus will receive a WM_KILLFOCUS message. When the child window has input focus, the parent window does not process the keyboard input.

转载请注明原文地址:https://www.9cbs.com/read-42216.html

New Post(0)