2 Thanks to theForger from winprog.org
10 const char g_szClassName
[] = "myWindowClass";
11 const char g_szChildClassName
[] = "myMDIChildWindowClass";
13 #define IDC_MAIN_MDI 101
14 #define IDC_MAIN_TOOL 102
15 #define IDC_MAIN_STATUS 103
17 #define IDC_CHILD_EDIT 101
19 #define ID_MDI_FIRSTCHILD 50000
21 HWND g_hMDIClient
= NULL
;
22 HWND g_hMainWindow
= NULL
;
24 BOOL
LoadTextFileToEdit(HWND hEdit
, LPCTSTR pszFileName
)
27 BOOL bSuccess
= FALSE
;
29 hFile
= CreateFile(pszFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
30 OPEN_EXISTING
, 0, NULL
);
31 if(hFile
!= INVALID_HANDLE_VALUE
)
35 dwFileSize
= GetFileSize(hFile
, NULL
);
36 if(dwFileSize
!= 0xFFFFFFFF)
40 pszFileText
= GlobalAlloc(GPTR
, dwFileSize
+ 1);
41 if(pszFileText
!= NULL
)
45 if(ReadFile(hFile
, pszFileText
, dwFileSize
, &dwRead
, NULL
))
47 pszFileText
[dwFileSize
] = 0; // Add null terminator
48 if(SetWindowText(hEdit
, pszFileText
))
49 bSuccess
= TRUE
; // It worked!
51 GlobalFree(pszFileText
);
59 BOOL
SaveTextFileFromEdit(HWND hEdit
, LPCTSTR pszFileName
)
62 BOOL bSuccess
= FALSE
;
64 hFile
= CreateFile(pszFileName
, GENERIC_WRITE
, 0, NULL
,
65 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
66 if(hFile
!= INVALID_HANDLE_VALUE
)
70 dwTextLength
= GetWindowTextLength(hEdit
);
71 // No need to bother if there's no text.
75 DWORD dwBufferSize
= dwTextLength
+ 1;
77 pszText
= GlobalAlloc(GPTR
, dwBufferSize
);
80 if(GetWindowText(hEdit
, pszText
, dwBufferSize
))
84 if(WriteFile(hFile
, pszText
, dwTextLength
, &dwWritten
, NULL
))
95 void DoFileOpen(HWND hwnd
)
98 char szFileName
[MAX_PATH
] = "";
100 ZeroMemory(&ofn
, sizeof(ofn
));
102 ofn
.lStructSize
= sizeof(ofn
);
103 ofn
.hwndOwner
= hwnd
;
104 ofn
.lpstrFilter
= "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
105 ofn
.lpstrFile
= szFileName
;
106 ofn
.nMaxFile
= MAX_PATH
;
107 ofn
.Flags
= OFN_EXPLORER
| OFN_FILEMUSTEXIST
| OFN_HIDEREADONLY
;
108 ofn
.lpstrDefExt
= "txt";
110 if(GetOpenFileName(&ofn
))
112 HWND hEdit
= GetDlgItem(hwnd
, IDC_CHILD_EDIT
);
113 if(LoadTextFileToEdit(hEdit
, szFileName
))
115 SendDlgItemMessage(g_hMainWindow
, IDC_MAIN_STATUS
, SB_SETTEXT
, 0, (LPARAM
)"Opened...");
116 SendDlgItemMessage(g_hMainWindow
, IDC_MAIN_STATUS
, SB_SETTEXT
, 1, (LPARAM
)szFileName
);
118 SetWindowText(hwnd
, szFileName
);
123 void DoFileSave(HWND hwnd
)
126 char szFileName
[MAX_PATH
] = "";
128 ZeroMemory(&ofn
, sizeof(ofn
));
130 ofn
.lStructSize
= sizeof(ofn
);
131 ofn
.hwndOwner
= hwnd
;
132 ofn
.lpstrFilter
= "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
133 ofn
.lpstrFile
= szFileName
;
134 ofn
.nMaxFile
= MAX_PATH
;
135 ofn
.lpstrDefExt
= "txt";
136 ofn
.Flags
= OFN_EXPLORER
| OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
138 if(GetSaveFileName(&ofn
))
140 HWND hEdit
= GetDlgItem(hwnd
, IDC_CHILD_EDIT
);
141 if(SaveTextFileFromEdit(hEdit
, szFileName
))
143 SendDlgItemMessage(g_hMainWindow
, IDC_MAIN_STATUS
, SB_SETTEXT
, 0, (LPARAM
)"Saved...");
144 SendDlgItemMessage(g_hMainWindow
, IDC_MAIN_STATUS
, SB_SETTEXT
, 1, (LPARAM
)szFileName
);
146 SetWindowText(hwnd
, szFileName
);
151 HWND
CreateNewMDIChild(HWND hMDIClient
)
156 mcs
.szTitle
= "[Untitled]";
157 mcs
.szClass
= g_szChildClassName
;
158 mcs
.hOwner
= GetModuleHandle(NULL
);
159 mcs
.x
= mcs
.cx
= CW_USEDEFAULT
;
160 mcs
.y
= mcs
.cy
= CW_USEDEFAULT
;
161 mcs
.style
= MDIS_ALLCHILDSTYLES
;
163 hChild
= (HWND
)SendMessage(hMDIClient
, WM_MDICREATE
, 0, (LONG
)&mcs
);
166 MessageBox(hMDIClient
, "MDI Child creation failed.", "Oh Oh...",
167 MB_ICONEXCLAMATION
| MB_OK
);
172 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
183 int statwidths
[] = {100, -1};
185 CLIENTCREATESTRUCT ccs
;
189 // Find window menu where children will be listed
190 ccs
.hWindowMenu
= GetSubMenu(GetMenu(hwnd
), 2);
191 ccs
.idFirstChild
= ID_MDI_FIRSTCHILD
;
193 g_hMDIClient
= CreateWindowEx(WS_EX_CLIENTEDGE
, "mdiclient", NULL
,
194 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
| WS_VISIBLE
,
195 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
196 hwnd
, (HMENU
)IDC_MAIN_MDI
, GetModuleHandle(NULL
), (LPVOID
)&ccs
);
198 if(g_hMDIClient
== NULL
)
199 MessageBox(hwnd
, "Could not create MDI client.", "Error", MB_OK
| MB_ICONERROR
);
203 hTool
= CreateWindowEx(0, TOOLBARCLASSNAME
, NULL
, WS_CHILD
| WS_VISIBLE
, 0, 0, 0, 0,
204 hwnd
, (HMENU
)IDC_MAIN_TOOL
, GetModuleHandle(NULL
), NULL
);
206 MessageBox(hwnd
, "Could not create tool bar.", "Error", MB_OK
| MB_ICONERROR
);
208 // Send the TB_BUTTONSTRUCTSIZE message, which is required for
209 // backward compatibility.
210 SendMessage(hTool
, TB_BUTTONSTRUCTSIZE
, (WPARAM
)sizeof(TBBUTTON
), 0);
212 tbab
.hInst
= HINST_COMMCTRL
;
213 tbab
.nID
= IDB_STD_SMALL_COLOR
;
214 SendMessage(hTool
, TB_ADDBITMAP
, 0, (LPARAM
)&tbab
);
216 ZeroMemory(tbb
, sizeof(tbb
));
217 tbb
[0].iBitmap
= STD_FILENEW
;
218 tbb
[0].fsState
= TBSTATE_ENABLED
;
219 tbb
[0].fsStyle
= TBSTYLE_BUTTON
;
220 tbb
[0].idCommand
= ID_FILE_NEW
;
222 tbb
[1].iBitmap
= STD_FILEOPEN
;
223 tbb
[1].fsState
= TBSTATE_ENABLED
;
224 tbb
[1].fsStyle
= TBSTYLE_BUTTON
;
225 tbb
[1].idCommand
= ID_FILE_OPEN
;
227 tbb
[2].iBitmap
= STD_FILESAVE
;
228 tbb
[2].fsState
= TBSTATE_ENABLED
;
229 tbb
[2].fsStyle
= TBSTYLE_BUTTON
;
230 tbb
[2].idCommand
= ID_FILE_SAVEAS
;
232 SendMessage(hTool
, TB_ADDBUTTONS
, sizeof(tbb
)/sizeof(TBBUTTON
), (LPARAM
)&tbb
);
236 hStatus
= CreateWindowEx(0, STATUSCLASSNAME
, NULL
,
237 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
, 0, 0, 0, 0,
238 hwnd
, (HMENU
)IDC_MAIN_STATUS
, GetModuleHandle(NULL
), NULL
);
240 SendMessage(hStatus
, SB_SETPARTS
, sizeof(statwidths
)/sizeof(int), (LPARAM
)statwidths
);
241 SendMessage(hStatus
, SB_SETTEXT
, 0, (LPARAM
)"Hi there :)");
258 // Size toolbar and get height
260 hTool
= GetDlgItem(hwnd
, IDC_MAIN_TOOL
);
261 SendMessage(hTool
, TB_AUTOSIZE
, 0, 0);
263 GetWindowRect(hTool
, &rcTool
);
264 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
266 // Size status bar and get height
268 hStatus
= GetDlgItem(hwnd
, IDC_MAIN_STATUS
);
269 SendMessage(hStatus
, WM_SIZE
, 0, 0);
271 GetWindowRect(hStatus
, &rcStatus
);
272 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
274 // Calculate remaining height and size edit
276 GetClientRect(hwnd
, &rcClient
);
278 iMDIHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
280 hMDI
= GetDlgItem(hwnd
, IDC_MAIN_MDI
);
281 SetWindowPos(hMDI
, NULL
, 0, iToolHeight
, rcClient
.right
, iMDIHeight
, SWP_NOZORDER
);
291 switch(LOWORD(wParam
))
294 PostMessage(hwnd
, WM_CLOSE
, 0, 0);
297 CreateNewMDIChild(g_hMDIClient
);
301 HWND hChild
= CreateNewMDIChild(g_hMDIClient
);
310 HWND hChild
= (HWND
)SendMessage(g_hMDIClient
, WM_MDIGETACTIVE
,0,0);
313 SendMessage(hChild
, WM_CLOSE
, 0, 0);
318 SendMessage(g_hMDIClient
, WM_MDITILE
, 0, 0);
320 case ID_WINDOW_CASCADE
:
321 SendMessage(g_hMDIClient
, WM_MDICASCADE
, 0, 0);
325 if(LOWORD(wParam
) >= ID_MDI_FIRSTCHILD
)
327 DefFrameProc(hwnd
, g_hMDIClient
, WM_COMMAND
, wParam
, lParam
);
331 HWND hChild
= (HWND
)SendMessage(g_hMDIClient
, WM_MDIGETACTIVE
,0,0);
334 SendMessage(hChild
, WM_COMMAND
, wParam
, lParam
);
341 return DefFrameProc(hwnd
, g_hMDIClient
, msg
, wParam
, lParam
);
346 LRESULT CALLBACK
MDIChildWndProc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
355 // Create Edit Control
357 hEdit
= CreateWindowEx(WS_EX_CLIENTEDGE
, "EDIT", "",
358 WS_CHILD
| WS_VISIBLE
| WS_VSCROLL
| WS_HSCROLL
| ES_MULTILINE
| ES_AUTOVSCROLL
| ES_AUTOHSCROLL
,
359 0, 0, 100, 100, hwnd
, (HMENU
)IDC_CHILD_EDIT
, GetModuleHandle(NULL
), NULL
);
361 MessageBox(hwnd
, "Could not create edit box.", "Error", MB_OK
| MB_ICONERROR
);
363 hfDefault
= GetStockObject(DEFAULT_GUI_FONT
);
364 SendMessage(hEdit
, WM_SETFONT
, (WPARAM
)hfDefault
, MAKELPARAM(FALSE
, 0));
369 HMENU hMenu
, hFileMenu
;
372 hMenu
= GetMenu(g_hMainWindow
);
373 if(hwnd
== (HWND
)lParam
)
374 { //being activated, enable the menus
375 EnableFlag
= MF_ENABLED
;
378 { //being de-activated, gray the menus
379 EnableFlag
= MF_GRAYED
;
382 EnableMenuItem(hMenu
, 1, MF_BYPOSITION
| EnableFlag
);
383 EnableMenuItem(hMenu
, 2, MF_BYPOSITION
| EnableFlag
);
385 hFileMenu
= GetSubMenu(hMenu
, 0);
386 EnableMenuItem(hFileMenu
, ID_FILE_SAVEAS
, MF_BYCOMMAND
| EnableFlag
);
388 EnableMenuItem(hFileMenu
, ID_FILE_CLOSE
, MF_BYCOMMAND
| EnableFlag
);
389 EnableMenuItem(hFileMenu
, ID_FILE_CLOSEALL
, MF_BYCOMMAND
| EnableFlag
);
391 DrawMenuBar(g_hMainWindow
);
395 switch(LOWORD(wParam
))
404 SendDlgItemMessage(hwnd
, IDC_CHILD_EDIT
, WM_CUT
, 0, 0);
407 SendDlgItemMessage(hwnd
, IDC_CHILD_EDIT
, WM_COPY
, 0, 0);
410 SendDlgItemMessage(hwnd
, IDC_CHILD_EDIT
, WM_PASTE
, 0, 0);
419 // Calculate remaining height and size edit
421 GetClientRect(hwnd
, &rcClient
);
423 hEdit
= GetDlgItem(hwnd
, IDC_CHILD_EDIT
);
424 SetWindowPos(hEdit
, NULL
, 0, 0, rcClient
.right
, rcClient
.bottom
, SWP_NOZORDER
);
426 return DefMDIChildProc(hwnd
, msg
, wParam
, lParam
);
428 return DefMDIChildProc(hwnd
, msg
, wParam
, lParam
);
434 BOOL
SetUpMDIChildWindowClass(HINSTANCE hInstance
)
438 wc
.cbSize
= sizeof(WNDCLASSEX
);
439 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
440 wc
.lpfnWndProc
= MDIChildWndProc
;
443 wc
.hInstance
= hInstance
;
444 wc
.hIcon
= LoadIcon(NULL
, (LPCTSTR
)IDI_APPLICATION
);
445 wc
.hCursor
= LoadCursor(NULL
, (LPCTSTR
)IDC_ARROW
);
446 wc
.hbrBackground
= (HBRUSH
)(COLOR_3DFACE
+1);
447 wc
.lpszMenuName
= NULL
;
448 wc
.lpszClassName
= g_szChildClassName
;
449 wc
.hIconSm
= LoadIcon(NULL
, (LPCTSTR
)IDI_APPLICATION
);
451 if(!RegisterClassEx(&wc
))
453 MessageBox(0, "Could Not Register Child Window", "Oh Oh...",
454 MB_ICONEXCLAMATION
| MB_OK
);
462 int WINAPI
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
,
463 LPSTR lpCmdLine
, int nCmdShow
)
469 InitCommonControls();
471 wc
.cbSize
= sizeof(WNDCLASSEX
);
473 wc
.lpfnWndProc
= WndProc
;
476 wc
.hInstance
= hInstance
;
477 wc
.hIcon
= LoadIcon(NULL
, (LPCTSTR
)IDI_APPLICATION
);
478 wc
.hCursor
= LoadCursor(NULL
, (LPCTSTR
)IDC_ARROW
);
479 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+1);
480 wc
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
481 wc
.lpszClassName
= g_szClassName
;
482 wc
.hIconSm
= LoadIcon(NULL
, (LPCTSTR
)IDI_APPLICATION
);
484 if(!RegisterClassEx(&wc
))
486 MessageBox(NULL
, "Window Registration Failed!", "Error!",
487 MB_ICONEXCLAMATION
| MB_OK
);
491 if(!SetUpMDIChildWindowClass(hInstance
))
494 hwnd
= CreateWindowEx(
497 "MDI Test Application",
498 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
,
499 CW_USEDEFAULT
, CW_USEDEFAULT
, 480, 320,
500 NULL
, NULL
, hInstance
, NULL
);
504 MessageBox(NULL
, "Window Creation Failed!", "Error!",
505 MB_ICONEXCLAMATION
| MB_OK
);
509 g_hMainWindow
= hwnd
;
511 ShowWindow(hwnd
, nCmdShow
);
514 while(GetMessage(&Msg
, NULL
, 0, 0) > 0)
516 if (!TranslateMDISysAccel(g_hMDIClient
, &Msg
))
518 TranslateMessage(&Msg
);
519 DispatchMessage(&Msg
);