⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 app_four.html

📁 forgers-win32-tutorial
💻 HTML
📖 第 1 页 / 共 2 页
字号:
going to be any good with no windows to act on.  I've disabled all these items by defaultin the resource so that I don't need to add extra code to do it when the application first startsup.<PRE CLASS="SNIP">LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch(msg)    {        case WM_CREATE:        {            HFONT hfDefault;            HWND hEdit;            // Create Edit Control            hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",                 WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,                 0, 0, 100, 100, hwnd, (HMENU)IDC_CHILD_EDIT, GetModuleHandle(NULL), NULL);            if(hEdit == NULL)                MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);            hfDefault = GetStockObject(DEFAULT_GUI_FONT);            SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));        }        break;        case WM_MDIACTIVATE:        {            HMENU hMenu, hFileMenu;            UINT EnableFlag;            hMenu = GetMenu(g_hMainWindow);            if(hwnd == (HWND)lParam)            {      //being activated, enable the menus                EnableFlag = MF_ENABLED;            }            else            {                          //being de-activated, gray the menus                EnableFlag = MF_GRAYED;            }            EnableMenuItem(hMenu, 1, MF_BYPOSITION | EnableFlag);            EnableMenuItem(hMenu, 2, MF_BYPOSITION | EnableFlag);            hFileMenu = GetSubMenu(hMenu, 0);            EnableMenuItem(hFileMenu, ID_FILE_SAVEAS, MF_BYCOMMAND | EnableFlag);            EnableMenuItem(hFileMenu, ID_FILE_CLOSE, MF_BYCOMMAND | EnableFlag);            EnableMenuItem(hFileMenu, ID_FILE_CLOSEALL, MF_BYCOMMAND | EnableFlag);            DrawMenuBar(g_hMainWindow);        }        break;        case WM_COMMAND:            switch(LOWORD(wParam))            {                case ID_FILE_OPEN:                    DoFileOpen(hwnd);                break;                case ID_FILE_SAVEAS:                    DoFileSave(hwnd);                break;                case ID_EDIT_CUT:                    SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_CUT, 0, 0);                break;                case ID_EDIT_COPY:                    SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_COPY, 0, 0);                break;                case ID_EDIT_PASTE:                    SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_PASTE, 0, 0);                break;            }        break;        case WM_SIZE:        {            HWND hEdit;            RECT rcClient;            // Calculate remaining height and size edit            GetClientRect(hwnd, &rcClient);            hEdit = GetDlgItem(hwnd, IDC_CHILD_EDIT);            SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER);        }        return DefMDIChildProc(hwnd, msg, wParam, lParam);        default:            return DefMDIChildProc(hwnd, msg, wParam, lParam);        }    return 0;}</PRE><P>I've implemented the File Open and Save as commands, the <CODE>DoFileOpen()</CODE> and <CODE>DoFileSave()</CODE> are nearly the same as in previous examples with theID of the edit control changed, and additionally setting the title of the MDI Childto the filename.<P>The Edit commands are easy, because the edit control has built in support for them, we just tell it what to do.<P>Remember I mentioned that there are little things you need to remember or your application willbehave strangely?  Note that I've called <CODE>DefMDIChildProc()</CODE> at the end of <CODE>WM_SIZE</CODE>, this is important otherwise the system wont' have a chance to do it's own processing on the message.  You can look up <CODE>DefMDIChildProc()</CODE> in MSDNfor a list of the messages that it processes, and always be sure to pass them to it.<H3>Creating and Destroying Windows</H3>MDI Child windows are not created directly, isntead we send a <CODE>WM_MDICREATE</CODE> message to the client window telling it what kind of window we want by setting the members of an <CODE>MDICREATESTRUCT</CODE>. You can look up the various members of this struct in your documentation, they are fairly straight forward.  The return value from the <CODE>WM_MDICREATE</CODE> message is the handle to the newly created window.<PRE CLASS="SNIP">HWND CreateNewMDIChild(HWND hMDIClient){     MDICREATESTRUCT mcs;    HWND hChild;    mcs.szTitle = "[Untitled]";    mcs.szClass = g_szChildClassName;    mcs.hOwner  = GetModuleHandle(NULL);    mcs.x = mcs.cx = CW_USEDEFAULT;    mcs.y = mcs.cy = CW_USEDEFAULT;    mcs.style = MDIS_ALLCHILDSTYLES;    hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LONG)&mcs);    if(!hChild)    {        MessageBox(hMDIClient, "MDI Child creation failed.", "Oh Oh...",            MB_ICONEXCLAMATION | MB_OK);    }    return hChild;}</PRE><P>One member of <CODE>MDICREATESTRUCT</CODE> that I didn't use that can be quite usefull isthe <CODE>lParam</CODE> member.  This can be used to send any 32bit value (like a pointer) tothe child you are creating in order to provide it with any custom information you choose.In the <CODE>WM_CREATE</CODE> handler for your child window, the <CODE>lParam</CODE> value for the <CODE>WM_CREATE</CODE>message will point to a <CODE>CREATESTRUCT</CODE>.  the <CODE>lpCreateParams</CODE> member of that structurewill point to the <CODE>MDICREATESTRUCT</CODE> you sent along with <CODE>WM_MDICREATE</CODE>.  So in orderto access the <CODE>lParam</CODE> value from the Child window you need to do something likethis in the child window procedure...<PRE CLASS="SNIP">    case WM_CREATE:    {        CREATESTRUCT* pCreateStruct;        MDICREATESTRUCT* pMDICreateStruct;        pCreateStruct = (CREATESTRUCT*)lParam;        pMDICreateStruct = (MDICREATESTRUCT*)pCreateStruct->lpCreateParams;        /*        pMDICreateStruct now points to the same MDICREATESTRUCT that you        sent along with the WM_MDICREATE message and you can use it        to access the lParam.        */    }    break;</PRE><P>If you don't want to bother with those two extra pointers you can access thelParam in one step with<CODE>((MDICREATESTRUCT*)((CREATESTRUCT*)lParam)->lpCreateParams)->lParam</CODE><P>Now we can implement the File commands on our menu in our Frame window procedure:<PRE CLASS="SNIP">    case ID_FILE_NEW:        CreateNewMDIChild(g_hMDIClient);    break;    case ID_FILE_OPEN:    {        HWND hChild = CreateNewMDIChild(g_hMDIClient);        if(hChild)        {            DoFileOpen(hChild);         }    }    break;    case ID_FILE_CLOSE:    {        HWND hChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE,0,0);        if(hChild)        {            SendMessage(hChild, WM_CLOSE, 0, 0);        }    }    break;</PRE><P>We can also provide some default MDI processing of window arrangment for our Window menu,since MDI supports this itself it's not much work.<PRE CLASS="SNIP">    case ID_WINDOW_TILE:        SendMessage(g_hMDIClient, WM_MDITILE, 0, 0);    break;    case ID_WINDOW_CASCADE:        SendMessage(g_hMDIClient, WM_MDICASCADE, 0, 0);    break;</PRE><HR><FONT SIZE="-1">Copyright &copy; 1998-2003, Brook Miles (<A HREF="mailto:forger(nospam)winprog.org">theForger</A>).  All rights reserved.</FONT><SCRIPT language="JavaScript"><!--   var re = /\(nospam\)/ig;   var str;   for(i = 0;i < document.links.length;i++)    {      str = "" + document.links(i).href;      if(str.search(re) != -1)         document.links(i).href = str.replace(re, "@");      str = "" + document.links(i).innerHTML;      if(str.search(re) != -1)         document.links(i).innerHTML = str.replace(re, "@");   }--></SCRIPT></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -