Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenchildwnd.c
Go to the documentation of this file.
00001 /* 00002 * Regedit child window 00003 * 00004 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <regedit.h> 00022 00023 ChildWnd* g_pChildWnd; 00024 static int last_split; 00025 HBITMAP SizingPattern = 0; 00026 HBRUSH SizingBrush = 0; 00027 static TCHAR Suggestions[256]; 00028 00029 extern LPCTSTR get_root_key_name(HKEY hRootKey) 00030 { 00031 if (hRootKey == HKEY_CLASSES_ROOT) return _T("HKEY_CLASSES_ROOT"); 00032 if (hRootKey == HKEY_CURRENT_USER) return _T("HKEY_CURRENT_USER"); 00033 if (hRootKey == HKEY_LOCAL_MACHINE) return _T("HKEY_LOCAL_MACHINE"); 00034 if (hRootKey == HKEY_USERS) return _T("HKEY_USERS"); 00035 if (hRootKey == HKEY_CURRENT_CONFIG) return _T("HKEY_CURRENT_CONFIG"); 00036 if (hRootKey == HKEY_DYN_DATA) return _T("HKEY_DYN_DATA"); 00037 return _T("UKNOWN HKEY, PLEASE REPORT"); 00038 } 00039 00040 extern void ResizeWnd(int cx, int cy) 00041 { 00042 HDWP hdwp = BeginDeferWindowPos(3); 00043 RECT rt, rs, rb; 00044 const int tHeight = 18; 00045 SetRect(&rt, 0, 0, cx, cy); 00046 cy = 0; 00047 if (hStatusBar != NULL) 00048 { 00049 GetWindowRect(hStatusBar, &rs); 00050 cy = rs.bottom - rs.top; 00051 } 00052 GetWindowRect(g_pChildWnd->hAddressBtnWnd, &rb); 00053 cx = g_pChildWnd->nSplitPos + SPLIT_WIDTH/2; 00054 DeferWindowPos(hdwp, g_pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); 00055 DeferWindowPos(hdwp, g_pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); 00056 DeferWindowPos(hdwp, g_pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, g_pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); 00057 DeferWindowPos(hdwp, g_pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); 00058 EndDeferWindowPos(hdwp); 00059 } 00060 00061 /******************************************************************************* 00062 * Local module support methods 00063 */ 00064 00065 static void draw_splitbar(HWND hWnd, int x) 00066 { 00067 RECT rt; 00068 HGDIOBJ OldObj; 00069 HDC hdc = GetDC(hWnd); 00070 00071 if(!SizingPattern) 00072 { 00073 const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA}; 00074 SizingPattern = CreateBitmap(8, 8, 1, 1, Pattern); 00075 } 00076 if(!SizingBrush) 00077 { 00078 SizingBrush = CreatePatternBrush(SizingPattern); 00079 } 00080 GetClientRect(hWnd, &rt); 00081 rt.left = x - SPLIT_WIDTH/2; 00082 rt.right = x + SPLIT_WIDTH/2+1; 00083 OldObj = SelectObject(hdc, SizingBrush); 00084 PatBlt(hdc, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, PATINVERT); 00085 SelectObject(hdc, OldObj); 00086 ReleaseDC(hWnd, hdc); 00087 } 00088 00089 static void OnPaint(HWND hWnd) 00090 { 00091 PAINTSTRUCT ps; 00092 RECT rt; 00093 00094 GetClientRect(hWnd, &rt); 00095 BeginPaint(hWnd, &ps); 00096 FillRect(ps.hdc, &rt, GetSysColorBrush(COLOR_BTNFACE)); 00097 EndPaint(hWnd, &ps); 00098 } 00099 00100 /******************************************************************************* 00101 * finish_splitbar [internal] 00102 * 00103 * make the splitbar invisible and resize the windows 00104 * (helper for ChildWndProc) 00105 */ 00106 static void finish_splitbar(HWND hWnd, int x) 00107 { 00108 RECT rt; 00109 00110 draw_splitbar(hWnd, last_split); 00111 last_split = -1; 00112 GetClientRect(hWnd, &rt); 00113 g_pChildWnd->nSplitPos = x; 00114 ResizeWnd(rt.right, rt.bottom); 00115 ReleaseCapture(); 00116 } 00117 00118 /******************************************************************************* 00119 * 00120 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG) 00121 * 00122 * PURPOSE: Processes WM_COMMAND messages for the main frame window. 00123 * 00124 */ 00125 00126 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 00127 { 00128 HTREEITEM hSelection; 00129 HKEY hRootKey; 00130 LPCTSTR keyPath, s; 00131 WORD wID = LOWORD(wParam); 00132 00133 UNREFERENCED_PARAMETER(message); 00134 00135 switch (wID) 00136 { 00137 /* Parse the menu selections: */ 00138 case ID_REGISTRY_EXIT: 00139 DestroyWindow(hWnd); 00140 break; 00141 case ID_VIEW_REFRESH: 00142 /* TODO */ 00143 break; 00144 case ID_TREE_EXPANDBRANCH: 00145 (void)TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_EXPAND); 00146 break; 00147 case ID_TREE_COLLAPSEBRANCH: 00148 (void)TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_COLLAPSE); 00149 break; 00150 case ID_TREE_RENAME: 00151 SetFocus(g_pChildWnd->hTreeWnd); 00152 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); 00153 break; 00154 case ID_TREE_DELETE: 00155 hSelection = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 00156 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, hSelection, &hRootKey); 00157 00158 if (keyPath == 0 || *keyPath == 0) 00159 { 00160 MessageBeep(MB_ICONHAND); 00161 } 00162 else if (DeleteKey(hWnd, hRootKey, keyPath)) 00163 DeleteNode(g_pChildWnd->hTreeWnd, 0); 00164 break; 00165 case ID_TREE_EXPORT: 00166 ExportRegistryFile(g_pChildWnd->hTreeWnd); 00167 break; 00168 case ID_EDIT_FIND: 00169 FindDialog(hWnd); 00170 break; 00171 case ID_EDIT_COPYKEYNAME: 00172 hSelection = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 00173 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, hSelection, &hRootKey); 00174 CopyKeyName(hWnd, hRootKey, keyPath); 00175 break; 00176 case ID_EDIT_NEW_KEY: 00177 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); 00178 break; 00179 case ID_EDIT_NEW_STRINGVALUE: 00180 case ID_EDIT_NEW_BINARYVALUE: 00181 case ID_EDIT_NEW_DWORDVALUE: 00182 SendMessage(hFrameWnd, WM_COMMAND, wParam, lParam); 00183 break; 00184 case ID_SWITCH_PANELS: 00185 g_pChildWnd->nFocusPanel = !g_pChildWnd->nFocusPanel; 00186 SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd); 00187 break; 00188 default: 00189 if ((wID >= ID_TREE_SUGGESTION_MIN) && (wID <= ID_TREE_SUGGESTION_MAX)) 00190 { 00191 s = Suggestions; 00192 while(wID > ID_TREE_SUGGESTION_MIN) 00193 { 00194 if (*s) 00195 s += _tcslen(s) + 1; 00196 wID--; 00197 } 00198 SelectNode(g_pChildWnd->hTreeWnd, s); 00199 break; 00200 } 00201 return FALSE; 00202 } 00203 return TRUE; 00204 } 00205 00206 /******************************************************************************* 00207 * 00208 * Key suggestion 00209 */ 00210 00211 #define MIN(a,b) ((a < b) ? (a) : (b)) 00212 00213 static void SuggestKeys(HKEY hRootKey, LPCTSTR pszKeyPath, LPTSTR pszSuggestions, 00214 size_t iSuggestionsLength) 00215 { 00216 TCHAR szBuffer[256]; 00217 TCHAR szLastFound[256]; 00218 size_t i; 00219 HKEY hOtherKey, hSubKey; 00220 BOOL bFound; 00221 00222 memset(pszSuggestions, 0, iSuggestionsLength * sizeof(*pszSuggestions)); 00223 iSuggestionsLength--; 00224 00225 /* Are we a root key in HKEY_CLASSES_ROOT? */ 00226 if ((hRootKey == HKEY_CLASSES_ROOT) && pszKeyPath[0] && !_tcschr(pszKeyPath, TEXT('\\'))) 00227 { 00228 do 00229 { 00230 bFound = FALSE; 00231 00232 /* Check default key */ 00233 if (QueryStringValue(hRootKey, pszKeyPath, NULL, 00234 szBuffer, COUNT_OF(szBuffer)) == ERROR_SUCCESS) 00235 { 00236 /* Sanity check this key; it cannot be empty, nor can it be a 00237 * loop back */ 00238 if ((szBuffer[0] != '\0') && _tcsicmp(szBuffer, pszKeyPath)) 00239 { 00240 if (RegOpenKey(hRootKey, szBuffer, &hOtherKey) == ERROR_SUCCESS) 00241 { 00242 lstrcpyn(pszSuggestions, TEXT("HKCR\\"), (int) iSuggestionsLength); 00243 i = _tcslen(pszSuggestions); 00244 pszSuggestions += i; 00245 iSuggestionsLength -= i; 00246 00247 lstrcpyn(pszSuggestions, szBuffer, (int) iSuggestionsLength); 00248 i = MIN(_tcslen(pszSuggestions) + 1, iSuggestionsLength); 00249 pszSuggestions += i; 00250 iSuggestionsLength -= i; 00251 RegCloseKey(hOtherKey); 00252 00253 bFound = TRUE; 00254 _tcscpy(szLastFound, szBuffer); 00255 pszKeyPath = szLastFound; 00256 } 00257 } 00258 } 00259 } 00260 while(bFound && (iSuggestionsLength > 0)); 00261 00262 /* Check CLSID key */ 00263 if (RegOpenKey(hRootKey, pszKeyPath, &hSubKey) == ERROR_SUCCESS) 00264 { 00265 if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer, 00266 COUNT_OF(szBuffer)) == ERROR_SUCCESS) 00267 { 00268 lstrcpyn(pszSuggestions, TEXT("HKCR\\CLSID\\"), (int) iSuggestionsLength); 00269 i = _tcslen(pszSuggestions); 00270 pszSuggestions += i; 00271 iSuggestionsLength -= i; 00272 00273 lstrcpyn(pszSuggestions, szBuffer, (int) iSuggestionsLength); 00274 i = MIN(_tcslen(pszSuggestions) + 1, iSuggestionsLength); 00275 pszSuggestions += i; 00276 iSuggestionsLength -= i; 00277 } 00278 RegCloseKey(hSubKey); 00279 } 00280 } 00281 } 00282 00283 00284 LRESULT CALLBACK AddressBarProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 00285 { 00286 WNDPROC oldwndproc; 00287 static TCHAR s_szNode[256]; 00288 oldwndproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hwnd, GWL_USERDATA); 00289 00290 switch (uMsg) 00291 { 00292 case WM_KEYUP: 00293 if (wParam == VK_RETURN) 00294 { 00295 GetWindowText(hwnd, s_szNode, sizeof(s_szNode) / sizeof(s_szNode[0])); 00296 SelectNode(g_pChildWnd->hTreeWnd, s_szNode); 00297 } 00298 break; 00299 default: 00300 break; 00301 } 00302 return CallWindowProc(oldwndproc, hwnd, uMsg, wParam, lParam); 00303 } 00304 00305 /******************************************************************************* 00306 * 00307 * FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG) 00308 * 00309 * PURPOSE: Processes messages for the child windows. 00310 * 00311 * WM_COMMAND - process the application menu 00312 * WM_PAINT - Paint the main window 00313 * WM_DESTROY - post a quit message and return 00314 * 00315 */ 00316 LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 00317 { 00318 BOOL Result; 00319 00320 switch (message) 00321 { 00322 case WM_CREATE: 00323 { 00324 WNDPROC oldproc; 00325 HFONT hFont; 00326 TCHAR buffer[MAX_PATH]; 00327 /* load "My Computer" string */ 00328 LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR)); 00329 00330 g_pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd)); 00331 if (!g_pChildWnd) return 0; 00332 00333 _tcsncpy(g_pChildWnd->szPath, buffer, MAX_PATH); 00334 g_pChildWnd->nSplitPos = 250; 00335 g_pChildWnd->hWnd = hWnd; 00336 g_pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP, 00337 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 00338 hWnd, (HMENU)0, hInst, 0); 00339 g_pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON, 00340 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 00341 hWnd, (HMENU)0, hInst, 0); 00342 g_pChildWnd->hTreeWnd = CreateTreeView(hWnd, g_pChildWnd->szPath, (HMENU) TREE_WINDOW); 00343 g_pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, g_pChildWnd->szPath*/); 00344 SetFocus(g_pChildWnd->hTreeWnd); 00345 00346 /* set the address bar and button font */ 00347 if ((g_pChildWnd->hAddressBarWnd) && (g_pChildWnd->hAddressBtnWnd)) 00348 { 00349 hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); 00350 SendMessage(g_pChildWnd->hAddressBarWnd, 00351 WM_SETFONT, 00352 (WPARAM)hFont, 00353 0); 00354 SendMessage(g_pChildWnd->hAddressBtnWnd, 00355 WM_SETFONT, 00356 (WPARAM)hFont, 00357 0); 00358 } 00359 /* Subclass the AddressBar */ 00360 oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_WNDPROC); 00361 SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc); 00362 SetWindowLongPtr(g_pChildWnd->hAddressBarWnd, GWL_WNDPROC, (DWORD_PTR)AddressBarProc); 00363 break; 00364 } 00365 case WM_COMMAND: 00366 if(HIWORD(wParam) == BN_CLICKED) 00367 { 00368 PostMessage(g_pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0); 00369 } 00370 00371 if (!_CmdWndProc(hWnd, message, wParam, lParam)) 00372 { 00373 goto def; 00374 } 00375 break; 00376 case WM_PAINT: 00377 OnPaint(hWnd); 00378 return 0; 00379 case WM_SETCURSOR: 00380 if (LOWORD(lParam) == HTCLIENT) 00381 { 00382 POINT pt; 00383 GetCursorPos(&pt); 00384 ScreenToClient(hWnd, &pt); 00385 if (pt.x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && pt.x<g_pChildWnd->nSplitPos+SPLIT_WIDTH/2+1) 00386 { 00387 SetCursor(LoadCursor(0, IDC_SIZEWE)); 00388 return TRUE; 00389 } 00390 } 00391 goto def; 00392 case WM_DESTROY: 00393 DestroyTreeView(); 00394 DestroyListView(g_pChildWnd->hListWnd); 00395 DestroyMainMenu(); 00396 HeapFree(GetProcessHeap(), 0, g_pChildWnd); 00397 g_pChildWnd = NULL; 00398 PostQuitMessage(0); 00399 break; 00400 case WM_LBUTTONDOWN: 00401 { 00402 RECT rt; 00403 int x = (short)LOWORD(lParam); 00404 GetClientRect(hWnd, &rt); 00405 if (x>=g_pChildWnd->nSplitPos-SPLIT_WIDTH/2 && x<g_pChildWnd->nSplitPos+SPLIT_WIDTH/2+1) 00406 { 00407 last_split = g_pChildWnd->nSplitPos; 00408 draw_splitbar(hWnd, last_split); 00409 SetCapture(hWnd); 00410 } 00411 break; 00412 } 00413 00414 case WM_LBUTTONUP: 00415 case WM_RBUTTONDOWN: 00416 if (GetCapture() == hWnd) 00417 { 00418 finish_splitbar(hWnd, LOWORD(lParam)); 00419 } 00420 break; 00421 00422 case WM_CAPTURECHANGED: 00423 if (GetCapture()==hWnd && last_split>=0) 00424 draw_splitbar(hWnd, last_split); 00425 break; 00426 00427 case WM_KEYDOWN: 00428 if (wParam == VK_ESCAPE) 00429 if (GetCapture() == hWnd) 00430 { 00431 RECT rt; 00432 draw_splitbar(hWnd, last_split); 00433 GetClientRect(hWnd, &rt); 00434 ResizeWnd(rt.right, rt.bottom); 00435 last_split = -1; 00436 ReleaseCapture(); 00437 SetCursor(LoadCursor(0, IDC_ARROW)); 00438 } 00439 break; 00440 00441 case WM_MOUSEMOVE: 00442 if (GetCapture() == hWnd) 00443 { 00444 HDC hdc; 00445 RECT rt; 00446 HGDIOBJ OldObj; 00447 int x = LOWORD(lParam); 00448 if(!SizingPattern) 00449 { 00450 const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA}; 00451 SizingPattern = CreateBitmap(8, 8, 1, 1, Pattern); 00452 } 00453 if(!SizingBrush) 00454 { 00455 SizingBrush = CreatePatternBrush(SizingPattern); 00456 } 00457 00458 GetClientRect(hWnd, &rt); 00459 x = (SHORT) min(max(x, SPLIT_MIN), rt.right - SPLIT_MIN); 00460 if(last_split != x) 00461 { 00462 rt.left = last_split-SPLIT_WIDTH/2; 00463 rt.right = last_split+SPLIT_WIDTH/2+1; 00464 hdc = GetDC(hWnd); 00465 OldObj = SelectObject(hdc, SizingBrush); 00466 PatBlt(hdc, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, PATINVERT); 00467 last_split = x; 00468 rt.left = x-SPLIT_WIDTH/2; 00469 rt.right = x+SPLIT_WIDTH/2+1; 00470 PatBlt(hdc, rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, PATINVERT); 00471 SelectObject(hdc, OldObj); 00472 ReleaseDC(hWnd, hdc); 00473 } 00474 } 00475 break; 00476 00477 case WM_SETFOCUS: 00478 if (g_pChildWnd != NULL) 00479 { 00480 SetFocus(g_pChildWnd->nFocusPanel? g_pChildWnd->hListWnd: g_pChildWnd->hTreeWnd); 00481 } 00482 break; 00483 00484 case WM_TIMER: 00485 break; 00486 00487 case WM_NOTIFY: 00488 if ((int)wParam == TREE_WINDOW && g_pChildWnd != NULL) 00489 { 00490 switch (((LPNMHDR)lParam)->code) 00491 { 00492 case TVN_ITEMEXPANDING: 00493 return !OnTreeExpanding(g_pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam); 00494 case TVN_SELCHANGED: 00495 { 00496 LPCTSTR keyPath, rootName; 00497 LPTSTR fullPath; 00498 HKEY hRootKey; 00499 00500 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey); 00501 if (keyPath) 00502 { 00503 RefreshListView(g_pChildWnd->hListWnd, hRootKey, keyPath); 00504 rootName = get_root_key_name(hRootKey); 00505 fullPath = HeapAlloc(GetProcessHeap(), 0, (_tcslen(rootName) + 1 + _tcslen(keyPath) + 1) * sizeof(TCHAR)); 00506 if (fullPath) 00507 { 00508 /* set (correct) the address bar text */ 00509 if(keyPath[0] != '\0') 00510 _stprintf(fullPath, _T("%s\\%s"), rootName, keyPath); 00511 else 00512 fullPath = _tcscpy(fullPath, rootName); 00513 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath); 00514 SendMessage(g_pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath); 00515 HeapFree(GetProcessHeap(), 0, fullPath); 00516 /* disable hive manipulation items temporarily (enable only if necessary) */ 00517 EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_GRAYED); 00518 EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_GRAYED); 00519 /* compare the strings to see if we should enable/disable the "Load Hive" menus accordingly */ 00520 if (!(_tcsicmp(rootName, TEXT("HKEY_LOCAL_MACHINE")) && 00521 _tcsicmp(rootName, TEXT("HKEY_USERS")))) 00522 { 00523 // enable the unload menu item if at the root 00524 // otherwise enable the load menu item if there is no slash in keyPath (ie. immediate child selected) 00525 if(keyPath[0] == '\0') 00526 EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_ENABLED); 00527 else if(!_tcschr(keyPath, _T('\\'))) 00528 EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_ENABLED); 00529 } 00530 } 00531 } 00532 } 00533 break; 00534 case NM_SETFOCUS: 00535 g_pChildWnd->nFocusPanel = 0; 00536 break; 00537 case TVN_BEGINLABELEDIT: 00538 { 00539 LPNMTVDISPINFO ptvdi; 00540 /* cancel label edit for rootkeys */ 00541 ptvdi = (LPNMTVDISPINFO) lParam; 00542 if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) || 00543 !TreeView_GetParent(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem))) 00544 return TRUE; 00545 break; 00546 } 00547 case TVN_ENDLABELEDIT: 00548 { 00549 LPCTSTR keyPath; 00550 HKEY hRootKey; 00551 HKEY hKey = NULL; 00552 LPNMTVDISPINFO ptvdi; 00553 LONG lResult = TRUE; 00554 TCHAR szBuffer[MAX_PATH]; 00555 00556 ptvdi = (LPNMTVDISPINFO) lParam; 00557 if (ptvdi->item.pszText) 00558 { 00559 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey); 00560 _sntprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), _T("%s\\%s"), keyPath, ptvdi->item.pszText); 00561 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey); 00562 if (RegOpenKeyEx(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS) 00563 { 00564 lResult = FALSE; 00565 RegCloseKey(hKey); 00566 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem); 00567 } 00568 else 00569 { 00570 if (RenameKey(hRootKey, keyPath, ptvdi->item.pszText) != ERROR_SUCCESS) 00571 lResult = FALSE; 00572 } 00573 return lResult; 00574 } 00575 } 00576 default: 00577 return 0; 00578 } 00579 } 00580 else 00581 { 00582 if ((int)wParam == LIST_WINDOW && g_pChildWnd != NULL) 00583 { 00584 switch (((LPNMHDR)lParam)->code) 00585 { 00586 case NM_SETFOCUS: 00587 g_pChildWnd->nFocusPanel = 1; 00588 break; 00589 default: 00590 if(!ListWndNotifyProc(g_pChildWnd->hListWnd, wParam, lParam, &Result)) 00591 { 00592 goto def; 00593 } 00594 return Result; 00595 break; 00596 } 00597 } 00598 } 00599 break; 00600 00601 case WM_CONTEXTMENU: 00602 { 00603 POINT pt; 00604 if((HWND)wParam == g_pChildWnd->hListWnd) 00605 { 00606 int i, cnt; 00607 BOOL IsDefault; 00608 pt.x = (short) LOWORD(lParam); 00609 pt.y = (short) HIWORD(lParam); 00610 cnt = ListView_GetSelectedCount(g_pChildWnd->hListWnd); 00611 i = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED | LVNI_SELECTED); 00612 if (pt.x == -1 && pt.y == -1) 00613 { 00614 RECT rc; 00615 if (i != -1) 00616 { 00617 rc.left = LVIR_BOUNDS; 00618 SendMessage(g_pChildWnd->hListWnd, LVM_GETITEMRECT, i, (LPARAM) &rc); 00619 pt.x = rc.left + 8; 00620 pt.y = rc.top + 8; 00621 } 00622 else 00623 pt.x = pt.y = 0; 00624 ClientToScreen(g_pChildWnd->hListWnd, &pt); 00625 } 00626 if(i == -1) 00627 { 00628 TrackPopupMenu(GetSubMenu(hPopupMenus, PM_NEW), TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL); 00629 } 00630 else 00631 { 00632 HMENU mnu = GetSubMenu(hPopupMenus, PM_MODIFYVALUE); 00633 SetMenuDefaultItem(mnu, ID_EDIT_MODIFY, MF_BYCOMMAND); 00634 IsDefault = IsDefaultValue(g_pChildWnd->hListWnd, i); 00635 if(cnt == 1) 00636 EnableMenuItem(mnu, ID_EDIT_RENAME, MF_BYCOMMAND | (IsDefault ? MF_DISABLED | MF_GRAYED : MF_ENABLED)); 00637 else 00638 EnableMenuItem(mnu, ID_EDIT_RENAME, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); 00639 EnableMenuItem(mnu, ID_EDIT_MODIFY, MF_BYCOMMAND | (cnt == 1 ? MF_ENABLED : MF_DISABLED | MF_GRAYED)); 00640 EnableMenuItem(mnu, ID_EDIT_MODIFY_BIN, MF_BYCOMMAND | (cnt == 1 ? MF_ENABLED : MF_DISABLED | MF_GRAYED)); 00641 00642 TrackPopupMenu(mnu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL); 00643 } 00644 } 00645 else if ((HWND)wParam == g_pChildWnd->hTreeWnd) 00646 { 00647 TVHITTESTINFO hti; 00648 HMENU hContextMenu; 00649 TVITEM item; 00650 MENUITEMINFO mii; 00651 TCHAR resource[256]; 00652 TCHAR buffer[256]; 00653 LPTSTR s; 00654 LPCTSTR keyPath; 00655 HKEY hRootKey; 00656 int iLastPos; 00657 WORD wID; 00658 00659 pt.x = (short) LOWORD(lParam); 00660 pt.y = (short) HIWORD(lParam); 00661 00662 if (pt.x == -1 && pt.y == -1) 00663 { 00664 RECT rc; 00665 hti.hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 00666 if (hti.hItem != NULL) 00667 { 00668 TreeView_GetItemRect(g_pChildWnd->hTreeWnd, hti.hItem, &rc, TRUE); 00669 pt.x = rc.left + 8; 00670 pt.y = rc.top + 8; 00671 ClientToScreen(g_pChildWnd->hTreeWnd, &pt); 00672 hti.flags = TVHT_ONITEM; 00673 } 00674 else 00675 hti.flags = 0; 00676 } 00677 else 00678 { 00679 hti.pt.x = pt.x; 00680 hti.pt.y = pt.y; 00681 ScreenToClient(g_pChildWnd->hTreeWnd, &hti.pt); 00682 (void)TreeView_HitTest(g_pChildWnd->hTreeWnd, &hti); 00683 } 00684 00685 if (hti.flags & TVHT_ONITEM) 00686 { 00687 hContextMenu = GetSubMenu(hPopupMenus, PM_TREECONTEXT); 00688 (void)TreeView_SelectItem(g_pChildWnd->hTreeWnd, hti.hItem); 00689 00690 memset(&item, 0, sizeof(item)); 00691 item.mask = TVIF_STATE | TVIF_CHILDREN; 00692 item.hItem = hti.hItem; 00693 (void)TreeView_GetItem(g_pChildWnd->hTreeWnd, &item); 00694 00695 /* Set the Expand/Collapse menu item appropriately */ 00696 LoadString(hInst, (item.state & TVIS_EXPANDED) ? IDS_COLLAPSE : IDS_EXPAND, buffer, sizeof(buffer) / sizeof(buffer[0])); 00697 memset(&mii, 0, sizeof(mii)); 00698 mii.cbSize = sizeof(mii); 00699 mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID; 00700 mii.fState = (item.cChildren > 0) ? MFS_DEFAULT : MFS_GRAYED; 00701 mii.wID = (item.state & TVIS_EXPANDED) ? ID_TREE_COLLAPSEBRANCH : ID_TREE_EXPANDBRANCH; 00702 mii.dwTypeData = (LPTSTR) buffer; 00703 SetMenuItemInfo(hContextMenu, 0, TRUE, &mii); 00704 00705 /* Remove any existing suggestions */ 00706 memset(&mii, 0, sizeof(mii)); 00707 mii.cbSize = sizeof(mii); 00708 mii.fMask = MIIM_ID; 00709 GetMenuItemInfo(hContextMenu, GetMenuItemCount(hContextMenu) - 1, TRUE, &mii); 00710 if ((mii.wID >= ID_TREE_SUGGESTION_MIN) && (mii.wID <= ID_TREE_SUGGESTION_MAX)) 00711 { 00712 do 00713 { 00714 iLastPos = GetMenuItemCount(hContextMenu) - 1; 00715 GetMenuItemInfo(hContextMenu, iLastPos, TRUE, &mii); 00716 RemoveMenu(hContextMenu, iLastPos, MF_BYPOSITION); 00717 } 00718 while((mii.wID >= ID_TREE_SUGGESTION_MIN) && (mii.wID <= ID_TREE_SUGGESTION_MAX)); 00719 } 00720 00721 /* Come up with suggestions */ 00722 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hRootKey); 00723 SuggestKeys(hRootKey, keyPath, Suggestions, sizeof(Suggestions) / sizeof(Suggestions[0])); 00724 if (Suggestions[0]) 00725 { 00726 AppendMenu(hContextMenu, MF_SEPARATOR, 0, NULL); 00727 00728 LoadString(hInst, IDS_GOTO_SUGGESTED_KEY, resource, sizeof(resource) / sizeof(resource[0])); 00729 00730 s = Suggestions; 00731 wID = ID_TREE_SUGGESTION_MIN; 00732 while(*s && (wID <= ID_TREE_SUGGESTION_MAX)) 00733 { 00734 _sntprintf(buffer, sizeof(buffer) / sizeof(buffer[0]), resource, s); 00735 00736 memset(&mii, 0, sizeof(mii)); 00737 mii.cbSize = sizeof(mii); 00738 mii.fMask = MIIM_STRING | MIIM_ID; 00739 mii.wID = wID++; 00740 mii.dwTypeData = buffer; 00741 InsertMenuItem(hContextMenu, GetMenuItemCount(hContextMenu), TRUE, &mii); 00742 00743 s += _tcslen(s) + 1; 00744 } 00745 } 00746 TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, g_pChildWnd->hWnd, NULL); 00747 } 00748 } 00749 break; 00750 } 00751 00752 case WM_SIZE: 00753 if (wParam != SIZE_MINIMIZED && g_pChildWnd != NULL) 00754 { 00755 ResizeWnd(LOWORD(lParam), HIWORD(lParam)); 00756 } 00757 /* fall through */ 00758 default: 00759 def: 00760 return DefWindowProc(hWnd, message, wParam, lParam); 00761 } 00762 return 0; 00763 } Generated on Sun May 27 2012 04:17:36 for ReactOS by
1.7.6.1
|