6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
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.
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.
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.
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
42 ////////////////////////////////////////////////////////////////////////////////
46 BOOL bInMenuLoop
= FALSE
; // Tells us if we are in the menu loop
48 ////////////////////////////////////////////////////////////////////////////////
49 // Local module support methods
52 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
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;
62 if (IsWindowVisible(hStatusBar
)) {
63 int parts
[] = {300, 500};
65 SendMessage(hStatusBar
, WM_SIZE
, 0, 0);
66 SendMessage(hStatusBar
, SB_SETPARTS
, 2, (LPARAM
)&parts
);
67 GetClientRect(hStatusBar
, &rt
);
68 prect
->bottom
-= rt
.bottom
;
70 MoveWindow(hMDIClient
, prect
->left
-1,prect
->top
-1,prect
->right
+2,prect
->bottom
+1, TRUE
);
73 static void resize_frame(HWND hWnd
, int cx
, int cy
)
75 RECT rect
= {0, 0, cx
, cy
};
77 resize_frame_rect(hWnd
, &rect
);
80 void resize_frame_client(HWND hWnd
)
84 GetClientRect(hWnd
, &rect
);
85 resize_frame_rect(hWnd
, &rect
);
88 ////////////////////////////////////////////////////////////////////////////////
89 static HHOOK hcbthook
;
90 static ChildWnd
* newchild
= NULL
;
92 LRESULT CALLBACK
CBTProc(int code
, WPARAM wParam
, LPARAM lParam
)
94 if (code
== HCBT_CREATEWND
&& newchild
) {
95 ChildWnd
* pChildWnd
= newchild
;
97 pChildWnd
->hWnd
= (HWND
)wParam
;
98 SetWindowLong(pChildWnd
->hWnd
, GWL_USERDATA
, (LPARAM
)pChildWnd
);
100 return CallNextHookEx(hcbthook
, code
, wParam
, lParam
);
104 HWND
create_child_window(ChildWnd
* pChildWnd
)
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*/
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
)
118 UnhookWindowsHookEx(hcbthook
);
119 return pChildWnd
->hWnd
;
125 void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
127 BOOL vis
= IsWindowVisible(hchild
);
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
);
136 static HWND
InitChildWindow(LPTSTR param
)
138 //TCHAR drv[_MAX_DRIVE];
139 TCHAR path
[MAX_PATH
];
140 ChildWnd
* pChildWnd
= NULL
;
142 LPCTSTR root = Globals.drives;
144 for(i = cmd - ID_DRIVE_FIRST; i--; root++)
147 if (activate_drive_window(root))
149 _tsplitpath(root, drv, 0, 0, 0);
150 if (!SetCurrentDirectory(drv)) {
151 display_error(hWnd, GetLastError());
155 GetCurrentDirectory(MAX_PATH
, path
);
156 // pChildWnd = alloc_child_window(path);
157 // if (!create_child_window(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*/
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
) {
184 newchild
= pChildWnd
= NULL
;
186 return pChildWnd
->hWnd
;
191 BOOL CALLBACK
CloseEnumProc(HWND hWnd
, LPARAM lParam
)
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);
202 void OnEnterMenuLoop(HWND hWnd
)
206 // Update the status bar pane sizes
208 SendMessage(hStatusBar
, SB_SETPARTS
, 1, (long)&nParts
);
210 SendMessage(hStatusBar
, SB_SETTEXT
, (WPARAM
)0, (LPARAM
)_T(""));
213 void OnExitMenuLoop(HWND hWnd
)
219 // Update the status bar pane sizes
220 GetClientRect(hWnd
, &rc
);
223 nParts
[2] = rc
.right
;
224 SendMessage(hStatusBar
, SB_SETPARTS
, 3, (long)nParts
);
225 SendMessage(hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)_T(""));
229 void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
233 strcpy(str
, TEXT(""));
234 if (nFlags
& MF_POPUP
) {
235 if (hSysMenu
!= GetMenu(hWnd
)) {
236 if (nItemID
== 2) nItemID
= 5;
239 if (LoadString(hInst
, nItemID
, str
, 100)) {
240 // load appropriate string
242 // first newline terminates actual string
243 lpsz
= _tcschr(lpsz
, '\n');
247 SendMessage(hStatusBar
, SB_SETTEXT
, 0, (LPARAM
)str
);
250 ////////////////////////////////////////////////////////////////////////////////
252 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
254 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
258 LRESULT
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
264 switch (LOWORD(wParam
)) {
265 case ID_WINDOW_CLOSEALL
:
266 EnumChildWindows(hMDIClient
, &CloseEnumProc
, 0);
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);
274 SendMessage(hWnd
, WM_CLOSE
, 0, 0);
276 case ID_OPTIONS_TOOLBAR
:
277 toggle_child(hWnd
, LOWORD(wParam
), hToolBar
);
279 case ID_OPTIONS_STATUSBAR
:
280 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
284 case ID_WINDOW_NEW_WINDOW
:
285 InitChildWindow("Child Window");
287 case ID_WINDOW_CASCADE
:
288 SendMessage(hMDIClient
, WM_MDICASCADE
, 0, 0);
290 case ID_WINDOW_TILE_HORZ
:
291 SendMessage(hMDIClient
, WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
293 case ID_WINDOW_TILE_VERT
:
294 SendMessage(hMDIClient
, WM_MDITILE
, MDITILE_VERTICAL
, 0);
296 case ID_WINDOW_ARRANGE_ICONS
:
297 SendMessage(hMDIClient
, WM_MDIICONARRANGE
, 0, 0);
303 hChildWnd
= (HWND
)SendMessage(hMDIClient
, WM_MDIGETACTIVE
, 0, 0);
304 if (IsWindow(hChildWnd
))
305 SendMessage(hChildWnd
, WM_COMMAND
, wParam
, lParam
);
307 return DefFrameProc(hWnd
, hMDIClient
, message
, wParam
, lParam
);
313 ////////////////////////////////////////////////////////////////////////////////
315 // FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
317 // PURPOSE: Processes messages for the main frame window.
319 // WM_COMMAND - process the application menu
320 // WM_DESTROY - post a quit message and return
324 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
329 HMENU hMenuWindow
= GetSubMenu(hMenuFrame
, GetMenuItemCount(hMenuFrame
)-2);
330 CLIENTCREATESTRUCT ccs
= { hMenuWindow
, IDW_FIRST_CHILD
};
332 hMDIClient
= CreateWindow(_T("MDICLIENT"), NULL
,
333 WS_CHILD
|WS_CLIPCHILDREN
|WS_VISIBLE
,
335 hWnd
, (HMENU
)1, hInst
, &ccs
);
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
,
341 hWnd
, (HMENU
)0, hInst
, &ccs
);
346 return _CmdWndProc(hWnd
, message
, wParam
, lParam
);
349 resize_frame_client(hWnd
);
351 case WM_ENTERMENULOOP
:
352 OnEnterMenuLoop(hWnd
);
354 case WM_EXITMENULOOP
:
355 OnExitMenuLoop(hWnd
);
358 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
363 case WM_QUERYENDSESSION
:
365 SendMessage(hWnd
, WM_COMMAND
, ID_WINDOW_CLOSEALL
, 0);
366 if (GetWindow(hMDIClient
, GW_CHILD
) != NULL
)
370 return DefFrameProc(hWnd
, hMDIClient
, message
, wParam
, lParam
);