底层的MDI程序是如何建立的

来源:互联网 发布:linux脚本压缩文件 编辑:程序博客网 时间:2024/04/28 23:09

代码示例:

// MDIAppDemo.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "MDIAppDemo.h"#define ID_FIRSTWINDOW 50000typedef struct tagHELLODATA{UINT iColorIndex;COLORREF clrText;} HELLODATA, *PHELLODATA;typedef struct tagRECTDATA{short cxClient;short cyClient;}RECTDATA, *PRECTDATA;// 前置函数申明LRESULT CALLBACKFrameWndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACKHelloWndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACKRectWndProc(HWND, UINT, WPARAM, LPARAM);BOOL CALLBACK CloseEnumProc(HWND, LPARAM);//全局变量TCHAR szFrameWndClass[] = _T("FrameWndClass");TCHAR szHelloWndClass[] = _T("HelloWndClass");TCHAR szRectWndClass[] = _T("RectWndClass");HMENU hMenuInit;HMENU hMenuInitWindow;HMENU hMenuHello;HMENU hMenuHelloWindow;HMENU hMenuRect;HMENU hMenuRectWindow;HINSTANCE hInst;int APIENTRY _tWinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPTSTR    lpCmdLine,                     int       nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);hInst = hInstance;WNDCLASS wc;//注册主框架类wc.style= CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc= FrameWndProc;wc.cbClsExtra= 0;wc.cbWndExtra= sizeof(HANDLE);wc.hInstance= hInstance;wc.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MDIAPPDEMO));wc.hCursor= LoadCursor(NULL, IDC_ARROW);wc.hbrBackground= (HBRUSH)(COLOR_APPWORKSPACE+1);wc.lpszMenuName= NULL;wc.lpszClassName= szFrameWndClass;RegisterClass(&wc);//注册Hello窗口类wc.style= CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc= HelloWndProc;wc.cbClsExtra= 0;wc.cbWndExtra= 0;wc.hInstance= hInstance;wc.hIcon= LoadIcon(NULL, IDI_APPLICATION);wc.hCursor= LoadCursor(NULL, IDC_IBEAM);wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName= NULL;wc.lpszClassName= szHelloWndClass;RegisterClass(&wc);//注册Rect窗口类wc.style= CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc= RectWndProc;wc.cbClsExtra= 0;wc.cbWndExtra= sizeof(HANDLE);wc.hInstance= hInstance;wc.hIcon= LoadIcon(NULL, IDI_APPLICATION);wc.hCursor= LoadCursor(NULL, IDC_CROSS);wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName= NULL;wc.lpszClassName= szRectWndClass;RegisterClass(&wc);//初始化菜单hMenuInit = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_INIT));hMenuInitWindow = GetSubMenu(hMenuInit, 0);hMenuHello = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_HELLO));hMenuHelloWindow = GetSubMenu(hMenuHello, 2);hMenuRect = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_RECT));hMenuRectWindow = GetSubMenu(hMenuRect, 1);HWND hWndFrame = CreateWindow(szFrameWndClass,  _T("MDIAppDemo"),  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,  CW_USEDEFAULT,  CW_USEDEFAULT,  CW_USEDEFAULT,  CW_USEDEFAULT,  NULL,  hMenuInit,  hInstance,  NULL);HWND hWndClient = GetWindow(hWndFrame, GW_CHILD);ShowWindow(hWndFrame, nCmdShow);UpdateWindow(hWndFrame);// 主消息循坏MSG msg;while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}//清理工作DestroyMenu(hMenuHello);DestroyMenu(hMenuRect);return (int) msg.wParam;}LRESULT CALLBACK FrameWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){static HWND hwndClient;CLIENTCREATESTRUCT clientCreateStruct;HWND hwndChild;MDICREATESTRUCT mdiCreateStruct;switch(uMsg){case WM_CREATE:clientCreateStruct.hWindowMenu = hMenuInitWindow;clientCreateStruct.idFirstChild = ID_FIRSTWINDOW;hwndClient = CreateWindow(_T("MDIClient"),  NULL,  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,  0,0,0,0,//注意:这里都是0!  hwnd,  (HMENU)1,  hInst,  (PSTR)(&clientCreateStruct));return 0;case WM_COMMAND:switch(LOWORD(wParam)){case IDM_FILE_NEWHELLO:mdiCreateStruct.szClass = szHelloWndClass;mdiCreateStruct.szTitle = _T("Hello Window");mdiCreateStruct.hOwner = hInst;mdiCreateStruct.x = CW_USEDEFAULT;mdiCreateStruct.y = CW_USEDEFAULT;mdiCreateStruct.cx = CW_USEDEFAULT;mdiCreateStruct.cy = CW_USEDEFAULT;mdiCreateStruct.style = 0;mdiCreateStruct.lParam = 0;hwndChild = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM)(LPMDICREATESTRUCT)&mdiCreateStruct);return 0;case IDM_FILE_NEWRECT:mdiCreateStruct.szClass = szRectWndClass;mdiCreateStruct.szTitle = _T("Rect Window");mdiCreateStruct.hOwner = hInst;mdiCreateStruct.x = CW_USEDEFAULT;mdiCreateStruct.y = CW_USEDEFAULT;mdiCreateStruct.cx = CW_USEDEFAULT;mdiCreateStruct.cy = CW_USEDEFAULT;mdiCreateStruct.style = 0;mdiCreateStruct.lParam = 0;hwndChild = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM)(LPMDICREATESTRUCT)&mdiCreateStruct);return 0;case IDM_FILE_CLOSE:hwndChild = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0);if(SendMessage(hwndChild, WM_QUERYENDSESSION, 0, 0))SendMessage(hwndClient, WM_MDIDESTROY, (WPARAM)hwndChild, 0);return 0;case IDM_FILE_EXIT:SendMessage(hwnd, WM_CLOSE, 0, 0);return 0;//窗口布局case IDM_WINDOW_TILE:SendMessage(hwndClient, WM_MDITILE, 0, 0);return 0;case IDM_WINDOW_CASCADE:SendMessage(hwndClient, WM_MDICASCADE, 0, 0);return 0;case IDM_WINDOW_ARRANGEICONS:SendMessage(hwndClient, WM_MDIICONARRANGE, 0, 0);return 0;case IDM_WINDOW_CLOSEALL:EnumChildWindows(hwndClient, CloseEnumProc, 0);return 0;default:hwndChild = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0); if(IsWindow(hwndChild)){SendMessage(hwndChild, WM_COMMAND, wParam, lParam);}break;}// end inner switchbreak;case WM_QUERYENDSESSION:case WM_CLOSE:SendMessage(hwnd, WM_COMMAND, IDM_WINDOW_CLOSEALL, 0);//尝试关闭所有窗口if(NULL != GetWindow(hwndClient, GW_CHILD)){//如果这个if语句体执行了,说明还有子窗口没有被关闭return 0;}break;case WM_DESTROY:PostQuitMessage(0);}// end outer switchreturn DefFrameProc(hwnd, hwndClient, uMsg, wParam, lParam);}LRESULT CALLBACK HelloWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){static COLORREF clrTextArray[] = {RGB(0, 0, 0),RGB(255, 0, 0),RGB(0, 255, 0),RGB(0, 0, 255),RGB(255, 255, 255)};static HWND hwndClient, hwndFrame;HMENU hFrameMenu;PHELLODATA pHelloData;HDC hdc;PAINTSTRUCT ps;RECT rect;switch(uMsg){case WM_CREATE:pHelloData = (PHELLODATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HELLODATA));pHelloData->iColorIndex = IDM_COLOR_BLACK;pHelloData->clrText = clrTextArray[0];SetWindowLong(hwnd, GWL_USERDATA, (long)pHelloData);hwndClient = GetParent(hwnd);hwndFrame = GetParent(hwndClient);return 0;case WM_PAINT:hdc = BeginPaint(hwnd, &ps);pHelloData = (PHELLODATA)GetWindowLong(hwnd, GWL_USERDATA);SetTextColor(hdc, pHelloData->clrText);GetClientRect(hwnd, &rect);DrawText(hdc, _T("Hello World!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);EndPaint(hwnd, &ps);case WM_COMMAND:switch(LOWORD(wParam)){//从IDM_COLOR_BLACK至IDM_COLOR_WHITE,其ID数值必须是连续的case IDM_COLOR_BLACK:case IDM_COLOR_RED:case IDM_COLOR_GREEN:case IDM_COLOR_BLUE:case IDM_COLOR_WHITE:pHelloData = (PHELLODATA)GetWindowLong(hwnd, GWL_USERDATA);hFrameMenu = GetMenu(hwndFrame);CheckMenuItem(hFrameMenu, pHelloData->iColorIndex, MF_UNCHECKED);//对于菜单的WM_COMMAND消息,wParam高位为0,低位为菜单的ID//所以此时wParam等于LOWORD(wParam)pHelloData->iColorIndex = wParam;CheckMenuItem(hFrameMenu, pHelloData->iColorIndex, MF_CHECKED);pHelloData->clrText = clrTextArray[wParam - IDM_COLOR_BLACK];InvalidateRect(hwnd, NULL, FALSE);}return 0;//注意与WM_MDIGETACTIVE区分case WM_MDIACTIVATE:if(lParam == (LPARAM)hwnd)SendMessage(hwndClient, WM_MDISETMENU, (WPARAM)hMenuHello, (LPARAM)hMenuHelloWindow);pHelloData = (PHELLODATA)GetWindowLong(hwnd, GWL_USERDATA);CheckMenuItem(hMenuHello, pHelloData->iColorIndex, (lParam == (LPARAM)hwnd) ? MF_CHECKED : MF_UNCHECKED);//如果当前窗口失去焦点,则将菜单还原成初始菜单if(lParam != (LPARAM)hwnd)SendMessage(hwndClient, WM_MDISETMENU, (WPARAM)hMenuInit, (LPARAM)hMenuInitWindow);DrawMenuBar(hwndFrame);return 0;case WM_QUERYENDSESSION:case WM_CLOSE:if(IDOK != MessageBox(hwnd,_T("OK to close window?"), _T("Hello"), MB_ICONQUESTION | MB_OKCANCEL))return 0;break;case WM_DESTROY:pHelloData = (PHELLODATA)GetWindowLong(hwnd, 0);HeapFree(GetProcessHeap(), 0, pHelloData);return 0;}return DefMDIChildProc(hwnd, uMsg, wParam, lParam);}BOOL CALLBACK CloseEnumProc(HWND hwnd, LPARAM lParam){if(GetWindow(hwnd, GW_OWNER))return TRUE;SendMessage(GetParent(hwnd), WM_MDIRESTORE, (WPARAM)hwnd, 0);if(!SendMessage(hwnd, WM_QUERYENDSESSION, 0, 0))return TRUE;SendMessage(GetParent(hwnd), WM_MDIDESTROY, (WPARAM)hwnd, 0);return TRUE;}LRESULT CALLBACK RectWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){static HWND hwndClient, hwndFrame;PRECTDATA pRectData;int iLeft, iRight, iTop, iBottom;short nRed, nGreen, nBlue;HDC hdc;PAINTSTRUCT ps;HBRUSH hBrush;switch(uMsg){case WM_CREATE:pRectData = (PRECTDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RECTDATA));SetWindowLong(hwnd, 0, (long)pRectData);SetTimer(hwnd, 1, 250, NULL);hwndClient = GetParent(hwnd);hwndFrame = GetParent(hwndClient);return 0;case WM_SIZE:if(wParam != SIZE_MINIMIZED){pRectData = (PRECTDATA)GetWindowLong(hwnd, 0);pRectData->cxClient = LOWORD(lParam);pRectData->cyClient = HIWORD(lParam);}break;case WM_TIMER:pRectData = (PRECTDATA)GetWindowLong(hwnd, 0);iLeft = rand() % pRectData->cxClient;iRight = rand() % pRectData->cxClient;;iTop = rand() % pRectData->cyClient;iBottom = rand() % pRectData->cyClient;nRed = rand() & 255;nGreen = rand() & 255;nBlue = rand() & 255;hdc = GetDC(hwnd);hBrush = CreateSolidBrush(RGB(nRed, nGreen, nBlue));SelectObject(hdc, hBrush);Rectangle(hdc, min(iLeft, iRight), min(iTop, iBottom), max(iLeft, iRight), max(iTop, iBottom));ReleaseDC(hwnd, hdc);DeleteObject(hBrush);return 0;case WM_PAINT:InvalidateRect(hwnd, NULL, TRUE);hdc = BeginPaint(hwnd, &ps);EndPaint(hwnd, &ps);return 0;case WM_MDIACTIVATE:if(lParam == (LPARAM)hwnd)SendMessage(hwndClient, WM_MDISETMENU, (WPARAM)hMenuRect, (LPARAM)hMenuRectWindow);elseSendMessage(hwndClient, WM_MDISETMENU, (WPARAM)hMenuInit, (LPARAM)hMenuInitWindow);DrawMenuBar(hwndFrame);return 0;case WM_DESTROY:pRectData = (PRECTDATA)GetWindowLong(hwnd, 0);HeapFree(GetProcessHeap(), 0, pRectData);KillTimer(hwnd, 1);//因为子窗口的创建与子窗口本身无关,而是由Client窗口创建的,所以不需要发送PostQuitMessage()return 0;}return DefMDIChildProc(hwnd, uMsg, wParam, lParam);}


0 0
原创粉丝点击