"Windows Programming" series 11th: Multi-Document Interface framework

Source: Internet
Author: User

The example above is a single-document interface framework, which means that the client area inside the window is a document interface that can be programmed to input or draw text and graphics output, but not multiple documents. For example, the following ultraedit is a typical multi-document interface, he can edit multiple documents at the same time, each document can also be maximized, minimized, and so on, we are today to see how the basic framework of multi-document implementation.

The frame creation of the multiple file interface takes a few steps.

    • Main frame window creation

The creation of the main frame window is no different from the normal window, it is to register a class and create an overlapping window with the class, this can be done with the CREATEWINDOW/CREATEWINDOWEX function, the main frame window can use its own menu and the status bar.

    • Client Area window creation

The creation of the client area is also used in your CreateWindow, but you need to specify the class as "mdiclient", and this class will create a multi-document client Area window. Alternatively, use the CreateWindowEx function to specify an extension style of ws_ex_mdichild. The customer area does not require menus and status bars.

    • View Window creation

Creating a work or view window as the actual document window, this also requires registering the class yourself and creating the view window that you need. The view window can have its own menu, which generally does not require a status bar. When the view window is active, the menu of the main window needs to be replaced with the menu of the view window, as it is often the case that the window is being manipulated and the menu substitution is taken for granted. Menu settings are completed by Wm_mdisetmenu message. The message is defined as follows:

SendMessage (Hwndcontrol, Wm_mdisetmenu, WParam, LParam) WParam represents the New frame Window menu, LParam represents the menu handle to set

OK, the basic API is these, the following we directly on the demo program to demonstrate, because the view is generally a multi-document instance, so the demo code with the class to store the view, each view is an instance of a class:

The main file, which includes the main frame window, the client window has been called by the view window:

#include  <windows.h> #define  client_wnd_bground#define idm_firstchild 1001#define  IDM_FILE_NEW   1002HINSTANCE g_hInst; Tchar     szmdimainframe[]= text ("Mdi main frame"); Tchar     gszappname[]    = text ("MDI Demo"); hwnd      ghwndmdiclient; hwnd      ghwndmainframe; Hmenu     ghmainframemenu;void createchildwndmenu (void); Hwnd createdocview (hwnd hparentwnd, hinstance hinstance); static lresult callback  mainframeproc (Hwnd hwnd, uint message, wparam wparam, lparam lparam); #ifdef  CLIENT_WND_BGROUNDstatic WNDPROC pfOrigClientWndProc; Lresult callback clientwndsubclassproc (Hwnd hwnd, uint umsg, wparam wparam,  lparam lparam) {  &Nbsp; switch (umsg)     {    case WM_ERASEBKGND:         {             rect rect;            hdc hdc =   (HDC) Wparam;            getclientrect (hwnd,  &rect);            hbrush hbr  = createsolidbrush (RGB (125, 150, 125));             HBRUSH holdbr =  (Hbrush) SelectObject (HDC,&NBSP;HBR);             fillrect (HDC,&NBSP;&AMP;RECT,&NBSP;HBR);             selectobject (HDC,&NBSP;HOLDBR);         &nBsp;   deleteobject (HBR);        }         return TRUE;    default:         break;    }    return callwindowproc ( Pforigclientwndproc, hwnd, umsg, wparam, lparam); &nbsp #endifHMENU   Createmainframemenu (void) {    //Main frame menu     HMENU hMenu =  CreateMenu ();     //File menu     hmenu hfilemenu = createmenu ();     appendmenu (Hfilemenu, mf_string, idm_file_new, text ("&New"));     appendmenu (hmenu, mf_popup,  (uint_ptr) hfilemenu, text ("&File"));     return hmenu;} Int winapi winmain (hinstance hinstance, hinstance hprevinstance, lpstr  LpcmdlinE, int nshowcmd) {    msg msg;    wndclassex  Wndclass = {0};    wndclass.cbsize= sizeof (WNDCLASSEX);     wndclass.style= cs_hredraw | cs_vredraw;    wndclass.lpfnwndproc=  MainFrameProc;    wndclass.hInstance= hInstance;     Wndclass.hicon= null;    wndclass.hcursor= loadcursor (NULL, IDC_ARROW);     wndclass.hbrBackground=  (Hbrush) getstockobject (White_brush);     wndclass.lpszclassname= szmdimainframe;    if (! RegisterClassEx (&wndclass))     {         MessageBox (Null, text ("this program requires windows nt!"),  gszappname, mb_ Iconerror);         return 0;    }    g_hinst = hinstance;     Ghmainframemenu = createmainframemenu ();     createchildwndmenu ();     //create the main mdi frame window    ghwndmainframe  = createwindow (szmdimainframe,                                   gszAppName,                                   WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,                                  CW_USEDEFAULT,// allows system choose an x position                                  cw_usedefault,// allows system  choose a y position                                  400,                                  300,                                 null,// handle  to parent window                                 ghmainframemenu,// handle  to menu                                  hinstance,// handle to the instance of module                                  null);// long pointer to a  value to be passed to the window through the      showwindow (ghwndmainframe,  sw_show);     updatewindow (GhWndMainFrame);     while (GetMessage (&msg, null, 0, 0))     {         TranslateMessage (&msg)  ;        dispatchmessage (&msg)  ;    }    return msg.wparam ;} Lresult callback mainframeproc (Hwnd hwnd, uint message, wparam wparam,  lparam lparam) {    switch (message)     {     case WM_CREATE:        {             CLIENTCREATESTRUCT ccs;             ccs.hWindowMenu = NULL;             ccs.idFirstChild = IDM_FIRSTCHILD;             ghwndmdiclient&nbSp;= createwindow (TEXT ("Mdiclient"), null,                                          ws_child | ws_ clipchildren | ws_visible,                                          0, 0, 0, 0, hwnd, null,                                           g_hInst,  (void *) &ccs); #ifdef  CLIENT_WND_BGROUND             pforigclientwndproc =  (WNDPROC) SetWindowLong (Ghwndmdiclient, gwl_wndproc,   (LONG) clientwndsubclassproc); #endif         }         return 0;    case WM_COMMAND:         switch (LoWord (wParam))         {         case IDM_FILE_NEW:             createdocview (Ghwndmdiclient, g_hinst);             return 0;        }         break;    case WM_DESTROY:         postquitmessage (0);         return  0;    }&nBsp;   return defframeproc (hwnd, ghwndmdiclient, message, wparam,  LParam);}

Below is the view window, each view window is described by a class, this article is just a demo, only to instantiate a view window as a demonstration:

#include  <windows.h> #define  idm_edit_copy 1003#define idm_edit_paste 1004class  cviewinfo{public:    cviewinfo (hinstance hinst);     ~ Cviewinfo ();     hwnd createviewwindow (Hwnd hparentwnd);p rivate:     HINSTANCE m_hInst;    HWND m_hWndView;}; Static tchar szviewwndname[] = text ("View window"); static cviewinfo *g_ psysteminfo;static hmenu      ghchildwndmenu;extern hmenu       ghMainFrameMenu; Cviewinfo::cviewinfo (Hinstance hinst) {    m_hwndview = null;     m_hinst = hinst;} Cviewinfo::~cviewinfo () {    m_hwndview = null;} Lresult callback viewwindowproc (Hwnd hwnd, uint message, wparam wparam,  lparam&nbsP;lparam) {    switch (message) &NBSP;&NBSP;&NBSP;&NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;CASE&NBSP;WM _mdiactivate:        {             hwnd hwndclient = getparent (HWND);             hwnd hwndframe  = getparent (hWndClient);             hmenu hmenu = getsubmenu ( ghchildwndmenu, 0);            if  ( lparam ==  (LParam) hWnd)             {                 sendmessage ( hwndclient, wm_mdisetmenu,  (WPARAM) ghchildwndmenu,  (LPARAM) hMenu);           &nbSp;     enablemenuitem (ghchildwndmenu, idm_edit_copy, mf_grayed);             }             // set the framewindow menu if losing focus             if  (lparam !=  (LParam) HWND)             {                 sendmessage (HWndClient, WM_MDISETMENU,   (WPARAM) ghmainframemenu,  (LPARAM) NULL);             }            // call  drawmenubar after the menu items are set            &nBsp;drawmenubar (hwndframe);             return  0 ;        }    case wm_close:         delete g_pSystemInfo;         break;    case WM_DESTROY:         return 0;    }    return defmdichildproc (hWnd,  Message, wparam, lparam); //frame window calls defframeproc rather  Than defwindowproc}hwnd cviewinfo::createviewwindow (Hwnd hparentwnd) {     Wndclassex wcdoc;    wcdoc.cbsize= sizeof (wndclassex);     wcdoc.style= cs_hredraw | cs_vredraw;    wcdoc.lpfnwndproc=  Viewwindowproc;    wcdoC.cbclsextra= 0;    wcdoc.cbwndextra= 0;    wcdoc.hinstance=  m_hInst;    wcDoc.hIcon= NULL;    wcDoc.hCursor=  LoadCursor (Null, idc_arrow);    wcdoc.hbrbackground=  (HBRUSH)   Getstockobject (White_brush);    wcdoc.lpszmenuname= null;     wcdoc.lpszclassname= szviewwndname;    wcdoc.hiconsm= null;     if (! RegisterClassEx (&wcdoc))     {        dword  dw_lasterror = getlasterror ();         if (ERROR_CLASS_ Already_exists != dw_lasterror)         {             return 0;         }    }    m_hwndview = createwindowex (ws_ex_mdichild, szviewwndname,                                   text ("New view"),  0,  CW_USEDEFAULT,                                 cw_ usedefault, 300, 200,                                  hparentwnd, null, m_hinst, null);     return m_hwndview;} Hwnd createdocview (hwnd hparentwnd, hinstance hinstance) {    hwnd  hView;    G_psysteminfo = new cviewinfo (HINSTANCE);     hview = g_ Psysteminfo->createviewwindow (Hparentwnd);    if  (HView == NULL)      {        delete g_pSystemInfo;         g_pSystemInfo = NULL;    }     return hview;} Void createchildwndmenu (void) {    //view menu     ghchildwndmenu  = createmenu ();     //Edit Menu     hmenu heditmenu =  createmenu ();     appendmenu (Heditmenu, mf_string, idm_edit_copy, text ("&copy"));     appendmenu (Heditmenu, mf_string, idm_edit_paste, text ("&Paste"));     appendmenu (ghchildwndmenu, mf_popup,  (uint_ptr) HEditMenu, TEXT ("& Edit "));

After running this instance, the interface is as follows:

Select File->new Create a new view after the demo program below, you can see the menu programming View menu:

When maximized, you can see the View window and fill the client window:

Although this program implements only one instance of a view, it is easy to add one, just try to call the Createdocview function in the menu and handle the object pointer correctly. The instance does not add a status bar because this is not required for multiple documents, and the additional reader can refer to the previous Create toolbar and StatusBar article.

This example realizes a basic multi-document window frame, the reader friend can add the toolbar, the status bar, the view window to create the processing of the class, the multi-instance and the concrete demand, completes the practical multi-document interface.


More experience Exchange can join the Windows programming discussion QQ Group :454398517.


Focus on the public platform: The programmer Interaction Alliance (coder_online), you can get the first original technical articles, and (java/c/c++/android/windows/ Linux) Technology Daniel is a friend, online communication programming experience, get programming basics, solve programming problems. Programmer Interactive Alliance , Developer's own home.

Reprint Please specify the source http://www.coderonline.net/?p=2052 , thank you for your cooperation!

"Windows Programming" series 11th: Multi-Document Interface framework

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.