[APPLICATIONS] Fix 64 bit issues
[reactos.git] / base / applications / mmc / console.c
1 /*
2 * ReactOS Management Console
3 * Copyright (C) 2006 - 2007 Thomas Weidenmueller
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "precomp.h"
21
22 #include "resource.h"
23
24 #define NDEBUG
25 #include <debug.h>
26
27 typedef struct _CONSOLE_MAINFRAME_WND
28 {
29 HWND hwnd;
30 HWND hwndMDIClient;
31
32 HMENU hMenuConsoleSmall;
33 HMENU hMenuConsoleLarge;
34 INT nConsoleCount;
35 union
36 {
37 DWORD Flags;
38 struct
39 {
40 DWORD AppAuthorMode : 1;
41 };
42 };
43 } CONSOLE_MAINFRAME_WND, *PCONSOLE_MAINFRAME_WND;
44
45 typedef struct _CONSOLE_CHILDFRM_WND
46 {
47 HWND hwnd;
48 PCONSOLE_MAINFRAME_WND MainFrame;
49 PTSTR pFileName;
50 } CONSOLE_CHILDFRM_WND, *PCONSOLE_CHILDFRM_WND;
51
52 static const TCHAR szMMCMainFrame[] = TEXT("MMCMainFrame");
53 static const TCHAR szMMCChildFrm[] = TEXT("MMCChildFrm");
54
55 static ULONG NewConsoleCount = 0;
56
57 PCONSOLE_CHILDFRM_WND
58 GetActiveChildInfo(VOID)
59 {
60 HWND hWndMDIChild;
61
62 hWndMDIChild = (HWND)SendMessageW(hwndMDIClient, WM_MDIGETACTIVE, 0, 0);
63 if (hWndMDIChild == NULL)
64 return NULL;
65
66 return (PCONSOLE_CHILDFRM_WND)GetWindowLongPtr(hWndMDIChild, 0);
67 }
68
69
70 static LPTSTR
71 CreateNewConsoleTitle(VOID)
72 {
73 LPTSTR lpTitle;
74
75 if (LoadAndFormatString(hAppInstance,
76 IDS_CONSOLETITLE,
77 &lpTitle,
78 ++NewConsoleCount) == 0)
79 {
80 lpTitle = NULL;
81 }
82
83 return lpTitle;
84 }
85
86 HWND
87 CreateNewMDIChild(PCONSOLE_MAINFRAME_WND Info,
88 HWND hwndMDIClient)
89 {
90 MDICREATESTRUCT mcs;
91 HWND hChild;
92
93 mcs.szTitle = CreateNewConsoleTitle();
94 mcs.szClass = szMMCChildFrm;
95 mcs.hOwner = GetModuleHandle(NULL);
96 mcs.x = mcs.cx = CW_USEDEFAULT;
97 mcs.y = mcs.cy = CW_USEDEFAULT;
98 mcs.style = MDIS_ALLCHILDSTYLES;
99
100 hChild = (HWND)SendMessage(hwndMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs);
101 if (hChild)
102 {
103 Info->nConsoleCount++;
104 }
105
106 return hChild;
107 }
108
109
110 static LRESULT
111 FrameOnCreate(HWND hwnd,
112 LPARAM lParam)
113 {
114 PCONSOLE_MAINFRAME_WND Info;
115 CLIENTCREATESTRUCT ccs;
116 LPCTSTR lpFileName = (LPCTSTR)(((LPCREATESTRUCT)lParam)->lpCreateParams);
117
118 Info = HeapAlloc(hAppHeap,
119 HEAP_ZERO_MEMORY,
120 sizeof(CONSOLE_MAINFRAME_WND));
121 if (Info == NULL)
122 return -1;
123
124 Info->hwnd = hwnd;
125
126 SetWindowLongPtr(hwnd,
127 0,
128 (LONG_PTR)Info);
129
130 Info->hMenuConsoleSmall = LoadMenu(hAppInstance,
131 MAKEINTRESOURCE(IDM_CONSOLE_SMALL));
132
133 Info->hMenuConsoleLarge = LoadMenu(hAppInstance,
134 MAKEINTRESOURCE(IDM_CONSOLE_LARGE));
135
136 if (lpFileName == NULL)
137 {
138 /* FIXME */
139 Info->AppAuthorMode = TRUE;
140 // Info->lpConsoleTitle = TEXT("ReactOS Management Console");
141 }
142 else
143 {
144 Info->AppAuthorMode = TRUE;
145 // Info->lpConsoleTitle = CreateNewConsoleTitle();
146 }
147
148 SetMenu(Info->hwnd,
149 Info->hMenuConsoleSmall);
150
151 SetWindowText(Info->hwnd, TEXT("ReactOS Management Console"));
152
153 ccs.hWindowMenu = GetSubMenu(Info->hMenuConsoleLarge, 1);
154 ccs.idFirstChild = IDM_MDI_FIRSTCHILD;
155
156 /* Create the MDI client window */
157 hwndMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE,
158 L"MDICLIENT",
159 (LPCTSTR)NULL,
160 WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE | WS_BORDER,
161 CW_USEDEFAULT,
162 CW_USEDEFAULT,
163 CW_USEDEFAULT,
164 CW_USEDEFAULT,
165 hwnd,
166 (HMENU)0xCAC,
167 hAppInstance,
168 (LPVOID)&ccs);
169
170 ShowWindow(Info->hwndMDIClient, SW_SHOW);
171
172 return 0;
173 }
174
175
176 static VOID
177 SetFileName(
178 PCONSOLE_CHILDFRM_WND Info,
179 PWSTR pFileName)
180 {
181 DPRINT1("SetFileName(&p \'%S\')\n", Info, pFileName);
182
183 if (Info->pFileName != NULL)
184 {
185 HeapFree(GetProcessHeap(), 0, Info->pFileName);
186 Info->pFileName = NULL;
187 }
188
189 if (pFileName != NULL)
190 {
191 Info->pFileName = HeapAlloc(GetProcessHeap(),
192 0,
193 (_tcslen(pFileName) + 1) * sizeof(TCHAR));
194 if (Info->pFileName != NULL)
195 _tcscpy(Info->pFileName, pFileName);
196 }
197 }
198
199 static BOOL
200 DoSaveFileAs(
201 HWND hWnd,
202 PCONSOLE_CHILDFRM_WND pChildInfo);
203
204 static BOOL
205 DoSaveFile(
206 HWND hWnd,
207 PCONSOLE_CHILDFRM_WND pChildInfo)
208 {
209 DPRINT1("pChildInfo %p\n", pChildInfo);
210
211 DPRINT1("FileName %S\n", pChildInfo->pFileName);
212
213 if (pChildInfo->pFileName == NULL)
214 return DoSaveFileAs(hWnd, pChildInfo);
215
216 /* FIXME: Save the console here! */
217
218 return TRUE;
219 }
220
221 static BOOL
222 DoSaveFileAs(
223 HWND hWnd,
224 PCONSOLE_CHILDFRM_WND pChildInfo)
225 {
226 OPENFILENAME saveas;
227 TCHAR szPath[MAX_PATH];
228
229 DPRINT1("pChildInfo %p\n", pChildInfo);
230 DPRINT1("FileName %S\n", pChildInfo->pFileName);
231
232 ZeroMemory(&saveas, sizeof(saveas));
233
234 if (pChildInfo->pFileName != NULL)
235 {
236 _tcscpy(szPath, pChildInfo->pFileName);
237 }
238 else
239 {
240 GetWindowText(pChildInfo->hwnd, szPath, MAX_PATH);
241 _tcscat(szPath, TEXT(".msc"));
242 }
243
244 saveas.lStructSize = sizeof(OPENFILENAME);
245 saveas.hwndOwner = hWnd;
246 saveas.hInstance = hAppInstance;
247 saveas.lpstrFilter = L"MSC Files\0*.msc\0";
248 saveas.lpstrFile = szPath;
249 saveas.nMaxFile = MAX_PATH;
250 saveas.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
251 saveas.lpstrDefExt = L"msc";
252
253 if (GetSaveFileName(&saveas))
254 {
255 /* HACK: Because in ROS, Save-As boxes don't check the validity
256 * of file names and thus, here, szPath can be invalid !! We only
257 * see its validity when we call DoSaveFile()... */
258 SetFileName(pChildInfo, szPath);
259
260 if (DoSaveFile(hWnd, pChildInfo))
261 {
262 // UpdateWindowCaption();
263 return TRUE;
264 }
265 else
266 {
267 SetFileName(pChildInfo, NULL);
268 return FALSE;
269 }
270 }
271 else
272 {
273 return FALSE;
274 }
275 }
276
277 static BOOL
278 FrameOnSave(
279 HWND hWnd)
280 {
281 PCONSOLE_CHILDFRM_WND pChildInfo;
282
283 pChildInfo = GetActiveChildInfo();
284 if (pChildInfo == NULL)
285 return FALSE;
286
287 return DoSaveFile(hWnd, pChildInfo);
288 }
289
290
291 static BOOL
292 FrameOnSaveAs(
293 HWND hWnd)
294 {
295 PCONSOLE_CHILDFRM_WND pChildInfo;
296
297 pChildInfo = GetActiveChildInfo();
298 if (pChildInfo == NULL)
299 return FALSE;
300
301 return DoSaveFileAs(hWnd, pChildInfo);
302 }
303
304 static VOID
305 FrameOnCommand(HWND hwnd,
306 UINT uMsg,
307 WPARAM wParam,
308 LPARAM lParam)
309 {
310 PCONSOLE_MAINFRAME_WND Info;
311 HWND hChild;
312
313 Info = (PCONSOLE_MAINFRAME_WND)GetWindowLongPtr(hwnd, 0);
314
315 switch (LOWORD(wParam))
316 {
317 case IDM_FILE_NEW:
318 CreateNewMDIChild(Info, hwndMDIClient);
319 SetMenu(Info->hwnd,
320 Info->hMenuConsoleLarge);
321 break;
322
323 case IDM_FILE_SAVE:
324 FrameOnSave(hwnd);
325 break;
326
327 case IDM_FILE_SAVEAS:
328 FrameOnSaveAs(hwnd);
329 break;
330
331 case IDM_FILE_EXIT:
332 PostMessage(hwnd, WM_CLOSE, 0, 0);
333 break;
334
335 default:
336 if (LOWORD(wParam) >= IDM_MDI_FIRSTCHILD)
337 {
338 DefFrameProc(hwnd, hwndMDIClient, uMsg, wParam, lParam);
339 }
340 else
341 {
342 hChild = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0);
343 if (hChild)
344 {
345 SendMessage(hChild, WM_COMMAND, wParam, lParam);
346 }
347 }
348 break;
349 }
350 }
351
352
353 static VOID
354 FrameOnSize(HWND hMainWnd,
355 WORD cx,
356 WORD cy)
357 {
358 RECT rcClient; //, rcTool, rcStatus;
359 // int lvHeight, iToolHeight, iStatusHeight;
360
361 /* Size toolbar and get height */
362 // SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0);
363 // GetWindowRect(Info->hTool, &rcTool);
364 // iToolHeight = rcTool.bottom - rcTool.top;
365
366 /* Size status bar and get height */
367 // SendMessage(Info->hStatus, WM_SIZE, 0, 0);
368 // GetWindowRect(Info->hStatus, &rcStatus);
369 // iStatusHeight = rcStatus.bottom - rcStatus.top;
370
371 /* Calculate remaining height and size list view */
372 GetClientRect(hMainWnd, &rcClient);
373 // lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
374 SetWindowPos(hwndMDIClient, //Info->hTreeView,
375 NULL,
376 0,
377 0, //iToolHeight,
378 rcClient.right,
379 rcClient.bottom, //lvHeight,
380 SWP_NOZORDER);
381 }
382
383
384 static LRESULT CALLBACK
385 ConsoleMainFrameWndProc(IN HWND hwnd,
386 IN UINT uMsg,
387 IN WPARAM wParam,
388 IN LPARAM lParam)
389 {
390 PCONSOLE_MAINFRAME_WND Info;
391
392 Info = (PCONSOLE_MAINFRAME_WND)GetWindowLongPtr(hwnd,
393 0);
394
395 switch (uMsg)
396 {
397 case WM_CREATE:
398 return FrameOnCreate(hwnd,
399 lParam);
400
401 case WM_COMMAND:
402 FrameOnCommand(hwnd,
403 uMsg,
404 wParam,
405 lParam);
406 break;
407
408 case WM_SIZE:
409 FrameOnSize(hwnd,
410 LOWORD(lParam),
411 HIWORD(lParam));
412 break;
413
414 case WM_CLOSE:
415 DestroyWindow(hwnd);
416 break;
417
418 case WM_DESTROY:
419 if (Info != NULL)
420 {
421 SetMenu(Info->hwnd,
422 NULL);
423
424 if (Info->hMenuConsoleSmall != NULL)
425 {
426 DestroyMenu(Info->hMenuConsoleSmall);
427 Info->hMenuConsoleSmall = NULL;
428 }
429
430 if (Info->hMenuConsoleLarge != NULL)
431 {
432 DestroyMenu(Info->hMenuConsoleLarge);
433 Info->hMenuConsoleLarge = NULL;
434 }
435
436 HeapFree(hAppHeap,
437 0,
438 Info);
439 }
440
441 PostQuitMessage(0);
442 break;
443
444 case WM_USER_CLOSE_CHILD:
445 Info->nConsoleCount--;
446 if (Info->nConsoleCount == 0)
447 {
448 SetMenu(Info->hwnd,
449 Info->hMenuConsoleSmall);
450 }
451 break;
452
453 default:
454 return DefFrameProc(hwnd,
455 hwndMDIClient,
456 uMsg,
457 wParam,
458 lParam);
459 }
460
461 return 0;
462 }
463
464
465 static LRESULT CALLBACK
466 ConsoleChildFrmProc(IN HWND hwnd,
467 IN UINT uMsg,
468 IN WPARAM wParam,
469 IN LPARAM lParam)
470 {
471 PCONSOLE_CHILDFRM_WND Info;
472
473 Info = (PCONSOLE_CHILDFRM_WND)GetWindowLongPtr(hwnd,
474 0);
475
476 switch (uMsg)
477 {
478 case WM_CREATE:
479 Info = HeapAlloc(hAppHeap,
480 HEAP_ZERO_MEMORY,
481 sizeof(CONSOLE_CHILDFRM_WND));
482 if (Info != NULL)
483 {
484 Info->hwnd = hwnd;
485
486 SetWindowLongPtr(hwnd,
487 0,
488 (LONG_PTR)Info);
489 }
490 break;
491
492 case WM_DESTROY:
493 if (Info != NULL)
494 {
495 if (Info->pFileName)
496 HeapFree(hAppHeap, 0, Info->pFileName);
497
498 HeapFree(hAppHeap, 0, Info);
499 }
500
501 PostMessage(hwndMainConsole, WM_USER_CLOSE_CHILD, 0, 0);
502 break;
503
504 default:
505 return DefMDIChildProc(hwnd, uMsg, wParam, lParam);
506 }
507
508 return 0;
509 }
510
511
512 BOOL
513 RegisterMMCWndClasses(VOID)
514 {
515 WNDCLASSEX wc = {0};
516 BOOL Ret;
517
518 /* Register the MMCMainFrame window class */
519 wc.cbSize = sizeof(WNDCLASSEX);
520 wc.style = 0;
521 wc.lpfnWndProc = ConsoleMainFrameWndProc;
522 wc.cbClsExtra = 0;
523 wc.cbWndExtra = sizeof(PCONSOLE_MAINFRAME_WND);
524 wc.hInstance = hAppInstance;
525 wc.hIcon = LoadIcon(hAppInstance,
526 MAKEINTRESOURCE(IDI_MAINAPP));
527 wc.hCursor = LoadCursor(NULL,
528 MAKEINTRESOURCE(IDC_ARROW));
529 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
530 wc.lpszMenuName = NULL;
531 wc.lpszClassName = szMMCMainFrame;
532
533 Ret = (RegisterClassEx(&wc) != (ATOM)0);
534
535 if (Ret)
536 {
537 /* Register the MMCChildFrm window class */
538 wc.cbSize = sizeof(WNDCLASSEX);
539 wc.style = CS_HREDRAW | CS_VREDRAW;
540 wc.lpfnWndProc = ConsoleChildFrmProc;
541 wc.cbClsExtra = 0;
542 wc.cbWndExtra = sizeof(PCONSOLE_CHILDFRM_WND);
543 wc.hInstance = hAppInstance;
544 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
545 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
546 wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
547 wc.lpszMenuName = NULL;
548 wc.lpszClassName = szMMCChildFrm;
549 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
550
551 Ret = (RegisterClassEx(&wc) != (ATOM)0);
552 if (!Ret)
553 {
554 UnregisterClass(szMMCMainFrame,
555 hAppInstance);
556 }
557 }
558
559 return Ret;
560 }
561
562 VOID
563 UnregisterMMCWndClasses(VOID)
564 {
565 UnregisterClass(szMMCChildFrm,
566 hAppInstance);
567 UnregisterClass(szMMCMainFrame,
568 hAppInstance);
569 }
570
571 HWND
572 CreateConsoleWindow(IN LPCTSTR lpFileName OPTIONAL,
573 int nCmdShow)
574 {
575 HWND hWndConsole;
576 LONG_PTR FileName = (LONG_PTR)lpFileName;
577
578 hWndConsole = CreateWindowEx(WS_EX_WINDOWEDGE,
579 szMMCMainFrame,
580 NULL,
581 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
582 CW_USEDEFAULT,
583 CW_USEDEFAULT,
584 CW_USEDEFAULT,
585 CW_USEDEFAULT,
586 NULL,
587 NULL,
588 hAppInstance,
589 (PVOID)FileName);
590
591 if (hWndConsole != NULL)
592 {
593 ShowWindow(hWndConsole, nCmdShow);
594 }
595
596 return hWndConsole;
597 }