Replace GRAPH_ functions with Win SDK equivalents.
[wine] / dlls / shell32 / shell32_main.c
1 /*
2  *                              Shell basics
3  *
4  *  1998 Marcus Meissner
5  *  1998 Juergen Schmied (jsch)  *  <juergen.schmied@metronet.de>
6  */
7 #include <assert.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <ctype.h>
12 #include "windows.h"
13 #include "winerror.h"
14 #include "file.h"
15 #include "shell.h"
16 #include "heap.h"
17 #include "module.h"
18 #include "neexe.h"
19 #include "resource.h"
20 #include "dlgs.h"
21 #include "win.h"
22 #include "cursoricon.h"
23 #include "interfaces.h"
24 #include "sysmetrics.h"
25 #include "shlobj.h"
26 #include "debug.h"
27 #include "winreg.h"
28 #include "imagelist.h"
29 #include "sysmetrics.h"
30 #include "commctrl.h"
31 #include "authors.h"
32 #include "pidl.h"
33 #include "shell32_main.h"
34
35 /*************************************************************************
36  *                              CommandLineToArgvW      [SHELL32.7]
37  */
38 LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
39 { LPWSTR  *argv,s,t;
40         int     i;
41   TRACE(shell,"\n");
42
43         /* to get writeable copy */
44         cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
45         s=cmdline;i=0;
46   while (*s)
47   { /* space */
48     if (*s==0x0020) 
49     { i++;
50                         s++;
51                         while (*s && *s==0x0020)
52                                 s++;
53                         continue;
54                 }
55                 s++;
56         }
57         argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
58         s=t=cmdline;
59         i=0;
60   while (*s)
61   { if (*s==0x0020)
62     { *s=0;
63                         argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
64                         *s=0x0020;
65                         while (*s && *s==0x0020)
66                                 s++;
67                         if (*s)
68                                 t=s+1;
69                         else
70                                 t=s;
71                         continue;
72                 }
73                 s++;
74         }
75         if (*t)
76                 argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
77         HeapFree( GetProcessHeap(), 0, cmdline );
78         argv[i]=NULL;
79         *numargs=i;
80         return argv;
81 }
82
83 /*************************************************************************
84  *                              Control_RunDLL          [SHELL32.12]
85  *
86  * Wild speculation in the following!
87  *
88  * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
89  */
90
91 void WINAPI Control_RunDLL( HWND32 hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
92 {
93     FIXME(shell, "(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
94           debugstr_a(cmd), arg4);
95 }
96
97 /*************************************************************************
98  *  SHGetFileInfoA              [SHELL32.254]
99  *
100  * FIXME
101  *   
102  */
103
104 DWORD WINAPI SHGetFileInfo32A(LPCSTR path,DWORD dwFileAttributes,
105                               SHFILEINFO32A *psfi, UINT32 sizeofpsfi,
106                               UINT32 flags )
107 {       CHAR szTemp[MAX_PATH];
108         LPPIDLDATA      pData;
109         DWORD ret=0;
110   
111         TRACE(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
112               path,dwFileAttributes,psfi,sizeofpsfi,flags);
113
114         /* translate the pidl to a path*/
115         if (flags & SHGFI_PIDL)
116         { SHGetPathFromIDList32A ((LPCITEMIDLIST)path,szTemp);
117           TRACE(shell,"pidl=%p is %s\n",path,szTemp);
118         }
119         else
120         { TRACE(shell,"path=%p\n",path);
121         }
122
123         if (flags & SHGFI_ATTRIBUTES)
124         { if (flags & SHGFI_PIDL)
125           { pData = _ILGetDataPointer((LPCITEMIDLIST)path);
126             psfi->dwAttributes = pData->u.generic.dwSFGAO; /* fixme: no direct access*/
127             ret=TRUE;
128           }
129           else
130           { psfi->dwAttributes=SFGAO_FILESYSTEM;
131             ret=TRUE;
132           }
133           FIXME(shell,"file attributes, stub\n");           
134         }
135
136         if (flags & SHGFI_DISPLAYNAME)
137         { if (flags & SHGFI_PIDL)
138           { strcpy(psfi->szDisplayName,szTemp);
139           }
140           else
141           { strcpy(psfi->szDisplayName,path);
142           }
143           TRACE(shell,"displayname=%s\n", psfi->szDisplayName);   
144           ret=TRUE;
145         }
146   
147         if (flags & SHGFI_TYPENAME)
148         { FIXME(shell,"get the file type, stub\n");
149           strcpy(psfi->szTypeName,"FIXME: Type");
150           ret=TRUE;
151         }
152   
153   if (flags & SHGFI_ICONLOCATION)
154   { FIXME(shell,"location of icon, stub\n");
155     strcpy(psfi->szDisplayName,"");
156     ret=TRUE;
157   }
158
159   if (flags & SHGFI_EXETYPE)
160     FIXME(shell,"type of executable, stub\n");
161
162   if (flags & SHGFI_LINKOVERLAY)
163     FIXME(shell,"set icon to link, stub\n");
164
165   if (flags & SHGFI_OPENICON)
166     FIXME(shell,"set to open icon, stub\n");
167
168   if (flags & SHGFI_SELECTED)
169     FIXME(shell,"set icon to selected, stub\n");
170
171   if (flags & SHGFI_SHELLICONSIZE)
172     FIXME(shell,"set icon to shell size, stub\n");
173
174   if (flags & SHGFI_USEFILEATTRIBUTES)
175     FIXME(shell,"use the dwFileAttributes, stub\n");
176  
177   if (flags & SHGFI_ICON)
178   { FIXME(shell,"icon handle\n");
179     if (flags & SHGFI_SMALLICON)
180      { TRACE(shell,"set to small icon\n"); 
181        psfi->hIcon=pImageList_GetIcon(ShellSmallIconList,32,ILD_NORMAL);
182        ret = (DWORD) ShellSmallIconList;
183      }
184      else
185      { TRACE(shell,"set to big icon\n");
186        psfi->hIcon=pImageList_GetIcon(ShellBigIconList,32,ILD_NORMAL);
187        ret = (DWORD) ShellBigIconList;
188      }      
189   }
190
191   if (flags & SHGFI_SYSICONINDEX)
192   {  FIXME(shell,"get the SYSICONINDEX\n");
193      psfi->iIcon=32;
194      if (flags & SHGFI_SMALLICON)
195      { TRACE(shell,"set to small icon\n"); 
196        ret = (DWORD) ShellSmallIconList;
197      }
198      else        
199      { TRACE(shell,"set to big icon\n");
200        ret = (DWORD) ShellBigIconList;
201      }
202   }
203
204  
205   return ret;
206 }
207
208 /*************************************************************************
209  *  SHGetFileInfo32W            [SHELL32.255]
210  *
211  * FIXME
212  *   
213  */
214
215 DWORD WINAPI SHGetFileInfo32W(LPCWSTR path,DWORD dwFileAttributes,
216                               SHFILEINFO32W *psfi, UINT32 sizeofpsfi,
217                               UINT32 flags )
218 {       FIXME(shell,"(%s,0x%lx,%p,0x%x,0x%x)\n",
219               debugstr_w(path),dwFileAttributes,psfi,sizeofpsfi,flags);
220         return 0;
221 }
222
223 /*************************************************************************
224  *             ExtractIcon32A   (SHELL32.133)
225  */
226 HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName,
227         UINT32 nIconIndex )
228 {   HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
229     TRACE(shell,"\n");
230     if( handle )
231     {
232         HICON16* ptr = (HICON16*)GlobalLock16(handle);
233         HICON16  hIcon = *ptr;
234
235         GlobalFree16(handle);
236         return hIcon;
237     }
238     return 0;
239 }
240
241 /*************************************************************************
242  *             ExtractIcon32W   (SHELL32.180)
243  */
244 HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName,
245         UINT32 nIconIndex )
246 { LPSTR  exefn;
247   HICON32  ret;
248   TRACE(shell,"\n");
249
250   exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
251   ret = ExtractIcon32A(hInstance,exefn,nIconIndex);
252
253         HeapFree(GetProcessHeap(),0,exefn);
254         return ret;
255 }
256
257 /*************************************************************************
258  *             FindExecutable32A   (SHELL32.184)
259  */
260 HINSTANCE32 WINAPI FindExecutable32A( LPCSTR lpFile, LPCSTR lpDirectory,
261                                       LPSTR lpResult )
262 { HINSTANCE32 retval=31;    /* default - 'No association was found' */
263     char old_dir[1024];
264
265   TRACE(shell, "File %s, Dir %s\n", 
266                  (lpFile != NULL?lpFile:"-"), 
267                  (lpDirectory != NULL?lpDirectory:"-"));
268
269     lpResult[0]='\0'; /* Start off with an empty return string */
270
271     /* trap NULL parameters on entry */
272     if (( lpFile == NULL ) || ( lpResult == NULL ))
273   { /* FIXME - should throw a warning, perhaps! */
274         return 2; /* File not found. Close enough, I guess. */
275     }
276
277     if (lpDirectory)
278   { GetCurrentDirectory32A( sizeof(old_dir), old_dir );
279         SetCurrentDirectory32A( lpDirectory );
280     }
281
282     retval = SHELL_FindExecutable( lpFile, "open", lpResult );
283
284   TRACE(shell, "returning %s\n", lpResult);
285   if (lpDirectory)
286     SetCurrentDirectory32A( old_dir );
287     return retval;
288 }
289
290 typedef struct
291 { LPCSTR  szApp;
292     LPCSTR  szOtherStuff;
293     HICON32 hIcon;
294 } ABOUT_INFO;
295
296 #define         IDC_STATIC_TEXT         100
297 #define         IDC_LISTBOX             99
298 #define         IDC_WINE_TEXT           98
299
300 #define         DROP_FIELD_TOP          (-15)
301 #define         DROP_FIELD_HEIGHT       15
302
303 extern HICON32 hIconTitleFont;
304
305 static BOOL32 __get_dropline( HWND32 hWnd, LPRECT32 lprect )
306 { HWND32 hWndCtl = GetDlgItem32(hWnd, IDC_WINE_TEXT);
307     if( hWndCtl )
308   { GetWindowRect32( hWndCtl, lprect );
309         MapWindowPoints32( 0, hWnd, (LPPOINT32)lprect, 2 );
310         lprect->bottom = (lprect->top += DROP_FIELD_TOP);
311         return TRUE;
312     }
313     return FALSE;
314 }
315
316 /*************************************************************************
317  *                              SHAppBarMessage32       [SHELL32.207]
318  */
319 UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data)
320 { FIXME(shell,"(0x%08lx,%p): stub\n", msg, data);
321 #if 0
322   switch (msg)
323   { case ABM_ACTIVATE:
324         case ABM_GETAUTOHIDEBAR:
325         case ABM_GETSTATE:
326         case ABM_GETTASKBARPOS:
327         case ABM_NEW:
328         case ABM_QUERYPOS:
329         case ABM_REMOVE:
330         case ABM_SETAUTOHIDEBAR:
331         case ABM_SETPOS:
332         case ABM_WINDOWPOSCHANGED:
333             ;
334     }
335 #endif
336     return 0;
337 }
338
339 /*************************************************************************
340  * SHBrowseForFolderA [SHELL32.209]
341  *
342  */
343 LPITEMIDLIST WINAPI SHBrowseForFolder32A (LPBROWSEINFO32A lpbi)
344 { FIXME (shell, "(%lx,%s) empty stub!\n", (DWORD)lpbi, lpbi->lpszTitle);
345   return NULL;
346 }
347
348 /*************************************************************************
349  *  SHGetDesktopFolder          [SHELL32.216]
350  * 
351  *  SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
352  *  CLSID_ShellDesktop
353  *  CoCreateInstance(CLSID_Desktop, NULL, CLSCTX_INPROC, IID_IShellFolder, &pshf);
354  *
355  * RETURNS
356  *   the interface to the shell desktop folder.
357  *
358  * FIXME
359  *   the pdesktopfolder has to be released at the end (at dll unloading???)
360  */
361 LPSHELLFOLDER pdesktopfolder=NULL;
362
363 DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder)
364 { HRESULT       hres = E_OUTOFMEMORY;
365   LPCLASSFACTORY lpclf;
366         TRACE(shell,"%p->(%p)\n",shellfolder,*shellfolder);
367
368   if (pdesktopfolder)
369         {       hres = NOERROR;
370         }
371         else
372   { lpclf = IClassFactory_Constructor();
373     /* fixme: the buildin IClassFactory_Constructor is at the moment only 
374                 for rclsid=CLSID_ShellDesktop, so we get the right Interface (jsch)*/
375     if(lpclf)
376     { hres = lpclf->lpvtbl->fnCreateInstance(lpclf,NULL,(REFIID)&IID_IShellFolder, (void*)&pdesktopfolder);
377                   lpclf->lpvtbl->fnRelease(lpclf);
378           }  
379   }
380         
381   if (pdesktopfolder)
382         { *shellfolder = pdesktopfolder;
383     pdesktopfolder->lpvtbl->fnAddRef(pdesktopfolder);
384         }
385   else
386         { *shellfolder=NULL;
387         }       
388
389   TRACE(shell,"-- %p->(%p)\n",shellfolder, *shellfolder);
390         return hres;
391 }
392 /*************************************************************************
393  *                       SHGetPathFromIDList            [SHELL32.221][NT 4.0: SHELL32.219]
394  */
395 BOOL32 WINAPI SHGetPathFromIDList32(LPCITEMIDLIST pidl,LPSTR pszPath)     
396 { TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
397   return SHGetPathFromIDList32A(pidl,pszPath);
398 }
399
400 /*************************************************************************
401  *                       SHGetSpecialFolderLocation     [SHELL32.223]
402  * gets the folder locations from the registry and creates a pidl
403  * creates missing reg keys and directorys
404  * 
405  * PARAMS
406  *   hwndOwner [I]
407  *   nFolder   [I] CSIDL_xxxxx
408  *   ppidl     [O] PIDL of a special folder
409  *
410  * RETURNS
411  *    HResult
412  *
413  * FIXME
414  *   - look for "User Shell Folder" first
415  *
416  */
417 HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl)
418 { LPSHELLFOLDER shellfolder;
419   DWORD pchEaten,tpathlen=MAX_PATH,type,dwdisp,res;
420   CHAR pszTemp[256],buffer[256],tpath[MAX_PATH],npath[MAX_PATH];
421   LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
422   HKEY key;
423
424         enum 
425         { FT_UNKNOWN= 0x00000000,
426           FT_DIR=     0x00000001, 
427           FT_DESKTOP= 0x00000002,
428           FT_SPECIAL= 0x00000003
429         } tFolder; 
430
431         TRACE(shell,"(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
432
433         strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
434
435         res=RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp);
436         if (res)
437         { ERR(shell,"Could not create key %s %08lx \n",buffer,res);
438           return E_OUTOFMEMORY;
439         }
440
441         tFolder=FT_DIR; 
442         switch (nFolder)
443         { case CSIDL_BITBUCKET:
444             strcpy (buffer,"xxx");                      /*not in the registry*/
445             TRACE (shell,"looking for Recycler\n");
446             tFolder=FT_UNKNOWN;
447             break;
448           case CSIDL_CONTROLS:
449             strcpy (buffer,"xxx");                      /*virtual folder*/
450             TRACE (shell,"looking for Control\n");
451             tFolder=FT_UNKNOWN;
452             break;
453           case CSIDL_DESKTOP:
454             strcpy (buffer,"xxx");                      /*virtual folder*/
455             TRACE (shell,"looking for Desktop\n");
456             tFolder=FT_DESKTOP;                 
457             break;
458           case CSIDL_DESKTOPDIRECTORY:
459           case CSIDL_COMMON_DESKTOPDIRECTORY:
460             strcpy (buffer,"Desktop");
461             break;
462           case CSIDL_DRIVES:
463             strcpy (buffer,"xxx");                      /*virtual folder*/
464             TRACE (shell,"looking for Drives\n");
465             tFolder=FT_SPECIAL;
466             break;
467           case CSIDL_FONTS:
468             strcpy (buffer,"Fonts");                    
469             break;
470           case CSIDL_NETHOOD:
471             strcpy (buffer,"NetHood");                  
472             break;
473           case CSIDL_PRINTHOOD:
474             strcpy (buffer,"PrintHood");                        
475             break;
476           case CSIDL_NETWORK:
477             strcpy (buffer,"xxx");                              /*virtual folder*/
478             TRACE (shell,"looking for Network\n");
479             tFolder=FT_UNKNOWN;
480             break;
481           case CSIDL_APPDATA:
482             strcpy (buffer,"Appdata");                  
483             break;
484           case CSIDL_PERSONAL:
485             strcpy (buffer,"Personal");                 
486             break;
487           case CSIDL_FAVORITES:
488             strcpy (buffer,"Favorites");                        
489             break;
490           case CSIDL_PRINTERS:
491             strcpy (buffer,"PrintHood");
492             break;
493           case CSIDL_COMMON_PROGRAMS:
494           case CSIDL_PROGRAMS:
495             strcpy (buffer,"Programs");                 
496             break;
497           case CSIDL_RECENT:
498             strcpy (buffer,"Recent");
499             break;
500           case CSIDL_SENDTO:
501             strcpy (buffer,"SendTo");
502             break;
503           case CSIDL_COMMON_STARTMENU:
504           case CSIDL_STARTMENU:
505             strcpy (buffer,"Start Menu");
506             break;
507           case CSIDL_COMMON_STARTUP:  
508           case CSIDL_STARTUP:
509             strcpy (buffer,"Startup");                  
510             break;
511           case CSIDL_TEMPLATES:
512             strcpy (buffer,"Templates");                        
513             break;
514           default:
515             ERR (shell,"unknown CSIDL 0x%08x\n", nFolder);
516             tFolder=FT_UNKNOWN;                 
517             break;
518         }
519
520         TRACE(shell,"Key=%s\n",buffer);
521
522         type=REG_SZ;
523
524         switch (tFolder)
525         { case FT_DIR:
526             /* Directory: get the value from the registry, if its not there 
527                         create it and the directory*/
528             if (RegQueryValueEx32A(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
529             { GetWindowsDirectory32A(npath,MAX_PATH);
530               PathAddBackslash32A(npath);
531               switch (nFolder)
532               { case CSIDL_DESKTOPDIRECTORY:
533                 case CSIDL_COMMON_DESKTOPDIRECTORY:
534                   strcat (npath,"Desktop");
535                   break;
536                 case CSIDL_FONTS:
537                   strcat (npath,"Fonts");                       
538                   break;
539                 case CSIDL_NETHOOD:
540                   strcat (npath,"NetHood");                     
541                   break;
542                 case CSIDL_PRINTHOOD:
543                   strcat (npath,"PrintHood");                   
544                   break;
545                 case CSIDL_APPDATA:
546                   strcat (npath,"Appdata");                     
547                   break;
548                 case CSIDL_PERSONAL:
549                   strcpy (npath,"C:\\Personal");                        
550                   break;
551                 case CSIDL_FAVORITES:
552                   strcat (npath,"Favorites");                   
553                   break;
554                 case CSIDL_PRINTERS:
555                   strcat (npath,"PrintHood");                   
556                   break;
557                 case CSIDL_COMMON_PROGRAMS:
558                 case CSIDL_PROGRAMS:
559                   strcat (npath,"Start Menu");                  
560                   CreateDirectory32A(npath,NULL);
561                   strcat (npath,"\\Programs");                  
562                   break;
563                 case CSIDL_RECENT:
564                   strcat (npath,"Recent");
565                   break;
566                 case CSIDL_SENDTO:
567                   strcat (npath,"SendTo");
568                   break;
569                 case CSIDL_COMMON_STARTMENU:
570                 case CSIDL_STARTMENU:
571                   strcat (npath,"Start Menu");
572                   break;
573                 case CSIDL_COMMON_STARTUP:  
574                 case CSIDL_STARTUP:
575                   strcat (npath,"Start Menu");                  
576                   CreateDirectory32A(npath,NULL);
577                   strcat (npath,"\\Startup");                   
578                   break;
579                 case CSIDL_TEMPLATES:
580                   strcat (npath,"Templates");                   
581                   break;
582                 default:
583                   RegCloseKey(key);
584                   return E_OUTOFMEMORY;
585               }
586               if (RegSetValueEx32A(key,buffer,0,REG_SZ,(LPBYTE)npath,sizeof(npath)+1))
587               { ERR(shell,"could not create value %s\n",buffer);
588                 RegCloseKey(key);
589                 return E_OUTOFMEMORY;
590               }
591               TRACE(shell,"value %s=%s created\n",buffer,npath);
592               CreateDirectory32A(npath,NULL);
593               strcpy(tpath,npath);
594             }
595             break;
596           case FT_DESKTOP:
597             strcpy (tpath,"Desktop");
598             break;
599           case FT_SPECIAL:
600             if (nFolder==CSIDL_DRIVES)
601             strcpy (tpath,"My Computer");
602             break;
603           default:
604             RegCloseKey(key);
605             return E_OUTOFMEMORY;
606         }
607
608         RegCloseKey(key);
609
610         TRACE(shell,"Value=%s\n",tpath);
611         LocalToWideChar32(lpszDisplayName, tpath, 256);
612   
613         if (SHGetDesktopFolder(&shellfolder)==S_OK)
614         { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,hwndOwner, NULL,lpszDisplayName,&pchEaten,ppidl,NULL);
615           shellfolder->lpvtbl->fnRelease(shellfolder);
616         }
617
618         TRACE(shell, "-- (new pidl %p)\n",*ppidl);
619         return NOERROR;
620 }
621 /*************************************************************************
622  * SHHelpShortcuts_RunDLL [SHELL32.224]
623  *
624  */
625 DWORD WINAPI SHHelpShortcuts_RunDLL (DWORD dwArg1, DWORD dwArg2, DWORD dwArg3, DWORD dwArg4)
626 { FIXME (exec, "(%lx, %lx, %lx, %lx) empty stub!\n",
627         dwArg1, dwArg2, dwArg3, dwArg4);
628
629   return 0;
630 }
631
632 /*************************************************************************
633  * SHLoadInProc [SHELL32.225]
634  *
635  */
636
637 DWORD WINAPI SHLoadInProc (DWORD dwArg1)
638 { FIXME (shell, "(%lx) empty stub!\n", dwArg1);
639     return 0;
640 }
641
642 /*************************************************************************
643  *             ShellExecute32A   (SHELL32.245)
644  */
645 HINSTANCE32 WINAPI ShellExecute32A( HWND32 hWnd, LPCSTR lpOperation,
646                                     LPCSTR lpFile, LPCSTR lpParameters,
647                                     LPCSTR lpDirectory, INT32 iShowCmd )
648 {   TRACE(shell,"\n");
649     return ShellExecute16( hWnd, lpOperation, lpFile, lpParameters,
650                            lpDirectory, iShowCmd );
651 }
652
653
654 /*************************************************************************
655  *             AboutDlgProc32  (not an exported API function)
656  */
657 LRESULT WINAPI AboutDlgProc32( HWND32 hWnd, UINT32 msg, WPARAM32 wParam,
658                                LPARAM lParam )
659 {   HWND32 hWndCtl;
660     char Template[512], AppTitle[512];
661
662     TRACE(shell,"\n");
663
664     switch(msg)
665     { case WM_INITDIALOG:
666       { ABOUT_INFO *info = (ABOUT_INFO *)lParam;
667             if (info)
668         { const char* const *pstr = SHELL_People;
669                 SendDlgItemMessage32A(hWnd, stc1, STM_SETICON32,info->hIcon, 0);
670                 GetWindowText32A( hWnd, Template, sizeof(Template) );
671                 sprintf( AppTitle, Template, info->szApp );
672                 SetWindowText32A( hWnd, AppTitle );
673                 SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT),
674                                   info->szOtherStuff );
675                 hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
676                 SendMessage32A( hWndCtl, WM_SETREDRAW, 0, 0 );
677                 SendMessage32A( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
678                 while (*pstr)
679           { SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)*pstr );
680                     pstr++;
681                 }
682                 SendMessage32A( hWndCtl, WM_SETREDRAW, 1, 0 );
683             }
684         }
685         return 1;
686
687     case WM_PAINT:
688       { RECT32 rect;
689             PAINTSTRUCT32 ps;
690             HDC32 hDC = BeginPaint32( hWnd, &ps );
691
692             if( __get_dropline( hWnd, &rect ) ) {
693                 SelectObject32( hDC, GetStockObject32( BLACK_PEN ) );
694                 MoveToEx32( hDC, rect.left, rect.top, NULL );
695                 LineTo32( hDC, rect.right, rect.bottom );
696             }
697             EndPaint32( hWnd, &ps );
698         }
699         break;
700
701     case WM_LBTRACKPOINT:
702         hWndCtl = GetDlgItem32(hWnd, IDC_LISTBOX);
703         if( (INT16)GetKeyState16( VK_CONTROL ) < 0 )
704       { if( DragDetect32( hWndCtl, *((LPPOINT32)&lParam) ) )
705         { INT32 idx = SendMessage32A( hWndCtl, LB_GETCURSEL32, 0, 0 );
706                 if( idx != -1 )
707           { INT32 length = SendMessage32A( hWndCtl, LB_GETTEXTLEN32, (WPARAM32)idx, 0 );
708                     HGLOBAL16 hMemObj = GlobalAlloc16( GMEM_MOVEABLE, length + 1 );
709                     char* pstr = (char*)GlobalLock16( hMemObj );
710
711                     if( pstr )
712             { HCURSOR16 hCursor = LoadCursor16( 0, MAKEINTRESOURCE16(OCR_DRAGOBJECT) );
713                         SendMessage32A( hWndCtl, LB_GETTEXT32, (WPARAM32)idx, (LPARAM)pstr );
714                         SendMessage32A( hWndCtl, LB_DELETESTRING32, (WPARAM32)idx, 0 );
715                         UpdateWindow32( hWndCtl );
716                         if( !DragObject16((HWND16)hWnd, (HWND16)hWnd, DRAGOBJ_DATA, 0, (WORD)hMemObj, hCursor) )
717                             SendMessage32A( hWndCtl, LB_ADDSTRING32, (WPARAM32)-1, (LPARAM)pstr );
718                     }
719             if( hMemObj )
720               GlobalFree16( hMemObj );
721                 }
722             }
723         }
724         break;
725
726     case WM_QUERYDROPOBJECT:
727         if( wParam == 0 )
728       { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
729             if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
730         { RECT32 rect;
731                 if( __get_dropline( hWnd, &rect ) )
732           { POINT32 pt;
733             pt.x=lpDragInfo->pt.x;
734             pt.x=lpDragInfo->pt.y;
735                     rect.bottom += DROP_FIELD_HEIGHT;
736                     if( PtInRect32( &rect, pt ) )
737             { SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
738                         return TRUE;
739                     }
740                 }
741             }
742         }
743         break;
744
745     case WM_DROPOBJECT:
746         if( wParam == hWnd )
747       { LPDRAGINFO lpDragInfo = (LPDRAGINFO)PTR_SEG_TO_LIN((SEGPTR)lParam);
748             if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
749         { char* pstr = (char*)GlobalLock16( (HGLOBAL16)(lpDragInfo->hList) );
750                 if( pstr )
751           { static char __appendix_str[] = " with";
752
753                     hWndCtl = GetDlgItem32( hWnd, IDC_WINE_TEXT );
754                     SendMessage32A( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
755                     if( !lstrncmp32A( Template, "WINE", 4 ) )
756                         SetWindowText32A( GetDlgItem32(hWnd, IDC_STATIC_TEXT), Template );
757                     else
758           { char* pch = Template + strlen(Template) - strlen(__appendix_str);
759                         *pch = '\0';
760                         SendMessage32A( GetDlgItem32(hWnd, IDC_LISTBOX), LB_ADDSTRING32, 
761                                         (WPARAM32)-1, (LPARAM)Template );
762                     }
763
764                     lstrcpy32A( Template, pstr );
765                     lstrcat32A( Template, __appendix_str );
766                     SetWindowText32A( hWndCtl, Template );
767                     SetWindowLong32A( hWnd, DWL_MSGRESULT, 1 );
768                     return TRUE;
769                 }
770             }
771         }
772         break;
773
774     case WM_COMMAND:
775         if (wParam == IDOK)
776     {  EndDialog32(hWnd, TRUE);
777             return TRUE;
778         }
779         break;
780     }
781     return 0;
782 }
783
784
785 /*************************************************************************
786  *             ShellAbout32A   (SHELL32.243)
787  */
788 BOOL32 WINAPI ShellAbout32A( HWND32 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
789                              HICON32 hIcon )
790 {   ABOUT_INFO info;
791     TRACE(shell,"\n");
792     info.szApp        = szApp;
793     info.szOtherStuff = szOtherStuff;
794     info.hIcon        = hIcon;
795     if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
796     return DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
797                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
798                                       hWnd, AboutDlgProc32, (LPARAM)&info );
799 }
800
801
802 /*************************************************************************
803  *             ShellAbout32W   (SHELL32.244)
804  */
805 BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff,
806                              HICON32 hIcon )
807 {   BOOL32 ret;
808     ABOUT_INFO info;
809
810     TRACE(shell,"\n");
811     
812     info.szApp        = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
813     info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
814     info.hIcon        = hIcon;
815     if (!hIcon) info.hIcon = LoadIcon16( 0, MAKEINTRESOURCE16(OIC_WINEICON) );
816     ret = DialogBoxIndirectParam32A( WIN_GetWindowInstance( hWnd ),
817                          SYSRES_GetResPtr( SYSRES_DIALOG_SHELL_ABOUT_MSGBOX ),
818                                       hWnd, AboutDlgProc32, (LPARAM)&info );
819     HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
820     HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
821     return ret;
822 }
823
824 /*************************************************************************
825  *                              Shell_NotifyIcon        [SHELL32.296]
826  *      FIXME
827  *      This function is supposed to deal with the systray.
828  *      Any ideas on how this is to be implimented?
829  */
830 BOOL32 WINAPI Shell_NotifyIcon( DWORD dwMessage, PNOTIFYICONDATA pnid )
831 {   TRACE(shell,"\n");
832     return FALSE;
833 }
834
835 /*************************************************************************
836  *                              Shell_NotifyIcon        [SHELL32.297]
837  *      FIXME
838  *      This function is supposed to deal with the systray.
839  *      Any ideas on how this is to be implimented?
840  */
841 BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATA pnid )
842 {   TRACE(shell,"\n");
843     return FALSE;
844 }
845
846 /*************************************************************************
847  * FreeIconList
848  */
849 void WINAPI FreeIconList( DWORD dw )
850 { FIXME(shell, "(%lx): stub\n",dw);
851 }
852
853 /*************************************************************************
854  * SHGetPathFromIDList32A        [SHELL32.261][NT 4.0: SHELL32.220]
855  *
856  * PARAMETERS
857  *  pidl,   [IN] pidl 
858  *  pszPath [OUT] path
859  *
860  * RETURNS 
861  *  path from a passed PIDL.
862  *
863  * NOTES
864  *     exported by name
865  *
866  * FIXME
867  *  fnGetDisplayNameOf can return different types of OLEString
868  */
869 DWORD WINAPI SHGetPathFromIDList32A (LPCITEMIDLIST pidl,LPSTR pszPath)
870 {       STRRET lpName;
871         LPSHELLFOLDER shellfolder;
872         CHAR  buffer[MAX_PATH],tpath[MAX_PATH];
873         DWORD type,tpathlen=MAX_PATH,dwdisp;
874         HKEY  key;
875
876         TRACE(shell,"(pidl=%p,%p)\n",pidl,pszPath);
877
878   if (!pidl)
879   {  strcpy(buffer,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\");
880
881      if (RegCreateKeyEx32A(HKEY_CURRENT_USER,buffer,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&key,&dwdisp))
882      { return E_OUTOFMEMORY;
883      }
884      type=REG_SZ;    
885      strcpy (buffer,"Desktop");                                 /*registry name*/
886      if ( RegQueryValueEx32A(key,buffer,NULL,&type,(LPBYTE)tpath,&tpathlen))
887      { GetWindowsDirectory32A(tpath,MAX_PATH);
888        PathAddBackslash32A(tpath);
889        strcat (tpath,"Desktop");                                /*folder name*/
890        RegSetValueEx32A(key,buffer,0,REG_SZ,(LPBYTE)tpath,tpathlen);
891        CreateDirectory32A(tpath,NULL);
892      }
893      RegCloseKey(key);
894      strcpy(pszPath,tpath);
895   }
896   else
897   { if (SHGetDesktopFolder(&shellfolder)==S_OK)
898         { shellfolder->lpvtbl->fnGetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&lpName);
899           shellfolder->lpvtbl->fnRelease(shellfolder);
900         }
901   /*WideCharToLocal32(pszPath, lpName.u.pOleStr, MAX_PATH);*/
902         strcpy(pszPath,lpName.u.cStr);
903         /* fixme free the olestring*/
904   }
905         TRACE(shell,"-- (%s)\n",pszPath);
906         return NOERROR;
907 }
908 /*************************************************************************
909  * SHGetPathFromIDList32W [SHELL32.262]
910  */
911 DWORD WINAPI SHGetPathFromIDList32W (LPCITEMIDLIST pidl,LPWSTR pszPath)
912 {       char sTemp[MAX_PATH];
913
914         TRACE (shell,"(pidl=%p)\n", pidl);
915
916         SHGetPathFromIDList32A (pidl, sTemp);
917         lstrcpyAtoW(pszPath, sTemp);
918
919         TRACE(shell,"-- (%s)\n",debugstr_w(pszPath));
920
921         return NOERROR;
922 }
923
924
925 void    (CALLBACK* pDLLInitComctl)(void);
926 INT32   (CALLBACK* pImageList_AddIcon) (HIMAGELIST himl, HICON32 hIcon);
927 INT32   (CALLBACK* pImageList_ReplaceIcon) (HIMAGELIST, INT32, HICON32);
928 HIMAGELIST (CALLBACK * pImageList_Create) (INT32,INT32,UINT32,INT32,INT32);
929 HICON32 (CALLBACK * pImageList_GetIcon) (HIMAGELIST, INT32, UINT32);
930 INT32   (CALLBACK* pImageList_GetImageCount)(HIMAGELIST);
931
932 LPVOID  (CALLBACK* pCOMCTL32_Alloc) (INT32);  
933 BOOL32  (CALLBACK* pCOMCTL32_Free) (LPVOID);  
934
935 HDPA    (CALLBACK* pDPA_Create) (INT32);  
936 INT32   (CALLBACK* pDPA_InsertPtr) (const HDPA, INT32, LPVOID); 
937 BOOL32  (CALLBACK* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM); 
938 LPVOID  (CALLBACK* pDPA_GetPtr) (const HDPA, INT32);   
939 BOOL32  (CALLBACK* pDPA_Destroy) (const HDPA); 
940 INT32   (CALLBACK *pDPA_Search) (const HDPA, LPVOID, INT32, PFNDPACOMPARE, LPARAM, UINT32);
941 static BOOL32 bShell32IsInitialized=0;
942 /*************************************************************************
943  * SHELL32 LibMain
944  *
945  * FIXME
946  *  at the moment the icons are extracted from shell32.dll
947  *  free the imagelists
948  */
949 HINSTANCE32 shell32_hInstance; 
950
951 BOOL32 WINAPI Shell32LibMain(HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
952 { HINSTANCE32 hComctl32;
953
954   TRACE(shell,"0x%x 0x%lx %p\n", hinstDLL, fdwReason, lpvReserved);
955
956   shell32_hInstance = hinstDLL;
957   
958   if (fdwReason==DLL_PROCESS_ATTACH && !bShell32IsInitialized)
959   { hComctl32 = LoadLibrary32A("COMCTL32.DLL"); 
960     if (hComctl32)
961     { pDLLInitComctl=GetProcAddress32(hComctl32,"InitCommonControlsEx");
962       if (pDLLInitComctl)
963       { pDLLInitComctl();
964       }
965       pImageList_Create=GetProcAddress32(hComctl32,"ImageList_Create");
966       pImageList_AddIcon=GetProcAddress32(hComctl32,"ImageList_AddIcon");
967       pImageList_ReplaceIcon=GetProcAddress32(hComctl32,"ImageList_ReplaceIcon");
968       pImageList_GetIcon=GetProcAddress32(hComctl32,"ImageList_GetIcon");
969       pImageList_GetImageCount=GetProcAddress32(hComctl32,"ImageList_GetImageCount");
970
971       /* imports by ordinal, pray that it works*/
972       pCOMCTL32_Alloc=GetProcAddress32(hComctl32, (LPCSTR)71L);
973       pCOMCTL32_Free=GetProcAddress32(hComctl32, (LPCSTR)73L);
974       pDPA_Create=GetProcAddress32(hComctl32, (LPCSTR)328L);
975       pDPA_Destroy=GetProcAddress32(hComctl32, (LPCSTR)329L);
976       pDPA_GetPtr=GetProcAddress32(hComctl32, (LPCSTR)332L);
977       pDPA_InsertPtr=GetProcAddress32(hComctl32, (LPCSTR)334L);
978       pDPA_Sort=GetProcAddress32(hComctl32, (LPCSTR)338L);
979       pDPA_Search=GetProcAddress32(hComctl32, (LPCSTR)339L);
980
981       FreeLibrary32(hComctl32);
982     }
983     else
984     { /* panic, imediately exit wine*/
985       ERR(shell,"P A N I C error getting functionpointers\n");
986       exit (1);
987     }
988     SIC_Initialize();
989     bShell32IsInitialized = TRUE;
990   }
991   return TRUE;
992 }