3b60edb167115393798327b1655b6ffb11a5f1d8
[reactos.git] / rosapps / regedit / regedit.cpp
1 /*
2 * ReactOS regedit
3 *
4 * regedit.cpp
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 "regedit.h"
38 #include "regtree.h"
39 #include "reglist.h"
40 #include "resource.h"
41 #include <shellapi.h>
42 //#include <winspool.h>
43
44
45 // Global Variables:
46 HINSTANCE hInst; // current instance
47
48 HWND hMainWnd; // Main Window
49 HWND hStatusWnd; // Status Bar Window
50
51 HWND hTreeWnd; // Tree Control Window
52 HWND hListWnd; // List Control Window
53 HWND hSplitWnd; // Splitter Bar Control Window
54
55 int nMinimumWidth; // Minimum width of the dialog (OnSize()'s cx)
56 int nMinimumHeight; // Minimum height of the dialog (OnSize()'s cy)
57
58 int nOldWidth; // Holds the previous client area width
59 int nOldHeight; // Holds the previous client area height
60
61 BOOL bInMenuLoop = FALSE; // Tells us if we are in the menu loop
62
63 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
64 TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
65 TCHAR szFrameClass[MAX_LOADSTRING]; // The title bar text
66
67 // Foward declarations of functions included in this code module:
68 ATOM MyRegisterClass(HINSTANCE hInstance);
69 ATOM MyRegisterClass2(HINSTANCE hInstance);
70 BOOL InitInstance(HINSTANCE, int);
71 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
72 LRESULT CALLBACK FrameWndProc(HWND, UINT, WPARAM, LPARAM);
73
74 int APIENTRY WinMain(HINSTANCE hInstance,
75 HINSTANCE hPrevInstance,
76 LPSTR lpCmdLine,
77 int nCmdShow)
78 {
79 MSG msg;
80 HACCEL hAccelTable;
81
82 // Initialize global strings
83 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
84 LoadString(hInstance, IDC_REGEDIT, szWindowClass, MAX_LOADSTRING);
85 LoadString(hInstance, IDC_REGEDIT_FRAME, szFrameClass, MAX_LOADSTRING);
86
87 MyRegisterClass(hInstance);
88 MyRegisterClass2(hInstance);
89
90 // Perform application initialization:
91 if (!InitInstance(hInstance, nCmdShow)) {
92 return FALSE;
93 }
94 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_REGEDIT);
95
96 // Main message loop:
97 while (GetMessage(&msg, NULL, 0, 0)) {
98 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
99 TranslateMessage(&msg);
100 DispatchMessage(&msg);
101 }
102 }
103 return msg.wParam;
104 }
105
106
107
108 //
109 // FUNCTION: MyRegisterClass()
110 //
111 // PURPOSE: Registers the window class.
112 //
113 // COMMENTS:
114 //
115 // This function and its usage is only necessary if you want this code
116 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
117 // function that was added to Windows 95. It is important to call this function
118 // so that the application will get 'well formed' small icons associated
119 // with it.
120 //
121 ATOM MyRegisterClass(HINSTANCE hInstance)
122 {
123 WNDCLASSEX wcex;
124
125 wcex.cbSize = sizeof(WNDCLASSEX);
126 wcex.style = CS_HREDRAW | CS_VREDRAW;
127 wcex.lpfnWndProc = (WNDPROC)WndProc;
128 wcex.cbClsExtra = 0;
129 wcex.cbWndExtra = 0;
130 wcex.hInstance = hInstance;
131 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_REGEDIT);
132 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
133 wcex.hbrBackground = (HBRUSH)SS_BLACKRECT/*(COLOR_WINDOW+1)*/;
134 // wcex.lpszMenuName = (LPCSTR)IDC_REGEDIT;
135 wcex.lpszMenuName = (LPCSTR)IDR_REGEDIT_MENU;
136 wcex.lpszClassName = szWindowClass;
137 wcex.hIconSm = LoadIcon((HINSTANCE)wcex.hInstance, (LPCTSTR)IDI_SMALL);
138 return RegisterClassEx(&wcex);
139 }
140
141 ATOM MyRegisterClass2(HINSTANCE hInstance)
142 {
143 WNDCLASSEX wcex;
144
145 wcex.cbSize = sizeof(WNDCLASSEX);
146 wcex.style = CS_HREDRAW | CS_VREDRAW;
147 wcex.lpfnWndProc = (WNDPROC)FrameWndProc;
148 wcex.cbClsExtra = 0;
149 wcex.cbWndExtra = 0;
150 wcex.hInstance = hInstance;
151 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_REGEDIT);
152 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
153 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
154 wcex.lpszMenuName = (LPCSTR)IDR_REGEDIT_MENU;
155 wcex.lpszClassName = szFrameClass;
156 wcex.hIconSm = LoadIcon((HINSTANCE)wcex.hInstance, (LPCTSTR)IDI_SMALL);
157 return RegisterClassEx(&wcex);
158 }
159
160 //
161 //
162 // FUNCTION: InitInstance(HANDLE, int)
163 //
164 // PURPOSE: Saves instance handle and creates main window
165 //
166 // COMMENTS:
167 //
168 // In this function, we save the instance handle in a global variable and
169 // create and display the main program window.
170 //
171 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
172 {
173 int nParts[3];
174
175 // Initialize the Windows Common Controls DLL
176 InitCommonControls();
177
178 hInst = hInstance; // Store instance handle in our global variable
179 hMainWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
180 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
181 if (!hMainWnd) {
182 return FALSE;
183 }
184
185 // Get the minimum window sizes
186 // GetWindowRect(hMainWnd, &rc);
187 // nMinimumWidth = (rc.right - rc.left);
188 // nMinimumHeight = (rc.bottom - rc.top);
189
190 // Create the status bar
191 hStatusWnd = CreateStatusWindow(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS,
192 "", hMainWnd, STATUS_WINDOW);
193 if (!hStatusWnd)
194 return FALSE;
195
196 // Create the status bar panes
197 nParts[0] = 100;
198 nParts[1] = 210;
199 nParts[2] = 400;
200 SendMessage(hStatusWnd, SB_SETPARTS, 3, (long)nParts);
201
202 /*
203 hSplitWnd = CreateWindow(szFrameClass, "splitter window", WS_VISIBLE|WS_CHILD,
204 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
205 hMainWnd, (HMENU)SPLIT_WINDOW, hInstance, NULL);
206 if (!hSplitWnd)
207 return FALSE;
208 */
209 hTreeWnd = CreateTreeView(hMainWnd, "c:\\foobar.txt");
210 if (!hTreeWnd)
211 return FALSE;
212
213 hListWnd = CreateListView(hMainWnd, "");
214 if (!hListWnd)
215 return FALSE;
216
217 ShowWindow(hMainWnd, nCmdShow);
218 UpdateWindow(hMainWnd);
219 return TRUE;
220 }
221
222
223 // OnSize()
224 // This function handles all the sizing events for the application
225 // It re-sizes every window, and child window that needs re-sizing
226 void OnSize(UINT nType, int cx, int cy)
227 {
228 int nParts[3];
229 int nXDifference;
230 int nYDifference;
231 RECT rc;
232
233 if (nType == SIZE_MINIMIZED)
234 return;
235
236 nXDifference = cx - nOldWidth;
237 nYDifference = cy - nOldHeight;
238 nOldWidth = cx;
239 nOldHeight = cy;
240
241 // Update the status bar size
242 GetWindowRect(hStatusWnd, &rc);
243 SendMessage(hStatusWnd, WM_SIZE, nType, MAKELPARAM(cx, cy + (rc.bottom - rc.top)));
244
245 // Update the status bar pane sizes
246 nParts[0] = bInMenuLoop ? -1 : 100;
247 nParts[1] = 210;
248 nParts[2] = cx;
249 SendMessage(hStatusWnd, SB_SETPARTS, bInMenuLoop ? 1 : 3, (long)nParts);
250
251 GetWindowRect(hStatusWnd, &rc);
252
253 MoveWindow(hTreeWnd,0,0,cx/2,cy-(rc.bottom - rc.top),TRUE);
254 MoveWindow(hListWnd,cx/2,0,cx,cy-(rc.bottom - rc.top),TRUE);
255
256 }
257
258 void OnEnterMenuLoop(HWND hWnd)
259 {
260 int nParts;
261
262 // Update the status bar pane sizes
263 nParts = -1;
264 SendMessage(hStatusWnd, SB_SETPARTS, 1, (long)&nParts);
265 bInMenuLoop = TRUE;
266 SendMessage(hStatusWnd, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
267 }
268
269 void OnExitMenuLoop(HWND hWnd)
270 {
271 RECT rc;
272 int nParts[3];
273 // TCHAR text[260];
274
275 bInMenuLoop = FALSE;
276 // Update the status bar pane sizes
277 GetClientRect(hWnd, &rc);
278 nParts[0] = 100;
279 nParts[1] = 210;
280 nParts[2] = rc.right;
281 SendMessage(hStatusWnd, SB_SETPARTS, 3, (long)nParts);
282 SendMessage(hStatusWnd, SB_SETTEXT, 0, (LPARAM)_T(""));
283 // wsprintf(text, _T("CPU Usage: %3d%%"), PerfDataGetProcessorUsage());
284 // SendMessage(hStatusWnd, SB_SETTEXT, 1, (LPARAM)text);
285 // wsprintf(text, _T("Processes: %d"), PerfDataGetProcessCount());
286 // SendMessage(hStatusWnd, SB_SETTEXT, 0, (LPARAM)text);
287 }
288
289 void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
290 {
291 TCHAR str[100];
292
293 strcpy(str, TEXT(""));
294 if (nFlags & MF_POPUP) {
295 if (hSysMenu != GetMenu(hWnd)) {
296 if (nItemID == 2) nItemID = 5;
297 }
298 }
299 if (LoadString(hInst, nItemID, str, 100)) {
300 // load appropriate string
301 LPTSTR lpsz = str;
302 // first newline terminates actual string
303 lpsz = _tcschr(lpsz, '\n');
304 if (lpsz != NULL)
305 *lpsz = '\0';
306 }
307 SendMessage(hStatusWnd, SB_SETTEXT, 0, (LPARAM)str);
308 }
309
310
311 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
312 {
313 int wmId, wmEvent;
314 PAINTSTRUCT ps;
315 HDC hdc;
316 TCHAR szHello[MAX_LOADSTRING];
317 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
318
319 switch (message) {
320 case WM_COMMAND:
321 wmId = LOWORD(wParam);
322 wmEvent = HIWORD(wParam);
323 // Parse the menu selections:
324 switch (wmId) {
325 case IDM_ABOUT:
326 // ShowAboutBox(hWnd);
327 {
328 HICON hIcon = LoadIcon(hInst, (LPCTSTR)IDI_REGEDIT);
329 ShellAbout(hWnd, szTitle, "FrameWndProc", hIcon);
330 //if (hIcon) DestroyIcon(hIcon); // NOT REQUIRED
331 }
332 break;
333 case IDM_EXIT:
334 DestroyWindow(hWnd);
335 break;
336 default:
337 return DefWindowProc(hWnd, message, wParam, lParam);
338 }
339 break;
340 case WM_PAINT:
341 hdc = BeginPaint(hWnd, &ps);
342 // TODO: Add any drawing code here...
343 RECT rt;
344 GetClientRect(hWnd, &rt);
345 DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
346 EndPaint(hWnd, &ps);
347 break;
348 case WM_DESTROY:
349 PostQuitMessage(0);
350 break;
351 default:
352 return DefWindowProc(hWnd, message, wParam, lParam);
353 }
354 return 0;
355 }
356
357
358 //
359 // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
360 //
361 // PURPOSE: Processes messages for the main window.
362 //
363 // WM_COMMAND - process the application menu
364 // WM_PAINT - Paint the main window
365 // WM_DESTROY - post a quit message and return
366 //
367 //
368 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
369 {
370 int wmId, wmEvent;
371 PAINTSTRUCT ps;
372 HDC hdc;
373 //TCHAR szHello[MAX_LOADSTRING];
374 //LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
375
376 switch (message) {
377 case WM_COMMAND:
378 wmId = LOWORD(wParam);
379 wmEvent = HIWORD(wParam);
380 // Parse the menu selections:
381 switch (wmId) {
382 case ID_REGISTRY_PRINTERSETUP:
383 //PRINTDLG pd;
384 //PrintDlg(&pd);
385 //PAGESETUPDLG psd;
386 //PageSetupDlg(&psd);
387 break;
388 case ID_REGISTRY_OPENLOCAL:
389 {
390 HWND hChildWnd;
391 // hChildWnd = CreateWindow(szFrameClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CHILD,
392 // CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWnd, NULL, hInst, NULL);
393 hChildWnd = CreateWindow(szFrameClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CHILD,
394 0, 0, 150, 170, hWnd, NULL, hInst, NULL);
395 if (hChildWnd) {
396 ShowWindow(hChildWnd, 1);
397 UpdateWindow(hChildWnd);
398 }
399 }
400 break;
401 case IDM_ABOUT:
402 // ShowAboutBox(hWnd);
403 {
404 HICON hIcon = LoadIcon(hInst, (LPCTSTR)IDI_REGEDIT);
405 ShellAbout(hWnd, szTitle, "", hIcon);
406 //if (hIcon) DestroyIcon(hIcon); // NOT REQUIRED
407 }
408 break;
409 case IDM_EXIT:
410 DestroyWindow(hWnd);
411 break;
412 default:
413 return DefWindowProc(hWnd, message, wParam, lParam);
414 }
415 break;
416 case WM_SIZE:
417 // Handle the window sizing in it's own function
418 OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
419 break;
420 case WM_PAINT:
421 hdc = BeginPaint(hWnd, &ps);
422 // TODO: Add any drawing code here...
423 RECT rt;
424 GetClientRect(hWnd, &rt);
425 //DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
426 EndPaint(hWnd, &ps);
427 break;
428 case WM_DESTROY:
429 PostQuitMessage(0);
430 break;
431 case WM_TIMER:
432 break;
433
434 case WM_ENTERMENULOOP:
435 OnEnterMenuLoop(hWnd);
436 break;
437 case WM_EXITMENULOOP:
438 OnExitMenuLoop(hWnd);
439 break;
440 case WM_MENUSELECT:
441 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
442 break;
443 default:
444 return DefWindowProc(hWnd, message, wParam, lParam);
445 }
446 return 0;
447 }