4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
35 /********************************************************************************
36 * Global and Local Variables:
39 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
41 /*******************************************************************************
42 * Local module support methods
45 static void resize_frame_rect(HWND hWnd, PRECT prect)
49 if (IsWindowVisible(hToolBar)) {
50 SendMessage(hToolBar, WM_SIZE, 0, 0);
51 GetClientRect(hToolBar, &rt);
52 prect->top = rt.bottom+3;
53 prect->bottom -= rt.bottom+3;
56 if (IsWindowVisible(hStatusBar)) {
57 SetupStatusBar(hWnd, TRUE);
58 GetClientRect(hStatusBar, &rt);
59 prect->bottom -= rt.bottom;
61 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
64 static void resize_frame_client(HWND hWnd)
68 GetClientRect(hWnd, &rect);
69 resize_frame_rect(hWnd, &rect);
72 /********************************************************************************/
74 static void OnEnterMenuLoop(HWND hWnd)
78 /* Update the status bar pane sizes */
80 SendMessage(hStatusBar, SB_SETPARTS, 1, (long)&nParts);
82 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
85 static void OnExitMenuLoop(HWND hWnd)
88 /* Update the status bar pane sizes*/
89 SetupStatusBar(hWnd, TRUE);
93 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
98 if (nFlags & MF_POPUP) {
99 if (hSysMenu != GetMenu(hWnd)) {
100 if (nItemID == 2) nItemID = 5;
103 if (LoadString(hInst, nItemID, str, 100)) {
104 /* load appropriate string*/
106 /* first newline terminates actual string*/
107 lpsz = _tcschr(lpsz, '\n');
111 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
114 void SetupStatusBar(HWND hWnd, BOOL bResize)
118 GetClientRect(hWnd, &rc);
122 SendMessage(hStatusBar, WM_SIZE, 0, 0);
123 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
127 void UpdateStatusBar(void)
129 /* real updating of status bar happens in the treeview selection
130 * change handler, so fake a selection change to it, but don't
131 * refresh the listview or the current selection will change */
132 OnTreeSelectionChanged(g_pChildWnd->hTreeWnd, g_pChildWnd->hListWnd,
133 TreeView_GetSelection(g_pChildWnd->hTreeWnd), FALSE);
136 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
138 BOOL vis = IsWindowVisible(hchild);
139 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
141 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
142 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
143 resize_frame_client(hWnd);
146 static BOOL CheckCommDlgError(HWND hWnd)
148 DWORD dwErrorCode = CommDlgExtendedError();
149 switch (dwErrorCode) {
150 case CDERR_DIALOGFAILURE:
152 case CDERR_FINDRESFAILURE:
154 case CDERR_NOHINSTANCE:
156 case CDERR_INITIALIZATION:
160 case CDERR_LOCKRESFAILURE:
162 case CDERR_NOTEMPLATE:
164 case CDERR_LOADRESFAILURE:
166 case CDERR_STRUCTSIZE:
168 case CDERR_LOADSTRFAILURE:
170 case FNERR_BUFFERTOOSMALL:
172 case CDERR_MEMALLOCFAILURE:
174 case FNERR_INVALIDFILENAME:
176 case CDERR_MEMLOCKFAILURE:
178 case FNERR_SUBCLASSFAILURE:
186 static UINT_PTR CALLBACK ImportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
188 OPENFILENAME* pOpenFileName;
193 pOpenFileName = (OPENFILENAME*)lParam;
196 pOfNotify = (OFNOTIFY*)lParam;
197 if (pOfNotify->hdr.code == CDN_INITDONE) {}
205 #define MAX_CUSTOM_FILTER_SIZE 50
206 TCHAR CustomFilterBuffer[MAX_CUSTOM_FILTER_SIZE];
207 TCHAR FileNameBuffer[_MAX_PATH];
208 TCHAR FileTitleBuffer[_MAX_PATH];
210 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
212 memset(pofn, 0, sizeof(OPENFILENAME));
213 pofn->lStructSize = sizeof(OPENFILENAME);
214 pofn->hwndOwner = hWnd;
215 pofn->hInstance = hInst;
217 pofn->lpstrFilter = _T("Registration Files\0*.reg\0Win9x/NT4 Registration Files (REGEDIT4)\0*.reg\0All Files (*.*)\0*.*\0\0");
218 pofn->lpstrCustomFilter = CustomFilterBuffer;
219 pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
220 pofn->nFilterIndex = 0;
221 pofn->lpstrFile = FileNameBuffer;
222 pofn->nMaxFile = _MAX_PATH;
223 pofn->lpstrFileTitle = FileTitleBuffer;
224 pofn->nMaxFileTitle = _MAX_PATH;
225 /* pofn->lpstrInitialDir = _T("");*/
226 /* pofn->lpstrTitle = _T("Import Registry File");*/
227 /* pofn->Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER + OFN_ENABLESIZING;*/
228 pofn->Flags = OFN_HIDEREADONLY;
229 /* pofn->nFileOffset = ;*/
230 /* pofn->nFileExtension = ;*/
231 /* pofn->lpstrDefExt = _T("");*/
232 /* pofn->lCustData = ;*/
233 /* pofn->lpfnHook = ImportRegistryFile_OFNHookProc;*/
234 /* pofn->lpTemplateName = _T("ID_DLG_IMPORT_REGFILE");*/
235 /* pofn->lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);*/
236 /* pofn->FlagsEx = ;*/
240 static BOOL ImportRegistryFile(HWND hWnd)
244 InitOpenFileName(hWnd, &ofn);
245 ofn.lpstrTitle = _T("Import Registry File");
246 /* ofn.lCustData = ;*/
247 if (GetOpenFileName(&ofn)) {
248 if (!import_registry_file(ofn.lpstrFile)) {
249 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
253 get_file_name(&s, filename, MAX_PATH);
255 printf("No file name is specified\n%s", usage);
259 while (filename[0]) {
260 if (!import_registry_file(filename)) {
262 printf("Can't open file \"%s\"\n", filename);
266 get_file_name(&s, filename, MAX_PATH);
271 CheckCommDlgError(hWnd);
277 static BOOL ExportRegistryFile(HWND hWnd)
280 TCHAR ExportKeyPath[_MAX_PATH];
282 ExportKeyPath[0] = _T('\0');
283 InitOpenFileName(hWnd, &ofn);
284 ofn.lpstrTitle = _T("Export Registry File");
285 /* ofn.lCustData = ;*/
286 ofn.Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER;
287 ofn.lpfnHook = ImportRegistryFile_OFNHookProc;
288 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);
289 if (GetSaveFileName(&ofn)) {
291 result = export_registry_key(ofn.lpstrFile, ExportKeyPath);
292 /*result = export_registry_key(ofn.lpstrFile, NULL);*/
293 /*if (!export_registry_key(ofn.lpstrFile, NULL)) {*/
295 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
299 TCHAR filename[MAX_PATH];
301 get_file_name(&s, filename, MAX_PATH);
303 printf("No file name is specified\n%s", usage);
308 TCHAR reg_key_name[KEY_MAX_LEN];
309 get_file_name(&s, reg_key_name, KEY_MAX_LEN);
310 export_registry_key(filename, reg_key_name);
312 export_registry_key(filename, NULL);
317 CheckCommDlgError(hWnd);
322 static BOOL PrintRegistryHive(HWND hWnd, LPCTSTR path)
327 ZeroMemory(&pd, sizeof(PRINTDLG));
328 pd.lStructSize = sizeof(PRINTDLG);
330 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
331 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
332 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
334 pd.nFromPage = 0xFFFF;
337 pd.nMaxPage = 0xFFFF;
339 /* GDI calls to render output. */
340 DeleteDC(pd.hDC); /* Delete DC when done.*/
346 hResult = PrintDlgEx(&pd);
347 if (hResult == S_OK) {
348 switch (pd.dwResultAction) {
349 case PD_RESULT_APPLY:
350 /*The user clicked the Apply button and later clicked the Cancel button. This indicates that the user wants to apply the changes made in the property sheet, but does not yet want to print. The PRINTDLGEX structure contains the information specified by the user at the time the Apply button was clicked. */
352 case PD_RESULT_CANCEL:
353 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
355 case PD_RESULT_PRINT:
356 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
364 /*Insufficient memory. */
367 /* One or more arguments are invalid. */
370 /*Invalid pointer. */
376 /*Unspecified error. */
387 static BOOL CopyKeyName(HWND hWnd, LPCTSTR keyName)
391 result = OpenClipboard(hWnd);
393 result = EmptyClipboard();
396 /*HANDLE hClipData;*/
397 /*hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);*/
400 /* error emptying clipboard*/
401 /* DWORD dwError = GetLastError(); */
404 if (!CloseClipboard()) {
405 /* error closing clipboard*/
406 /* DWORD dwError = GetLastError(); */
410 /* error opening clipboard*/
411 /* DWORD dwError = GetLastError(); */
417 /*******************************************************************************
419 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
421 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
424 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
429 TCHAR newKey[MAX_NEW_KEY_LEN];
432 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
433 valueName = GetValueName(g_pChildWnd->hListWnd);
435 switch (LOWORD(wParam)) {
436 case ID_REGISTRY_IMPORTREGISTRYFILE:
437 ImportRegistryFile(hWnd);
439 case ID_REGISTRY_EXPORTREGISTRYFILE:
440 ExportRegistryFile(hWnd);
442 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
444 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
446 case ID_REGISTRY_PRINT:
447 PrintRegistryHive(hWnd, _T(""));
450 if (GetFocus() == g_pChildWnd->hTreeWnd) {
451 if (keyPath == 0 || *keyPath == 0) {
452 MessageBeep(MB_ICONHAND);
453 } else if (DeleteKey(hWnd, hKeyRoot, keyPath)) {
454 DeleteNode(g_pChildWnd->hTreeWnd, 0);
456 } else if (GetFocus() == g_pChildWnd->hListWnd) {
457 if (DeleteValue(hWnd, hKeyRoot, keyPath, valueName))
458 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
462 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
463 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
465 case ID_EDIT_COPYKEYNAME:
466 CopyKeyName(hWnd, _T(""));
468 case ID_EDIT_NEW_KEY:
469 if (CreateKey(hWnd, hKeyRoot, keyPath, newKey)) {
470 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKey))
471 StartKeyRename(g_pChildWnd->hTreeWnd);
474 case ID_EDIT_NEW_STRINGVALUE:
477 case ID_EDIT_NEW_BINARYVALUE:
478 valueType = REG_BINARY;
480 case ID_EDIT_NEW_DWORDVALUE:
481 valueType = REG_DWORD;
484 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
485 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
486 StartValueRename(g_pChildWnd->hListWnd);
487 /* FIXME: start rename */
491 if (keyPath == 0 || *keyPath == 0) {
492 MessageBeep(MB_ICONHAND);
493 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
494 StartKeyRename(g_pChildWnd->hTreeWnd);
495 } else if (GetFocus() == g_pChildWnd->hListWnd) {
496 StartValueRename(g_pChildWnd->hListWnd);
500 case ID_REGISTRY_PRINTERSETUP:
503 /*PAGESETUPDLG psd;*/
504 /*PageSetupDlg(&psd);*/
506 case ID_REGISTRY_OPENLOCAL:
508 case ID_REGISTRY_EXIT:
511 case ID_VIEW_REFRESH:
512 RefreshTreeView(g_pChildWnd->hTreeWnd);
513 /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
515 /*case ID_OPTIONS_TOOLBAR:*/
516 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
518 case ID_VIEW_STATUSBAR:
519 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
521 case ID_HELP_HELPTOPICS:
522 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
527 case ID_VIEW_SPLIT: {
530 GetClientRect(g_pChildWnd->hWnd, &rt);
531 pt.x = rt.left + g_pChildWnd->nSplitPos;
532 pt.y = (rt.bottom / 2);
534 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
535 SetCursorPos(pts.x, pts.y);
536 SetCursor(LoadCursor(0, IDC_SIZEWE));
537 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
548 /********************************************************************************
550 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
552 * PURPOSE: Processes messages for the main frame window.
554 * WM_COMMAND - process the application menu
555 * WM_DESTROY - post a quit message and return
559 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
563 CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
564 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
565 hWnd, NULL, hInst, 0);
568 if (!_CmdWndProc(hWnd, message, wParam, lParam))
569 return DefWindowProc(hWnd, message, wParam, lParam);
573 SetFocus(g_pChildWnd->hWnd);
576 resize_frame_client(hWnd);
580 case WM_ENTERMENULOOP:
581 OnEnterMenuLoop(hWnd);
583 case WM_EXITMENULOOP:
584 OnExitMenuLoop(hWnd);
587 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
590 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
593 return DefWindowProc(hWnd, message, wParam, lParam);