339a4b8435202b1e84792fd745c033146098f126
[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 "shell.h"
48 #include "network.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 new_top = --prect->top + rt.bottom+1;
81 MoveWindow(Globals.hDriveBar, 0, prect->top, rt.right, new_top, TRUE);
82 prect->top = new_top;
83 prect->bottom -= rt.bottom+2;
84 }
85 if (IsWindowVisible(Globals.hStatusBar)) {
86 SetupStatusBar(TRUE);
87 // int parts[] = {300, 500};
88 // SendMessage(Globals.hStatusBar, WM_SIZE, 0, 0);
89 // SendMessage(Globals.hStatusBar, SB_SETPARTS, 2, (LPARAM)&parts);
90 GetClientRect(Globals.hStatusBar, &rt);
91 prect->bottom -= rt.bottom;
92 }
93 MoveWindow(Globals.hMDIClient, prect->left-1,prect->top-1,prect->right+2,prect->bottom+1, TRUE);
94 }
95
96 static void resize_frame(HWND hWnd, int cx, int cy)
97 {
98 RECT rect = {0, 0, cx, cy};
99
100 resize_frame_rect(hWnd, &rect);
101 }
102
103 void resize_frame_client(HWND hWnd)
104 {
105 RECT rect;
106
107 GetClientRect(hWnd, &rect);
108 resize_frame_rect(hWnd, &rect);
109 }
110
111 ////////////////////////////////////////////////////////////////////////////////
112 static HHOOK hcbthook;
113 static ChildWnd* newchild = NULL;
114
115 static LRESULT CALLBACK CBTProc(int code, WPARAM wParam, LPARAM lParam)
116 {
117 if (code == HCBT_CREATEWND && newchild) {
118 ChildWnd* pChildWnd = newchild;
119 newchild = NULL;
120 pChildWnd->hWnd = (HWND)wParam;
121 SetWindowLong(pChildWnd->hWnd, GWL_USERDATA, (LPARAM)pChildWnd);
122 }
123 return CallNextHookEx(hcbthook, code, wParam, lParam);
124 }
125
126
127 /*
128 BOOL FindChildWindow(int cmd)
129 {
130 TCHAR drv[_MAX_DRIVE];
131 LPCTSTR root = Globals.drives;
132 int i;
133 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
134 while(*root)
135 root++;
136 if (activate_drive_window(root))
137 return TRUE;
138 _tsplitpath(root, drv, 0, 0, 0);
139 if (!SetCurrentDirectory(drv)) {
140 display_error(hWnd, GetLastError());
141 //return TRUE;
142 }
143 return FALSE;
144 }
145 */
146
147 static ChildWnd* alloc_child_window(LPCTSTR path)
148 {
149 TCHAR drv[_MAX_DRIVE+1], dir[_MAX_DIR], name[_MAX_FNAME], ext[_MAX_EXT];
150 ChildWnd* pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd));
151 Root* root = &pChildWnd->root;
152 Entry* entry;
153
154 memset(pChildWnd, 0, sizeof(ChildWnd));
155 pChildWnd->left.treePane = TRUE;
156 pChildWnd->left.visible_cols = 0;
157 pChildWnd->right.treePane = FALSE;
158 #ifndef _NO_EXTENSIONS
159 pChildWnd->right.visible_cols = COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES|COL_INDEX|COL_LINKS;
160 #else
161 pChildWnd->right.visible_cols = COL_SIZE|COL_DATE|COL_TIME|COL_ATTRIBUTES;
162 #endif
163 pChildWnd->pos.length = sizeof(WINDOWPLACEMENT);
164 pChildWnd->pos.flags = 0;
165 pChildWnd->pos.showCmd = SW_SHOWNORMAL;
166 pChildWnd->pos.rcNormalPosition.left = CW_USEDEFAULT;
167 pChildWnd->pos.rcNormalPosition.top = CW_USEDEFAULT;
168 pChildWnd->pos.rcNormalPosition.right = CW_USEDEFAULT;
169 pChildWnd->pos.rcNormalPosition.bottom = CW_USEDEFAULT;
170 pChildWnd->nFocusPanel = 0;
171 pChildWnd->nSplitPos = 200;
172 pChildWnd->sortOrder = SORT_NAME;
173 pChildWnd->header_wdths_ok = FALSE;
174 lstrcpy(pChildWnd->szPath, path);
175 _tsplitpath(path, drv, dir, name, ext);
176 #if !defined(_NO_EXTENSIONS) && defined(__linux__)
177 if (*path == '/') {
178 root->drive_type = GetDriveType(path);
179 lstrcat(drv, _T("/"));
180 lstrcpy(root->volname, _T("root fs"));
181 root->fs_flags = 0;
182 lstrcpy(root->fs, _T("unixfs"));
183 lstrcpy(root->path, _T("/"));
184 entry = read_tree_unix(root, path, pChildWnd->sortOrder);
185 } else
186 #endif
187 {
188 root->drive_type = GetDriveType(path);
189 lstrcat(drv, _T("\\"));
190 GetVolumeInformation(drv, root->volname, _MAX_FNAME, 0, 0, &root->fs_flags, root->fs, _MAX_DIR);
191 lstrcpy(root->path, drv);
192 entry = read_tree_win(root, path, pChildWnd->sortOrder);
193 }
194 //@@lstrcpy(root->entry.data.cFileName, drv);
195 wsprintf(root->entry.data.cFileName, _T("%s - %s"), drv, root->fs);
196 root->entry.data.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
197 pChildWnd->left.root = &root->entry;
198 set_curdir(pChildWnd, entry);
199 return pChildWnd;
200 }
201
202 HWND CreateChildWindow(int drv_id)
203 {
204 //TCHAR drv[_MAX_DRIVE];
205 TCHAR path[MAX_PATH];
206 ChildWnd* pChildWnd = NULL;
207 /*
208 LPCTSTR root = Globals.drives;
209 int i;
210 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
211 while(*root)
212 root++;
213 if (activate_drive_window(root))
214 return 0;
215 _tsplitpath(root, drv, 0, 0, 0);
216 if (!SetCurrentDirectory(drv)) {
217 display_error(hWnd, GetLastError());
218 return 0;
219 }
220 */
221 GetCurrentDirectory(MAX_PATH, path);
222 // pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd));
223 pChildWnd = alloc_child_window(path);
224 // if (!create_child_window(pChildWnd))
225 // free(pChildWnd);
226
227 if (pChildWnd != NULL) {
228 MDICREATESTRUCT mcs = {
229 szChildClass, path, hInst,
230 // CW_USEDEFAULT, CW_USEDEFAULT,
231 // CW_USEDEFAULT, CW_USEDEFAULT,
232 20, 20, 200, 200,
233 WS_MAXIMIZE, 0
234 // 0/*style*/, 0/*lParam*/
235 };
236 hcbthook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId());
237 newchild = pChildWnd;
238 pChildWnd->hWnd = (HWND)SendMessage(Globals.hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs);
239 UnhookWindowsHookEx(hcbthook);
240 if (pChildWnd->hWnd != NULL) {
241 return pChildWnd->hWnd;
242 } else {
243 free(pChildWnd);
244 newchild = pChildWnd = NULL;
245 }
246 }
247 return 0;
248 }
249
250 static BOOL CALLBACK CloseEnumProc(HWND hWnd, LPARAM lParam)
251 {
252 if (!GetWindow(hWnd, GW_OWNER)) {
253 SendMessage(GetParent(hWnd), WM_MDIRESTORE, (WPARAM)hWnd, 0);
254 if (SendMessage(hWnd, WM_QUERYENDSESSION, 0, 0)) {
255 SendMessage(GetParent(hWnd), WM_MDIDESTROY, (WPARAM)hWnd, 0);
256 }
257 }
258 return 1;
259 }
260
261 static void OnEnterMenuLoop(HWND hWnd)
262 {
263 int nParts;
264
265 // Update the status bar pane sizes
266 nParts = -1;
267 SendMessage(Globals.hStatusBar, SB_SETPARTS, 1, (long)&nParts);
268 bInMenuLoop = TRUE;
269 SendMessage(Globals.hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
270 }
271
272 static void OnExitMenuLoop(HWND hWnd)
273 {
274 RECT rc;
275 int nParts[3];
276
277 bInMenuLoop = FALSE;
278 // Update the status bar pane sizes
279 GetClientRect(hWnd, &rc);
280 nParts[0] = 100;
281 nParts[1] = 210;
282 nParts[2] = rc.right;
283 SendMessage(Globals.hStatusBar, SB_SETPARTS, 3, (long)nParts);
284 SendMessage(Globals.hStatusBar, SB_SETTEXT, 0, (LPARAM)_T(""));
285 SetupStatusBar(TRUE);
286 UpdateStatusBar();
287 }
288
289 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
290 {
291 TCHAR str[100];
292
293 if (hSysMenu == NULL) return;
294
295 _tcscpy(str, _T(""));
296 if (nFlags & MF_POPUP) {
297 switch (nItemID) {
298 case ID_FILE_MENU:
299 //EnableMenuItem(hSysMenu, uIDEnableItem, MF_BYCOMMAND|MF_ENABLED);
300 break;
301 case ID_DISK_MENU:
302 // EnableMenuItem(hSysMenu, ID_DISK_COPY_DISK, MF_BYCOMMAND|MF_GRAYED);
303 EnableMenuItem(hSysMenu, ID_DISK_COPY_DISK, MF_BYCOMMAND|MF_ENABLED);
304 break;
305 case ID_TREE_MENU:
306 case ID_VIEW_MENU:
307 case ID_OPTIONS_MENU:
308 case ID_SECURITY_MENU:
309 case ID_WINDOW_MENU:
310 case ID_HELP_MENU:
311 break;
312 }
313 // if (hSysMenu != GetMenu(hWnd)) {
314 // if (nItemID == 2) nItemID = 5;
315 // }
316 }
317 if (LoadString(Globals.hInstance, nItemID, str, 100)) {
318 // load appropriate string
319 LPTSTR lpsz = str;
320 // first newline terminates actual string
321 lpsz = _tcschr(lpsz, '\n');
322 if (lpsz != NULL)
323 *lpsz = '\0';
324 }
325 SendMessage(Globals.hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
326 }
327
328
329 static BOOL activate_drive_window(LPCTSTR path)
330 {
331 TCHAR drv1[_MAX_DRIVE], drv2[_MAX_DRIVE];
332 HWND child_wnd;
333
334 _tsplitpath(path, drv1, 0, 0, 0);
335
336 // search for a already open window for the same drive
337 for (child_wnd = GetNextWindow(Globals.hMDIClient,GW_CHILD);
338 child_wnd;
339 child_wnd = GetNextWindow(child_wnd, GW_HWNDNEXT)) {
340 ChildWnd* pChildWnd = (ChildWnd*) GetWindowLong(child_wnd, GWL_USERDATA);
341 if (pChildWnd) {
342 _tsplitpath(pChildWnd->root.path, drv2, 0, 0, 0);
343 if (!lstrcmpi(drv2, drv1)) {
344 SendMessage(Globals.hMDIClient, WM_MDIACTIVATE, (WPARAM)child_wnd, 0);
345 if (IsMinimized(child_wnd))
346 ShowWindow(child_wnd, SW_SHOWNORMAL);
347 return TRUE;
348 }
349 }
350 }
351 return FALSE;
352 }
353
354 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
355 {
356 BOOL vis = IsWindowVisible(hchild);
357
358 CheckMenuItem(Globals.hMenuOptions, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
359 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
360 #ifndef _NO_EXTENSIONS
361 if (g_fullscreen.mode)
362 fullscreen_move(hWnd);
363 #endif
364 resize_frame_client(hWnd);
365 }
366
367 ////////////////////////////////////////////////////////////////////////////////
368 //
369 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
370 //
371 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
372 //
373 //
374
375 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
376 {
377 UINT cmd = LOWORD(wParam);
378 HWND hChildWnd;
379 // HWND hwndClient = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
380 // if (hwndClient)
381 // if (SendMessage(hwndClient, WM_DISPATCH_COMMAND, wParam, lParam))
382 // return 0;
383
384 if (cmd >= ID_DRIVE_FIRST && cmd <= (ID_DRIVE_FIRST + 0xFF)) {
385 TCHAR drv[_MAX_DRIVE];
386 //TCHAR path[MAX_PATH];
387 //ChildWnd* pChildWnd;
388 LPCTSTR root = Globals.drives;
389 int i;
390 for (i = cmd - ID_DRIVE_FIRST; i--; root++)
391 while (*root)
392 root++;
393 if (activate_drive_window(root)) {
394 return TRUE;
395 }
396 _tsplitpath(root, drv, 0, 0, 0);
397 if (!SetCurrentDirectory(drv)) {
398 display_error(hWnd, GetLastError());
399 return TRUE;
400 }
401 //GetCurrentDirectory(MAX_PATH, path); //@@ letztes Verzeichnis pro Laufwerk speichern
402 //CreateChildWindow(path);
403 CreateChildWindow(cmd - ID_DRIVE_FIRST);
404
405 // pChildWnd = alloc_child_window(path);
406 // if (!create_child_window(pChildWnd))
407 // free(pChildWnd);
408 } else {
409 switch (cmd) {
410 case ID_WINDOW_CLOSEALL:
411 EnumChildWindows(Globals.hMDIClient, &CloseEnumProc, 0);
412 break;
413 case ID_WINDOW_CLOSE:
414 hChildWnd = (HWND) SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
415 if (!SendMessage(hChildWnd, WM_QUERYENDSESSION, 0, 0))
416 SendMessage(Globals.hMDIClient, WM_MDIDESTROY, (WPARAM)hChildWnd, 0);
417 break;
418
419 case ID_DISK_COPY_DISK:
420 CopyDisk(hWnd);
421 break;
422 case ID_DISK_LABEL_DISK:
423 LabelDisk(hWnd);
424 break;
425 case ID_DISK_FORMAT_DISK:
426 FormatDisk(hWnd);
427 #if 0
428 // SHFormatDrive(hWnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
429 {
430 UINT OldMode = SetErrorMode(0); // Get the current Error Mode settings.
431 SetErrorMode(OldMode & ~SEM_FAILCRITICALERRORS); // Force O/S to handle
432 // Call SHFormatDrive here.
433 SHFormatDrive(hWnd, 0 /* A: */, SHFMT_ID_DEFAULT, 0);
434 SetErrorMode(OldMode); // Put it back the way it was.
435 }
436 #endif
437 break;
438 case ID_DISK_CONNECT_NETWORK_DRIVE:
439 MapNetworkDrives(hWnd, TRUE);
440 break;
441 case ID_DISK_DISCONNECT_NETWORK_DRIVE:
442 MapNetworkDrives(hWnd, FALSE);
443 break;
444 case ID_DISK_SHARE_AS:
445 ModifySharing(hWnd, TRUE);
446 break;
447 case ID_DISK_STOP_SHARING:
448 ModifySharing(hWnd, FALSE);
449 break;
450 case ID_DISK_SELECT_DRIVE:
451 break;
452
453 case ID_VIEW_BY_FILE_TYPE:
454 {
455 struct ExecuteDialog dlg = {{0}};
456 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_VIEW_TYPE), hWnd, ViewFileTypeWndProc, (LPARAM)&dlg) == IDOK) {
457 }
458 }
459 break;
460 case ID_OPTIONS_CONFIRMATION:
461 {
462 struct ExecuteDialog dlg = {{0}};
463 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_OPTIONS_CONFIRMATON), hWnd, OptionsConfirmationWndProc, (LPARAM)&dlg) == IDOK) {
464 }
465 }
466 break;
467 case ID_OPTIONS_FONT:
468 break;
469 case ID_OPTIONS_CUSTOMISE_TOOLBAR:
470 SendMessage(Globals.hToolBar, TB_CUSTOMIZE, 0, 0);
471 break;
472 case ID_OPTIONS_TOOLBAR:
473 toggle_child(hWnd, cmd, Globals.hToolBar);
474 break;
475 case ID_OPTIONS_DRIVEBAR:
476 toggle_child(hWnd, cmd, Globals.hDriveBar);
477 break;
478 case ID_OPTIONS_STATUSBAR:
479 toggle_child(hWnd, cmd, Globals.hStatusBar);
480 break;
481 case ID_OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT:
482 if (Globals.Options & OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT) {
483 Globals.Options &= ~OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT;
484 CheckMenuItem(Globals.hMenuOptions, cmd, MF_CHECKED);
485 } else {
486 Globals.Options |= OPTIONS_OPEN_NEW_WINDOW_ON_CONNECT;
487 CheckMenuItem(Globals.hMenuOptions, cmd, MF_BYCOMMAND | MF_CHECKED);
488 }
489 break;
490 case ID_OPTIONS_MINIMISE_ON_USE:
491 if (Globals.Options & ID_OPTIONS_MINIMISE_ON_USE) {
492 Globals.Options &= ~ID_OPTIONS_MINIMISE_ON_USE;
493 CheckMenuItem(Globals.hMenuOptions, cmd, MF_CHECKED);
494 } else {
495 Globals.Options |= ID_OPTIONS_MINIMISE_ON_USE;
496 CheckMenuItem(Globals.hMenuOptions, cmd, MF_BYCOMMAND | MF_CHECKED);
497 }
498 break;
499 case ID_OPTIONS_SAVE_ON_EXIT:
500 if (Globals.Options & OPTIONS_SAVE_ON_EXIT) {
501 Globals.Options &= ~OPTIONS_SAVE_ON_EXIT;
502 CheckMenuItem(Globals.hMenuOptions, cmd, MF_CHECKED);
503 } else {
504 Globals.Options |= OPTIONS_SAVE_ON_EXIT;
505 CheckMenuItem(Globals.hMenuOptions, cmd, MF_BYCOMMAND | MF_CHECKED);
506 }
507 break;
508 case ID_WINDOW_NEW_WINDOW:
509 CreateChildWindow(-1);
510 break;
511 case ID_WINDOW_CASCADE:
512 SendMessage(Globals.hMDIClient, WM_MDICASCADE, 0, 0);
513 break;
514 case ID_WINDOW_TILE_HORZ:
515 SendMessage(Globals.hMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
516 break;
517 case ID_WINDOW_TILE_VERT:
518 SendMessage(Globals.hMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
519 break;
520 case ID_WINDOW_ARRANGE_ICONS:
521 SendMessage(Globals.hMDIClient, WM_MDIICONARRANGE, 0, 0);
522 break;
523 case ID_WINDOW_REFRESH:
524 // TODO:
525 break;
526 case ID_HELP_CONTENTS:
527 WinHelp(hWnd, _T("winfile"), HELP_CONTENTS, 0);
528 break;
529 case ID_HELP_SEARCH_HELP:
530 WinHelp(hWnd, _T("winfile"), HELP_FINDER, 0);
531 break;
532 case ID_HELP_HOW_TO_USE_HELP:
533 WinHelp(hWnd, _T("winfile"), HELP_HELPONHELP, 0);
534 break;
535 case ID_HELP_ABOUT:
536 #ifdef WINSHELLAPI
537 ShellAbout(hWnd, szTitle, "", LoadIcon(Globals.hInstance, (LPCTSTR)IDI_WINFILE));
538 #else
539 ShowAboutBox(hWnd);
540 #endif
541 break;
542 default:
543 /*
544 if ((cmd<IDW_FIRST_CHILD || cmd>=IDW_FIRST_CHILD+0x100) &&
545 (cmd<SC_SIZE || cmd>SC_RESTORE)) {
546 MessageBox(hWnd, _T("Not yet implemented"), _T("Winefile"), MB_OK);
547 }
548 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
549 */
550 /*
551 hChildWnd = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
552 if (IsWindow(hChildWnd))
553 SendMessage(hChildWnd, WM_COMMAND, wParam, lParam);
554 else
555 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
556 */
557 return FALSE;
558 }
559 }
560 return TRUE;
561 }
562
563
564 static TBBUTTON tbButtonNew[] = {
565 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
566 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
567 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
568 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
569 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
570 };
571
572 static LRESULT MsgNotify(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
573 {
574 LPNMHDR lpnmhdr;
575
576 //LPNMHDR lpnmhdr;
577 static int nResetCount;
578 static LPTBBUTTON lpSaveButtons;
579 //LPARAM lParam;
580
581
582 lpnmhdr = (LPNMHDR)lparam;
583 /*
584 // The following code allows the toolbar to be customized.
585 // If you return FALSE the Customize Toolbar dialog flashes
586 // and goes away.
587
588 if (lpnmhdr->code == TBN_QUERYINSERT || lpnmhdr->code == TBN_QUERYDELETE) {
589 return TRUE;
590 }
591
592 if (lpnmhdr->code == TBN_GETBUTTONINFO) {
593 LPTBNOTIFY lpTbNotify = (LPTBNOTIFY)lparam;
594 char szBuffer[20];
595
596 // int tbButtonNew[20] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
597 TBBUTTON tbButtonNew[] = {
598 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
599 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
600 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
601 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
602 {0, ID_WINDOW_CASCADE, TBSTATE_ENABLED, TBSTYLE_BUTTON},
603 };
604
605 // 20 = total number of buttons.
606 // tbButton and tbButtonNew send information about
607 // the other 12 buttons in tbButtonNew.
608 if (lpTbNotify->iItem < 5) {
609 lpTbNotify->tbButton = tbButtonNew[lpTbNotify->iItem];
610 // LoadString(hInst, 4000+lpTbNotify->iItem, szBuffer, sizeof(szBuffer));
611 LoadString(hInst, lpTbNotify->iItem, szBuffer, sizeof(szBuffer));
612 lstrcpy (lpTbNotify->pszText, szBuffer);
613 lpTbNotify->cchText = sizeof (szBuffer);
614 return TRUE;
615 } else {
616 return 0;
617 }
618 }
619 */
620 switch (lpnmhdr->code) {
621 case TBN_QUERYINSERT:
622 case TBN_QUERYDELETE:
623 return TRUE;
624
625 case TBN_GETBUTTONINFO:
626 {
627 LPTBNOTIFY lpTbNotify = (LPTBNOTIFY)lparam;
628 char szBuffer[20];
629 /*
630 typedef struct _TBBUTTON {
631 int iBitmap;
632 int idCommand;
633 BYTE fsState;
634 BYTE fsStyle;
635 DWORD dwData;
636 INT_PTR iString;
637 } TBBUTTON, NEAR* PTBBUTTON, FAR* LPTBBUTTON;
638 */
639 // 20 = total number of buttons.
640 // tbButton and tbButtonNew send information about
641 // the other 12 buttons in tbButtonNew.
642 if (lpTbNotify->iItem < 12) {
643 lpTbNotify->tbButton = tbButtonNew[lpTbNotify->iItem];
644 LoadString(hInst, lpTbNotify->iItem + 32769, szBuffer, sizeof(szBuffer));
645 lstrcpy (lpTbNotify->pszText, szBuffer);
646 lpTbNotify->cchText = sizeof (szBuffer);
647 return TRUE;
648 } else {
649 return 0;
650 }
651 }
652 break;
653
654 case TBN_BEGINADJUST: // Start customizing the toolbar.
655 {
656 LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
657 int i;
658
659 // Allocate memory to store the button information.
660 nResetCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
661 lpSaveButtons = (LPTBBUTTON)GlobalAlloc(GPTR, sizeof(TBBUTTON) * nResetCount);
662
663 // Save the current configuration so if the user presses
664 // reset, the original toolbar can be restored.
665 for (i = 0; i < nResetCount; i++) {
666 SendMessage(lpTB->hdr.hwndFrom, TB_GETBUTTON, i, (LPARAM)(lpSaveButtons + i));
667 }
668 }
669 return TRUE;
670
671 case TBN_RESET:
672 {
673 LPTBNOTIFY lpTB = (LPTBNOTIFY)lparam;
674 int nCount, i;
675
676 // Remove all of the existing buttons starting with the last and working down.
677 nCount = SendMessage(lpTB->hdr.hwndFrom, TB_BUTTONCOUNT, 0, 0);
678 for (i = nCount - 1; i >= 0; i--) {
679 SendMessage(lpTB->hdr.hwndFrom, TB_DELETEBUTTON, i, 0);
680 }
681
682 // Restore the buttons that were saved.
683 SendMessage(lpTB->hdr.hwndFrom, TB_ADDBUTTONS, (WPARAM)nResetCount, (LPARAM)lpSaveButtons);
684 }
685 return TRUE;
686
687 case TBN_ENDADJUST:
688 // Free the memory allocated during TBN_BEGINADJUST
689 GlobalFree((HGLOBAL)lpSaveButtons);
690 return TRUE;
691 }
692 return 0;
693 }
694
695 ////////////////////////////////////////////////////////////////////////////////
696 //
697 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
698 //
699 // PURPOSE: Processes messages for the main frame window.
700 //
701 // WM_COMMAND - process the application menu
702 // WM_DESTROY - post a quit message and return
703 //
704 //
705
706 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
707 {
708 switch (message) {
709 case WM_CREATE:
710 {
711 HMENU hMenuWindow = GetSubMenu(Globals.hMenuFrame, GetMenuItemCount(Globals.hMenuFrame)-2);
712 CLIENTCREATESTRUCT ccs = { hMenuWindow, IDW_FIRST_CHILD };
713 Globals.hMDIClient = CreateWindowEx(0, _T("MDICLIENT"), NULL,
714 //WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER,
715 WS_EX_MDICHILD|WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,
716 0, 0, 0, 0,
717 hWnd, (HMENU)0, hInst, &ccs);
718 }
719 CheckShellAvailable();
720 CheckNetworkAvailable();
721 CreateChildWindow(-1);
722 break;
723
724 case WM_NOTIFY:
725
726 if (MsgNotify(hWnd, message, wParam, lParam)) return TRUE;
727 // return MsgNotify(hWnd, message, wParam, lParam);
728 switch (((LPNMHDR)lParam)->code) {
729 case TTN_GETDISPINFO:
730 {
731 LPTOOLTIPTEXT lpttt;
732 lpttt = (LPTOOLTIPTEXT)lParam;
733 lpttt->hinst = hInst;
734 // load appropriate string
735 lpttt->lpszText = MAKEINTRESOURCE(lpttt->hdr.idFrom);
736 }
737 break;
738 default:
739 break;
740 }
741 break;
742
743 case WM_COMMAND:
744 if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
745 // if (LOWORD(wParam) > ID_CMD_FIRST && LOWORD(wParam) < ID_CMD_LAST) {
746 HWND hChildWnd = (HWND)SendMessage(Globals.hMDIClient, WM_MDIGETACTIVE, 0, 0);
747 if (IsWindow(hChildWnd))
748 if (SendMessage(hChildWnd, WM_DISPATCH_COMMAND, wParam, lParam))
749 break;
750 // }
751 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
752 }
753 break;
754 case WM_SIZE:
755 resize_frame_client(hWnd);
756 break;
757 case WM_ENTERMENULOOP:
758 OnEnterMenuLoop(hWnd);
759 break;
760 case WM_EXITMENULOOP:
761 OnExitMenuLoop(hWnd);
762 break;
763 case WM_MENUSELECT:
764 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
765 break;
766 case WM_DESTROY:
767 WinHelp(hWnd, _T("winfile"), HELP_QUIT, 0);
768 PostQuitMessage(0);
769 break;
770 case WM_QUERYENDSESSION:
771 case WM_CLOSE:
772 SendMessage(hWnd, WM_COMMAND, ID_WINDOW_CLOSEALL, 0);
773 if (GetWindow(Globals.hMDIClient, GW_CHILD) != NULL)
774 return 0;
775 // else fall thru...
776 default: //def:
777 return DefFrameProc(hWnd, Globals.hMDIClient, message, wParam, lParam);
778 }
779 return 0;
780 }