1 /* 2 * ReactOS Application 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 "main.h" 38 #include "about.h" 39 #include "framewnd.h" 40 41 42 //////////////////////////////////////////////////////////////////////////////// 43 // Global Variables: 44 // 45 46 BOOL bInMenuLoop = FALSE; // Tells us if we are in the menu loop 47 48 //////////////////////////////////////////////////////////////////////////////// 49 // Local module support methods 50 // 51 52 static void resize_frame_rect(HWND hWnd, PRECT prect) 53 { 54 RECT rt; 55 56 if (IsWindowVisible(hToolBar)) { 57 SendMessage(hToolBar, WM_SIZE, 0, 0); 58 GetClientRect(hToolBar, &rt); 59 prect->top = rt.bottom+3; 60 prect->bottom -= rt.bottom+3; 61 } 62 if (IsWindowVisible(hStatusBar)) { 63 int parts[] = {300, 500}; 64 65 SendMessage(hStatusBar, WM_SIZE, 0, 0); 66 SendMessage(hStatusBar, SB_SETPARTS, 2, (LPARAM)&parts); 67 GetClientRect(hStatusBar, &rt); 68 prect->bottom -= rt.bottom; 69 } 70 MoveWindow(hMDIClient, prect->left-1,prect->top-1,prect->right+2,prect->bottom+1, TRUE); 71 } 72 73 /* static void resize_frame(HWND hWnd, int cx, int cy) 74 { 75 RECT rect = {0, 0, cx, cy}; 76 77 resize_frame_rect(hWnd, &rect); 78 }*/ 79 80 void resize_frame_client(HWND hWnd) 81 { 82 RECT rect; 83 84 GetClientRect(hWnd, &rect); 85 resize_frame_rect(hWnd, &rect); 86 } 87 88 //////////////////////////////////////////////////////////////////////////////// 89 static HHOOK hcbthook; 90 static ChildWnd* newchild = NULL; 91 92 LRESULT CALLBACK CBTProc(int code, WPARAM wParam, LPARAM lParam) 93 { 94 if (code == HCBT_CREATEWND && newchild) { 95 ChildWnd* pChildWnd = newchild; 96 newchild = NULL; 97 pChildWnd->hWnd = (HWND)wParam; 98 SetWindowLongPtr(pChildWnd->hWnd, GWLP_USERDATA, (LPARAM)pChildWnd); 99 } 100 return CallNextHookEx(hcbthook, code, wParam, lParam); 101 } 102 103 #if 0 104 HWND create_child_window(ChildWnd* pChildWnd) 105 { 106 MDICREATESTRUCT mcs = { 107 szChildClass, (LPTSTR)pChildWnd->path, hInst, 108 pChildWnd->pos.rcNormalPosition.left, pChildWnd->pos.rcNormalPosition.top, 109 pChildWnd->pos.rcNormalPosition.right-pChildWnd->pos.rcNormalPosition.left, 110 pChildWnd->pos.rcNormalPosition.bottom-pChildWnd->pos.rcNormalPosition.top, 111 0/*style*/, 0/*lParam*/ 112 }; 113 hcbthook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId()); 114 newchild = pChildWnd; 115 pChildWnd->hWnd = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs); 116 if (!pChildWnd->hWnd) 117 return 0; 118 UnhookWindowsHookEx(hcbthook); 119 return pChildWnd->hWnd; 120 } 121 122 #endif 123 124 125 void toggle_child(HWND hWnd, UINT cmd, HWND hchild) 126 { 127 BOOL vis = IsWindowVisible(hchild); 128 129 HMENU hMenuOptions = GetSubMenu(hMenuFrame, ID_OPTIONS_MENU); 130 CheckMenuItem(hMenuOptions, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED); 131 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW); 132 resize_frame_client(hWnd); 133 } 134 135 136 static HWND InitChildWindow(LPTSTR param) 137 { 138 //TCHAR drv[_MAX_DRIVE]; 139 TCHAR path[MAX_PATH]; 140 ChildWnd* pChildWnd = NULL; 141 /* 142 LPCTSTR root = Globals.drives; 143 int i; 144 for(i = cmd - ID_DRIVE_FIRST; i--; root++) 145 while(*root) 146 root++; 147 if (activate_drive_window(root)) 148 return 0; 149 _tsplitpath(root, drv, 0, 0, 0); 150 if (!SetCurrentDirectory(drv)) { 151 display_error(hWnd, GetLastError()); 152 return 0; 153 } 154 */ 155 GetCurrentDirectory(MAX_PATH, path); 156 // pChildWnd = alloc_child_window(path); 157 // if (!create_child_window(pChildWnd)) 158 // free(pChildWnd); 159 pChildWnd = (ChildWnd*)malloc(sizeof(ChildWnd)); 160 if (pChildWnd != NULL) { 161 MDICREATESTRUCT mcs = { 162 szChildClass, path, hInst, 163 CW_USEDEFAULT, CW_USEDEFAULT, 164 CW_USEDEFAULT, CW_USEDEFAULT, 165 0/*style*/, 0/*lParam*/ 166 }; 167 memset(pChildWnd, 0, sizeof(ChildWnd)); 168 lstrcpy(pChildWnd->szPath, path); 169 pChildWnd->pos.length = sizeof(WINDOWPLACEMENT); 170 pChildWnd->pos.flags = 0; 171 pChildWnd->pos.showCmd = SW_SHOWNORMAL; 172 pChildWnd->pos.rcNormalPosition.left = CW_USEDEFAULT; 173 pChildWnd->pos.rcNormalPosition.top = CW_USEDEFAULT; 174 pChildWnd->pos.rcNormalPosition.right = CW_USEDEFAULT; 175 pChildWnd->pos.rcNormalPosition.bottom = CW_USEDEFAULT; 176 pChildWnd->nFocusPanel = 0; 177 pChildWnd->nSplitPos = 200; 178 hcbthook = SetWindowsHookEx(WH_CBT, CBTProc, 0, GetCurrentThreadId()); 179 newchild = pChildWnd; 180 pChildWnd->hWnd = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs); 181 UnhookWindowsHookEx(hcbthook); 182 if (pChildWnd->hWnd == NULL) { 183 free(pChildWnd); 184 newchild = pChildWnd = NULL; 185 } 186 return pChildWnd->hWnd; 187 } 188 return 0; 189 } 190 191 BOOL CALLBACK CloseEnumProc(HWND hWnd, LPARAM lParam) 192 { 193 if (!GetWindow(hWnd, GW_OWNER)) { 194 SendMessage(GetParent(hWnd), WM_MDIRESTORE, (WPARAM)hWnd, 0); 195 if (SendMessage(hWnd, WM_QUERYENDSESSION, 0, 0)) { 196 SendMessage(GetParent(hWnd), WM_MDIDESTROY, (WPARAM)hWnd, 0); 197 } 198 } 199 return 1; 200 } 201 202 void OnEnterMenuLoop(HWND hWnd) 203 { 204 int nParts; 205 206 // Update the status bar pane sizes 207 nParts = -1; 208 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts); 209 bInMenuLoop = TRUE; 210 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T("")); 211 } 212 213 void OnExitMenuLoop(HWND hWnd) 214 { 215 RECT rc; 216 int nParts[3]; 217 218 bInMenuLoop = FALSE; 219 // Update the status bar pane sizes 220 GetClientRect(hWnd, &rc); 221 nParts[0] = 100; 222 nParts[1] = 210; 223 nParts[2] = rc.right; 224 SendMessage(hStatusBar, SB_SETPARTS, 3, (LPARAM)nParts); 225 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)_T("")); 226 UpdateStatusBar(); 227 } 228 229 void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu) 230 { 231 TCHAR str[100]; 232 233 strcpy(str, TEXT("")); 234 if (nFlags & MF_POPUP) { 235 if (hSysMenu != GetMenu(hWnd)) { 236 if (nItemID == 2) nItemID = 5; 237 } 238 } 239 if (LoadString(hInst, nItemID, str, 100)) { 240 // load appropriate string 241 LPTSTR lpsz = str; 242 // first newline terminates actual string 243 lpsz = _tcschr(lpsz, '\n'); 244 if (lpsz != NULL) 245 *lpsz = '\0'; 246 } 247 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str); 248 } 249 250 //////////////////////////////////////////////////////////////////////////////// 251 // 252 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG) 253 // 254 // PURPOSE: Processes WM_COMMAND messages for the main frame window. 255 // 256 // 257 258 LRESULT _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 259 { 260 HWND hChildWnd; 261 262 if (1) { 263 264 switch (LOWORD(wParam)) { 265 case ID_WINDOW_CLOSEALL: 266 EnumChildWindows(hMDIClient, &CloseEnumProc, 0); 267 break; 268 case ID_WINDOW_CLOSE: 269 hChildWnd = (HWND) SendMessage(hMDIClient, WM_MDIGETACTIVE, 0, 0); 270 if (!SendMessage(hChildWnd, WM_QUERYENDSESSION, 0, 0)) 271 SendMessage(hMDIClient, WM_MDIDESTROY, (WPARAM)hChildWnd, 0); 272 break; 273 case ID_FILE_EXIT: 274 SendMessage(hWnd, WM_CLOSE, 0, 0); 275 break; 276 case ID_OPTIONS_TOOLBAR: 277 toggle_child(hWnd, LOWORD(wParam), hToolBar); 278 break; 279 case ID_OPTIONS_STATUSBAR: 280 toggle_child(hWnd, LOWORD(wParam), hStatusBar); 281 break; 282 283 case ID_FILE_OPEN: 284 case ID_WINDOW_NEW_WINDOW: 285 InitChildWindow("Child Window"); 286 return 0; 287 case ID_WINDOW_CASCADE: 288 SendMessage(hMDIClient, WM_MDICASCADE, 0, 0); 289 break; 290 case ID_WINDOW_TILE_HORZ: 291 SendMessage(hMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0); 292 break; 293 case ID_WINDOW_TILE_VERT: 294 SendMessage(hMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0); 295 break; 296 case ID_WINDOW_ARRANGE_ICONS: 297 SendMessage(hMDIClient, WM_MDIICONARRANGE, 0, 0); 298 break; 299 case ID_HELP_ABOUT: 300 ShowAboutBox(hWnd); 301 break; 302 default: 303 hChildWnd = (HWND)SendMessage(hMDIClient, WM_MDIGETACTIVE, 0, 0); 304 if (IsWindow(hChildWnd)) 305 SendMessage(hChildWnd, WM_COMMAND, wParam, lParam); 306 else 307 return DefFrameProc(hWnd, hMDIClient, message, wParam, lParam); 308 } 309 } 310 return 0; 311 } 312 313 //////////////////////////////////////////////////////////////////////////////// 314 // 315 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG) 316 // 317 // PURPOSE: Processes messages for the main frame window. 318 // 319 // WM_COMMAND - process the application menu 320 // WM_DESTROY - post a quit message and return 321 // 322 // 323 324 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 325 { 326 switch (message) { 327 case WM_CREATE: 328 { 329 HMENU hMenuWindow = GetSubMenu(hMenuFrame, GetMenuItemCount(hMenuFrame)-2); 330 CLIENTCREATESTRUCT ccs = { hMenuWindow, IDW_FIRST_CHILD }; 331 #if 0 332 hMDIClient = CreateWindow(_T("MDICLIENT"), NULL, 333 WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE, 334 0, 0, 0, 0, 335 hWnd, (HMENU)1, hInst, &ccs); 336 #else 337 hMDIClient = CreateWindowEx(0, _T("MDICLIENT"), NULL, 338 // hMDIClient = CreateWindowEx(0, (LPCTSTR)(int)hChildWndClass, NULL, 339 WS_CHILD|WS_CLIPCHILDREN|WS_VSCROLL|WS_HSCROLL|WS_VISIBLE|WS_BORDER, 340 0, 0, 0, 0, 341 hWnd, (HMENU)0, hInst, &ccs); 342 #endif 343 } 344 break; 345 case WM_COMMAND: 346 return _CmdWndProc(hWnd, message, wParam, lParam); 347 break; 348 case WM_SIZE: 349 resize_frame_client(hWnd); 350 break; 351 case WM_ENTERMENULOOP: 352 OnEnterMenuLoop(hWnd); 353 break; 354 case WM_EXITMENULOOP: 355 OnExitMenuLoop(hWnd); 356 break; 357 case WM_MENUSELECT: 358 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); 359 break; 360 case WM_DESTROY: 361 PostQuitMessage(0); 362 break; 363 case WM_QUERYENDSESSION: 364 case WM_CLOSE: 365 SendMessage(hWnd, WM_COMMAND, ID_WINDOW_CLOSEALL, 0); 366 if (GetWindow(hMDIClient, GW_CHILD) != NULL) 367 return 0; 368 // else fall thru... 369 default: 370 return DefFrameProc(hWnd, hMDIClient, message, wParam, lParam); 371 } 372 return 0; 373 } 374 375 376