diff --git a/programs/regedit/childwnd.c b/programs/regedit/childwnd.c index bb031f6731b..d79e8afda9f 100644 --- a/programs/regedit/childwnd.c +++ b/programs/regedit/childwnd.c @@ -247,6 +247,20 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa case NM_SETFOCUS: pChildWnd->nFocusPanel = 1; break; + case TVN_ENDLABELEDIT: { + HKEY hRootKey; + LPNMTVDISPINFO dispInfo = (LPNMTVDISPINFO)lParam; + LPCTSTR path = GetItemPath(pChildWnd->hTreeWnd, 0, &hRootKey); + BOOL res = RenameKey(hWnd, hRootKey, path, dispInfo->item.pszText); + if (res) { + TVITEMEX item; + item.mask = TVIF_HANDLE | TVIF_TEXT; + item.hItem = TreeView_GetSelection(pChildWnd->hTreeWnd); + item.pszText = dispInfo->item.pszText; + TreeView_SetItem(pChildWnd->hTreeWnd, &item); + } + return res; + } default: goto def; } diff --git a/programs/regedit/edit.c b/programs/regedit/edit.c index 7b11fc54609..45b490bdf17 100644 --- a/programs/regedit/edit.c +++ b/programs/regedit/edit.c @@ -156,13 +156,12 @@ done: return NULL; } -BOOL CreateKey(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath) +BOOL CreateKey(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath, LPTSTR keyName) { BOOL result = FALSE; LONG lRet = ERROR_SUCCESS; HKEY retKey; - TCHAR keyName[32]; - TCHAR newKey[COUNT_OF(keyName) - 4]; + TCHAR newKey[MAX_NEW_KEY_LEN - 4]; int keyNum; HKEY hKey; @@ -340,3 +339,47 @@ done: RegCloseKey(hKey); return result; } + + +BOOL RenameKey(HWND hwnd, HKEY hRootKey, LPCTSTR keyPath, LPCTSTR newName) +{ + LPTSTR parentPath = 0; + LPCTSTR srcSubKey = 0; + HKEY parentKey = 0; + HKEY destKey = 0; + BOOL result = FALSE; + LONG lRet; + + if (!keyPath || !newName) return FALSE; + + if (!strrchr(keyPath, '\\')) { + parentKey = hRootKey; + srcSubKey = keyPath; + } else { + parentPath = strdup(keyPath); + srcSubKey = strrchr(parentPath, '\\') + 1; + *((LPTSTR)srcSubKey - 1) = 0; + lRet = RegOpenKeyEx(hRootKey, parentPath, 0, KEY_READ | KEY_CREATE_SUB_KEY, &parentKey); + if (lRet != ERROR_SUCCESS) goto done; + } + + lRet = RegCreateKey(parentKey, newName, &destKey); + if (lRet != ERROR_SUCCESS) goto done; + + /* FIXME: SHCopyKey does not copy the security attributes */ + lRet = SHCopyKey(parentKey, srcSubKey, destKey, 0); + if (lRet != ERROR_SUCCESS) goto done; + + lRet = SHDeleteKey(hRootKey, keyPath); + if (lRet != ERROR_SUCCESS) goto done; + + result = TRUE; + +done: + RegCloseKey(destKey); + if (parentKey) { + RegCloseKey(parentKey); + free(parentPath); + } + return result; +} diff --git a/programs/regedit/framewnd.c b/programs/regedit/framewnd.c index ad691783ace..33b460e22e2 100644 --- a/programs/regedit/framewnd.c +++ b/programs/regedit/framewnd.c @@ -438,6 +438,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) HKEY hKeyRoot = 0; LPCTSTR keyPath; LPCTSTR valueName; + TCHAR newKey[MAX_NEW_KEY_LEN]; DWORD valueType; keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); @@ -458,9 +459,11 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) PrintRegistryHive(hWnd, _T("")); break; case ID_EDIT_DELETE: - if (GetFocus() == g_pChildWnd->hTreeWnd) { + if (keyPath == 0 || *keyPath == 0) { + MessageBeep(MB_ICONHAND); + } else if (GetFocus() == g_pChildWnd->hTreeWnd) { if (DeleteKey(hWnd, hKeyRoot, keyPath)) - ;/* FIXME: TreeView should be refreshed */ + DeleteNode(g_pChildWnd->hTreeWnd, 0); } else if (GetFocus() == g_pChildWnd->hListWnd) { if (DeleteValue(hWnd, hKeyRoot, keyPath, valueName)) RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); @@ -474,8 +477,10 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) CopyKeyName(hWnd, _T("")); break; case ID_EDIT_NEW_KEY: - CreateKey(hWnd, hKeyRoot, keyPath); - /* FIXME: TreeView should be refreshed */ + if (CreateKey(hWnd, hKeyRoot, keyPath, newKey)) { + if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKey)) + StartKeyRename(g_pChildWnd->hTreeWnd); + } break; case ID_EDIT_NEW_STRINGVALUE: valueType = REG_SZ; @@ -487,10 +492,19 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) valueType = REG_DWORD; /* fall through */ create_value: - if (CreateValue(hWnd, hKeyRoot, keyPath, valueType)) + if (CreateValue(hWnd, hKeyRoot, keyPath, valueType)) { RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); + /* FIXME: start rename */ + } + break; case ID_EDIT_RENAME: - StartValueRename(g_pChildWnd->hListWnd); + if (keyPath == 0 || *keyPath == 0) { + MessageBeep(MB_ICONHAND); + } else if (GetFocus() == g_pChildWnd->hTreeWnd) { + StartKeyRename(g_pChildWnd->hTreeWnd); + } else if (GetFocus() == g_pChildWnd->hListWnd) { + StartValueRename(g_pChildWnd->hListWnd); + } break; break; case ID_REGISTRY_PRINTERSETUP: diff --git a/programs/regedit/listview.c b/programs/regedit/listview.c index a35e381e247..851942992b2 100644 --- a/programs/regedit/listview.c +++ b/programs/regedit/listview.c @@ -251,14 +251,13 @@ static void ListViewPopUpMenu(HWND hWnd, POINT pt) { } -BOOL StartValueRename(HWND hwndLV) +HWND StartValueRename(HWND hwndLV) { int item; item = ListView_GetNextItem(hwndLV, -1, LVNI_FOCUSED | LVNI_SELECTED); - if (item < 0) return FALSE; - if (!ListView_EditLabel(hwndLV, item)) return FALSE; - return TRUE; + if (item < 0) return 0; + return ListView_EditLabel(hwndLV, item); } static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) diff --git a/programs/regedit/main.h b/programs/regedit/main.h index e4ad9631b03..3c5abe5741a 100644 --- a/programs/regedit/main.h +++ b/programs/regedit/main.h @@ -35,6 +35,8 @@ #define PM_MODIFYVALUE 0 #define PM_NEW 1 +#define MAX_NEW_KEY_LEN 128 + extern HINSTANCE hInst; /******************************************************************************/ @@ -89,7 +91,7 @@ extern void UpdateStatusBar(void); /* listview.c */ extern HWND CreateListView(HWND hwndParent, int id); extern BOOL RefreshListView(HWND hwndLV, HKEY hKeyRoot, LPCTSTR keyPath); -extern BOOL StartValueRename(HWND hwndLV); +extern HWND StartValueRename(HWND hwndLV); extern LPCTSTR GetValueName(HWND hwndLV); extern BOOL ListWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result); extern BOOL IsDefaultValue(HWND hwndLV, int i); @@ -98,13 +100,17 @@ extern BOOL IsDefaultValue(HWND hwndLV, int i); extern HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, int id); extern BOOL OnTreeExpanding(HWND hWnd, NMTREEVIEW* pnmtv); extern LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey); +extern BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem); +extern HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPTSTR name); +extern HWND StartKeyRename(HWND hwndTV); /* edit.c */ -extern BOOL CreateKey(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath); +extern BOOL CreateKey(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath, LPTSTR newKeyName); extern BOOL CreateValue(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath, DWORD valueType); extern BOOL ModifyValue(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath, LPCTSTR valueName); extern BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath); extern BOOL DeleteValue(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath, LPCTSTR valueName); extern BOOL RenameValue(HWND hwnd, HKEY hRootKey, LPCTSTR keyPath, LPCTSTR oldName, LPCTSTR newName); +extern BOOL RenameKey(HWND hwnd, HKEY hRootKey, LPCTSTR keyPath, LPCTSTR newName); #endif /* __MAIN_H__ */ diff --git a/programs/regedit/treeview.c b/programs/regedit/treeview.c index 1e3eed3227d..9d61d545250 100644 --- a/programs/regedit/treeview.c +++ b/programs/regedit/treeview.c @@ -102,6 +102,13 @@ LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey) return pathBuffer; } +BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem) +{ + if (!hItem) hItem = TreeView_GetSelection(hwndTV); + if (!hItem) return FALSE; + return TreeView_DeleteItem(hwndTV, hItem); +} + static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HKEY hKey, DWORD dwChildren) { TVITEM tvi; @@ -121,6 +128,47 @@ static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HK } +HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPTSTR name) +{ + TCHAR buf[MAX_NEW_KEY_LEN]; + HTREEITEM hNewItem = 0; + TVITEMEX item; + + if (!hItem) hItem = TreeView_GetSelection(hwndTV); + if (!hItem) return FALSE; + if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDEDONCE)) { + hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0); + } else { + item.mask = TVIF_CHILDREN | TVIF_HANDLE; + item.hItem = hItem; + if (!TreeView_GetItem(hwndTV, &item)) return FALSE; + item.cChildren = 1; + if (!TreeView_SetItem(hwndTV, &item)) return FALSE; + } + TreeView_Expand(hwndTV, hItem, TVE_EXPAND); + if (!hNewItem) { + for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem)) { + item.mask = TVIF_HANDLE | TVIF_TEXT; + item.hItem = hNewItem; + item.pszText = buf; + item.cchTextMax = COUNT_OF(buf); + if (!TreeView_GetItem(hwndTV, &item)) continue; + if (lstrcmp(name, item.pszText) == 0) break; + } + } + if (hNewItem) TreeView_SelectItem(hwndTV, hNewItem); + + return hNewItem; +} + +HWND StartKeyRename(HWND hwndTV) +{ + HTREEITEM hItem; + + if(!(hItem = TreeView_GetSelection(hwndTV))) return 0; + return TreeView_EditLabel(hwndTV, hItem); +} + static BOOL InitTreeViewItems(HWND hwndTV, LPTSTR pHostName) { TVITEM tvi;