PATCH: Editing DLL overrides in winecfg

Robert van Herk robert at robertvanherk.nl
Sun Jan 4 12:20:06 CST 2004


Hi all,

This is a patch that adds a tabsheet to winecfg, that allows the user to 
change the dll overrides; both globally and per app.

With special thanx to Mike Hearn ;-).

Grtz,
Robert
-------------- next part --------------
? programs/winecfg/tbsLibraries.c
Index: programs/winecfg/En.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/En.rc,v
retrieving revision 1.14
diff -u -r1.14 En.rc
--- programs/winecfg/En.rc	26 Nov 2003 03:55:01 -0000	1.14
+++ programs/winecfg/En.rc	4 Jan 2004 18:20:36 -0000
@@ -96,15 +96,18 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    GROUPBOX        "Static",IDC_STATIC,8,4,244,157
-    CONTROL         "Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,59,144,57,10
-    CONTROL         "Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,121,144,72,10
-    LTEXT           "Libraries can be specified individually to be either builtin or native. A DLL entry specified as ""*"" pertains to all DLLs not specified explicitly.",
-                    IDC_STATIC,15,17,228,27
-    CONTROL         "List3",IDC_LIST_DLLS,"SysListView32",LVS_LIST | 
-                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | 
-                    WS_TABSTOP,15,47,227,90
-    LTEXT           "Load order:",IDC_STATIC,16,144,37,8
+    GROUPBOX        "DLL Overrides",IDC_STATIC,8,4,244,240
+    LTEXT           "Libraries can be specified individually to be either builtin or native. A DLL entry specified as ""*"" pertains to all DLLs not specified explicitly.\n\nBe careful, wrong settings here have the potential to pretty much kill your setup."
+                    ,  IDC_STATIC,15,17,228,47
+    CONTROL         "DLL Overrides", IDC_TREE_DLLS, "SysTreeView32", WS_TABSTOP | TVS_LINESATROOT | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS, 15,65,142,172
+    LTEXT           "Load order:",IDC_STATIC,163,65,37,8
+    CONTROL         "Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,163,80,57,10
+    CONTROL         "Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,163,95,72,10
+    PUSHBUTTON	    "Add application...",IDC_DLLS_ADDAPP,163,114,82,14
+    PUSHBUTTON	    "Remove application",IDC_DLLS_REMOVEAPP, 163,134,82,14
+    PUSHBUTTON	    "Add DLL override for:",IDC_DLLS_ADDDLL, 163,154,82,14
+    COMBOBOX        IDC_DLLLIST,163,174,82,14,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | CBS_SORT | CBS_LOWERCASE
+    PUSHBUTTON	    "Remove DLL override",IDC_DLLS_REMOVEDLL,163,194,82,14
 END
 
 IDD_SYSTEMCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: programs/winecfg/Es.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Es.rc,v
retrieving revision 1.4
diff -u -r1.4 Es.rc
--- programs/winecfg/Es.rc	26 Nov 2003 03:55:01 -0000	1.4
+++ programs/winecfg/Es.rc	4 Jan 2004 18:20:37 -0000
@@ -84,15 +84,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    GROUPBOX        "Estático",IDC_STATIC,8,4,244,157
-    CONTROL         "Integrado (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,59,144,57,10
-    CONTROL         "Nativo (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,121,144,72,10
-    LTEXT           "Las librerías pueden especificarse individualmente para ser integradas o nativas. Una entrada de DLL especificada como ""*"" se refiere a todas las DLL no especificadas explícitamente.",
-                    IDC_STATIC,15,17,228,27
-    CONTROL         "List3",IDC_LIST_DLLS,"SysListView32",LVS_LIST | 
-                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | 
-                    WS_TABSTOP,15,47,227,90
-    LTEXT           "Orden de carga:",IDC_STATIC,16,144,37,8
 END
 
 IDD_SYSTEMCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: programs/winecfg/Makefile.in
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Makefile.in,v
retrieving revision 1.6
diff -u -r1.6 Makefile.in
--- programs/winecfg/Makefile.in	3 Oct 2003 05:01:33 -0000	1.6
+++ programs/winecfg/Makefile.in	4 Jan 2004 18:20:37 -0000
@@ -4,7 +4,7 @@
 VPATH     = @srcdir@
 MODULE    = winecfg.exe
 APPMODE   = gui
-IMPORTS   = comctl32 user32 advapi32
+IMPORTS   = comctl32 user32 advapi32 comdlg32
 
 C_SRCS = \
 	appdefaults.c \
@@ -12,7 +12,8 @@
 	main.c \
 	properties.c \
 	winecfg.c \
-	x11drvdlg.c
+	x11drvdlg.c \
+	tbsLibraries.c
 
 RC_SRCS = winecfg.rc
 RC_BINSRC = winecfg.rc
Index: programs/winecfg/Pt.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Pt.rc,v
retrieving revision 1.4
diff -u -r1.4 Pt.rc
--- programs/winecfg/Pt.rc	26 Nov 2003 03:55:01 -0000	1.4
+++ programs/winecfg/Pt.rc	4 Jan 2004 18:20:37 -0000
@@ -40,7 +40,6 @@
     GROUPBOX        "Comportamento padrão",IDC_STATIC,8,115,244,97
     LTEXT           "Wine providencia a aplicações Windows, a habilidade de se parecer a várias versões e estilos de Windows",
                     IDC_STATIC,15,128,227,20
-    GROUPBOX        "Informação",IDC_STATIC,8,4,244,106
     CTEXT           "This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.",
                     IDC_STATIC,119,44,124,59
 END
@@ -93,15 +92,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    GROUPBOX        "Estático",IDC_STATIC,8,4,244,157
-    CONTROL         "Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,59,144,57,10
-    CONTROL         "Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,121,144,72,10
-    LTEXT           "Bibliotecas podem ser especificadas individualmente a ser builtin ou native. Uma entrada de DLL especificada como ""*"" define todas as DLLs não especificadas explicitamente.",
-                    IDC_STATIC,15,17,228,27
-    CONTROL         "List3",IDC_LIST_DLLS,"SysListView32",LVS_LIST | 
-                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | 
-                    WS_TABSTOP,15,47,227,90
-    LTEXT           "Ordem de carga:",IDC_STATIC,16,144,37,8
 END
 
 
Index: programs/winecfg/Ru.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Ru.rc,v
retrieving revision 1.2
diff -u -r1.2 Ru.rc
--- programs/winecfg/Ru.rc	26 Nov 2003 03:55:01 -0000	1.2
+++ programs/winecfg/Ru.rc	4 Jan 2004 18:20:39 -0000
@@ -97,15 +97,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    GROUPBOX        "Ñòàòè÷íûå",IDC_STATIC,8,4,244,157
-    CONTROL         "Âñòðîåííàÿ (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,59,144,57,10
-    CONTROL         "Âíåøíÿÿ (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,121,144,72,10
-    LTEXT           "Ìîæíî èíäèâèäóëüíî âûáðàòü èñïîëüçîâàòü âíóòðåííèå èëè âíåøíèå áèáëèîòåêè. Çàïèñü ""*"" äåéñòâóåò íà âñå áèáëèîòåêè íå ïåðå÷èñëåííûå íàïðÿìóþ.",
-                    IDC_STATIC,15,17,228,27
-    CONTROL         "List3",IDC_LIST_DLLS,"SysListView32",LVS_LIST | 
-                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | 
-                    WS_TABSTOP,15,47,227,90
-    LTEXT           "Ïîðÿäîê çàãðóçêè:",IDC_STATIC,16,144,37,8
 END
 
 IDD_SYSTEMCFG DIALOG DISCARDABLE  0, 0, 260, 250
Index: programs/winecfg/Si.rc
===================================================================
RCS file: /home/wine/wine/programs/winecfg/Si.rc,v
retrieving revision 1.3
diff -u -r1.3 Si.rc
--- programs/winecfg/Si.rc	26 Nov 2003 03:55:01 -0000	1.3
+++ programs/winecfg/Si.rc	4 Jan 2004 18:20:39 -0000
@@ -88,15 +88,6 @@
 STYLE WS_CHILD | WS_DISABLED
 FONT 8, "MS Sans Serif"
 BEGIN
-    GROUPBOX        "Static",IDC_STATIC,8,4,244,157
-    CONTROL         "Builtin (Wine)",IDC_RAD_BUILTIN,"Button", BS_AUTORADIOBUTTON | WS_GROUP,59,144,57,10
-    CONTROL         "Native (Windows)",IDC_RAD_NATIVE,"Button", BS_AUTORADIOBUTTON,121,144,72,10
-    LTEXT           "Libraries can be specified individually to be either builtin or native. A DLL entry specified as ""*"" pertains to all DLLs not specified explicitly.",
-                    IDC_STATIC,15,17,228,27
-    CONTROL         "List3",IDC_LIST_DLLS,"SysListView32",LVS_LIST | 
-                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | 
-                    WS_TABSTOP,15,47,227,90
-    LTEXT           "Load order:",IDC_STATIC,16,144,37,8
 END
 
 STRINGTABLE DISCARDABLE 
Index: programs/winecfg/main.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/main.c,v
retrieving revision 1.11
diff -u -r1.11 main.c
--- programs/winecfg/main.c	22 Oct 2003 03:02:26 -0000	1.11
+++ programs/winecfg/main.c	4 Jan 2004 18:20:39 -0000
@@ -177,22 +177,6 @@
     return FALSE;
 }
 
-
-INT_PTR CALLBACK
-DllDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-    switch (uMsg)
-    {
-    case WM_COMMAND:
-	break;
-
-    default:
-	break;
-    }
-    return FALSE;
-}
-
-
 #define NUM_PROPERTY_PAGES 5
 INT_PTR
 doPropertySheet (HINSTANCE hInstance, HWND hOwner)
@@ -235,7 +219,7 @@
     psp[2].hInstance = hInstance;
     psp[2].u.pszTemplate = MAKEINTRESOURCE (IDD_DLLCFG);
     psp[2].u2.pszIcon = NULL;
-    psp[2].pfnDlgProc = DllDlgProc;
+    psp[2].pfnDlgProc = LibrariesDlgProc;
     psp[2].pszTitle = "Libraries";
     psp[2].lParam = 0;
     
Index: programs/winecfg/resource.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/resource.h,v
retrieving revision 1.9
diff -u -r1.9 resource.h
--- programs/winecfg/resource.h	30 Sep 2003 00:27:55 -0000	1.9
+++ programs/winecfg/resource.h	4 Jan 2004 18:20:39 -0000
@@ -54,9 +54,12 @@
 #define IDC_XSHM                        1028
 #define IDC_RAD_BUILTIN                 1029
 #define IDC_RAD_NATIVE                  1030
-#define IDC_LIST_DLLS                   1031
-#define IDC_LIST_BUILTIN_DLLS           1031
-#define IDC_LIST_NATIVE_DLLS            1032
+#define IDC_TREE_DLLS                   1031
+#define IDC_DLLS_ADDAPP                 8000
+#define IDC_DLLS_ADDDLL                 8001
+#define IDC_DLLS_REMOVEAPP              8002
+#define IDC_DLLS_REMOVEDLL              8003
+#define IDC_DLLLIST                     8004
 #define IDC_RADIO_DEFAULT_BUILTIN       1033
 #define IDC_RADIO_DEFAULT_NATIVE        1034
 #define IDC_RADIO_VIRTUAL               1035
Index: programs/winecfg/winecfg.c
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.c,v
retrieving revision 1.17
diff -u -r1.17 winecfg.c
--- programs/winecfg/winecfg.c	24 Oct 2003 04:18:17 -0000	1.17
+++ programs/winecfg/winecfg.c	4 Jan 2004 18:20:39 -0000
@@ -132,7 +132,8 @@
  * const char *value : the value to set the configuration key to
  *
  * Returns 0 on success, non-zero otherwise
- *
+ * 
+ * If *valueName or *value is NULL, an empty section will be created
  */
 int setConfigValue (const char *subkey, const char *valueName, const char *value) {
     DWORD res = 1;
@@ -141,11 +142,10 @@
     WINE_TRACE("subkey=%s, valueName=%s, value=%s\n", subkey, valueName, value);
 
     assert( subkey != NULL );
-    assert( valueName != NULL );
-    assert( value != NULL );
     
     res = RegCreateKey(configKey, subkey, &key);
     if (res != ERROR_SUCCESS) goto end;
+    if (value == NULL || valueName == NULL) goto end;
 
     res = RegSetValueEx(key, valueName, 0, REG_SZ, value, strlen(value) + 1);
     if (res != ERROR_SUCCESS) goto end;
Index: programs/winecfg/winecfg.h
===================================================================
RCS file: /home/wine/wine/programs/winecfg/winecfg.h,v
retrieving revision 1.11
diff -u -r1.11 winecfg.h
--- programs/winecfg/winecfg.h	9 Oct 2003 04:39:01 -0000	1.11
+++ programs/winecfg/winecfg.h	4 Jan 2004 18:20:39 -0000
@@ -109,6 +109,7 @@
 INT_PTR CALLBACK DriveDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 INT_PTR CALLBACK DriveEditDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 INT_PTR CALLBACK AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
 /* some basic utilities to make win32 suck less */
 char *getDialogItemText(HWND hDlg, WORD controlID);
@@ -117,5 +118,4 @@
 
 
 #define WINE_KEY_ROOT "Software\\Wine\\Wine\\Config"
-
 #endif
--- /dev/null	2003-12-26 12:00:33.000000000 +0100
+++ programs/winecfg/tbsLibraries.c	2004-01-04 18:00:39.000000000 +0100
@@ -0,0 +1,505 @@
+/*
+ * WineCfg libraries tabsheet
+ *
+ * Copyright 2004 Robert van Herk
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <windows.h>
+#include <commdlg.h>
+#include <wine/debug.h>
+#include <stdio.h>
+#include "winecfg.h"
+#include "resource.h"
+WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
+
+typedef enum _DLGMODE
+{
+	DLL,
+	APP,
+	GLOBAL,
+} DLGMODE;
+
+typedef enum _DLLMODE {
+	BUILTIN,
+	NATIVE
+} DLLMODE;
+
+typedef struct _DLLOVERRIDE
+{
+	char* lpcKey;    /*The actual dll name*/
+	DLLMODE mode;
+} DLLOVERRIDE, *LPDLLOVERRIDE;
+
+LPDLLOVERRIDE CreateDLLOverride(char* lpcKey)
+{
+	LPDLLOVERRIDE out = HeapAlloc(GetProcessHeap(),0,sizeof(DLLOVERRIDE));
+	out->lpcKey = strdup (lpcKey);
+	return out;
+}
+
+VOID FreeDLLOverride(LPDLLOVERRIDE ldo)
+{
+	if (ldo->lpcKey)
+		free(ldo->lpcKey);
+	HeapFree(GetProcessHeap(),0,ldo);
+}
+
+typedef struct _APPL
+{
+	BOOL isGlobal;
+	char* lpcApplication;
+	char* lpcSection; /*Registry section*/
+} APPL, *LPAPPL;
+
+LPAPPL CreateAppl(BOOL isGlobal, char* application, char* section)
+{
+	LPAPPL out;
+	out = HeapAlloc(GetProcessHeap(),0,sizeof(APPL));
+	out->lpcApplication = strdup(application);
+	out->lpcSection = strdup(section);
+	out->isGlobal = isGlobal;
+	return out;
+}
+
+VOID FreeAppl(LPAPPL lpAppl)
+{
+	if (lpAppl->lpcApplication)
+		free(lpAppl->lpcApplication); /* The strings were strdup-ped, so we use "free" */
+	if (lpAppl->lpcSection)
+		free(lpAppl->lpcSection);
+	HeapFree(GetProcessHeap(),0,lpAppl);
+}
+
+typedef struct _ITEMTAG
+{
+	LPAPPL lpAppl;
+	LPDLLOVERRIDE lpDo;
+} ITEMTAG, *LPITEMTAG;
+
+LPITEMTAG CreateItemTag()
+{
+	LPITEMTAG out;
+	out = HeapAlloc(GetProcessHeap(),0,sizeof(ITEMTAG));
+	out->lpAppl = 0;
+	out->lpDo = 0;
+	return out;
+}
+
+VOID FreeItemTag(LPITEMTAG lpit)
+{
+	if (lpit->lpAppl)
+		FreeAppl(lpit->lpAppl);
+	if (lpit->lpDo)
+		FreeDLLOverride(lpit->lpDo);
+	HeapFree(GetProcessHeap(),0,lpit);
+}
+
+VOID UpdateDLLList(HWND hDlg, char* dll)
+{
+	/*Add if it isn't already in*/
+	if (SendDlgItemMessage(hDlg, IDC_DLLLIST, CB_FINDSTRING, 1, (LPARAM) dll) == CB_ERR)
+		SendDlgItemMessage(hDlg,IDC_DLLLIST,CB_ADDSTRING,0,(LPARAM) dll);
+}
+
+VOID LoadLibrarySettings(LPAPPL appl /*DON'T FREE, treeview will own this*/, HWND hDlg, HWND hwndTV)
+{
+	HKEY key;
+	int i;
+	DWORD size;
+	DWORD readSize;
+	char name [255];
+	char read [255];
+	LPITEMTAG lpIt;
+	TVINSERTSTRUCT tis;	
+	HTREEITEM hParent;
+	LPDLLOVERRIDE lpdo;
+	
+	WINE_TRACE("opening %s\n", appl->lpcSection);
+	if (RegOpenKey (configKey, appl->lpcSection, &key) == ERROR_SUCCESS)
+	{
+		i = 0;
+		size = 255;
+		readSize = 255;
+		
+		lpIt = CreateItemTag();
+		lpIt->lpAppl = appl;
+
+		tis.hParent = NULL;
+		tis.hInsertAfter = TVI_LAST;
+		tis.item.mask = TVIF_TEXT | TVIF_PARAM;
+		tis.item.pszText = appl->lpcApplication;
+		tis.item.lParam = (LPARAM)lpIt;
+		hParent = TreeView_InsertItem(hwndTV,&tis);
+		tis.hParent = hParent;
+
+		while (RegEnumValue(key, i, name, &size, NULL, NULL, read, &readSize) == ERROR_SUCCESS)
+		{                           
+			WINE_TRACE("Reading value %s, namely %s\n", name, read);
+			
+			lpIt = CreateItemTag();
+			lpdo = CreateDLLOverride(name);
+			lpIt->lpDo = lpdo;
+			tis.item.lParam = (LPARAM)lpIt;
+			tis.item.pszText = name;
+			if (strncmp (read, "built", 5) == 0)
+				lpdo->mode = BUILTIN;
+			else
+				lpdo->mode = NATIVE;
+
+			TreeView_InsertItem(hwndTV,&tis);
+			UpdateDLLList(hDlg, name);
+			i ++; size = 255; readSize = 255;
+		}
+		RegCloseKey(key);
+	}
+}
+
+VOID SetEnabledDLLControls(HWND dialog, DLGMODE dlgmode)
+{
+	if (dlgmode == DLL) {
+		enable(IDC_RAD_BUILTIN);
+		enable(IDC_RAD_NATIVE);
+		enable(IDC_DLLS_REMOVEDLL);
+	} else {
+		disable(IDC_RAD_BUILTIN);
+		disable(IDC_RAD_NATIVE);
+		disable(IDC_DLLS_REMOVEDLL);
+	}
+
+	if (dlgmode == APP) {
+		enable(IDC_DLLS_REMOVEAPP);
+	}
+	else {
+		disable(IDC_DLLS_REMOVEAPP);
+	}
+}
+
+VOID OnInitLibrariesDlg(HWND hDlg)
+{
+	HWND hwndTV;
+	LPAPPL lpAppl;
+	HKEY applKey;
+	int i;
+	DWORD size;
+	char appl [255];
+	char lpcKey [255];
+	FILETIME ft;
+
+	hwndTV = GetDlgItem(hDlg,IDC_TREE_DLLS);
+	lpAppl = CreateAppl(TRUE,"Global DLL Overrides", "DllOverrides");
+	LoadLibrarySettings(lpAppl, hDlg, hwndTV);
+	
+	/*And now the application specific stuff:*/
+	if (RegOpenKey(configKey, "AppDefaults", &applKey) == ERROR_SUCCESS) {
+		i = 0;
+		size = 255;
+		while (RegEnumKeyEx(applKey, i, appl, &size, NULL, NULL, NULL, &ft) == ERROR_SUCCESS)
+		{
+			sprintf(lpcKey, "AppDefaults\\%s\\DllOverrides", appl);
+			lpAppl = CreateAppl(FALSE,appl, lpcKey);
+			LoadLibrarySettings(lpAppl, hDlg, hwndTV);
+			i++; size = 255;
+		}
+		RegCloseKey(applKey);
+	}
+
+	SetEnabledDLLControls(hDlg, GLOBAL);
+}
+
+VOID OnTreeViewChangeItem(HWND hDlg, HWND hTV)
+{
+	TVITEM ti;
+	LPITEMTAG lpit;
+
+	ti.mask = TVIF_PARAM;
+	ti.hItem = TreeView_GetSelection(hTV);
+	if (TreeView_GetItem (hTV, &ti))
+	{
+		lpit = (LPITEMTAG) ti.lParam;
+		if (lpit->lpDo)
+		{
+			WINE_TRACE("%s\n", lpit->lpDo->lpcKey);
+			if (lpit->lpDo->mode == BUILTIN) {
+				CheckRadioButton(hDlg, IDC_RAD_BUILTIN, IDC_RAD_NATIVE, IDC_RAD_BUILTIN);
+			} else {
+				CheckRadioButton(hDlg, IDC_RAD_BUILTIN, IDC_RAD_NATIVE, IDC_RAD_NATIVE);
+			}
+			SetEnabledDLLControls(hDlg, DLL);
+		} else {
+			if (lpit->lpAppl)
+			{
+				if (lpit->lpAppl->isGlobal == TRUE)
+					SetEnabledDLLControls(hDlg, GLOBAL);
+				else
+					SetEnabledDLLControls(hDlg, APP);
+			}
+		}
+	}
+}
+
+VOID SetDLLMode(HWND hDlg, DLLMODE mode);
+VOID OnBuiltinClick(HWND hDlg)
+{
+	SetDLLMode(hDlg, BUILTIN);
+}
+VOID OnNativeClick(HWND hDlg)
+{
+	SetDLLMode(hDlg, NATIVE);
+}
+VOID SetDLLMode(HWND hDlg, DLLMODE mode)
+{
+	HWND hTV;
+	TVITEM ti;
+	LPITEMTAG lpit;
+	char* cMode;
+	TVITEM tiPar;
+	LPITEMTAG lpitPar;
+
+	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
+	ti.mask = TVIF_PARAM;
+	ti.hItem = TreeView_GetSelection(hTV);
+	if (TreeView_GetItem (hTV, &ti))
+	{
+		lpit = (LPITEMTAG) ti.lParam;
+		if (lpit->lpDo)
+		{
+			lpit->lpDo->mode = mode;
+			if (mode == NATIVE)
+				cMode = "native, builtin";
+			else
+				cMode = "builtin, native";
+
+			/*Find parent, so we can read registry section*/
+			tiPar.mask = TVIF_PARAM;
+			tiPar.hItem = TreeView_GetParent(hTV, ti.hItem);
+			if (TreeView_GetItem(hTV,&tiPar))
+			{
+				lpitPar = (LPITEMTAG) tiPar.lParam;
+				if (lpitPar->lpAppl)
+				{
+					addTransaction(lpitPar->lpAppl->lpcSection, lpit->lpDo->lpcKey, ACTION_SET, cMode);
+				}
+			}
+		}
+	}
+}
+
+VOID OnTreeViewDeleteItem(NMTREEVIEW* nmt)
+{
+	FreeItemTag((LPITEMTAG)(nmt->itemOld.lParam));
+}
+
+VOID OnAddDLLClick(HWND hDlg)
+{
+	HWND hTV;
+	TVITEM ti;
+	LPITEMTAG lpit;
+	LPITEMTAG lpitNew;
+	TVITEM childti;
+	char dll [255];
+	BOOL doAdd;
+	TVINSERTSTRUCT tis;
+
+	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
+	ti.mask = TVIF_PARAM;
+	ti.hItem = TreeView_GetSelection(hTV);
+	if (TreeView_GetItem (hTV, &ti))
+	{
+		lpit = (LPITEMTAG) ti.lParam;
+		if (lpit->lpDo) { /*Is this a DLL override (that is: a subitem), then find the parent*/
+			ti.hItem = TreeView_GetParent(hTV, ti.hItem);
+			if (TreeView_GetItem(hTV,&ti)) {
+				lpit = (LPITEMTAG) ti.lParam;
+			} else return;
+		}
+	} else return;
+	/*Now we should have an parent item*/
+	if (lpit->lpAppl)
+	{
+		lpitNew = CreateItemTag();
+		SendDlgItemMessage(hDlg,IDC_DLLLIST,WM_GETTEXT,(WPARAM)255, (LPARAM) dll);
+		if (strlen(dll) > 0) {
+			/*Is the dll already in the list? If so, don't do it*/
+			doAdd = TRUE;
+			childti.mask = TVIF_PARAM;
+			if ((childti.hItem = TreeView_GetNextItem(hTV, ti.hItem, TVGN_CHILD))) {
+				/*Retrieved first child*/
+				while (TreeView_GetItem (hTV, &childti))
+				{
+					if (strcmp(((LPITEMTAG)childti.lParam)->lpDo->lpcKey,dll) == 0) {
+						doAdd = FALSE;
+						break;
+					}
+					childti.hItem = TreeView_GetNextItem(hTV, childti.hItem, TVGN_NEXT);
+				}
+			}
+			if (doAdd)
+			{
+				lpitNew->lpDo = CreateDLLOverride(dll);
+				lpitNew->lpDo->mode = NATIVE;
+				tis.hInsertAfter = TVI_LAST;
+				tis.item.mask = TVIF_TEXT | TVIF_PARAM;
+				tis.item.pszText = dll;
+				tis.item.lParam = (LPARAM)lpitNew;
+				tis.hParent = ti.hItem;
+				TreeView_InsertItem(hTV,&tis);
+				UpdateDLLList(hDlg, dll);
+				addTransaction(lpit->lpAppl->lpcSection, dll, ACTION_SET, "native, builtin");
+			} else MessageBox(hDlg, "A DLL with that name is already in this list...", "", MB_OK | MB_ICONINFORMATION);
+		}
+	} else return;
+}
+
+VOID OnRemoveDLLClick(HWND hDlg)
+{
+	HWND hTV;
+	TVITEM ti;
+	LPITEMTAG lpit;
+	TVITEM tiPar;
+	LPITEMTAG lpitPar;
+
+	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
+	ti.mask = TVIF_PARAM;
+	ti.hItem = TreeView_GetSelection(hTV);
+	if (TreeView_GetItem (hTV, &ti)) {
+		lpit = (LPITEMTAG) ti.lParam;
+		if (lpit->lpDo)
+		{
+			/*Find parent for section*/
+			tiPar.mask = TVIF_PARAM;
+			tiPar.hItem = TreeView_GetParent(hTV, ti.hItem);
+			if (TreeView_GetItem(hTV,&tiPar))
+			{
+				lpitPar = (LPITEMTAG) tiPar.lParam;
+				if (lpitPar->lpAppl)
+				{
+					addTransaction(lpitPar->lpAppl->lpcSection, lpit->lpDo->lpcKey, ACTION_REMOVE, NULL);
+					TreeView_DeleteItem(hTV,ti.hItem);
+				}
+			}
+		}
+	}
+}
+
+VOID OnAddApplicationClick(HWND hDlg)
+{
+	char szFileTitle [255];
+	char szFile [255];
+	char lpcKey [255];
+
+	TVINSERTSTRUCT tis;
+	LPITEMTAG lpit;
+	OPENFILENAME ofn = { sizeof(OPENFILENAME),
+		0, /*hInst*/0, "Wine Programs (*.exe,*.exe.so)\0*.exe;*.exe.so\0", NULL, 0, 0, NULL,
+		0, NULL, 0, NULL, NULL,
+		OFN_SHOWHELP, 0, 0, NULL, 0, NULL };
+
+	ofn.lpstrFileTitle = szFileTitle;
+	ofn.lpstrFileTitle[0] = '\0';
+	ofn.nMaxFileTitle = sizeof(szFileTitle);
+	ofn.lpstrFile = szFile;
+	ofn.lpstrFile[0] = '\0';
+	ofn.nMaxFile = sizeof(szFile);
+
+	if (GetOpenFileName(&ofn))
+	{
+		tis.hParent = NULL;
+		tis.hInsertAfter = TVI_LAST;
+		tis.item.mask = TVIF_TEXT | TVIF_PARAM;
+		tis.item.pszText = szFileTitle;
+		lpit = CreateItemTag();
+		sprintf(lpcKey, "AppDefaults\\%s\\DllOverrides", szFileTitle);
+		lpit->lpAppl = CreateAppl(FALSE,szFileTitle,lpcKey);
+		tis.item.lParam = (LPARAM)lpit;
+		TreeView_InsertItem(GetDlgItem(hDlg,IDC_TREE_DLLS), &tis);
+		setConfigValue(lpcKey,NULL,NULL);
+	}
+}
+
+VOID OnRemoveApplicationClick(HWND hDlg)
+{
+	HWND hTV;
+	TVITEM ti;
+	LPITEMTAG lpit;
+
+	hTV = GetDlgItem(hDlg, IDC_TREE_DLLS);
+	ti.mask = TVIF_PARAM;
+	ti.hItem = TreeView_GetSelection(hTV);
+	if (TreeView_GetItem (hTV, &ti)) {
+		lpit = (LPITEMTAG) ti.lParam;
+		if (lpit->lpAppl)
+		{
+			addTransaction(lpit->lpAppl->lpcSection, NULL, ACTION_REMOVE, NULL);
+			TreeView_DeleteItem(hTV,ti.hItem);
+		}
+	}
+}
+
+INT_PTR CALLBACK
+LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	switch (uMsg)
+	{
+	case WM_INITDIALOG:
+		OnInitLibrariesDlg(hDlg);
+		break;  
+	case WM_NOTIFY:
+		switch (((LPNMHDR)lParam)->code) {
+		case TVN_SELCHANGED: {
+				switch(LOWORD(wParam)) {
+				case IDC_TREE_DLLS:
+					OnTreeViewChangeItem(hDlg, GetDlgItem(hDlg,IDC_TREE_DLLS));
+					break;
+				}
+			}
+			break;
+		case TVN_DELETEITEM:
+			OnTreeViewDeleteItem ((LPNMTREEVIEW)lParam);
+			break;
+		}
+		break;
+	case WM_COMMAND:
+		switch(HIWORD(wParam)) {
+		case BN_CLICKED:
+			switch(LOWORD(wParam)) {
+			case IDC_RAD_BUILTIN:
+				OnBuiltinClick(hDlg);
+				break;
+			case IDC_RAD_NATIVE:
+				OnNativeClick(hDlg);
+				break;
+			case IDC_DLLS_ADDAPP:
+				OnAddApplicationClick(hDlg);
+				break;
+			case IDC_DLLS_REMOVEAPP:
+				OnRemoveApplicationClick(hDlg);
+				break;
+			case IDC_DLLS_ADDDLL:
+				OnAddDLLClick(hDlg);
+				break;
+			case IDC_DLLS_REMOVEDLL:
+				OnRemoveDLLClick(hDlg);
+				break;
+			}
+			break;
+		}
+		break;
+	}
+
+	return 0;
+}


More information about the wine-patches mailing list