6a385d530a87eaa68e5895c43269733323cb31ee
[reactos.git] / rosapps / regedit / childwnd.c
1 /*
2 * ReactOS regedit
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 <assert.h>
38 #define ASSERT assert
39
40 #include "main.h"
41 #include "framewnd.h"
42 #include "childwnd.h"
43 #include "treeview.h"
44 #include "listview.h"
45
46
47 ////////////////////////////////////////////////////////////////////////////////
48
49 static void draw_splitbar(HWND hWnd, int x)
50 {
51 RECT rt;
52 HDC hdc = GetDC(hWnd);
53
54 GetClientRect(hWnd, &rt);
55 rt.left = x - SPLIT_WIDTH/2;
56 rt.right = x + SPLIT_WIDTH/2+1;
57 InvertRect(hdc, &rt);
58 ReleaseDC(hWnd, hdc);
59 }
60
61 #define _NO_EXTENSIONS
62
63 static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy)
64 {
65 HDWP hdwp = BeginDeferWindowPos(2);
66 RECT rt = {0, 0, cx, cy};
67
68 cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2;
69 DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
70 DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx+1, rt.top, rt.right-cx, rt.bottom-rt.top, SWP_NOZORDER|SWP_NOACTIVATE);
71 EndDeferWindowPos(hdwp);
72 }
73
74 static void OnSize(ChildWnd* pChildWnd, WPARAM wParam, LPARAM lParam)
75 {
76 if (wParam != SIZE_MINIMIZED && pChildWnd != NULL) {
77 ResizeWnd(pChildWnd, LOWORD(lParam), HIWORD(lParam));
78 }
79 }
80
81 static void OnPaint(HWND hWnd)
82 {
83 PAINTSTRUCT ps;
84 RECT rt;
85 HDC hdc;
86
87 GetClientRect(hWnd, &rt);
88 hdc = BeginPaint(hWnd, &ps);
89 FillRect(ps.hdc, &rt, GetStockObject(LTGRAY_BRUSH));
90 EndPaint(hWnd, &ps);
91 }
92
93
94 ////////////////////////////////////////////////////////////////////////////////
95 //
96 // FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
97 //
98 // PURPOSE: Processes WM_COMMAND messages for the main frame window.
99 //
100 //
101
102 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
103 {
104 switch (LOWORD(wParam)) {
105 // Parse the menu selections:
106 case ID_REGISTRY_EXIT:
107 DestroyWindow(hWnd);
108 break;
109 case ID_VIEW_REFRESH:
110 // TODO:
111 break;
112 default:
113 return FALSE;
114 }
115 return TRUE;
116 }
117
118 ////////////////////////////////////////////////////////////////////////////////
119 //
120 // FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
121 //
122 // PURPOSE: Processes messages for the child windows.
123 //
124 // WM_COMMAND - process the application menu
125 // WM_PAINT - Paint the main window
126 // WM_DESTROY - post a quit message and return
127 //
128 //
129 LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
130 {
131 static int last_split;
132 // ChildWnd* pChildWnd = (ChildWnd*)GetWindowLong(hWnd, GWL_USERDATA);
133 static ChildWnd* pChildWnd;
134
135 switch (message) {
136 case WM_CREATE:
137 pChildWnd = (ChildWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;
138 ASSERT(pChildWnd);
139 pChildWnd->nSplitPos = 250;
140 pChildWnd->hTreeWnd = CreateTreeView(hWnd, TREE_WINDOW, &pChildWnd->root);
141 pChildWnd->hListWnd = CreateListView(hWnd, LIST_WINDOW, &pChildWnd->root);
142 break;
143 case WM_COMMAND:
144 if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
145 return DefWindowProc(hWnd, message, wParam, lParam);
146 }
147 break;
148 case WM_PAINT:
149 OnPaint(hWnd);
150 return 0;
151 case WM_SETCURSOR:
152 if (LOWORD(lParam) == HTCLIENT) {
153 POINT pt;
154 GetCursorPos(&pt);
155 ScreenToClient(hWnd, &pt);
156 if (pt.x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.x<pChildWnd->nSplitPos+SPLIT_WIDTH/2+1) {
157 SetCursor(LoadCursor(0, IDC_SIZEWE));
158 return TRUE;
159 }
160 }
161 goto def;
162 //break;
163
164 case WM_DESTROY:
165 PostQuitMessage(0);
166 break;
167 case WM_LBUTTONDOWN: {
168 RECT rt;
169 int x = LOWORD(lParam);
170 GetClientRect(hWnd, &rt);
171 if (x>=pChildWnd->nSplitPos-SPLIT_WIDTH/2 && x<pChildWnd->nSplitPos+SPLIT_WIDTH/2+1) {
172 last_split = pChildWnd->nSplitPos;
173 #ifdef _NO_EXTENSIONS
174 draw_splitbar(hWnd, last_split);
175 #endif
176 SetCapture(hWnd);
177 }
178 break;}
179
180 case WM_LBUTTONUP:
181 if (GetCapture() == hWnd) {
182 #ifdef _NO_EXTENSIONS
183 RECT rt;
184 int x = LOWORD(lParam);
185 draw_splitbar(hWnd, last_split);
186 last_split = -1;
187 GetClientRect(hWnd, &rt);
188 pChildWnd->nSplitPos = x;
189 ResizeWnd(pChildWnd, rt.right, rt.bottom);
190 #endif
191 ReleaseCapture();
192 }
193 break;
194
195 #ifdef _NO_EXTENSIONS
196 case WM_CAPTURECHANGED:
197 if (GetCapture()==hWnd && last_split>=0)
198 draw_splitbar(hWnd, last_split);
199 break;
200 #endif
201 case WM_KEYDOWN:
202 if (wParam == VK_ESCAPE)
203 if (GetCapture() == hWnd) {
204 RECT rt;
205 #ifdef _NO_EXTENSIONS
206 draw_splitbar(hWnd, last_split);
207 #else
208 pChildWnd->nSplitPos = last_split;
209 #endif
210 GetClientRect(hWnd, &rt);
211 ResizeWnd(pChildWnd, rt.right, rt.bottom);
212 last_split = -1;
213 ReleaseCapture();
214 SetCursor(LoadCursor(0, IDC_ARROW));
215 }
216 break;
217
218 case WM_MOUSEMOVE:
219 if (GetCapture() == hWnd) {
220 RECT rt;
221 int x = LOWORD(lParam);
222 #ifdef _NO_EXTENSIONS
223 HDC hdc = GetDC(hWnd);
224 GetClientRect(hWnd, &rt);
225 rt.left = last_split-SPLIT_WIDTH/2;
226 rt.right = last_split+SPLIT_WIDTH/2+1;
227 InvertRect(hdc, &rt);
228 last_split = x;
229 rt.left = x-SPLIT_WIDTH/2;
230 rt.right = x+SPLIT_WIDTH/2+1;
231 InvertRect(hdc, &rt);
232 ReleaseDC(hWnd, hdc);
233 #else
234 GetClientRect(hWnd, &rt);
235 if (x>=0 && x<rt.right) {
236 pChildWnd->nSplitPos = x;
237 //resize_tree(pChildWnd, rt.right, rt.bottom);
238 rt.left = x-SPLIT_WIDTH/2;
239 rt.right = x+SPLIT_WIDTH/2+1;
240 InvalidateRect(hWnd, &rt, FALSE);
241 UpdateWindow(hTreeWnd);
242 UpdateWindow(hWnd);
243 UpdateWindow(hListWnd);
244 }
245 #endif
246 }
247 break;
248
249 #ifndef _NO_EXTENSIONS
250 case WM_GETMINMAXINFO:
251 DefWindowProc(hWnd, message, wParam, lParam);
252 {LPMINMAXINFO lpmmi = (LPMINMAXINFO)lParam;
253 lpmmi->ptMaxTrackSize.x <<= 1;//2*GetSystemMetrics(SM_CXSCREEN) / SM_CXVIRTUALSCREEN
254 lpmmi->ptMaxTrackSize.y <<= 1;//2*GetSystemMetrics(SM_CYSCREEN) / SM_CYVIRTUALSCREEN
255 break;}
256 #endif
257
258 case WM_SETFOCUS:
259 // SetCurrentDirectory(szPath);
260 if (pChildWnd != NULL) {
261 SetFocus(pChildWnd->nFocusPanel? pChildWnd->hListWnd: pChildWnd->hTreeWnd);
262 }
263 break;
264
265 case WM_TIMER:
266 break;
267
268 case WM_NOTIFY:
269 if ((int)wParam == TREE_WINDOW) {
270 if ((((LPNMHDR)lParam)->code) == TVN_SELCHANGED) {
271 Entry* entry = (Entry*)((NMTREEVIEW*)lParam)->itemNew.lParam;
272 if (entry != NULL) {
273 if (!entry->scanned) {
274 //scan_entry(pChildWnd, entry);
275 } else {
276 //RefreshList(pChildWnd->hListWnd, entry);
277 }
278 //RefreshList(pChildWnd->hListWnd, entry->down);
279 RefreshList(pChildWnd->hListWnd, entry);
280 }
281 }
282 if (!SendMessage(pChildWnd->hTreeWnd, message, wParam, lParam)) {
283 goto def;
284 }
285 }
286 if ((int)wParam == LIST_WINDOW) {
287 if (!SendMessage(pChildWnd->hListWnd, message, wParam, lParam)) {
288 goto def;
289 }
290 }
291 break;
292
293 case WM_SIZE:
294 if (wParam != SIZE_MINIMIZED) {
295 OnSize(pChildWnd, wParam, lParam);
296 }
297 // fall through
298 default: def:
299 return DefWindowProc(hWnd, message, wParam, lParam);
300 }
301 return 0;
302 }