Updated with latest work. Still far to go...
[reactos.git] / rosapps / winfile / framewnd.c
1 /*
2 * ReactOS winfile
3 *
4 * framewnd.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #ifdef _MSC_VER
24 #include "stdafx.h"
25 #else
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 #include <memory.h>
32 #include <tchar.h>
33 #include <process.h>
34 #include <stdio.h>
35 #endif
36
37 //#include <shellapi.h>
38 #include <windowsx.h>
39 #include <assert.h>
40 #define ASSERT assert
41
42 #include "main.h"
43 #include "about.h"
44 #include "framewnd.h"
45 #include "childwnd.h"
46 #include "utils.h"
47 #include "run.h"
48 #include "format.h"
49 #include "dialogs.h"
50
51
52 ////////////////////////////////////////////////////////////////////////////////
53 // Global Variables:
54 //
55
56 BOOL bInMenuLoop = FALSE; // Tells us if we are in the menu loop
57 int nOldWidth; // Holds the previous client area width
58 int nOldHeight; // Holds the previous client area height
59
60
61 ////////////////////////////////////////////////////////////////////////////////
62 // Local module support methods
63 //
64
65 static void resize_frame_rect(HWND hWnd, PRECT prect)
66 {
67 int new_top;
68 RECT rt;
69
70 if (IsWindowVisible(Globals.hToolBar)) {
71 SendMessage(Globals.hToolBar, WM_SIZE, 0, 0);
72 GetClientRect(Globals.hToolBar, &rt);
73 prect->top = rt.bottom+3;
74 prect->bottom -= rt.bottom+3;
75 }
76 if (IsWindowVisible(Globals.hDriveBar)) {
77 SendMessage(Globals.hDriveBar, WM_SIZE, 0, 0);
78 GetClientRect(Globals.hDriveBar, &rt);
79 new_top = --prect->top + rt.bottom+3;
80 MoveWindow(Globals.hDriveBar, 0, prect->top, rt.right, new_top, TRUE);
81 prect->top = new_top;
82 prect->bottom -= rt.bottom+2;
83 }
84 if (IsWindowVisible(Globals.hStatusBar)) {
85 SetupStatusBar(TRUE);
86 // int parts[] = {300, 500};
87 // SendMessage(Globals.hStatusBar, WM_SIZE, 0, 0);
88 // SendMessage(Globals.hStatusBar, SB_SETPARTS, 2, (LPARAM)&parts);
89 GetClientRect(Globals.hStatusBar, &rt);
90 prect->bottom -= rt.bottom;
91 }
92 MoveWindow(Globals.hMDIClient, prect->left-1,prect->top-1,prect->right+2,prect->bottom+1, TRUE);
93 }
94
95 static void resize_frame(HWND hWnd, int cx, int cy)
96 {
97 RECT rect = {0, 0, cx, cy};
98
99 resize_frame_rect(hWnd, &rect);
100 }
101
102 void resize_frame_client(HWND hWnd)
103 {
104 RECT rect;
105
106 GetClientRect(hWnd, &rect);
107 resize_frame_rect(hWnd, &rect);
108 }
109
110 ////////////////////////////////////////////////////////////////////////////////
111 static HHOOK hcbthook;
112 static ChildWnd* newchild = NULL;
113
114 static LRESULT CALLBACK CBTProc(int code, WPARAM wParam, LPARAM lParam)
115 {
116 if (code == HCBT_CREATEWND && newchild) {
117 ChildWnd* pChildWnd = newchild;
118 newchild = NULL;
119 pChildWnd->hWnd = (HWND)wParam;
120 SetWindowLong(pChildWnd->hWnd, GWL_USERDATA, (LPARAM)pChildWnd);
121 }
122 return CallNextHookEx(hcbthook, code, wParam, lParam);
123 }
124
125
126 /*
127 BOOL FindChildWindow(int cmd)
128 {
129 TCHAR drv[_MAX_DRIVE];
130 LPCTSTR root = Globals.drives;
131 int i;
132 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
133 while(*root)
134 root++;
135 if (activate_drive_window(root))
136 return TRUE;
137 _tsplitpath(root, drv, 0, 0, 0);
138 if (!SetCurrentDirectory(drv)) {
139 display_error(hWnd, GetLastError());
140 //return TRUE;
141 }
142 return FALSE;
143 }
144 */
145
146 static ChildWnd* alloc_child_window(LPCTSTR path)
147 {
148 TCHAR drv[_MAX_DRIVE+1], dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT];
149 ChildWnd* pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd));
150 Root* root = &pChildWnd->root;
151 Entry* entry;
152
153 memset(pChildWnd, 0, sizeof(ChildWnd));
154 pChildWnd->left.treePane = TRUE;
155 pChildWnd->left.visible_cols = 0;
156 pChildWnd->right.treePane = FALSE;
157 #ifndef _NO_EXTENSIONS
158 pChildWnd->right.visible_cols = COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_INDEX|COL_LINKS;
159 #else
160 pChildWnd->right.visible_cols = COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES;
161 #endif
162 pChildWnd->pos.length = sizeof(WINDOWPLACEMENT);
163 pChildWnd->pos.flags = 0;
164 pChildWnd->pos.showCmd = SW_SHOWNORMAL;
165 pChildWnd->pos.rcNormalPosition.left = CW_USEDEFAULT;
166 pChildWnd->pos.rcNormalPosition.top = CW_USEDEFAULT;
167 pChildWnd->pos.rcNormalPosition.right = CW_USEDEFAULT;
168 pChildWnd->pos.rcNormalPosition.bottom = CW_USEDEFAULT;
169 pChildWnd->nFocusPanel = 0;
170 pChildWnd->nSplitPos = 200;
171 pChildWnd->sortOrder = SORT_NAME;
172 pChildWnd->header_wdths_ok = FALSE;
173 lstrcpy(pChildWnd->szPath, path);
174 _tsplitpath(path, drv, dir, name, ext);
175 #if !defined(_NO_EXTENSIONS) && defined(__linux__)
176 if (*path == '/') {
177 root->drive_type = GetDriveType(path);
178 lstrcat(drv, _T("/"));
179 lstrcpy(root->volname, _T("root fs"));
180 root->fs_flags = 0;
181 lstrcpy(root->fs, _T("unixfs"));
182 lstrcpy(root->path, _T("/"));
183 entry = read_tree_unix(root, path, pChildWnd->sortOrder);
184 } else
185 #endif
186 {
187 root->drive_type = GetDriveType(path);
188 lstrcat(drv, _T("\\"));
189 GetVolumeInformation(drv, root->volname, _MAX_FNAME, 0, 0, &root->fs_flags, root->fs, _MAX_DIR);
190 lstrcpy(root->path, drv);
191 entry = read_tree_win(root, path, pChildWnd->sortOrder);
192 }
193 //@@lstrcpy(root->entry.data.cFileName, drv);
194 wsprintf(root->entry.data.cFileName, _T("%s - %s"), drv, root->fs);
195 root->entry.data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
196 pChildWnd->left.root = &root->entry;
197 set_curdir(pChildWnd, entry);
198 return pChildWnd;
199 }
200
201 HWND CreateChildWindow(int drv_id)
202 {
203 //TCHAR drv[_MAX_DRIVE];
204 TCHAR path[MAX_PATH];
205 ChildWnd* pChildWnd = NULL;
206 /*
207 LPCTSTR root = Globals.drives;
208 int i;
209 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
210 while(*root)
211 root++;
212 if (activate_drive_window(root))
213 return 0;
214 _tsplitpath(root, drv, 0, 0, 0);
215 if (!SetCurrentDirectory(drv)) {
216 display_error(hWnd, GetLastError());
217 return 0;
218 }
219 */
220 GetCurrentDirectory(MAX_PATH, path);
221 // pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd));
222 pChildWnd = alloc_child_window(path);
223 // if (!create_child_window(pChildWnd))
224 // free(pChildWnd);
225
226 if (pChildWnd != NULL) {
227 MDICREATESTRUCT mcs = {
228 szChildClass, path, hInst,
229 CW_USEDEFAULT, CW_USEDEFAULT,
230 CW_USEDEFAULT, CW_USEDEFAULT,
231 0/*style*/, 0/*lParam*/
232 };
233 hcbthook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId());
234 newchild = pChildWnd;
235 pChildWnd->hWnd = (HWND)SendMessage(Globals.hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs);
236 UnhookWindowsHookEx(hcbthook);
237 if (pChildWnd->hWnd == NULL) {
238 free(pChildWnd);
239 newchild = pChildWnd = NULL;
240 }
241 return pChildWnd->hWnd;
242 }
243 return 0;
244 }
245
246 BOOL CALLBACK CloseEnumProc(HWND hWnd, LPARAM lParam)
247 {
248 if (!GetWindow(hWnd, GW_OWNER)) {
249 SendMessage(GetParent(hWnd), WM_MDIRESTORE, (WPARAM)hWnd, 0);
250 if (SendMessage(hWnd, WM_QUERYENDSESSION, 0, 0)) {
251 SendMessage(GetParent(hWnd), WM_MDIDESTROY, (WPARAM)hWnd, 0);
252 }
253 }
254 return 1;
255 }
256
257 void OnEnterMenuLoop(HWND hWnd)
258 {
259 int nParts;
260
261 // Update the status bar pane sizes
262 nParts = -1;
263 SendMessage(Globals.hStatusBar, SB_SETPARTS, 1, (long)&nParts);
264 bInMenuLoop = TRUE;
265 SendMessage(Globals.hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
266 }
267
268 void OnExitMenuLoop(HWND hWnd)
269 {
270 RECT rc;
271 int nParts[3];
272
273 bInMenuLoop = FALSE;
274 // Update the status bar pane sizes
275 GetClientRect(hWnd, &rc);
276 nParts[0] = 100;
277 nParts[1] = 210;
278 nParts[2] = rc.right;
279 SendMessage(Globals.hStatusBar, SB_SETPARTS, 3, (long)nParts);
280 SendMessage(Globals.hStatusBar, SB_SETTEXT, 0, (LPARAM)_T(""));
281 SetupStatusBar(TRUE);
282 UpdateStatusBar();
283 }
284
285 void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
286 {
287 TCHAR str[100];
288
289 strcpy(str, TEXT(""));
290 if (nFlags & MF_POPUP) {
291 if (hSysMenu != GetMenu(hWnd)) {
292 if (nItemID == 2) nItemID = 5;
293 }
294 }
295 if (LoadString(Globals.hInstance, nItemID, str, 100)) {
296 // load appropriate string
297 LPTSTR lpsz = str;
298 // first newline terminates actual string
299 lpsz = _tcschr(lpsz, '\n');
300 if (lpsz != NULL)
301 *lpsz = '\0';
302 }
303 SendMessage(Globals.hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
304 }
305
306
307 static BOOL activate_drive_window(LPCTSTR path)
308 {
309 TCHAR drv1[_MAX_DRIVE], drv2[_MAX_DRIVE];
310 HWND child_wnd;
311
312 _tsplitpath(path, drv1, 0, 0, 0);
313
314 // search for a already open window for the same drive
315 for (child_wnd = GetNextWindow(Globals.hMDIClient,GW_CHILD);
316 child_wnd;
317 child_wnd = GetNextWindow(child_wnd, GW_HWNDNEXT)) {
318 ChildWnd* pChildWnd = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA);
319 if (pChildWnd) {
320 _tsplitpath(pChildWnd->root.path, drv2, 0, 0, 0);
321 if (!lstrcmpi(drv2, drv1)) {
322 SendMessage(Globals.hMDIClient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0);
323 if (IsMinimized(child_wnd))
324 ShowWindow(child_wnd, SW_SHOWNORMAL);
325 return TRUE;
326 }
327 }
328 }
329 return FALSE;
330 }
331
332 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
333 {
334 BOOL vis = IsWindowVisible(hchild);
335
336 CheckMenuItem(Globals.hMenuOptions, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
337 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
338 #ifndef _NO_EXTENSIONS
339 if (g_fullscreen.mode)
340 fullscreen_move(hWnd);
341 #endif
342 resize_frame_client(hWnd);
343 }
344
345 ////////////////////////////////////////////////////////////////////////////////
346
347
348 LRESULT CALLBACK EnumNetConnectionsProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
349 {
350 return 0;
351 }
352
353 /*
354 DWORD WNetOpenEnum(
355 DWORD dwScope, // scope of enumeration
356 DWORD dwType, // resource types to list
357 DWORD dwUsage, // resource usage to list
358 LPNETRESOURCE lpNetResource, // resource structure
359 LPHANDLE lphEnum // enumeration handle buffer
360 );
361
362 result = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, RESOURCEUSAGE_ALL, NULL, &EnumNetConnectionsProc);
363
364 */
365 DWORD MapNetworkDrives(HWND hWnd, BOOL connect)
366 {
367 DWORD result = 0L;
368 #if 1
369 if (connect) {
370 WNetConnectionDialog(hWnd, RESOURCETYPE_DISK);
371 } else {
372 WNetDisconnectDialog(hWnd, RESOURCETYPE_DISK);
373 }
374 #else
375 if (connect) {
376 NETRESOURCE netResouce;
377 CONNECTDLGSTRUCT connectDlg;
378
379 //netResouce.dwScope;
380 //netResouce.dwType;
381 netResouce.dwDisplayType = 0;
382 //netResouce.dwUsage;
383 //netResouce.lpLocalName;
384 //netResouce.lpRemoteName;
385 //netResouce.lpComment;
386 //netResouce.lpProvider;
387
388 //connectDlg.cbStructure;
389 connectDlg.hwndOwner = hWnd;
390 connectDlg.lpConnRes = &netResouce;
391 //connectDlg.dwFlags;
392 //connectDlg.dwDevNum;
393
394 result = WNetConnectionDialog1(&connectDlg);
395 } else {
396 DISCDLGSTRUCT disconnectDlg;
397 //disconnectDlg.cbStructure;
398 disconnectDlg.hwndOwner = hWnd;
399 //disconnectDlg.lpLocalName;
400 //disconnectDlg.lpRemoteName;
401 //disconnectDlg.dwFlags;
402 result = WNetDisconnectDialog1(&disconnectDlg);
403 }
404 #endif
405 return result;
406 }
407
408 ////////////////////////////////////////////////////////////////////////////////
409 //
410 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
411 //
412 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
413 //
414 //
415
416 LRESULT _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
417 {
418 UINT cmd = LOWORD(wParam);
419 HWND hChildWnd;
420 // HWND hwndClient = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
421 // if (hwndClient)
422 // if (SendMessage(hwndClient, WM_DISPATCH_COMMAND, wParam, lParam))
423 // return 0;
424
425 if (cmd >= ID_DRIVE_FIRST && cmd <= (ID_DRIVE_FIRST + 0xFF)) {
426 TCHAR drv[_MAX_DRIVE];
427 //TCHAR path[MAX_PATH];
428 //ChildWnd* pChildWnd;
429 LPCTSTR root = Globals.drives;
430 int i;
431 for (i = cmd - ID_DRIVE_FIRST; i--; root++)
432 while (*root)
433 root++;
434 if (activate_drive_window(root))
435 return 0;
436 _tsplitpath(root, drv, 0, 0, 0);
437 if (!SetCurrentDirectory(drv)) {
438 display_error(hWnd, GetLastError());
439 return 0;
440 }
441 //GetCurrentDirectory(MAX_PATH, path); //@@ letztes Verzeichnis pro Laufwerk speichern
442 //CreateChildWindow(path);
443 CreateChildWindow(cmd - ID_DRIVE_FIRST);
444
445 // pChildWnd = alloc_child_window(path);
446 // if (!create_child_window(pChildWnd))
447 // free(pChildWnd);
448 } else {
449 switch (cmd) {
450 case ID_WINDOW_CLOSEALL:
451 EnumChildWindows(Globals.hMDIClient, &CloseEnumProc, 0);
452 break;
453 case ID_WINDOW_CLOSE:
454 hChildWnd = (HWND) SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
455 if (!SendMessage(hChildWnd, WM_QUERYENDSESSION, 0, 0))
456 SendMessage(Globals.hMDIClient, WM_MDIDESTROY, (WPARAM)hChildWnd, 0);
457 break;
458 case ID_FILE_EXIT:
459 SendMessage(hWnd, WM_CLOSE, 0, 0);
460 break;
461 case ID_FILE_RUN:
462 OnFileRun();
463 break;
464 case ID_DISK_COPY_DISK:
465 break;
466 case ID_DISK_LABEL_DISK:
467 break;
468 case ID_DISK_FORMAT_DISK:
469 // SHFormatDrive(hWnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
470 {
471 UINT OldMode = SetErrorMode(0); // Get the current Error Mode settings.
472 SetErrorMode(OldMode & ~SEM_FAILCRITICALERRORS); // Force O/S to handle
473 // Call SHFormatDrive here.
474 SHFormatDrive(hWnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
475 SetErrorMode(OldMode); // Put it back the way it was.
476 }
477 break;
478 case ID_DISK_CONNECT_NETWORK_DRIVE:
479 MapNetworkDrives(hWnd, TRUE);
480 break;
481 case ID_DISK_DISCONNECT_NETWORK_DRIVE:
482 MapNetworkDrives(hWnd, FALSE);
483 break;
484 case ID_DISK_SHARE_AS:
485 break;
486 case ID_DISK_STOP_SHARING:
487 break;
488 case ID_DISK_SELECT_DRIVE:
489 break;
490
491
492 case ID_VIEW_BY_FILE_TYPE:
493 {
494 struct ExecuteDialog dlg = {{0}};
495 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_VIEW_TYPE), hWnd, ViewFileTypeWndProc, (LPARAM)&dlg) == IDOK) {
496 }
497 }
498 break;
499 case ID_OPTIONS_CONFIRMATION:
500 {
501 struct ExecuteDialog dlg = {{0}};
502 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_OPTIONS_CONFIRMATON), hWnd, OptionsConfirmationWndProc, (LPARAM)&dlg) == IDOK) {
503 }
504 }
505 break;
506 case ID_OPTIONS_FONT:
507 break;
508 case ID_OPTIONS_CUSTOMISE_TOOLBAR:
509 break;
510 case ID_OPTIONS_TOOLBAR:
511 toggle_child(hWnd, cmd, Globals.hToolBar);
512 break;
513 case ID_OPTIONS_DRIVEBAR:
514 toggle_child(hWnd, cmd, Globals.hDriveBar);
515 break;
516 case ID_OPTIONS_STATUSBAR:
517 toggle_child(hWnd, cmd, Globals.hStatusBar);
518 break;
519 case ID_OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT:
520 break;
521 case ID_OPTIONS_MINIMISE_ON_USE:
522 break;
523 case ID_OPTIONS_SAVE_ON_EXIT:
524 break;
525
526 case ID_WINDOW_NEW_WINDOW:
527 CreateChildWindow(-1);
528 // {
529 // ChildWnd* pChildWnd = alloc_child_window(path);
530 // if (!create_child_window(pChildWnd))
531 // free(pChildWnd);
532 // }
533 break;
534 case ID_WINDOW_CASCADE:
535 SendMessage(Globals.hMDIClient, WM_MDICASCADE, 0, 0);
536 break;
537 case ID_WINDOW_TILE_HORZ:
538 SendMessage(Globals.hMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
539 break;
540 case ID_WINDOW_TILE_VERT:
541 SendMessage(Globals.hMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
542 break;
543 case ID_WINDOW_ARRANGE_ICONS:
544 SendMessage(Globals.hMDIClient, WM_MDIICONARRANGE, 0, 0);
545 break;
546 case ID_HELP_CONTENTS:
547 WinHelp(hWnd, _T("winfile"), HELP_INDEX, 0);
548 break;
549 case ID_HELP_SEARCH_HELP:
550 break;
551 case ID_HELP_HOW_TO_USE_HELP:
552 #ifdef WINSHELLAPI
553 ShellAbout(hWnd, szTitle, "", LoadIcon(Globals.hInstance, (LPCTSTR)IDI_WINFILE));
554 #endif
555 break;
556 case ID_HELP_ABOUT:
557 ShowAboutBox(hWnd);
558 break;
559 default:
560 /*
561 if ((cmd<IDW_FIRST_CHILD || cmd>=IDW_FIRST_CHILD+0x100) &&
562 (cmd<SC_SIZE || cmd>SC_RESTORE)) {
563 MessageBox(hWnd, _T("Not yet implemented"), _T("Winefile"), MB_OK);
564 }
565 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
566 */
567 hChildWnd = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
568 if (IsWindow(hChildWnd))
569 SendMessage(hChildWnd, WM_COMMAND, wParam, lParam);
570 else
571 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
572 }
573 }
574 return 0;
575 }
576
577
578 ////////////////////////////////////////////////////////////////////////////////
579 //
580 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
581 //
582 // PURPOSE: Processes messages for the main frame window.
583 //
584 // WM_COMMAND - process the application menu
585 // WM_DESTROY - post a quit message and return
586 //
587 //
588
589 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
590 {
591 switch (message) {
592 case WM_CREATE:
593 {
594 HMENU hMenuWindow = GetSubMenu(Globals.hMenuFrame, GetMenuItemCount(Globals.hMenuFrame)-2);
595 CLIENTCREATESTRUCT ccs = { hMenuWindow, IDW_FIRST_CHILD };
596 #if 0
597 hMDIClient = CreateWindow(_T("MDICLIENT"), NULL,
598 WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,
599 0, 0, 0, 0,
600 hWnd, (HMENU)1, hInst, &ccs);
601 #else
602 Globals.hMDIClient = CreateWindowEx(0, _T("MDICLIENT"), NULL,
603 //WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER,
604 WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,
605 0, 0, 0, 0,
606 hWnd, (HMENU)0, hInst, &ccs);
607 #endif
608 }
609 break;
610 case WM_COMMAND:
611 return _CmdWndProc(hWnd, message, wParam, lParam);
612 break;
613 case WM_SIZE:
614 resize_frame_client(hWnd);
615 break;
616 case WM_ENTERMENULOOP:
617 OnEnterMenuLoop(hWnd);
618 break;
619 case WM_EXITMENULOOP:
620 OnExitMenuLoop(hWnd);
621 break;
622 case WM_MENUSELECT:
623 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
624 break;
625 case WM_DESTROY:
626 PostQuitMessage(0);
627 break;
628 case WM_QUERYENDSESSION:
629 case WM_CLOSE:
630 SendMessage(hWnd, WM_COMMAND, ID_WINDOW_CLOSEALL, 0);
631 if (GetWindow(Globals.hMDIClient, GW_CHILD) != NULL)
632 return 0;
633 // else fall thru...
634 default:
635 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
636 }
637 return 0;
638 }