Code:
#include <windows.h>
#include <commctrl.h>
#define WIN_CLASS_NAME "Main Window"
#define WIN_MDI_CHILD "Child MDI Window"
#define ID_CLIENT 10
#define IDM_WINDOWCHILD 200
#define CM_MENU_FILE_EXIT 1001
#define CM_MENU_FILE_NEW 1004
#define CM_MENU_FILE_CLOSE 1005
#define CM_MENU_WINDOW_TILEH 1030
#define CM_MENU_WINDOW_TILEV 1031
#define CM_MENU_WINDOW_CASCADE 1032
#define CM_MENU_WINDOW_ARRANGE 1033
#define CM_MENU_HELP_ABOUT 1060
#define IDC_EDIT 5000
#define IDC_STATUSBAR 5001
HWND hWndMain;
HINSTANCE hInst;
HWND hWndClient;
HWND hWndStatusBar;
HWND hWndMDI;
HMENU hMenuMain;
HMENU hMenuFile;
HMENU hMenuWindow;
HMENU hMenuHelp;
MDICREATESTRUCT mcs; //MDI Structure
//Procedure Prototypes:
LRESULT CALLBACK MainWindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
LRESULT CALLBACK MDIChildWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hprevinstance,
LPSTR lpcmdline,int ncmdshow)
{
HWND hwnd;
MSG msg;
WNDCLASS winclass;
/*---------Main Window--------------------------------------------------------*/
winclass.style = CS_DBLCLKS;
winclass.lpfnWndProc = MainWindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WIN_CLASS_NAME;
hInst = hinstance;
if (!RegisterClass(&winclass))
return(0);
/*----------------------------------------------------------------------------*/
/******************************************************************************/
/*---------MDI Child Window---------------------------------------------------*/
winclass.lpfnWndProc = (WNDPROC) MDIChildWndProc;
winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winclass.lpszMenuName = (LPCTSTR) NULL;
winclass.lpszClassName = WIN_MDI_CHILD;
if (!RegisterClass(&winclass))
return(0);
/*----------------------------------------------------------------------------*/
/******************************************************************************/
if (!(hwnd = CreateWindowEx(NULL,WIN_CLASS_NAME,
"MDI Window",
WS_TILEDWINDOW | WS_MAXIMIZEBOX | WS_SIZEBOX ,
0 ,0 ,800,400,NULL,NULL,hinstance,NULL)))
return(0);
hWndMain = hwnd;
INITCOMMONCONTROLSEX initControls;
initControls.dwICC = ICC_BAR_CLASSES;
initControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCommonControlsEx(&initControls);
/* MDI message loop */
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
if (!TranslateMDISysAccel(hWndClient, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/* instead of */
/*
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
*/
return(msg.wParam);
}
LRESULT CALLBACK MainWindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
case WM_CREATE:
{
int cx, cy;
RECT rct;
/*-------------MAIN MENU------------------------------------------------*/
//simple menu creation
hMenuMain = CreateMenu();
hMenuFile = CreatePopupMenu();
hMenuWindow = CreatePopupMenu();
hMenuHelp = CreatePopupMenu();
AppendMenu(hMenuFile, MF_STRING, CM_MENU_FILE_NEW, "&New");
AppendMenu(hMenuFile, MF_STRING, CM_MENU_FILE_CLOSE, "&Close");
AppendMenu(hMenuFile, MF_SEPARATOR, NULL, NULL);
AppendMenu(hMenuFile, MF_STRING, CM_MENU_FILE_EXIT, "&Exit");
AppendMenu(hMenuWindow, MF_STRING, CM_MENU_WINDOW_TILEH, "Tile &Horizontally");
AppendMenu(hMenuWindow, MF_STRING, CM_MENU_WINDOW_TILEV, "Tile &Vertically");
AppendMenu(hMenuWindow, MF_STRING, CM_MENU_WINDOW_CASCADE, "&Cascade");
AppendMenu(hMenuWindow, MF_STRING, CM_MENU_WINDOW_ARRANGE, "&Arrange");
AppendMenu(hMenuHelp, MF_STRING, CM_MENU_HELP_ABOUT, "&About");
AppendMenu(hMenuMain, MF_STRING | MF_POPUP, (UINT)hMenuFile, "&File");
AppendMenu(hMenuMain, MF_STRING | MF_POPUP, (UINT)hMenuWindow, "&Window");
AppendMenu(hMenuMain, MF_STRING | MF_POPUP, (UINT)hMenuHelp, "&Help");
SetMenu(hwnd, hMenuMain);
/*----------------------------------------------------------------------*/
/************************************************************************/
/*-------------MDI hWndClient-----------------------------------------------*/
CLIENTCREATESTRUCT ccs; //hWndClient structure init
ccs.hWindowMenu = hMenuWindow; //menu to append window names
ccs.idFirstChild = IDM_WINDOWCHILD; //mdi window id start uint
hWndClient = CreateWindowEx(WS_EX_CLIENTEDGE, "MDIClient", (LPCTSTR) NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
0, 0, 0, 0,
hwnd, (HMENU) ID_CLIENT, hInst, (LPSTR) &ccs);
hWndStatusBar = CreateWindow(STATUSCLASSNAME, "",
SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
hwnd, (HMENU)IDC_STATUSBAR, hInst, NULL);
ShowWindow(hWndClient, SW_SHOW); //show the hWndClient
/*----------------------------------------------------------------------*/
/************************************************************************/
GetWindowRect(hwnd, &rct);
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
cx = (int)(double)(cx / 2) - (double)((rct.right - rct.left) / 2);
cy = (int)(double)(cy / 2) - (double)((rct.bottom - rct.top) / 2);
MoveWindow(hwnd, cx, cy, rct.right - rct.left, rct.bottom - rct.top, TRUE);
ShowWindow(hwnd, SW_SHOW);
}
break;
case WM_SIZE:
{
SendMessage(hWndStatusBar, WM_SIZE, 0, 0);
}
break;
case WM_COMMAND:
{
/*-------------Main Menu------------------------------------------------*/
if(LOWORD(wparam)== CM_MENU_FILE_NEW) //new mdi window
{
mcs.szTitle = "Untitled"; //fill the mdi struct
mcs.szClass = WIN_MDI_CHILD; //class name
mcs.hOwner = hInst; //application instance
mcs.x = CW_USEDEFAULT; //x
mcs.y = CW_USEDEFAULT; //y
mcs.cx = CW_USEDEFAULT; //cx
mcs.cy = CW_USEDEFAULT; //cy
mcs.style = MDIS_ALLCHILDSTYLES; //style
SendMessage(hWndClient, WM_MDICREATE, 0, (LONG)&mcs); //create the mdi child
break;
}
if(LOWORD(wparam)== CM_MENU_FILE_CLOSE) //close
{
SendMessage(hWndMDI, WM_CLOSE, 0, 0); //hWndMDI tracks active mdi child
break;
}
if(LOWORD(wparam)== CM_MENU_FILE_EXIT) //exit
{
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
if(LOWORD(wparam)== CM_MENU_WINDOW_TILEH) //tile horizontally
{
PostMessage(hWndClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
break;
}
if(LOWORD(wparam)== CM_MENU_WINDOW_TILEV) //tile vertically
{
PostMessage(hWndClient, WM_MDITILE, MDITILE_VERTICAL, 0);
break;
}
if(LOWORD(wparam)== CM_MENU_WINDOW_CASCADE) //cascade
{
PostMessage(hWndClient, WM_MDICASCADE, 0, 0);
break;
}
if(LOWORD(wparam)== CM_MENU_WINDOW_ARRANGE) //arrange -defined but doesnt
//do anything?
{
PostMessage(hWndClient, WM_MDIICONARRANGE, 0, 0);
break;
}
if(LOWORD(wparam)== CM_MENU_HELP_ABOUT) //about box
{
MessageBox(hwnd, "MDI Application Shell", "About:", MB_OK);
break;
}
/*----------------------------------------------------------------------*/
/************************************************************************/
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
}
break;
}
/* new */
return (DefFrameProc(hwnd, hWndClient, msg, wparam, lparam));
/* old */
//return (DefWindowProc(hwnd, msg, wparam, lparam));
}
RECT rect;
LRESULT CALLBACK MDIChildWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
case WM_CREATE:
{
HFONT hFont = CreateFont(10,0,0,0,0,0,0,0,0,0,0,0,0,"Courier");
GetClientRect(hwnd, &rect);
CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL
| ES_MULTILINE | ES_WANTRETURN,
0, 0, rect.right - rect.left, rect.bottom - rect.top,
hwnd, (HMENU)IDC_EDIT, hInst, NULL);
SendDlgItemMessage(hwnd, IDC_EDIT, WM_SETFONT, (WPARAM)hFont, 0);
ShowWindow(hwnd, SW_SHOW);
hWndMDI = hwnd; //set this to active
}break;
case WM_MDIACTIVATE:
{
hWndMDI = hwnd; //set this to active
}break;
case WM_SIZE:
{
GetClientRect(hwnd, &rect);
MoveWindow(GetDlgItem(hwnd, IDC_EDIT), 0, 0, rect.right - rect.left,
rect.bottom - rect.top, TRUE);
break;
}
case WM_SYSCOMMAND:
{
if(wparam == SC_CLOSE)
{
SendMessage(hwnd, WM_CLOSE, 0, 0);
}
}break;
}
return DefMDIChildProc(hwnd, msg, wparam, lparam);
}