Re: New uninstaller #1/3

2005-03-10 Thread Mike McCormack
Jonathan Ernst wrote:
Here is the new uninstaller.
This is the first patch out of 3 of the new installer.
Thanks to Dmitry Timoshkov for helping me a lot with my first win32 program.
Changelog:
- use dialog instead of window
Hey Jonathan,
Your patch is still quite big.  You've rewritten every function in 
uninstaller.c, as far as I can tell.  Is there any reason you need to do 
that to convert to using a dialog?

I think you may need to break it up even further to get it applied, but 
the final decision isn't mine.  I'd encourage you to write a patch that 
only converts the window to a dialog, and get that applied first.  When 
that is done, you can think about unicode conversion.

Mike


Re: New uninstaller #1/3 (RESEND)

2005-03-10 Thread Alexandre Julliard
Jonathan Ernst [EMAIL PROTECTED] writes:


 +#include resource.h
 +#include En.rc

The new resource.h file is missing.

 -/* BINRES uninstaller.ico */
 -UNINSTALLER ICON MOVEABLE uninstaller.ico
 -/* {
 - '00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02'
 - '00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
 - '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'

You can't remove the icon data, this is needed for the BINRES stuff.

-- 
Alexandre Julliard
[EMAIL PROTECTED]



Re: New uninstaller

2005-03-08 Thread Jonathan Ernst
Le jeudi 03 mars 2005  21:51 +0900, Mike McCormack a crit :
 Hi Jonathan,
 
 You'll have more success getting this applied if you send each step as a 
 seperate patch.  I suggest starting by sending a single patch that 
 converts the uninstaller to use a dialog instead of a window, adds a 
 dialog resource in English and does nothing else.

Ok, once everything works I'll try to split it up as much as I can.

 
 Once that patch is accepted, move onto the other tasks you have listed 
 above.  One step at a time makes the patch easier to review, and reduces 
 the chance that a single line mistake will stop your entire patch from 
 going in.
 
 Additionally, there's no need to change the name of main.c to 
 uninstaller.c, that will just make it harder to see what has changed 
 between versions.

I thought it would be more homogeneous as taskmanager, winecfg where
using program_name.c files and that most of this file was rewritten by
the way. But I renamed it back in my latest test patch.
 

Thanks for your comments !


signature.asc
Description: Ceci est une partie de message	=?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=


Re: New uninstaller

2005-03-08 Thread Mike McCormack
Jonathan Ernst wrote:
Additionally, there's no need to change the name of main.c to 
uninstaller.c, that will just make it harder to see what has changed 
between versions.

I thought it would be more homogeneous as taskmanager, winecfg where
using program_name.c files and that most of this file was rewritten by
the way. But I renamed it back in my latest test patch.
It would look nicer if it was called uninstaller.c, but renaming files 
in CVS should be avoided as much as possible.  It makes patch management 
(doing diffs and reverting patches) difficult.

Mike


Re: New uninstaller

2005-03-08 Thread Dmitry Timoshkov
Jonathan Ernst [EMAIL PROTECTED] wrote:

 I tried to fix every char-WCHAR I though was worth it; please have a
 second look at it.
 
 The problem now with unicode is that when I try to strstr my token with
 the element of the list (entries[i].descr) it works only with the first
 letter (before to use unicode it was working very well).
 You can see the same problem (one letter .descr) when using the
 unintaller with --list.
 
 The second problem is that since I use unicode for the argvs, whatever
 argv I give I get the --list branch.

Your main mistake is that you are trying to handle ASCII strings with old
APIs, you can't do that. Unicode requires a completely different set of APIs,
and win32 provides one.

 +/*
 +TELL ME: IS IT STILL NEEDED WITH UNICODE ???
  len = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, NULL, 
 0, NULL, NULL); 

As I have said it already, you need to convert unicode strings to the encoding
of the underlying system before printing strings on console. CP_UNIXCP is 
supposed
to do exactly that task.

 +descr = HeapAlloc(GetProcessHeap(), 0, len);
 +WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, len, 
 NULL, NULL); */
 +printf(%s|||%s\n, entries[i].key, entries[i].descr);
 +/*HeapFree(GetProcessHeap(), 0, descr);*/

You have to HeapFree a HeapAlloc'ed memory block.

It's better to use W versions of APIs even if it's not strictly required.

 +if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, 0, 
 KEY_READ, hkeyUninst) != ERROR_SUCCESS)

RegOpenKeyExW in this case.

  {
 - MessageBox(0, Uninstall registry key not available (yet), nothing to do 
 !, appname, MB_OK);
 - return 0;
 +MessageBox(0, sRegistryKeyNotAvailable, sAppName, MB_OK);

MessageBoxW in this case.

  if (!entries)
 - entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));
 +entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));

Quite strange formatting.

  strcpy(key_app, REGSTR_PATH_UNINSTALL);
  strcat(key_app, \\);
  p = key_app+strlen(REGSTR_PATH_UNINSTALL)+1;

You shouldn't use string APIs supposed to handle ASCII strings. Use 
lstrcpyW,lstrcatW
and lstrlenW in this and all other cases.
 
 sizeOfSubKeyName = 255;
-for ( i=0;
-   RegEnumKeyExA( hkeyUninst, i, subKeyName, sizeOfSubKeyName,
-  NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS;
-   ++i )
+for (i=0; RegEnumKeyExA( hkeyUninst, i, subKeyName, sizeOfSubKeyName, 
NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i)

RegEnumKeyExW in this case.

 +static const WCHAR DisplayNameW[] = 
 {'D','i','s','p','l','a','y','N','a','m','e',0};
 +strcpy(p, subKeyName);

lstrcpyW

 +RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, hkeyApp);

RegOpenKeyExW

 +res = CreateProcess(NULL, entries[i].command, NULL, NULL, FALSE, 0, 
 NULL, NULL, si, info);

CreateProcessW

 +prevsel = SendMessage(hList, LB_GETCURSEL, 0, 0);

SendMessageW

and many,many,many others. Make sure to pass correct arguments to all the 
changed APIs.

For better understanding of what is going on add the following as the very first
line in main.c:

#define __WINESRC__

-- 
Dmitry.




Re: New uninstaller

2005-03-08 Thread Dmitry Timoshkov
Jonathan Ernst [EMAIL PROTECTED] wrote:

 I fixed/changed many things regarding unicode. It seems that now both
 outputing to the console and case insensitive find as you type feature
 (re-)work.
 
 I fixed most warnings, but there are still 4 lines that I couldn't fix
 (173,

cast entries[numentries-1].command to LPBYTE as you do 3 lines earlier.

 206,

wrong STARTUPINFO declaration, you need a unicode one with W suffix.

 215,

you can't use sprintf to print to a WCHAR string, use win32 API wsprintfW
instead.

 429). Can someone help me ?

  slen  = strlenW(String),
  plen  = strlenW(Pattern);

better use official API lstrlenW.

 /* find start of pattern in string */
 while (toupper(*start) != toupper(*Pattern))

You can't use toupper with unicode strings. I can't suggest a win32 equivalent
from the top of my head, you need to find out.

 pptr = (WCHAR *)Pattern;

There is no need for a cast here.

 
 while (toupper(*sptr) == toupper(*pptr))

same as above.

 Last but not least, since these changes the uninstaller crashes (very)
 often. I have an unhandled exception when retrieving some apps from the
 uninstall key and I don't know what cause this:
 
 err:seh:EXC_DefaultHandling Unhandled exception code c005 flags 0
 addr 0x77ecf5d4

Very likely a common error happening often in the process of unicodification:
buffer overflow due to not a correct memory allocation, or a not correct
initialization of a variable pointing to a buffer length (size of buffer in
bytes vs. WCHARs).

  For better understanding of what is going on add the following as the
  very first line in main.c:
  
  #define __WINESRC__
  
 
 When adding this line the compilation fails with this message:
 
 main.c:194: error: `STARTUPINFO' undeclared (first use in this function)
 
 Are some include(s) missing  ?

That's the point. I'd prefer that you could figure out that on your own.
Hint: look at the headers, and you will see that all those STARTUPINFO,
lstrcpy, RegOpenKey are not the real API names, but just macros depending
whether UNICODE is defined or not. In Wine using API macros is deprecated,
personally I'd prefer to not use them in programs/* either.

 Do you think I'm near the target ?

Definitely very close.

-- 
Dmitry.




Re: New uninstaller

2005-03-08 Thread Jonathan Ernst
Le mardi 08 mars 2005  23:29 +0800, Dmitry Timoshkov a crit :
 Jonathan Ernst [EMAIL PROTECTED] wrote:
 
 [...]

Thanks, fixed.

 You can't use toupper with unicode strings. I can't suggest a win32 equivalent
 from the top of my head, you need to find out.

It seems that CharUpperW works well.

[...]

  Last but not least, since these changes the uninstaller crashes (very)
  often. I have an unhandled exception when retrieving some apps from the
  uninstall key and I don't know what cause this:
  
  err:seh:EXC_DefaultHandling Unhandled exception code c005 flags 0
  addr 0x77ecf5d4
 
 Very likely a common error happening often in the process of unicodification:
 buffer overflow due to not a correct memory allocation, or a not correct
 initialization of a variable pointing to a buffer length (size of buffer in
 bytes vs. WCHARs).

Thanks for the hint. I found the allocation problem.

[...]

Fixed

Now everything works; thanks for your step by step help; I hope that
what I'me learning now will let me make more additions to Wine !

But: 

It is even possible to uninstall more than one app at a time, but I wish
that when an uninstaller has finished to uninstall an application the
list is updated, but it's not. What's and where's a clean way to do it ?

Please find attached main.c's diff.

Jonathan

P.S. Do I really have to split this new uninstaller in different patches
as nearly everything changed ?
Index: main.c
===
RCS file: /home/wine/wine/programs/uninstaller/main.c,v
retrieving revision 1.19
diff -u -r1.19 main.c
--- main.c	9 Dec 2004 14:07:59 -	1.19
+++ main.c	8 Mar 2005 16:40:50 -
@@ -1,8 +1,9 @@
 /*
- * QD Uninstaller (main.c)
+ * Uninstaller
  *
  * Copyright 2000 Andreas Mohr [EMAIL PROTECTED]
  * Copyright 2004 Hannu Valtonen [EMAIL PROTECTED]
+ * Copyright 2005 Jonathan Ernst [EMAIL PROTECTED]
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,104 +19,94 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * ToDo:
- * - add search box for locating entries quickly
  */
 
-
 #include stdlib.h
 #include stdio.h
 #include string.h
-#include time.h
-#include windows.h
-#include main.h
+#include windows.h
+#include resource.h 
 #include regstr.h
+#include wine/unicode.h
 #include wine/debug.h
 
-WINE_DEFAULT_DEBUG_CHANNEL(uninstaller);
-
-/* Work around a Wine bug which defines handles as UINT rather than LPVOID */
-#ifdef WINE_STRICT
-#define NULL_HANDLE NULL
-#else
-#define NULL_HANDLE 0
-#endif
-
-/* use multi-select listbox */
-#undef USE_MULTIPLESEL
-
-/* Delete uninstall registry key after execution.
- * This is probably a bad idea, because it's the
- * uninstall program that is supposed to do that.
- */
-#undef DEL_REG_KEY
-
-char appname[18];
 
-static char about_string[] =
-Wine Application Uninstaller (C) 2004 by Andreas Mohr [EMAIL PROTECTED] and Hannu Valtonen [EMAIL PROTECTED];
-static char program_description[] =
-	Please select the application you wish to uninstall:;
+WINE_DEFAULT_DEBUG_CHANNEL(uninstaller);
 
 typedef struct {
-char *key;
+WCHAR *key;
 WCHAR *descr;
-char *command;
+WCHAR *command;
 int active;
 } uninst_entry;
+static uninst_entry *entries = NULL;
+static unsigned int numentries = 0;
+static int list_need_update = 1;
+static int oldsel = -1;
+static WCHAR *sFilter;
+static WCHAR sAppName[MAX_STRING_LEN];
+static WCHAR sAboutTitle[MAX_STRING_LEN];
+static WCHAR sAbout[MAX_STRING_LEN];
+static WCHAR sRegistryKeyNotAvailable[MAX_STRING_LEN];
+static WCHAR sUninstallFailed[MAX_STRING_LEN];
+
+static int FetchUninstallInformation(void);
+static void UninstallProgram(void);
+static void UpdateList(HWND hList);
+static int cmp_by_name(const void *a, const void *b);
+static WCHAR *stristr(const WCHAR *String, const WCHAR *Pattern);
+
+
+static const WCHAR BackSlashW[] = { '\\', 0 };
+static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
+static const WCHAR PathUninistallW[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'U','n','i','n','s','t','a','l','l',0 };
+static const WCHAR UninstallCommandlineW[] = {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0};
 
-uninst_entry *entries = NULL;
-
-unsigned int numentries = 0;
-int list_need_update = 1;
-int oldsel = -1;
-
-struct {
-DWORD style;
-LPCSTR text;
-HWND hwnd;
-} button[] =
-{
-{ BS_PUSHBUTTON, Add/Remove, 0 },
-{ BS_PUSHBUTTON, About, 0 },
-{ BS_PUSHBUTTON, Exit, 0 }
-};
-
-#define NUM (sizeof(button)/sizeof(button[0]))
-
-int FetchUninstallInformation(void);
-void UninstallProgram(void

Re: New uninstaller

2005-03-08 Thread Dmitry Timoshkov
Jonathan Ernst [EMAIL PROTECTED] wrote:

 Thanks for the hint. I found the allocation problem.

Here is another one:

 +int len = GetWindowTextLengthW(GetDlgItem(hwnd, 
 IDC_FILTER));
 +if(len  0)
 +{
 +sFilter = (WCHAR*)GlobalAlloc(GPTR, len + 1);
 +GetDlgItemTextW(hwnd, IDC_FILTER, sFilter, len + 
 1);

And this one:

 +/* Load MessageBox's strings */
 +LoadStringW(hInst, IDS_APPNAME, sAppName, sizeof(sAppName));
 +LoadStringW(hInst, IDS_ABOUTTITLE, sAboutTitle, sizeof(sAboutTitle));
 +LoadStringW(hInst, IDS_ABOUT, sAbout, sizeof(sAbout));
 +LoadStringW(hInst, IDS_REGISTRYKEYNOTAVAILABLE, 
 sRegistryKeyNotAvailable, sizeof(sRegistryKeyNotAvailable));
 +LoadStringW(hInst, IDS_UNINSTALLFAILED, sUninstallFailed, 
 sizeof(sUninstallFailed));

LoadStringW takes number of WCHARs, not bytes.

Everything else seems to be good enough.

 P.S. Do I really have to split this new uninstaller in different patches
 as nearly everything changed ?

It's up to Alexandre to decide, just send your work to wine-patches.

-- 
Dmitry.





Re: New uninstaller

2005-03-08 Thread Mike McCormack

P.S. Do I really have to split this new uninstaller in different patches
as nearly everything changed ?

It's up to Alexandre to decide, just send your work to wine-patches.
I would suggest that you do split it into seperate patches.  If one of 
your patches causes a regression, it's easier to find the regression if 
the changes are small.  Secondly, it's easier to review and verify small 
patches.  Thirdly, since small patches are easier to check, they're 
easier to get accepted.

How about creating three seperate patches that:
1. Change to use a dialog
2. Change to use unicode
3. internationalize the code
This seems slower, but it will actually be faster, since you'll only 
need to perfect one patch at a time.

Mike


Re: New uninstaller

2005-03-03 Thread Mike McCormack
Jonathan Ernst wrote:
Here is the new uninstaller.
I'll be away all this week so I send it already as it works well here
(no regressions found) and has already some more features than the
current one (so Iguess it can be safely committed, but I might be wrong
of course).
With some help I'll be able to improve it (more unicodification, etc.)
when I'll come back.
Changelog:
- new uninstaller
- find as you type search
- use dialog instead of window
- internationalization
- more unicodification
- if the uninstaller cannot be found the user can choose to remove the
entry from the registry 
Hi Jonathan,
You'll have more success getting this applied if you send each step as a 
seperate patch.  I suggest starting by sending a single patch that 
converts the uninstaller to use a dialog instead of a window, adds a 
dialog resource in English and does nothing else.

Once that patch is accepted, move onto the other tasks you have listed 
above.  One step at a time makes the patch easier to review, and reduces 
the chance that a single line mistake will stop your entire patch from 
going in.

Additionally, there's no need to change the name of main.c to 
uninstaller.c, that will just make it harder to see what has changed 
between versions.

Mike


Re: New uninstaller

2005-02-27 Thread Dmitry Timoshkov
Jonathan Ernst [EMAIL PROTECTED] wrote:

  It's better to avoid using string tables, since now you have converted
  code to use dialog box instead.
 
 How can I do it for messageboxes ? Is there a way to define them in the
 resource files or do I have to make a dialog instead of messageboxes ?

Yes, one of the possibilities to use dialog boxes instead of message boxes.
But if it's inconvenient for you, then using string tables and LoadString
is the only option.

-- 
Dmitry.




Re: New uninstaller

2005-02-27 Thread Jonathan Ernst
Here is a new version.

I'm thinking to send it as is to wine-patches if nobody complains before
tonight (tomorrow I'll be leaving for one week).

Thanks everyone for your help.

Changelog:
- new uninstaller
- find as you type search
- use dialog instead of window
- internationalization
- if the uninstaller cannot be found the user can choose to remove the
entry from the registry
--- /dev/null	2005-02-27 10:25:27.710808616 +0100
+++ uninstaller.c	2005-02-27 11:55:05.0 +0100
@@ -0,0 +1,423 @@
+/*
+ * Uninstaller
+ *
+ * Copyright 2000 Andreas Mohr [EMAIL PROTECTED]
+ * Copyright 2004 Hannu Valtonen [EMAIL PROTECTED]
+ * Copyright 2005 Jonathan Ernst [EMAIL PROTECTED]
+ *
+ * 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 stdlib.h
+#include stdio.h
+#include string.h
+#include windows.h
+#include resource.h 
+#include regstr.h
+#include wine/debug.h
+
+WINE_DEFAULT_DEBUG_CHANNEL(uninstaller);
+
+typedef struct {
+char *key;
+WCHAR *descr;
+char *command;
+int active;
+} uninst_entry;
+uninst_entry *entries = NULL;
+unsigned int numentries = 0;
+int list_need_update = 1;
+int oldsel = -1;
+int FetchUninstallInformation(void);
+char *sFilter;
+WCHAR sAppName[MAX_STRING_LEN];
+WCHAR sAboutTitle[MAX_STRING_LEN];
+WCHAR sAbout[MAX_STRING_LEN];
+WCHAR sRegistryKeyNotAvailable[MAX_STRING_LEN];
+WCHAR sUninstallFailed[MAX_STRING_LEN];
+
+void UninstallProgram(void);
+void UpdateList(HWND hList);
+int cmp_by_name(const void *a, const void *b);
+char *stristr(const char *String, const char *Pattern);
+
+/**
+ * Used to output program list when used with --list
+ */
+void ListUninstallPrograms(void)
+{
+unsigned int i;
+int len;
+char *descr;
+
+if (! FetchUninstallInformation())
+return;
+
+for (i=0; i  numentries; i++)
+{
+len = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, NULL, 0, NULL, NULL); 
+descr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, len, NULL, NULL); 
+printf(%s|||%s\n, entries[i].key, descr);
+HeapFree(GetProcessHeap(), 0, descr);
+}
+}
+
+
+void RemoveSpecificProgram(char *name)
+{
+unsigned int i;
+
+if (! FetchUninstallInformation())
+return;
+
+for (i=0; i  numentries; i++)
+{
+if (strcmp(entries[i].key, name) == 0)
+{
+entries[i].active++;
+break;
+}
+}
+
+if (i  numentries)
+UninstallProgram();
+else
+{
+fprintf(stderr, Error: could not match application [%s]\n, name);
+}
+}
+
+
+/**
+ * Fetch informations from the uninstall key.
+ */
+int FetchUninstallInformation(void)
+{
+HKEY hkeyUninst, hkeyApp;
+int i;
+DWORD sizeOfSubKeyName, displen, uninstlen;
+char subKeyName[256];
+char key_app[1024];
+char *p;
+
+numentries = 0;
+oldsel = -1;
+if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL,
+			0, KEY_READ, hkeyUninst) != ERROR_SUCCESS )
+{
+	MessageBox(0, sRegistryKeyNotAvailable, sAppName, MB_OK);
+	return 0;
+}
+
+if (!entries)
+	entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));
+
+strcpy(key_app, REGSTR_PATH_UNINSTALL);
+strcat(key_app, \\);
+p = key_app+strlen(REGSTR_PATH_UNINSTALL)+1;
+
+sizeOfSubKeyName = 255;
+for ( i=0;
+	  RegEnumKeyExA( hkeyUninst, i, subKeyName, sizeOfSubKeyName,
+		  	 NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS;
+	  ++i )
+{
+	static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
+
+	strcpy(p, subKeyName);
+	RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, hkeyApp);
+
+	if ( (RegQueryValueExW(hkeyApp, DisplayNameW,
+		0, 0, NULL, displen) == ERROR_SUCCESS)
+	   (RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE,
+		0, 0, NULL, uninstlen) == ERROR_SUCCESS) )
+	{
+	numentries++;
+	entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry));
+	entries[numentries-1].key =
+		HeapAlloc(GetProcessHeap(), 0, strlen(subKeyName)+1);
+	strcpy(entries[numentries-1].key, subKeyName);
+	entries[numentries-1].descr =
+		HeapAlloc(GetProcessHeap(), 0, displen);
+	RegQueryValueExW

Re: New uninstaller

2005-02-27 Thread Dmitry Timoshkov
Jonathan Ernst [EMAIL PROTECTED] wrote:

 With some help I'll be able to improve it (more unicodification, etc.)
 when I'll come back.

You can't really convert to unicode partially, you have to do it in one go.
That not only will simplify things a lot, but also will save you a lot of time.

 +for (i=0; i  numentries; i++)
 +{
 +len = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, NULL, 
 0, NULL, NULL); 
 +descr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
 +WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, len, 
 NULL, NULL); 
 +printf(%s|||%s\n, entries[i].key, descr);

There is no need to allocate len * sizeof(WCHAR) bytes, len works just fine.

 +int wmain(int argc, char *argv[])

wmain takes 'WCHAR *argv[]' list.

All remaining problems are caused by the fact that now argv[] array
is passed in unicode but you still handle argv[] strings as ASCII and
pass them around to internal functions which accept 'char *' not 'WCHAR *'
strings.

-- 
Dmitry.




Re: New uninstaller

2005-02-26 Thread Jonathan Ernst
Le samedi 26 fvrier 2005  09:49 +0900, Mike McCormack a crit :
[...]
 Cool.  Some comments:
 
 The dialog box procedure should not handle WM_PAINT or WM_CLOSE, so just 
 delete those cases from the switch statement.
 
Ok I did it, but the listbox should be updated when the user ask to
uninstall someting OR the user changes the filter string ? How can I do
that using only WM_INITDIALOG ?

 Don't send WM_SETFONT messages to the controls in the dialog.  Let the 
 dialog template define what the dialog looks like.

I removed it.


 
 Your WM_INITDIALOG handler should fill the listbox, not WM_PAINT.
 
See my first question.

 You can remove the No items selected message if uninstall is clicked 
 without a listbox element select.  That's just going to annoy people, 
 and it's not internationalized.
I removed it. Internationalizaton will come after everything is alright.


Thanks.

P.S. Ivan Leo Puti I don't know if it'll be better to use WinMain. Using
WinMain will make me to parse the command line manually isn't it ?




uninstaller2.tar.gz
Description: application/compressed-tar


signature.asc
Description: Ceci est une partie de message	=?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=


Re: New uninstaller

2005-02-26 Thread Jonathan Ernst
Le samedi 26 fvrier 2005  12:09 +0800, Dmitry Timoshkov a crit :
[...]
  3) Stringtables
  a)Is there a way to load localized strings without having to guess
  beforehand the size of the string in each language ?
  b)Is there a way to not call LoadString for each string ?
  c)Where is the best place to load every string of a stringtable ? in
  main(), just before calling DialogBox() ?
 
 It's better to void using string tables, since now you have converted
 code to use dialog box instead.

How can I do it for messageboxes ? Is there a way to define them in the
resource files or do I have to make a dialog instead of messageboxes ?

Thanks everyone for your comments, I'll send an updated version soon.


signature.asc
Description: Ceci est une partie de message	=?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=


New uninstaller

2005-02-25 Thread Jonathan Ernst
As requested, I'm trying to make a new uninstaller using a dialog
instead of a window.

It's my first windows program and I have something working but there are
still some issues.

If someone could help with some of the following problems, I'd be very
thanfull.

1) Strange problem with UpdateWindow
uninstaller.c, line 264
I implemented a search/filter field and I want to repaint the window
after each input in the EDITTEXT control. However, when I call
UpdateWindow on this line, the value returned is 1 so that a WM_PAINT
message should be sent right ? But strangly no message is sent and I
have to make something else (like moving the dialog) to force the window
to repaint and filter the entries. 
The funny thing is that UpdateWindow on line 279 works just fine.
I guess it's a bug in my code and not in Wine so I'd be glad if you
could help me.

2) Improve filter code
Currently I filter the entries that match exactly the filter string. I
would like to at least make a case insensitive strstr on the string.
What's the best way to do it (See uninstaller.c, line 235)

3) Stringtables
a)Is there a way to load localized strings without having to guess
beforehand the size of the string in each language ?
b)Is there a way to not call LoadString for each string ?
c)Where is the best place to load every string of a stringtable ? in
main(), just before calling DialogBox() ?

4) Please tell me if you see things that are bad in the attached code,
so that I'll fix it before submitting a patch.

Thanks you for your help


uninstaller2.tar.gz
Description: application/compressed-tar


signature.asc
Description: Ceci est une partie de message	=?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=


Re: New uninstaller

2005-02-25 Thread Ivan Leo Puoti
Jonathan Ernst wrote:
4) Please tell me if you see things that are bad in the attached code,
so that I'll fix it before submitting a patch.
I think you probably want to pass a valid HINSTANCE to DialogBox, to do 
this you should
start your program with WinMain() instead of main().
Ivan.



Re: New uninstaller

2005-02-25 Thread Mike McCormack
Jonathan Ernst wrote:
As requested, I'm trying to make a new uninstaller using a dialog
instead of a window.
It's my first windows program and I have something working but there are
still some issues.
If someone could help with some of the following problems, I'd be very
thanfull.
Cool.  Some comments:
The dialog box procedure should not handle WM_PAINT or WM_CLOSE, so just 
delete those cases from the switch statement.

Don't send WM_SETFONT messages to the controls in the dialog.  Let the 
dialog template define what the dialog looks like.

Your WM_INITDIALOG handler should fill the listbox, not WM_PAINT.
You can remove the No items selected message if uninstall is clicked 
without a listbox element select.  That's just going to annoy people, 
and it's not internationalized.

Mike


Re: New uninstaller

2005-02-25 Thread Dmitry Timoshkov
Ivan Leo Puoti [EMAIL PROTECTED] wrote:

 Jonathan Ernst wrote:
  4) Please tell me if you see things that are bad in the attached code,
  so that I'll fix it before submitting a patch.
 
 I think you probably want to pass a valid HINSTANCE to DialogBox, to do this 
 you should
 start your program with WinMain() instead of main().

main() works just fine. GetModuleHandle(0) returns current HINSTANCE.

-- 
Dmitry.




Re: New uninstaller

2005-02-25 Thread Dmitry Timoshkov
Jonathan Ernst [EMAIL PROTECTED] wrote:

 1) Strange problem with UpdateWindow
 uninstaller.c, line 264
 I implemented a search/filter field and I want to repaint the window
 after each input in the EDITTEXT control. However, when I call
 UpdateWindow on this line, the value returned is 1 so that a WM_PAINT
 message should be sent right ?

No. UpdateWindow only sends WM_PAINT if there are invalidated areas to
repaint. You need to use InvalidateRect first.

Are you sure you want to repaint the whole window on each EN_CHANGE
and not some small area of a dialog?

 But strangly no message is sent and I
 have to make something else (like moving the dialog) to force the window
 to repaint and filter the entries. 
 The funny thing is that UpdateWindow on line 279 works just fine.
 I guess it's a bug in my code and not in Wine so I'd be glad if you
 could help me.

 2) Improve filter code
 Currently I filter the entries that match exactly the filter string. I
 would like to at least make a case insensitive strstr on the string.
 What's the best way to do it (See uninstaller.c, line 235)

Just send LB_FINDSTRING or LB_FINDSTRINGEXACT to listbox, it will do
the job for you.

 3) Stringtables
 a)Is there a way to load localized strings without having to guess
 beforehand the size of the string in each language ?
 b)Is there a way to not call LoadString for each string ?
 c)Where is the best place to load every string of a stringtable ? in
 main(), just before calling DialogBox() ?

It's better to void using string tables, since now you have converted
code to use dialog box instead.

 4) Please tell me if you see things that are bad in the attached code,
 so that I'll fix it before submitting a patch.

 +BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)

BOOL - INT_PTR

WM_PAINT is not needed for dialog boxes, user32 does the job.

 +int main(int argc, char *argv[])
 +{
 +MSG msg;
 +WNDCLASS wc;
 +HWND hWnd;
 +LPSTR token = NULL;
 +int i = 1;
 +HINSTANCE hInst = NULL;

HINSTANCE hInst = GetModuleHandle(0);

-- 
Dmitry.




Re: New uninstaller

2005-02-25 Thread Mike McCormack
Jonathan Ernst wrote:
Ok I did it, but the listbox should be updated when the user ask to
uninstall someting OR the user changes the filter string ? How can I do
that using only WM_INITDIALOG ?
You can get notifications from the controls that things change.  For 
example, the edit control will send a WM_COMMAND( EN_CHANGE ) when the 
contents change.

WM_INITDIALOG is just for setting things up.
So create a function like fill_combo_box(), and call it whenever you 
need to update the combo box... when handling WM_COMMAND( EN_CHANGE ), 
WM_INITDIALOG, etc.

Mike