Use Windows memory functions.
[wine/testsucceed.git] / programs / regedit / framewnd.c
blob7818f63b26a890c2939259eec529cb76476d8916
1 /*
2 * Regedit frame window
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 */
23 #include <windows.h>
24 #include <tchar.h>
25 #include <commctrl.h>
26 #include <commdlg.h>
27 #include <cderr.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <shellapi.h>
32 #include "main.h"
33 #include "regproc.h"
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)
47 RECT rt;
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 void resize_frame_client(HWND hWnd)
66 RECT rect;
68 GetClientRect(hWnd, &rect);
69 resize_frame_rect(hWnd, &rect);
72 /********************************************************************************/
74 static void OnEnterMenuLoop(HWND hWnd)
76 int nParts;
78 /* Update the status bar pane sizes */
79 nParts = -1;
80 SendMessage(hStatusBar, SB_SETPARTS, 1, (long)&nParts);
81 bInMenuLoop = TRUE;
82 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
85 static void OnExitMenuLoop(HWND hWnd)
87 bInMenuLoop = FALSE;
88 /* Update the status bar pane sizes*/
89 SetupStatusBar(hWnd, TRUE);
90 UpdateStatusBar();
93 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
95 TCHAR str[100];
97 _tcscpy(str, _T(""));
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*/
105 LPTSTR lpsz = str;
106 /* first newline terminates actual string*/
107 lpsz = _tcschr(lpsz, '\n');
108 if (lpsz != NULL)
109 *lpsz = '\0';
111 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
114 void SetupStatusBar(HWND hWnd, BOOL bResize)
116 RECT rc;
117 int nParts;
118 GetClientRect(hWnd, &rc);
119 nParts = rc.right;
120 /* nParts = -1;*/
121 if (bResize)
122 SendMessage(hStatusBar, WM_SIZE, 0, 0);
123 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
126 void UpdateStatusBar(void)
128 TCHAR text[260];
129 DWORD size;
131 size = sizeof(text)/sizeof(TCHAR);
132 GetComputerName(text, &size);
133 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
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:
151 break;
152 case CDERR_FINDRESFAILURE:
153 break;
154 case CDERR_NOHINSTANCE:
155 break;
156 case CDERR_INITIALIZATION:
157 break;
158 case CDERR_NOHOOK:
159 break;
160 case CDERR_LOCKRESFAILURE:
161 break;
162 case CDERR_NOTEMPLATE:
163 break;
164 case CDERR_LOADRESFAILURE:
165 break;
166 case CDERR_STRUCTSIZE:
167 break;
168 case CDERR_LOADSTRFAILURE:
169 break;
170 case FNERR_BUFFERTOOSMALL:
171 break;
172 case CDERR_MEMALLOCFAILURE:
173 break;
174 case FNERR_INVALIDFILENAME:
175 break;
176 case CDERR_MEMLOCKFAILURE:
177 break;
178 case FNERR_SUBCLASSFAILURE:
179 break;
180 default:
181 break;
183 return TRUE;
186 UINT_PTR CALLBACK ImportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
188 OPENFILENAME* pOpenFileName;
189 OFNOTIFY* pOfNotify;
191 switch (uiMsg) {
192 case WM_INITDIALOG:
193 pOpenFileName = (OPENFILENAME*)lParam;
194 break;
195 case WM_NOTIFY:
196 pOfNotify = (OFNOTIFY*)lParam;
197 if (pOfNotify->hdr.code == CDN_INITDONE) {}
198 break;
199 default:
200 break;
202 return 0L;
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 = ;*/
237 return TRUE;
240 static BOOL ImportRegistryFile(HWND hWnd)
242 OPENFILENAME ofn;
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);*/
250 return FALSE;
252 #if 0
253 get_file_name(&s, filename, MAX_PATH);
254 if (!filename[0]) {
255 printf("No file name is specified\n%s", usage);
256 return FALSE;
257 /*exit(1);*/
259 while (filename[0]) {
260 if (!import_registry_file(filename)) {
261 perror("");
262 printf("Can't open file \"%s\"\n", filename);
263 return FALSE;
264 /*exit(1);*/
266 get_file_name(&s, filename, MAX_PATH);
268 #endif
270 } else {
271 CheckCommDlgError(hWnd);
273 return TRUE;
277 static BOOL ExportRegistryFile(HWND hWnd)
279 OPENFILENAME ofn;
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)) {
290 BOOL result;
291 result = export_registry_key(ofn.lpstrFile, ExportKeyPath);
292 /*result = export_registry_key(ofn.lpstrFile, NULL);*/
293 /*if (!export_registry_key(ofn.lpstrFile, NULL)) {*/
294 if (!result) {
295 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
296 return FALSE;
298 #if 0
299 TCHAR filename[MAX_PATH];
300 filename[0] = '\0';
301 get_file_name(&s, filename, MAX_PATH);
302 if (!filename[0]) {
303 printf("No file name is specified\n%s", usage);
304 return FALSE;
305 /*exit(1);*/
307 if (s[0]) {
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);
311 } else {
312 export_registry_key(filename, NULL);
314 #endif
316 } else {
317 CheckCommDlgError(hWnd);
319 return TRUE;
322 BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
324 #if 1
325 PRINTDLG pd;
327 ZeroMemory(&pd, sizeof(PRINTDLG));
328 pd.lStructSize = sizeof(PRINTDLG);
329 pd.hwndOwner = hWnd;
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;
333 pd.nCopies = 1;
334 pd.nFromPage = 0xFFFF;
335 pd.nToPage = 0xFFFF;
336 pd.nMinPage = 1;
337 pd.nMaxPage = 0xFFFF;
338 if (PrintDlg(&pd)) {
339 /* GDI calls to render output. */
340 DeleteDC(pd.hDC); /* Delete DC when done.*/
342 #else
343 HRESULT hResult;
344 PRINTDLGEX pd;
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. */
351 break;
352 case PD_RESULT_CANCEL:
353 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
354 break;
355 case PD_RESULT_PRINT:
356 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
357 break;
358 default:
359 break;
361 } else {
362 switch (hResult) {
363 case E_OUTOFMEMORY:
364 /*Insufficient memory. */
365 break;
366 case E_INVALIDARG:
367 /* One or more arguments are invalid. */
368 break;
369 case E_POINTER:
370 /*Invalid pointer. */
371 break;
372 case E_HANDLE:
373 /*Invalid handle. */
374 break;
375 case E_FAIL:
376 /*Unspecified error. */
377 break;
378 default:
379 break;
381 return FALSE;
383 #endif
384 return TRUE;
387 BOOL CopyKeyName(HWND hWnd, LPTSTR keyName)
389 BOOL result;
391 result = OpenClipboard(hWnd);
392 if (result) {
393 result = EmptyClipboard();
394 if (result) {
396 /*HANDLE hClipData;*/
397 /*hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);*/
399 } else {
400 /* error emptying clipboard*/
401 /* DWORD dwError = GetLastError(); */
404 if (!CloseClipboard()) {
405 /* error closing clipboard*/
406 /* DWORD dwError = GetLastError(); */
409 } else {
410 /* error opening clipboard*/
411 /* DWORD dwError = GetLastError(); */
414 return result;
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)
426 HKEY hKeyRoot = 0;
427 LPCTSTR keyPath;
428 LPCTSTR valueName;
429 TCHAR newKey[MAX_NEW_KEY_LEN];
430 DWORD valueType;
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);
438 break;
439 case ID_REGISTRY_EXPORTREGISTRYFILE:
440 ExportRegistryFile(hWnd);
441 break;
442 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
443 break;
444 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
445 break;
446 case ID_REGISTRY_PRINT:
447 PrintRegistryHive(hWnd, _T(""));
448 break;
449 case ID_EDIT_DELETE:
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);
460 break;
461 case ID_EDIT_MODIFY:
462 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
463 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
464 break;
465 case ID_EDIT_COPYKEYNAME:
466 CopyKeyName(hWnd, _T(""));
467 break;
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);
473 break;
474 case ID_EDIT_NEW_STRINGVALUE:
475 valueType = REG_SZ;
476 goto create_value;
477 case ID_EDIT_NEW_BINARYVALUE:
478 valueType = REG_BINARY;
479 goto create_value;
480 case ID_EDIT_NEW_DWORDVALUE:
481 valueType = REG_DWORD;
482 /* fall through */
483 create_value:
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 */
489 break;
490 case ID_EDIT_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);
498 break;
499 break;
500 case ID_REGISTRY_PRINTERSETUP:
501 /*PRINTDLG pd;*/
502 /*PrintDlg(&pd);*/
503 /*PAGESETUPDLG psd;*/
504 /*PageSetupDlg(&psd);*/
505 break;
506 case ID_REGISTRY_OPENLOCAL:
507 break;
508 case ID_REGISTRY_EXIT:
509 DestroyWindow(hWnd);
510 break;
511 case ID_VIEW_REFRESH:
512 RefreshTreeView(g_pChildWnd->hTreeWnd);
513 /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
514 break;
515 /*case ID_OPTIONS_TOOLBAR:*/
516 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
517 /* break;*/
518 case ID_VIEW_STATUSBAR:
519 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
520 break;
521 case ID_HELP_HELPTOPICS:
522 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
523 break;
524 case ID_HELP_ABOUT:
525 ShowAboutBox(hWnd);
526 break;
527 case ID_VIEW_SPLIT: {
528 RECT rt;
529 POINT pt, pts;
530 GetClientRect(g_pChildWnd->hWnd, &rt);
531 pt.x = rt.left + g_pChildWnd->nSplitPos;
532 pt.y = (rt.bottom / 2);
533 pts = pt;
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));
539 return TRUE;
541 default:
542 return FALSE;
545 return TRUE;
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)
561 switch (message) {
562 case WM_CREATE:
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);
566 break;
567 case WM_COMMAND:
568 if (!_CmdWndProc(hWnd, message, wParam, lParam))
569 return DefWindowProc(hWnd, message, wParam, lParam);
570 break;
571 case WM_ACTIVATE:
572 if (LOWORD(hWnd))
573 SetFocus(g_pChildWnd->hWnd);
574 break;
575 case WM_SIZE:
576 resize_frame_client(hWnd);
577 break;
578 case WM_TIMER:
579 break;
580 case WM_ENTERMENULOOP:
581 OnEnterMenuLoop(hWnd);
582 break;
583 case WM_EXITMENULOOP:
584 OnExitMenuLoop(hWnd);
585 break;
586 case WM_MENUSELECT:
587 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
588 break;
589 case WM_DESTROY:
590 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
591 PostQuitMessage(0);
592 default:
593 return DefWindowProc(hWnd, message, wParam, lParam);
595 return 0;