Updated with latest progress. Started on a worker thread for network enumerating...
[reactos.git] / rosapps / winfile / childwnd.c
1 /*
2 * ReactOS winfile
3 *
4 * childwnd.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 <windowsx.h>
38 #include <ctype.h>
39 #include <assert.h>
40 #define ASSERT assert
41
42 #include "main.h"
43 #include "framewnd.h"
44 #include "childwnd.h"
45 #include "treeview.h"
46 #include "listview.h"
47 #include "dialogs.h"
48 #include "utils.h"
49 #include "run.h"
50 #include "trace.h"
51
52
53 #ifdef _NO_EXTENSIONS
54 //#define COLOR_SPLITBAR WHITE_BRUSH
55 #define COLOR_SPLITBAR LTGRAY_BRUSH
56 #else
57 #define COLOR_SPLITBAR LTGRAY_BRUSH
58 #endif
59
60 ////////////////////////////////////////////////////////////////////////////////
61 // Global Variables:
62 //
63
64
65 ////////////////////////////////////////////////////////////////////////////////
66 // Local module support methods
67 //
68
69 static BOOL pane_command(Pane* pane, UINT cmd)
70 {
71 switch(cmd) {
72 case ID_VIEW_NAME:
73 if (pane->visible_cols) {
74 pane->visible_cols = 0;
75 calc_widths(pane, TRUE);
76 #ifndef _NO_EXTENSIONS
77 set_header(pane);
78 #endif
79 InvalidateRect(pane->hWnd, 0, TRUE);
80 CheckMenuItem(Globals.hMenuView, ID_VIEW_NAME, MF_BYCOMMAND|MF_CHECKED);
81 // CheckMenuItem(Globals.hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND);
82 // CheckMenuItem(Globals.hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND);
83 }
84 break;
85 #if 0
86 case ID_VIEW_ALL_ATTRIBUTES:
87 if (pane->visible_cols != COL_ALL) {
88 pane->visible_cols = COL_ALL;
89 calc_widths(pane, TRUE);
90 InvalidateRect(pane->hWnd, 0, TRUE);
91 CheckMenuItem(Globals.hMenuView, ID_VIEW_NAME, MF_BYCOMMAND);
92 // CheckMenuItem(Globals.hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND|MF_CHECKED);
93 // CheckMenuItem(Globals.hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND);
94 }
95 break;
96 #endif
97 // TODO: more command ids...
98 default:
99 return FALSE;
100 }
101 return TRUE;
102 }
103
104 static void draw_splitbar(HWND hWnd, int x)
105 {
106 RECT rt;
107 HDC hdc = GetDC(hWnd);
108
109 GetClientRect(hWnd, &rt);
110 rt.left = x - SPLIT_WIDTH/2;
111 rt.right = x + SPLIT_WIDTH/2+1;
112 InvertRect(hdc, &rt);
113 ReleaseDC(hWnd, hdc);
114 }
115
116 static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy)
117 {
118 HDWP hdwp = BeginDeferWindowPos(2);
119 RECT rt = {0, 0, cx, cy};
120
121 cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2;
122 DeferWindowPos(hdwp, pChildWnd->left.hWnd, 0, rt.left, rt.top, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
123 DeferWindowPos(hdwp, pChildWnd->right.hWnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
124 EndDeferWindowPos(hdwp);
125 }
126
127 static void OnSize(ChildWnd* pChildWnd, WPARAM wParam, LPARAM lParam)
128 {
129 if (wParam != SIZE_MINIMIZED) {
130 ResizeWnd(pChildWnd, LOWORD(lParam), HIWORD(lParam));
131 }
132 }
133
134 void OnFileMove(HWND hWnd)
135 {
136 struct ExecuteDialog dlg = {{0}};
137 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_FILE_MOVE), hWnd, MoveFileWndProc, (LPARAM)&dlg) == IDOK) {
138 }
139 }
140
141 static void OnPaint(HWND hWnd, ChildWnd* pChildWnd)
142 {
143 HBRUSH lastBrush;
144 PAINTSTRUCT ps;
145 RECT rt;
146
147 BeginPaint(hWnd, &ps);
148 GetClientRect(hWnd, &rt);
149 lastBrush = SelectObject(ps.hdc, (HBRUSH)GetStockObject(COLOR_SPLITBAR));
150 Rectangle(ps.hdc, rt.left, rt.top-1, rt.right, rt.bottom+1);
151 SelectObject(ps.hdc, lastBrush);
152 // rt.top = rt.bottom - GetSystemMetrics(SM_CYHSCROLL);
153 // FillRect(ps.hdc, &rt, GetStockObject(BLACK_BRUSH));
154 EndPaint(hWnd, &ps);
155 }
156
157 ////////////////////////////////////////////////////////////////////////////////
158 //
159 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
160 //
161 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
162 //
163 //
164
165 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
166 {
167 //UINT cmd = LOWORD(wParam);
168 //HWND hChildWnd;
169
170 switch (LOWORD(wParam)) {
171 // Parse the menu selections:
172 /*
173 // case ID_FILE_MOVE:
174 // OnFileMove(hWnd);
175 // break;
176 case ID_FILE_COPY:
177 case ID_FILE_COPY_CLIPBOARD:
178 case ID_FILE_DELETE:
179 case ID_FILE_RENAME:
180 case ID_FILE_PROPERTIES:
181 case ID_FILE_COMPRESS:
182 case ID_FILE_UNCOMPRESS:
183 break;
184 // case ID_FILE_RUN:
185 // OnFileRun();
186 // break;
187 case ID_FILE_PRINT:
188 case ID_FILE_ASSOCIATE:
189 case ID_FILE_CREATE_DIRECTORY:
190 case ID_FILE_SEARCH:
191 case ID_FILE_SELECT_FILES:
192 break;
193 */
194 case ID_FILE_EXIT:
195 SendMessage(hWnd, WM_CLOSE, 0, 0);
196 break;
197 /*
198 case ID_DISK_COPY_DISK:
199 break;
200 case ID_DISK_LABEL_DISK:
201 break;
202 case ID_DISK_CONNECT_NETWORK_DRIVE:
203 MapNetworkDrives(hWnd, TRUE);
204 break;
205 case ID_DISK_DISCONNECT_NETWORK_DRIVE:
206 MapNetworkDrives(hWnd, FALSE);
207 break;
208 case ID_DISK_SHARE_AS:
209 break;
210 case ID_DISK_STOP_SHARING:
211 break;
212 case ID_DISK_SELECT_DRIVE:
213 break;
214 */
215 /*
216 case ID_TREE_EXPAND_ONE_LEVEL:
217 case ID_TREE_EXPAND_ALL:
218 case ID_TREE_EXPAND_BRANCH:
219 case ID_TREE_COLLAPSE_BRANCH:
220 MessageBeep(-1);
221 break;
222 */
223 case ID_VIEW_BY_FILE_TYPE:
224 {
225 struct ExecuteDialog dlg = {{0}};
226 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_VIEW_TYPE), hWnd, ViewFileTypeWndProc, (LPARAM)&dlg) == IDOK) {
227 }
228 }
229 break;
230 case ID_OPTIONS_CONFIRMATION:
231 {
232 struct ExecuteDialog dlg = {{0}};
233 if (DialogBoxParam(Globals.hInstance, MAKEINTRESOURCE(IDD_DIALOG_OPTIONS_CONFIRMATON), hWnd, OptionsConfirmationWndProc, (LPARAM)&dlg) == IDOK) {
234 }
235 }
236 break;
237 case ID_WINDOW_NEW_WINDOW:
238 CreateChildWindow(-1);
239 // {
240 // ChildWnd* pChildWnd = alloc_child_window(path);
241 // if (!create_child_window(pChildWnd))
242 // free(pChildWnd);
243 // }
244 break;
245 default:
246 // return DefMDIChildProc(hWnd, message, wParam, lParam);
247 return FALSE;
248 break;
249 }
250 return TRUE;
251 }
252
253 ////////////////////////////////////////////////////////////////////////////////
254 //
255 // FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
256 //
257 // PURPOSE: Processes messages for the child windows.
258 //
259 // WM_COMMAND - process the application menu
260 // WM_PAINT - Paint the main window
261 // WM_DESTROY - post a quit message and return
262 //
263 //
264 LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
265 {
266 static int last_split;
267
268 ChildWnd* pChildWnd = (ChildWnd*)GetWindowLong(hWnd, GWL_USERDATA);
269 ASSERT(pChildWnd);
270
271 switch(message) {
272 case WM_CREATE:
273 CreateTreeWnd(pChildWnd->hWnd, &pChildWnd->left, IDW_TREE_LEFT);
274 CreateListWnd(pChildWnd->hWnd, &pChildWnd->right, IDW_TREE_RIGHT, pChildWnd->szPath);
275 //create_tree_window(pChildWnd->hWnd, &pChildWnd->left, IDW_TREE_LEFT, IDW_HEADER_LEFT, pChildWnd->szPath);
276 //create_list_window(pChildWnd->hWnd, &pChildWnd->right, IDW_TREE_RIGHT, IDW_HEADER_RIGHT);
277 return 0;
278 break;
279 case WM_PAINT:
280 OnPaint(hWnd, pChildWnd);
281 return 0;
282 case WM_NCDESTROY:
283 // free_child_window(pChildWnd);
284 SetWindowLong(hWnd, GWL_USERDATA, 0);
285 break;
286 case WM_SETCURSOR:
287 if (LOWORD(lParam) == HTCLIENT) {
288 POINT pt;
289 GetCursorPos(&pt);
290 ScreenToClient(hWnd, &pt);
291 if (pt.x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.x<pChildWnd->nSplitPos+SPLIT_WIDTH/2+1) {
292 SetCursor(LoadCursor(0, IDC_SIZEWE));
293 return TRUE;
294 }
295 }
296 goto def;
297 case WM_LBUTTONDOWN: {
298 RECT rt;
299 int x = LOWORD(lParam);
300 GetClientRect(hWnd, &rt);
301 if (x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && x<pChildWnd->nSplitPos+SPLIT_WIDTH/2+1) {
302 last_split = pChildWnd->nSplitPos;
303 draw_splitbar(hWnd, last_split);
304 SetCapture(hWnd);
305 }
306 break;}
307
308 case WM_LBUTTONUP:
309 if (GetCapture() == hWnd) {
310 RECT rt;
311 int x = LOWORD(lParam);
312 draw_splitbar(hWnd, last_split);
313 last_split = -1;
314 GetClientRect(hWnd, &rt);
315 pChildWnd->nSplitPos = x;
316 ResizeWnd(pChildWnd, rt.right, rt.bottom);
317 ReleaseCapture();
318 }
319 break;
320
321 case WM_CAPTURECHANGED:
322 if (GetCapture()==hWnd && last_split>=0)
323 draw_splitbar(hWnd, last_split);
324 break;
325
326 case WM_KEYDOWN:
327 if (wParam == VK_ESCAPE)
328 if (GetCapture() == hWnd) {
329 RECT rt;
330 draw_splitbar(hWnd, last_split);
331 GetClientRect(hWnd, &rt);
332 ResizeWnd(pChildWnd, rt.right, rt.bottom);
333 last_split = -1;
334 ReleaseCapture();
335 SetCursor(LoadCursor(0, IDC_ARROW));
336 }
337 break;
338
339 case WM_MOUSEMOVE:
340 if (GetCapture() == hWnd) {
341 RECT rt;
342 int x = LOWORD(lParam);
343 HDC hdc = GetDC(hWnd);
344 GetClientRect(hWnd, &rt);
345 rt.left = last_split-SPLIT_WIDTH/2;
346 rt.right = last_split+SPLIT_WIDTH/2+1;
347 InvertRect(hdc, &rt);
348 last_split = x;
349 rt.left = x-SPLIT_WIDTH/2;
350 rt.right = x+SPLIT_WIDTH/2+1;
351 InvertRect(hdc, &rt);
352 ReleaseDC(hWnd, hdc);
353 }
354 break;
355
356 case WM_SETFOCUS:
357 SetCurrentDirectory(pChildWnd->szPath);
358 SetFocus(pChildWnd->nFocusPanel? pChildWnd->right.hWnd: pChildWnd->left.hWnd);
359 break;
360
361 case WM_DISPATCH_COMMAND:
362 if (_CmdWndProc(hWnd, message, wParam, lParam)) break;
363 if (1) {
364 return SendMessage(pChildWnd->right.hWnd, message, wParam, lParam);
365 } else {
366 return SendMessage(pChildWnd->left.hWnd, message, wParam, lParam);
367 }
368 break;
369
370 case WM_COMMAND:
371 if (_CmdWndProc(hWnd, message, wParam, lParam)) break;
372 return DefMDIChildProc(hWnd, message, wParam, lParam);
373
374 // if (LOWORD(wParam) > ID_CMD_FIRST && LOWORD(wParam) < ID_CMD_LAST) {
375 // if (!SendMessage(pChildWnd->right.hWnd, message, wParam, lParam)) {
376 // return DefMDIChildProc(hWnd, message, wParam, lParam);
377 // }
378 // } else {
379 // return _CmdWndProc(hWnd, message, wParam, lParam);
380 // }
381 break;
382 case WM_NOTIFY:
383 {
384 int idCtrl = (int)wParam;
385 //NMHDR* pnmh = (NMHDR*)lParam;
386 //return pane_notify(pnmh->idFrom==IDW_HEADER_LEFT? &pChildWnd->left: &pChildWnd->right, pnmh);
387 if ((int)wParam == IDW_TREE_LEFT) {
388 if ((((LPNMHDR)lParam)->code) == TVN_SELCHANGED) {
389 Entry* entry = (Entry*)((NMTREEVIEW*)lParam)->itemNew.lParam;
390 if (entry != NULL) {
391 //RefreshList(pChildWnd->right.hWnd, entry);
392 //void set_curdir(ChildWnd* child, Entry* entry)
393 set_curdir(pChildWnd, entry);
394 }
395 }
396 if (!SendMessage(pChildWnd->left.hWnd, message, wParam, lParam)) {
397 return DefMDIChildProc(hWnd, message, wParam, lParam);
398 }
399 } else
400 if ((int)wParam == IDW_TREE_RIGHT) {
401 if (!SendMessage(pChildWnd->right.hWnd, message, wParam, lParam)) {
402 return DefMDIChildProc(hWnd, message, wParam, lParam);
403 }
404 }
405 }
406 break;
407
408 case WM_SIZE:
409 if (wParam != SIZE_MINIMIZED && pChildWnd != NULL) {
410 ResizeWnd(pChildWnd, LOWORD(lParam), HIWORD(lParam));
411 }
412 // fall through
413 default: def:
414 return DefMDIChildProc(hWnd, message, wParam, lParam);
415 }
416 return 0;
417 }
418
419 ATOM RegisterChildWnd(HINSTANCE hInstance, int res_id)
420 {
421 WNDCLASSEX wcFrame = {
422 sizeof(WNDCLASSEX),
423 CS_HREDRAW | CS_VREDRAW/*style*/,
424 FrameWndProc,
425 0/*cbClsExtra*/,
426 0/*cbWndExtra*/,
427 hInstance,
428 LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINFILE)),
429 LoadCursor(0, IDC_ARROW),
430 0/*hbrBackground*/,
431 0/*lpszMenuName*/,
432 szFrameClass,
433 (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_WINFILE), IMAGE_ICON,
434 GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED)
435 };
436 ATOM hFrameWndClass = RegisterClassEx(&wcFrame); // register frame window class
437 return hFrameWndClass;
438 }