regedit: more cleanup

Dimitrie O. Paun dpaun at rogers.com
Wed Dec 10 23:37:40 CST 2003


A bunch of cleanup for the existing code before we start
on the edit part.

ChangeLog
    Remove most string size limitations.
    Better error handling. Less listview flicker.
    A bunch of style fixes and improvements.

Index: programs/regedit/about.c
===================================================================
RCS file: /var/cvs/wine/programs/regedit/about.c,v
retrieving revision 1.1
diff -u -r1.1 about.c
--- programs/regedit/about.c	7 Aug 2003 03:10:13 -0000	1.1
+++ programs/regedit/about.c	9 Dec 2003 03:49:03 -0000
@@ -28,18 +28,14 @@
 
 #include "main.h"
 
-extern HINSTANCE hInst;
-
 static INT_PTR CALLBACK AboutDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    HWND    hLicenseEditWnd;
     TCHAR   strLicense[0x1000];
 
     switch (message) {
     case WM_INITDIALOG:
-        hLicenseEditWnd = GetDlgItem(hDlg, IDC_LICENSE_EDIT);
-        LoadString(hInst, IDS_LICENSE, strLicense, 0x1000);
-        SetWindowText(hLicenseEditWnd, strLicense);
+        LoadString(hInst, IDS_LICENSE, strLicense, COUNT_OF(strLicense));
+        SetDlgItemText(hDlg, IDC_LICENSE_EDIT, strLicense);
         return TRUE;
     case WM_COMMAND:
         if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) {
Index: programs/regedit/childwnd.c
===================================================================
RCS file: /var/cvs/wine/programs/regedit/childwnd.c,v
retrieving revision 1.4
diff -u -r1.4 childwnd.c
--- programs/regedit/childwnd.c	8 Dec 2003 22:48:07 -0000	1.4
+++ programs/regedit/childwnd.c	11 Dec 2003 01:05:43 -0000
@@ -20,38 +20,26 @@
 
 #define WIN32_LEAN_AND_MEAN     /* Exclude rarely-used stuff from Windows headers */
 #include <windows.h>
-#include <tchar.h>
 #include <commctrl.h>
+#include <tchar.h>
+#include <stdio.h>
 
 #include "main.h"
 
-ChildWnd* pChildWnd;
+ChildWnd* g_pChildWnd;
 
 /*******************************************************************************
  * Local module support methods
  */
 
-/*FIXME: why do we need this, we should remove it, we have already FindRegRoot */
-static void MakeFullRegPath(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max)
+static LPCTSTR get_root_key_name(HKEY hRootKey)
 {
-    TVITEM item;
-    item.mask = TVIF_PARAM;
-    item.hItem = hItem;
-    if (TreeView_GetItem(hwndTV, &item)) {
-        if (item.hItem != TreeView_GetRoot(hwndTV)) {
-            /* recurse */
-            MakeFullRegPath(hwndTV, TreeView_GetParent(hwndTV, hItem), keyPath, pPathLen, max);
-            keyPath[*pPathLen] = _T('\\');
-            ++(*pPathLen);
-        }
-        item.mask = TVIF_TEXT;
-        item.hItem = hItem;
-        item.pszText = &keyPath[*pPathLen];
-        item.cchTextMax = max - *pPathLen;
-        if (TreeView_GetItem(hwndTV, &item)) {
-            *pPathLen += _tcslen(item.pszText);
-        }
-    }
+    if (hRootKey == HKEY_CLASSES_ROOT) return _T("HKEY_CLASSES_ROOT");
+    if (hRootKey == HKEY_CURRENT_USER) return _T("HKEY_CURRENT_USER");
+    if (hRootKey == HKEY_LOCAL_MACHINE) return _T("HKEY_LOCAL_MACHINE");
+    if (hRootKey == HKEY_USERS) return _T("HKEY_USERS");
+    if (hRootKey == HKEY_CURRENT_CONFIG) return _T("HKEY_CURRENT_CONFIG");
+    return _T("UKNOWN HKEY, PLEASE REPORT");
 }
 
 static void draw_splitbar(HWND hWnd, int x)
@@ -127,13 +115,15 @@
 LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
     static int last_split;
-    /*    ChildWnd* pChildWnd = (ChildWnd*)GetWindowLong(hWnd, GWL_USERDATA); */
+    ChildWnd* pChildWnd = g_pChildWnd;
 
     switch (message) {
     case WM_CREATE:
-        pChildWnd = (ChildWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams;
+        g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), 0, sizeof(ChildWnd));
         if (!pChildWnd) return 0;
+        _tcsncpy(pChildWnd->szPath, _T("My Computer"), MAX_PATH);
         pChildWnd->nSplitPos = 250;
+        pChildWnd->hWnd = hWnd;
         pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, TREE_WINDOW);
         pChildWnd->hListWnd = CreateListView(hWnd, LIST_WINDOW/*, pChildWnd->szPath*/);
         break;
@@ -157,6 +147,8 @@
         }
         goto def;
     case WM_DESTROY:
+        HeapFree(GetProcessHeap(), 0, pChildWnd);
+        pChildWnd = NULL;
         PostQuitMessage(0);
         break;
     case WM_LBUTTONDOWN: {
@@ -234,17 +226,21 @@
             case TVN_ITEMEXPANDING:
                 return !OnTreeExpanding(pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam);
             case TVN_SELCHANGED: {
-                    HKEY hKey;
-                    TCHAR keyPath[1000];
-                    int keyPathLen = 0;
-                    keyPath[0] = _T('\0');
-                    hKey = FindRegRoot(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR));
-                    RefreshListView(pChildWnd->hListWnd, hKey, keyPath);
-
-                    keyPathLen = 0;
-                    keyPath[0] = _T('\0');
-                    MakeFullRegPath(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR));
-                    SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)keyPath);
+                    LPCTSTR keyPath, rootName;
+		    LPTSTR fullPath;
+                    HKEY hRootKey;
+
+		    keyPath = GetItemPath(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey);
+		    if (keyPath) {
+                        RefreshListView(pChildWnd->hListWnd, hRootKey, keyPath);
+			rootName = get_root_key_name(hRootKey);
+			fullPath = HeapAlloc(GetProcessHeap(), 0, (lstrlen(rootName) + 1 + lstrlen(keyPath) + 1) * sizeof(TCHAR));
+			if (fullPath) {
+			    _stprintf(fullPath, "%s\\%s", rootName, keyPath);
+			    SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath);
+			    HeapFree(GetProcessHeap(), 0, fullPath);
+			}
+		    }
                 }
                 break;
             default:
Index: programs/regedit/framewnd.c
===================================================================
RCS file: /var/cvs/wine/programs/regedit/framewnd.c,v
retrieving revision 1.4
diff -u -r1.4 framewnd.c
--- programs/regedit/framewnd.c	8 Dec 2003 22:48:07 -0000	1.4
+++ programs/regedit/framewnd.c	11 Dec 2003 04:51:04 -0000
@@ -38,8 +38,6 @@
 
 static BOOL bInMenuLoop = FALSE;        /* Tells us if we are in the menu loop */
 
-static HWND hChildWnd;
-
 /*******************************************************************************
  * Local module support methods
  */
@@ -60,7 +58,7 @@
         GetClientRect(hStatusBar, &rt);
         prect->bottom -= rt.bottom;
     }
-    MoveWindow(hChildWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
+    MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
 }
 
 void resize_frame_client(HWND hWnd)
@@ -437,21 +435,20 @@
  */
 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    HKEY hKeyRoot, hKey;
-    TCHAR keyPath[1000] = { 0 };
-    TCHAR valueName[255] = { 0 };
-    int keyPathLen = 0, item;
+    HKEY hKeyRoot = 0, hKey = 0;
+    LPCTSTR keyPath;
+    LPCTSTR valueName;
     BOOL result = TRUE;
     LONG lRet;
 
-    hKeyRoot = FindRegRoot(pChildWnd->hTreeWnd, 0, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR));
-    lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, KEY_READ, &hKey);
-    if (lRet != ERROR_SUCCESS) hKey = 0;
-    item = ListView_GetNextItem(pChildWnd->hListWnd, -1, LVNI_FOCUSED);
-    if (item != -1) ListView_GetItemText(pChildWnd->hListWnd, item, 0, valueName, sizeof(valueName)/sizeof(TCHAR));
+    keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
+    valueName = GetValueName(g_pChildWnd->hListWnd);
+    if (keyPath) {
+        lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, KEY_READ, &hKey);
+        if (lRet != ERROR_SUCCESS) hKey = 0;
+    }
 
     switch (LOWORD(wParam)) {
-        /* Parse the menu selections:*/
     case ID_REGISTRY_IMPORTREGISTRYFILE:
         ImportRegistryFile(hWnd);
         break;
@@ -467,7 +464,7 @@
         break;
     case ID_EDIT_MODIFY:
         if (ModifyValue(hWnd, hKey, valueName))
-            RefreshListView(pChildWnd->hListWnd, hKeyRoot, keyPath);
+            RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
         break;
     case ID_EDIT_COPYKEYNAME:
         CopyKeyName(hWnd, _T(""));
@@ -486,22 +483,17 @@
     case ID_VIEW_REFRESH:
         RefreshView(hWnd);
         break;
-        /*	case ID_OPTIONS_TOOLBAR:*/
-        /*		toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
-        /*      break;*/
+   /*case ID_OPTIONS_TOOLBAR:*/
+   /*	toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
+   /*    break;*/
     case ID_VIEW_STATUSBAR:
         toggle_child(hWnd, LOWORD(wParam), hStatusBar);
         break;
     case ID_HELP_HELPTOPICS:
-        /*		WinHelp(hWnd, _T("regedit"), HELP_CONTENTS, 0);*/
         WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
         break;
     case ID_HELP_ABOUT:
-#ifdef WINSHELLAPI
-        /*        ShellAbout(hWnd, szTitle, _T(""), LoadIcon(hInst, (LPCTSTR)IDI_REGEDIT));*/
-#else
         ShowAboutBox(hWnd);
-#endif
         break;
     default:
         result = FALSE;
@@ -524,23 +516,15 @@
 
 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    static ChildWnd* pChildWnd = NULL;
-
     switch (message) {
-    case WM_CREATE: {
-            pChildWnd = HeapAlloc(GetProcessHeap(), 0, sizeof(ChildWnd));
-            _tcsncpy(pChildWnd->szPath, _T("My Computer"), MAX_PATH);
-            hChildWnd = CreateWindowEx(0, szChildClass, _T("regedit child window"),
-                                       /*                    WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|WS_BORDER,*/
-                                       WS_CHILD|WS_VISIBLE,
-                                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
-                                       hWnd, (HMENU)0, hInst, pChildWnd);
-        }
+    case WM_CREATE:
+        CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
+                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+                       hWnd, (HMENU)0, hInst, 0);
         break;
     case WM_COMMAND:
-        if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
+        if (!_CmdWndProc(hWnd, message, wParam, lParam))
             return DefWindowProc(hWnd, message, wParam, lParam);
-        }
         break;
     case WM_SIZE:
         resize_frame_client(hWnd);
@@ -557,10 +541,6 @@
         OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
         break;
     case WM_DESTROY:
-        if (pChildWnd) {
-            HeapFree(GetProcessHeap(), 0, pChildWnd);
-            pChildWnd = NULL;
-        }
         WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
         PostQuitMessage(0);
     default:
Index: programs/regedit/listview.c
===================================================================
RCS file: /var/cvs/wine/programs/regedit/listview.c,v
retrieving revision 1.3
diff -u -r1.3 listview.c
--- programs/regedit/listview.c	10 Dec 2003 02:10:52 -0000	1.3
+++ programs/regedit/listview.c	11 Dec 2003 05:30:15 -0000
@@ -19,15 +19,13 @@
  */
 
 #include <windows.h>
+#include <windowsx.h>
 #include <commctrl.h>
 #include <stdlib.h>
 #include <tchar.h>
 #include <process.h>
 #include <stdio.h>
 
-#include "commctrl.h"
-
-#include <windowsx.h>
 #include "main.h"
 
 typedef struct tagLINE_INFO
@@ -45,11 +43,37 @@
 static WNDPROC g_orgListWndProc;
 static DWORD g_columnToSort = ~0UL;
 static BOOL  g_invertSort = FALSE;
+static LPTSTR g_valueName;
 
 #define MAX_LIST_COLUMNS (IDS_LIST_COLUMN_LAST - IDS_LIST_COLUMN_FIRST + 1)
 static int default_column_widths[MAX_LIST_COLUMNS] = { 200, 175, 400 };
 static int column_alignment[MAX_LIST_COLUMNS] = { LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT };
 
+extern LPCTSTR GetValueName(HWND hwndLV)
+{
+    int item, len, maxLen;
+    LPTSTR newStr;
+
+    if (!g_valueName) g_valueName = HeapAlloc(GetProcessHeap(), 0, 1024);
+    if (!g_valueName) return NULL;
+    *g_valueName = 0;
+    maxLen = HeapSize(GetProcessHeap(), 0, g_valueName);
+    if (maxLen == (SIZE_T) - 1) return NULL;
+
+    item = ListView_GetNextItem(hwndLV, -1, LVNI_FOCUSED);
+    if (item == -1) return NULL;
+    do {
+        ListView_GetItemText(hwndLV, item, 0, g_valueName, maxLen);
+	len = _tcslen(g_valueName);
+	if (len < maxLen - 1) break;
+	newStr = HeapReAlloc(GetProcessHeap(), 0, g_valueName, maxLen * 2);
+	if (!newStr) return NULL;
+	g_valueName = newStr;
+	maxLen *= 2;
+    } while (TRUE);
+
+    return g_valueName;
+}
 
 /*******************************************************************************
  * Local module support methods
@@ -118,7 +142,7 @@
     }
 }
 
-static void CreateListColumns(HWND hWndListView)
+static BOOL CreateListColumns(HWND hWndListView)
 {
     TCHAR szText[50];
     int index;
@@ -134,11 +158,9 @@
         lvC.cx = default_column_widths[index];
         lvC.fmt = column_alignment[index];
         LoadString(hInst, IDS_LIST_COLUMN_FIRST + index, szText, sizeof(szText)/sizeof(TCHAR));
-        if (ListView_InsertColumn(hWndListView, index, &lvC) == -1) {
-            /* TODO: handle failure condition... */
-            break;
-        }
+        if (ListView_InsertColumn(hWndListView, index, &lvC) == -1) return FALSE;
     }
+    return TRUE;
 }
 
 /* OnGetDispInfo - processes the LVN_GETDISPINFO notification message.  */
@@ -168,9 +190,6 @@
         case REG_DWORD:
             plvdi->item.pszText = _T("REG_DWORD");
             break;
-            /*        case REG_DWORD_LITTLE_ENDIAN: */
-            /*            plvdi->item.pszText = _T("REG_DWORD_LITTLE_ENDIAN"); */
-            /*            break; */
         case REG_DWORD_BIG_ENDIAN:
             plvdi->item.pszText = _T("REG_DWORD_BIG_ENDIAN");
             break;
@@ -212,8 +231,7 @@
     
     if (g_columnToSort == 1 && l->dwValType != r->dwValType)
         return g_invertSort ? (int)r->dwValType - (int)l->dwValType : (int)l->dwValType - (int)r->dwValType;
-    if (g_columnToSort == 2)
-    {
+    if (g_columnToSort == 2) {
         /* FIXME: Sort on value */
     }
     return g_invertSort ? _tcscmp(r->name, l->name) : _tcscmp(l->name, r->name);
@@ -249,8 +267,7 @@
         case LVN_COLUMNCLICK:
             if (g_columnToSort == ((LPNMLISTVIEW)lParam)->iSubItem)
                 g_invertSort = !g_invertSort;
-            else
-            {
+            else {
                 g_columnToSort = ((LPNMLISTVIEW)lParam)->iSubItem;
                 g_invertSort = FALSE;
             }
@@ -332,80 +349,81 @@
                             WS_VISIBLE | WS_CHILD | LVS_REPORT,
                             0, 0, rcClient.right, rcClient.bottom,
                             hwndParent, (HMENU)id, hInst, NULL);
+    if (!hwndLV) return NULL;
     ListView_SetExtendedListViewStyle(hwndLV,  LVS_EX_FULLROWSELECT);
 
     /* Initialize the image list, and add items to the control.  */
     /*
-        if (!InitListViewImageLists(hwndLV) ||
-                !InitListViewItems(hwndLV, szName)) {
-            DestroyWindow(hwndLV);
-            return FALSE;
-        }
-     */
-    CreateListColumns(hwndLV);
+    if (!InitListViewImageLists(hwndLV)) goto fail;
+    if (!InitListViewItems(hwndLV, szName)) goto fail;
+    */
+    if (!CreateListColumns(hwndLV)) goto fail;
     g_orgListWndProc = SubclassWindow(hwndLV, ListWndProc);
     return hwndLV;
+fail:
+    DestroyWindow(hwndLV);
+    return NULL;
 }
 
-BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPTSTR keyPath)
+BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath)
 {
-    if (hwndLV != NULL) {
-        INT count, i;
-        count = ListView_GetItemCount(hwndLV);
-        for (i = 0; i < count; i++)
-        {
-            LVITEM item;
-            item.mask = LVIF_PARAM;
-            item.iItem = i;
-            ListView_GetItem(hwndLV, &item);
-            free(((LINE_INFO*)item.lParam)->name);
-            HeapFree(GetProcessHeap(), 0, (void*)item.lParam);
-        }
-        g_columnToSort = ~0UL;
-        ListView_DeleteAllItems(hwndLV);
+    DWORD max_sub_key_len;
+    DWORD max_val_name_len;
+    DWORD max_val_size;
+    DWORD val_count;
+    HKEY hNewKey;
+    LONG errCode;
+    INT count, i;
+    LVITEM item;
+
+    if (!hwndLV) return FALSE;
+
+    SendMessage(hwndLV, WM_SETREDRAW, FALSE, 0);
+    count = ListView_GetItemCount(hwndLV);
+    for (i = 0; i < count; i++) {
+        item.mask = LVIF_PARAM;
+        item.iItem = i;
+        ListView_GetItem(hwndLV, &item);
+        free(((LINE_INFO*)item.lParam)->name);
+        HeapFree(GetProcessHeap(), 0, (void*)item.lParam);
     }
+    g_columnToSort = ~0UL;
+    ListView_DeleteAllItems(hwndLV);
 
-    if (hKey != NULL) {
-        HKEY hNewKey;
-        LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey);
-        if (errCode == ERROR_SUCCESS) {
-            DWORD max_sub_key_len;
-            DWORD max_val_name_len;
-            DWORD max_val_size;
-            DWORD val_count;
-            ShowWindow(hwndLV, SW_HIDE);
-            /* get size information and resize the buffers if necessary */
-            errCode = RegQueryInfoKey(hNewKey, NULL, NULL, NULL, NULL,
-                                      &max_sub_key_len, NULL, &val_count, &max_val_name_len, &max_val_size, NULL, NULL);
-
-            #define BUF_HEAD_SPACE 2 /* TODO: check why this is required with ROS ??? */
-
-            if (errCode == ERROR_SUCCESS) {
-                TCHAR* ValName = HeapAlloc(GetProcessHeap(), 0, ++max_val_name_len * sizeof(TCHAR) + BUF_HEAD_SPACE);
-                DWORD dwValNameLen = max_val_name_len;
-                BYTE* ValBuf = HeapAlloc(GetProcessHeap(), 0, ++max_val_size/* + BUF_HEAD_SPACE*/);
-                DWORD dwValSize = max_val_size;
-                DWORD dwIndex = 0L;
-                DWORD dwValType;
-                /*                if (RegQueryValueEx(hNewKey, NULL, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { */
-                /*                    AddEntryToList(hwndLV, _T("(Default)"), dwValType, ValBuf, dwValSize); */
-                /*                } */
-                /*                dwValSize = max_val_size; */
-                while (RegEnumValue(hNewKey, dwIndex, ValName, &dwValNameLen, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) {
-                    ValBuf[dwValSize] = 0;
-                    AddEntryToList(hwndLV, ValName, dwValType, ValBuf, dwValSize);
-                    dwValNameLen = max_val_name_len;
-                    dwValSize = max_val_size;
-                    dwValType = 0L;
-                    ++dwIndex;
-                }
-                HeapFree(GetProcessHeap(), 0, ValBuf);
-                HeapFree(GetProcessHeap(), 0, ValName);
-            }
-            ListView_SortItems(hwndLV, CompareFunc, hwndLV); 
-            ShowWindow(hwndLV, SW_SHOW);
-            RegCloseKey(hNewKey);
+    errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey);
+    if (errCode != ERROR_SUCCESS) return FALSE;
+
+    /* get size information and resize the buffers if necessary */
+    errCode = RegQueryInfoKey(hNewKey, NULL, NULL, NULL, NULL, &max_sub_key_len, NULL, 
+                              &val_count, &max_val_name_len, &max_val_size, NULL, NULL);
+
+    #define BUF_HEAD_SPACE 2 /* FIXME: check why this is required with ROS ??? */
+
+    if (errCode == ERROR_SUCCESS) {
+        TCHAR* ValName = HeapAlloc(GetProcessHeap(), 0, ++max_val_name_len * sizeof(TCHAR) + BUF_HEAD_SPACE);
+        DWORD dwValNameLen = max_val_name_len;
+        BYTE* ValBuf = HeapAlloc(GetProcessHeap(), 0, ++max_val_size/* + BUF_HEAD_SPACE*/);
+        DWORD dwValSize = max_val_size;
+        DWORD dwIndex = 0L;
+        DWORD dwValType;
+        /*                if (RegQueryValueEx(hNewKey, NULL, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { */
+        /*                    AddEntryToList(hwndLV, _T("(Default)"), dwValType, ValBuf, dwValSize); */
+        /*                } */
+        /*                dwValSize = max_val_size; */
+        while (RegEnumValue(hNewKey, dwIndex, ValName, &dwValNameLen, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) {
+            ValBuf[dwValSize] = 0;
+            AddEntryToList(hwndLV, ValName, dwValType, ValBuf, dwValSize);
+            dwValNameLen = max_val_name_len;
+            dwValSize = max_val_size;
+            dwValType = 0L;
+            ++dwIndex;
         }
+        HeapFree(GetProcessHeap(), 0, ValBuf);
+        HeapFree(GetProcessHeap(), 0, ValName);
     }
+    ListView_SortItems(hwndLV, CompareFunc, hwndLV);
+    RegCloseKey(hNewKey);
+    SendMessage(hwndLV, WM_SETREDRAW, TRUE, 0);
+
     return TRUE;
 }
Index: programs/regedit/main.c
===================================================================
RCS file: /var/cvs/wine/programs/regedit/main.c,v
retrieving revision 1.6
diff -u -r1.6 main.c
--- programs/regedit/main.c	8 Dec 2003 22:48:07 -0000	1.6
+++ programs/regedit/main.c	11 Dec 2003 00:51:00 -0000
@@ -46,6 +46,7 @@
 LPCTSTR strClipboardFormat = _T("TODO: SET CORRECT FORMAT");
 
 
+#define MAX_LOADSTRING  100
 TCHAR szTitle[MAX_LOADSTRING];
 TCHAR szFrameClass[MAX_LOADSTRING];
 TCHAR szChildClass[MAX_LOADSTRING];
Index: programs/regedit/main.h
===================================================================
RCS file: /var/cvs/wine/programs/regedit/main.h,v
retrieving revision 1.7
diff -u -r1.7 main.h
--- programs/regedit/main.h	8 Dec 2003 22:48:07 -0000	1.7
+++ programs/regedit/main.h	11 Dec 2003 04:43:10 -0000
@@ -28,12 +28,12 @@
 #define TREE_WINDOW     2002
 #define LIST_WINDOW     2003
 
-#define MAX_LOADSTRING  100
 #define	SPLIT_WIDTH	5
-#define MAX_NAME_LEN    500
 
 #define COUNT_OF(a) (sizeof(a)/sizeof(a[0]))
 
+extern HINSTANCE hInst;
+
 /******************************************************************************/
 
 enum OPTION_FLAGS {
@@ -55,7 +55,7 @@
     WINDOWPLACEMENT pos;
     TCHAR   szPath[MAX_PATH];
 } ChildWnd;
-extern ChildWnd* pChildWnd;
+extern ChildWnd* g_pChildWnd;
 
 /*******************************************************************************
  * Global Variables:
@@ -84,12 +84,13 @@
 
 /* listview.c */
 extern HWND CreateListView(HWND hwndParent, int id);
-extern BOOL RefreshListView(HWND hwndTV, HKEY hKey, LPTSTR keyPath);
+extern BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath);
+extern LPCTSTR GetValueName(HWND hwndLV);
 
 /* treeview.c */
 extern HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, int id);
 extern BOOL OnTreeExpanding(HWND hWnd, NMTREEVIEW* pnmtv);
-extern HKEY FindRegRoot(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max);
+extern LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey);
 
 /* edit.c */
 BOOL ModifyValue(HWND hwnd, HKEY hKey, LPTSTR valueName);
Index: programs/regedit/treeview.c
===================================================================
RCS file: /var/cvs/wine/programs/regedit/treeview.c,v
retrieving revision 1.4
diff -u -r1.4 treeview.c
--- programs/regedit/treeview.c	8 Dec 2003 22:48:07 -0000	1.4
+++ programs/regedit/treeview.c	11 Dec 2003 05:26:27 -0000
@@ -39,53 +39,72 @@
 int Image_Closed;
 int Image_Root;
 
+static LPTSTR pathBuffer;
+
 #define CX_BITMAP    16
 #define CY_BITMAP    16
 #define NUM_BITMAPS  3
 
-
-HKEY FindRegRoot(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max)
+static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPTSTR* pKeyPath, int* pPathLen, int* pMaxLen)
 {
-    HKEY hKey = NULL;
     TVITEM item;
-
-    if (!hItem) hItem = TreeView_GetSelection(hwndTV);
+    int maxLen, len;
+    LPTSTR newStr;
 
     item.mask = TVIF_PARAM;
-    item.hItem = TreeView_GetParent(hwndTV, hItem);
+    item.hItem = hItem;
+    if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
+
+    if (item.lParam) {
+	/* found root key with valid key value */
+	*phKey = (HKEY)item.lParam;
+	return TRUE;
+    }
 
-    if (TreeView_GetItem(hwndTV, &item)) {
-        if (item.lParam == 0) {
-            /* recurse */
-            hKey = FindRegRoot(hwndTV, item.hItem, keyPath, pPathLen, max);
-            keyPath[*pPathLen] = _T('\\');
-            ++(*pPathLen);
-            item.mask = TVIF_TEXT;
-            item.hItem = hItem;
-            item.pszText = &keyPath[*pPathLen];
-            item.cchTextMax = max - *pPathLen;
-            if (TreeView_GetItem(hwndTV, &item)) {
-                *pPathLen += _tcslen(item.pszText);
-            }
-        } else {
-            /* found root key with valid key value */
-            hKey = (HKEY)item.lParam;
-            item.mask = TVIF_TEXT;
-            item.hItem = hItem;
-            /*            item.pszText = &keyPath[*pPathLen]; */
-            item.pszText = keyPath;
-            item.cchTextMax = max;
-            if (TreeView_GetItem(hwndTV, &item)) {
-                *pPathLen += _tcslen(item.pszText);
-            }
-        }
+    if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE;
+    if (*pPathLen) {
+        (*pKeyPath)[*pPathLen] = _T('\\');
+        ++(*pPathLen);
     }
-    return hKey;
+
+    do {
+        item.mask = TVIF_TEXT;
+        item.hItem = hItem;
+        item.pszText = *pKeyPath + *pPathLen;
+        item.cchTextMax = maxLen = *pMaxLen - *pPathLen;
+        if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
+        len = _tcslen(item.pszText);
+	if (len < maxLen - 1) {
+            *pPathLen += len;
+            break;
+	}
+	newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2);
+	if (!newStr) return FALSE;
+	*pKeyPath = newStr;
+	*pMaxLen *= 2;
+    } while(TRUE);
+
+    return TRUE;
+}
+
+LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey)
+{
+    int pathLen = 0, maxLen;
+
+    if (!pathBuffer) pathBuffer = HeapAlloc(GetProcessHeap(), 0, 1024);
+    if (!pathBuffer) return NULL;
+    *pathBuffer = 0;
+    maxLen = HeapSize(GetProcessHeap(), 0, pathBuffer);
+    if (maxLen == (SIZE_T) - 1) return NULL;
+    if (!hItem) hItem = TreeView_GetSelection(hwndTV);
+    if (!hItem) return NULL;
+    if (!get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen)) return NULL;
+    printf("hRoot=%p, keyPath='%s'\n", *phRootKey, pathBuffer);
+    return pathBuffer;
 }
 
 static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HKEY hKey, DWORD dwChildren)
 {
-    HTREEITEM hItem = 0;
     TVITEM tvi;
     TVINSERTSTRUCT tvins;
 
@@ -97,11 +116,9 @@
     tvi.cChildren = dwChildren;
     tvi.lParam = (LPARAM)hKey;
     tvins.u.item = tvi;
-    if (hKey) tvins.hInsertAfter = (HTREEITEM)TVI_LAST;
-    else      tvins.hInsertAfter = (HTREEITEM)TVI_SORT;
+    tvins.hInsertAfter = (HTREEITEM)(hKey ? TVI_LAST : TVI_SORT);
     tvins.hParent = hParent;
-    hItem = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
-    return hItem;
+    return TreeView_InsertItem(hwndTV, &tvins);
 }
 
 
@@ -125,24 +142,24 @@
     tvins.hInsertAfter = (HTREEITEM)TVI_FIRST;
     tvins.hParent = TVI_ROOT;
     /* Add the item to the tree view control.  */
-    hRoot = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+    if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
 
-    AddEntryToTree(hwndTV, hRoot, _T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT, 1);
-    AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER, 1);
-    AddEntryToTree(hwndTV, hRoot, _T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE, 1);
-    AddEntryToTree(hwndTV, hRoot, _T("HKEY_USERS"), HKEY_USERS, 1);
-    AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG, 1);
+    if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT, 1)) return FALSE;
+    if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER, 1)) return FALSE;
+    if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE, 1)) return FALSE;
+    if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_USERS"), HKEY_USERS, 1)) return FALSE;
+    if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG, 1)) return FALSE;
 
     return TRUE;
 }
 
+
 /*
  * InitTreeViewImageLists - creates an image list, adds three bitmaps
  * to it, and associates the image list with a tree view control.
  * Returns TRUE if successful, or FALSE otherwise.
  * hwndTV - handle to the tree view control.
  */
-
 static BOOL InitTreeViewImageLists(HWND hwndTV)
 {
     HIMAGELIST himl;  /* handle to image list  */
@@ -155,20 +172,19 @@
 
     /* Add the open file, closed file, and document bitmaps.  */
     hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FILE));
-    Image_Open = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
+    Image_Open = ImageList_Add(himl, hbmp, NULL);
     DeleteObject(hbmp);
 
     hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FILE));
-    Image_Closed = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
+    Image_Closed = ImageList_Add(himl, hbmp, NULL);
     DeleteObject(hbmp);
 
     hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_ROOT));
-    Image_Root = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
+    Image_Root = ImageList_Add(himl, hbmp, NULL);
     DeleteObject(hbmp);
 
     /* Fail if not all of the images were added.  */
-    if (ImageList_GetImageCount(himl) < 3)
-        return FALSE;
+    if (ImageList_GetImageCount(himl) < 3) return FALSE;
 
     /* Associate the image list with the tree view control.  */
     TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
@@ -178,9 +194,11 @@
 
 BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv)
 {
-    HKEY hKey;
-    TCHAR keyPath[1000];
-    int keyPathLen = 0;
+    DWORD dwCount, dwIndex, dwMaxSubKeyLen;
+    HKEY hRoot, hNewKey, hKey;
+    LPCTSTR keyPath;
+    LPTSTR Name;
+    LONG errCode;
 
     static int expanding;
     if (expanding) return FALSE;
@@ -189,54 +207,52 @@
     }
     expanding = TRUE;
 
-    /* check if this is either the root or a subkey item... */
-    if ((HKEY)pnmtv->itemNew.lParam == NULL) {
-        keyPath[0] = _T('\0');
-        hKey = FindRegRoot(hwndTV, pnmtv->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR));
+    keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
+    if (!keyPath) goto done;
+
+    if (*keyPath) {
+        errCode = RegOpenKeyEx(hRoot, keyPath, 0, KEY_READ, &hNewKey);
+        if (errCode != ERROR_SUCCESS) goto done;
     } else {
-        hKey = (HKEY)pnmtv->itemNew.lParam;
-        keyPath[0] = _T('\0');
+	hNewKey = hRoot;
     }
 
-    if (hKey != NULL) {
-        HKEY hNewKey;
-        LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey);
-        if (errCode == ERROR_SUCCESS) {
-            TCHAR Name[MAX_NAME_LEN];
-            DWORD cName = MAX_NAME_LEN;
-            FILETIME LastWriteTime;
-            DWORD dwIndex = 0L;
-            /*ShowWindow(hwndTV, SW_HIDE); */
-            while (RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, NULL, NULL, NULL, &LastWriteTime) == ERROR_SUCCESS) {
-                DWORD dwCount = 0L;
-                errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_READ, &hKey);
-                if (errCode == ERROR_SUCCESS) {
-                    TCHAR SubName[MAX_NAME_LEN];
-                    DWORD cSubName = MAX_NAME_LEN;
-                    /*                    if (RegEnumKeyEx(hKey, 0, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { */
-                    while (RegEnumKeyEx(hKey, dwCount, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
-                        ++dwCount;
-                    }
-                }
-                RegCloseKey(hKey);
-                AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwCount);
-                cName = MAX_NAME_LEN;
-                ++dwIndex;
-            }
-            /*ShowWindow(hwndTV, SW_SHOWNOACTIVATE); */
-            RegCloseKey(hNewKey);
-        }
+    errCode = RegQueryInfoKey(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
+    if (errCode != ERROR_SUCCESS) goto done;
+    dwMaxSubKeyLen++; /* account for the \0 terminator */
+    Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR));
+    if (!Name) goto done;
+
+    for (dwIndex = 0; dwIndex < dwCount; dwIndex++) {
+	DWORD cName = dwMaxSubKeyLen, dwSubCount;
+        FILETIME LastWriteTime;
+
+        errCode = RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, 0, 0, 0, &LastWriteTime);
+	if (errCode != ERROR_SUCCESS) continue;
+	errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
+	if (errCode == ERROR_SUCCESS) {
+	    errCode = RegQueryInfoKey(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
+	    RegCloseKey(hKey);
+	}
+	if (errCode != ERROR_SUCCESS) dwSubCount = 0;
+	printf("dwSubCount=%ld, Name=%s\n", dwSubCount, Name);
+        AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
     }
+    RegCloseKey(hNewKey);
+    HeapFree(GetProcessHeap(), 0, Name);
+
+done:
     expanding = FALSE;
+
     return TRUE;
 }
 
+
 /*
  * CreateTreeView - creates a tree view control.
  * Returns the handle to the new control if successful, or NULL otherwise.
  * hwndParent - handle to the control's parent window.
  */
-
 HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, int id)
 {
     RECT rcClient;


-- 
Dimi.




More information about the wine-patches mailing list