source: trunk/src/shell32/shell32_main.cpp@ 4032

Last change on this file since 4032 was 4032, checked in by phaller, 25 years ago

Synchronized shell32 with wine

File size: 34.2 KB
Line 
1/* $Id: shell32_main.cpp,v 1.12 2000-08-18 02:01:19 phaller Exp $ */
2
3/*
4 * Win32 SHELL32 for OS/2
5 *
6 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 * Shell basics
10 *
11 * 1998 Marcus Meissner
12 * 1998 Juergen Schmied (jsch) * <juergen.schmied@metronet.de>
13 *
14 * Corel WINE 20000324 level
15 */
16
17/*****************************************************************************
18 * Includes *
19 *****************************************************************************/
20
21#include <odin.h>
22#include <odinwrap.h>
23#include <os2sel.h>
24
25#include <stdlib.h>
26#include <string.h>
27
28#define ICOM_CINTERFACE 1
29#define CINTERFACE 1
30
31#include "wine/winuser16.h"
32#include "winerror.h"
33#include "heap.h"
34#include "resource.h"
35#include "dlgs.h"
36//#include "ldt.h"
37#include "sysmetrics.h"
38#include "debugtools.h"
39#include "winreg.h"
40#include "authors.h"
41#include "winversion.h"
42
43#include "shellapi.h"
44#include "pidl.h"
45
46#include "shlobj.h"
47#include "shell32_main.h"
48#include "shlguid.h"
49#include "wine/undocshell.h"
50#include "shpolicy.h"
51#include "shlwapi.h"
52
53#include <heapstring.h>
54#include <misc.h>
55
56
57/*****************************************************************************
58 * Local Variables *
59 *****************************************************************************/
60
61ODINDEBUGCHANNEL(SHELL32-MAIN)
62
63
64#define MORE_DEBUG 1
65
66BOOL VERSION_OsIsUnicode(VOID)
67{
68 return FALSE;
69}
70
71/*************************************************************************
72 * CommandLineToArgvW [SHELL32.7]
73 */
74
75ODINFUNCTION2(LPWSTR*, CommandLineToArgvW, LPWSTR, cmdline,
76 LPDWORD, numargs)
77{ LPWSTR *argv,s,t;
78 int i;
79
80 /* to get writeable copy */
81 cmdline = HEAP_strdupW( GetProcessHeap(), 0, cmdline);
82 s=cmdline;i=0;
83 while (*s)
84 { /* space */
85 if (*s==0x0020)
86 { i++;
87 s++;
88 while (*s && *s==0x0020)
89 s++;
90 continue;
91 }
92 s++;
93 }
94 argv=(LPWSTR*)HeapAlloc( GetProcessHeap(), 0, sizeof(LPWSTR)*(i+1) );
95 s=t=cmdline;
96 i=0;
97 while (*s)
98 { if (*s==0x0020)
99 { *s=0;
100 argv[i++]=HEAP_strdupW( GetProcessHeap(), 0, t );
101 *s=0x0020;
102 while (*s && *s==0x0020)
103 s++;
104 if (*s)
105 t=s+1;
106 else
107 t=s;
108 continue;
109 }
110 s++;
111 }
112 if (*t)
113 argv[i++]=(LPWSTR)HEAP_strdupW( GetProcessHeap(), 0, t );
114
115 HeapFree( GetProcessHeap(), 0, cmdline );
116 argv[i]=NULL;
117 *numargs=i;
118 return argv;
119}
120
121/*************************************************************************
122 * Control_RunDLL [SHELL32.12]
123 *
124 * Wild speculation in the following!
125 *
126 * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
127 */
128
129ODINPROCEDURE4(Control_RunDLL,HWND, hwnd,
130 LPCVOID,code,
131 LPCSTR, cmd,
132 DWORD, arg4)
133{
134 dprintf(("SHELL32:Shell32_Main:Control_RunDLL not implemented.\n"));
135}
136
137/*************************************************************************
138 * SHGetFileInfoA [SHELL32.254]
139 */
140
141ODINFUNCTION5(DWORD, SHGetFileInfoA, LPCSTR, path,
142 DWORD, dwFileAttributes,
143 SHFILEINFOA*, psfi,
144 UINT, sizeofpsfi,
145 UINT, flags )
146{
147 char szLoaction[MAX_PATH];
148 int iIndex;
149 DWORD ret = TRUE, dwAttributes = 0;
150 IShellFolder * psfParent = NULL;
151 IExtractIconA * pei = NULL;
152 LPITEMIDLIST pidlLast = NULL, pidl = NULL;
153 HRESULT hr = S_OK;
154
155 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA (%s,0x%lx,%p,0x%x,0x%x)\n",
156 (flags & SHGFI_PIDL)? "pidl" : path, dwFileAttributes, psfi, sizeofpsfi, flags));
157
158#ifdef MORE_DEBUG
159 ZeroMemory(psfi, sizeof(SHFILEINFOA));
160#endif
161 if ((flags & SHGFI_USEFILEATTRIBUTES) && (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL)))
162 return FALSE;
163
164 /* windows initializes this values regardless of the flags */
165 psfi->szDisplayName[0] = '\0';
166 psfi->szTypeName[0] = '\0';
167 psfi->iIcon = 0;
168
169 /* translate the path into a pidl only when SHGFI_USEFILEATTRIBUTES in not specified
170 the pidl functions fail on not existing file names */
171 if (flags & SHGFI_PIDL)
172 {
173 pidl = (LPCITEMIDLIST) path;
174 if (!pidl )
175 {
176 dprintf(("pidl is null!\n"));
177 return FALSE;
178 }
179 }
180 else if (!(flags & SHGFI_USEFILEATTRIBUTES))
181 {
182 hr = SHILCreateFromPathA ( path, &pidl, &dwAttributes);
183 /* note: the attributes in ISF::ParseDisplayName are not implemented */
184 }
185
186 /* get the parent shellfolder */
187 if (pidl)
188 {
189 hr = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidlLast);
190 }
191
192 /* get the attributes of the child */
193 if (SUCCEEDED(hr) && (flags & SHGFI_ATTRIBUTES))
194 {
195 if (!(flags & SHGFI_ATTR_SPECIFIED))
196 {
197 psfi->dwAttributes = 0xffffffff;
198 }
199 IShellFolder_GetAttributesOf(psfParent, 1 , &pidlLast, &(psfi->dwAttributes));
200 }
201
202 /* get the displayname */
203 if (SUCCEEDED(hr) && (flags & SHGFI_DISPLAYNAME))
204 {
205 if (flags & SHGFI_USEFILEATTRIBUTES)
206 {
207 strcpy (psfi->szDisplayName, PathFindFileNameA(path));
208 }
209 else
210 {
211 STRRET str;
212 hr = IShellFolder_GetDisplayNameOf(psfParent, pidlLast, SHGDN_INFOLDER, &str);
213 StrRetToStrNA (psfi->szDisplayName, MAX_PATH, &str, pidlLast);
214 }
215 }
216
217 /* get the type name */
218 if (SUCCEEDED(hr) && (flags & SHGFI_TYPENAME))
219 {
220 _ILGetFileType(pidlLast, psfi->szTypeName, 80);
221 }
222
223 /* ### icons ###*/
224 if (flags & SHGFI_LINKOVERLAY)
225 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA set icon to link, stub\n"));
226
227 if (flags & SHGFI_OPENICON)
228 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA set to open icon, stub\n"));
229
230 if (flags & SHGFI_SELECTED)
231 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA set icon to selected, stub\n"));
232
233 if (flags & SHGFI_SHELLICONSIZE)
234 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA set icon to shell size, stub\n"));
235
236 /* get the iconlocation */
237 if (SUCCEEDED(hr) && (flags & SHGFI_ICONLOCATION ))
238 {
239 UINT uDummy,uFlags;
240 hr = IShellFolder_GetUIObjectOf(psfParent, 0, 1, &pidlLast, &IID_IExtractIconA, &uDummy, (LPVOID*)&pei);
241
242 if (SUCCEEDED(hr))
243 {
244 hr = IExtractIconA_GetIconLocation(pei, (flags & SHGFI_OPENICON) ? GIL_OPENICON : 0, szLoaction, MAX_PATH, &iIndex, &uFlags);
245 /* fixme what to do with the index? */
246
247 if(uFlags != GIL_NOTFILENAME)
248 strcpy (psfi->szDisplayName, szLoaction);
249 else
250 ret = FALSE;
251
252 IExtractIconA_Release(pei);
253 }
254 }
255
256 /* get icon index (or load icon)*/
257 if (SUCCEEDED(hr) && (flags & (SHGFI_ICON | SHGFI_SYSICONINDEX)))
258 {
259 if (flags & SHGFI_USEFILEATTRIBUTES)
260 {
261 char sTemp [MAX_PATH];
262 char * szExt;
263 DWORD dwNr=0;
264
265 lstrcpynA(sTemp, path, MAX_PATH);
266 szExt = (LPSTR) PathFindExtensionA(sTemp);
267 if( szExt && HCR_MapTypeToValue(szExt, sTemp, MAX_PATH, TRUE)
268 && HCR_GetDefaultIcon(sTemp, sTemp, MAX_PATH, &dwNr))
269 {
270 if (!strcmp("%1",sTemp)) /* icon is in the file */
271 {
272 strcpy(sTemp, path);
273 }
274 /* FIXME: if sTemp contains a valid filename, get the icon
275 from there, index is in dwNr
276 */
277 psfi->iIcon = 2;
278 }
279 else /* default icon */
280 {
281 psfi->iIcon = 0;
282 }
283 }
284 else
285 {
286 if (!(PidlToSicIndex(psfParent, pidlLast, (flags && SHGFI_LARGEICON),
287 (flags & SHGFI_OPENICON) ? GIL_OPENICON : 0, (PUINT)&(psfi->iIcon))))
288 {
289 ret = FALSE;
290 }
291 }
292 if (ret)
293 {
294 ret = (DWORD) ((flags & SHGFI_LARGEICON) ? ShellBigIconList : ShellSmallIconList);
295 }
296 }
297
298 /* icon handle */
299 if (SUCCEEDED(hr) && (flags & SHGFI_ICON))
300 psfi->hIcon = pImageList_GetIcon((flags && SHGFI_LARGEICON) ? ShellBigIconList:ShellSmallIconList, psfi->iIcon, ILD_NORMAL);
301
302
303 if (flags & SHGFI_EXETYPE)
304 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA type of executable, stub\n"));
305
306 if (flags & (SHGFI_UNKNOWN1 | SHGFI_UNKNOWN2 | SHGFI_UNKNOWN3))
307 dprintf(("SHELL32:Shell32_main:SHGetFileInfoA unknown attribute!\n"));
308
309 if (psfParent)
310 IShellFolder_Release(psfParent);
311
312 if (hr != S_OK)
313 ret = FALSE;
314
315#ifdef MORE_DEBUG
316 TRACE_(shell) ("icon=0x%08x index=0x%08x attr=0x%08lx name=%s type=%s\n",
317 psfi->hIcon, psfi->iIcon, psfi->dwAttributes, psfi->szDisplayName, psfi->szTypeName);
318#endif
319 return ret;
320}
321
322/*************************************************************************
323 * SHGetFileInfoW [SHELL32.255]
324 */
325
326ODINFUNCTION5(DWORD, SHGetFileInfoW, LPCWSTR, path,
327 DWORD, dwFileAttributes,
328 SHFILEINFOW*, psfi,
329 UINT, sizeofpsfi,
330 UINT, flags)
331{
332 dprintf(("SHELL32:Shell32_main:SHGetFileInfoW not implemented\n"));
333 return 0;
334}
335
336
337/*************************************************************************
338 * ExtractIconA [SHELL32.133]
339 */
340
341ODINFUNCTION3(HICON, ExtractIconA, HINSTANCE, hInstance,
342 LPCSTR, lpszExeFileName,
343 UINT, nIconIndex )
344{
345 HGLOBAL handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
346 TRACE_(shell)("\n");
347 if( handle )
348 {
349 HICON* ptr = (HICON*)GlobalLock(handle);
350 HICON hIcon = *ptr;
351
352 GlobalFree(handle);
353 return hIcon;
354 }
355 return 0;
356}
357
358/*************************************************************************
359 * ExtractIconW [SHELL32.180]
360 */
361
362ODINFUNCTION3(HICON, ExtractIconW, HINSTANCE, hInstance,
363 LPCWSTR, lpszExeFileName,
364 UINT, nIconIndex )
365{ LPSTR exefn;
366 HICON ret;
367
368 exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
369 ret = ExtractIconA(hInstance,exefn,nIconIndex);
370
371 HeapFree(GetProcessHeap(),0,exefn);
372 return ret;
373}
374
375/*************************************************************************
376 * FindExecutableA [SHELL32.184]
377 */
378
379ODINFUNCTION3(HINSTANCE, FindExecutableA, LPCSTR, lpFile,
380 LPCSTR, lpDirectory,
381 LPSTR, lpResult )
382{ HINSTANCE retval=31; /* default - 'No association was found' */
383 char old_dir[1024];
384
385 dprintf(("File %s, Dir %s\n",
386 (lpFile != NULL?lpFile:"-"),
387 (lpDirectory != NULL?lpDirectory:"-")));
388
389 lpResult[0]='\0'; /* Start off with an empty return string */
390
391 /* trap NULL parameters on entry */
392 if (( lpFile == NULL ) || ( lpResult == NULL ))
393 { /* FIXME - should throw a warning, perhaps! */
394 return 2; /* File not found. Close enough, I guess. */
395 }
396
397 if (lpDirectory)
398 { GetCurrentDirectoryA( sizeof(old_dir), old_dir );
399 SetCurrentDirectoryA( lpDirectory );
400 }
401
402 retval = SHELL_FindExecutable( lpFile, "open", lpResult );
403
404 dprintf(("returning %s\n", lpResult));
405 if (lpDirectory)
406 SetCurrentDirectoryA( old_dir );
407 return retval;
408}
409
410/*************************************************************************
411 * FindExecutableW [SHELL32.219]
412 */
413ODINFUNCTION3(HINSTANCE, FindExecutableW, LPCWSTR, lpFile,
414 LPCWSTR, lpDirectory,
415 LPWSTR, lpResult )
416{
417 dprintf(("FindExecutableW not implemented.\n"));
418 return 31; /* default - 'No association was found' */
419}
420
421typedef struct
422{ LPCSTR szApp;
423 LPCSTR szOtherStuff;
424 HICON hIcon;
425} ABOUT_INFO;
426
427#define IDC_STATIC_TEXT 100
428#define IDC_LISTBOX 99
429#define IDC_ODIN_TEXT 98
430
431#define DROP_FIELD_TOP (-15)
432#define DROP_FIELD_HEIGHT 15
433
434#if 0 //CB: not used
435extern HICON hIconTitleFont;
436#endif
437
438static BOOL __get_dropline( HWND hWnd, LPRECT lprect )
439{ HWND hWndCtl = GetDlgItem(hWnd, IDC_ODIN_TEXT);
440 if( hWndCtl )
441 { GetWindowRect( hWndCtl, lprect );
442 MapWindowPoints( 0, hWnd, (LPPOINT)lprect, 2 );
443 lprect->bottom = (lprect->top += DROP_FIELD_TOP);
444 return TRUE;
445 }
446 return FALSE;
447}
448
449/*************************************************************************
450 * SHAppBarMessage32 [SHELL32.207]
451 */
452
453ODINFUNCTION2(UINT, SHAppBarMessage, DWORD, msg,
454 PAPPBARDATA, data)
455{
456 int width=data->rc.right - data->rc.left;
457 int height=data->rc.bottom - data->rc.top;
458 RECT rec=data->rc;
459
460 dprintf(("SHELL32: SHAppBarMessage.\n"));
461
462 switch (msg)
463 { case ABM_GETSTATE:
464 return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
465 case ABM_GETTASKBARPOS:
466 GetWindowRect(data->hWnd, &rec);
467 data->rc=rec;
468 return TRUE;
469 case ABM_ACTIVATE:
470 SetActiveWindow(data->hWnd);
471 return TRUE;
472 case ABM_GETAUTOHIDEBAR:
473 data->hWnd=GetActiveWindow();
474 return TRUE;
475 case ABM_NEW:
476 SetWindowPos(data->hWnd,HWND_TOP,rec.left,rec.top,
477 width,height,SWP_SHOWWINDOW);
478 return TRUE;
479 case ABM_QUERYPOS:
480 GetWindowRect(data->hWnd, &(data->rc));
481 return TRUE;
482 case ABM_REMOVE:
483 CloseHandle(data->hWnd);
484 return TRUE;
485 case ABM_SETAUTOHIDEBAR:
486 SetWindowPos(data->hWnd,HWND_TOP,rec.left+1000,rec.top,
487 width,height,SWP_SHOWWINDOW);
488 return TRUE;
489 case ABM_SETPOS:
490 data->uEdge=(ABE_RIGHT | ABE_LEFT);
491 SetWindowPos(data->hWnd,HWND_TOP,data->rc.left,data->rc.top,
492 width,height,SWP_SHOWWINDOW);
493 return TRUE;
494 case ABM_WINDOWPOSCHANGED:
495 SetWindowPos(data->hWnd,HWND_TOP,rec.left,rec.top,
496 width,height,SWP_SHOWWINDOW);
497 return TRUE;
498 }
499 return FALSE;
500}
501
502/*************************************************************************
503 * SHHelpShortcuts_RunDLL [SHELL32.224]
504 *
505 */
506
507ODINFUNCTION4(DWORD, SHHelpShortcuts_RunDLL, DWORD, dwArg1,
508 DWORD, dwArg2,
509 DWORD, dwArg3,
510 DWORD, dwArg4)
511{
512 dprintf(("SHELL32:Shell32_Main:SHHelpShortcuts_RunDLL not implemented.\n"));
513 return 0;
514}
515
516/*************************************************************************
517 * SHLoadInProc [SHELL32.225]
518 * Create an instance of specified object class from within the shell process
519 */
520
521ODINFUNCTION1(DWORD, SHLoadInProc, REFCLSID, rclsid)
522{
523 dprintf(("SHELL32: SHLoadInProc\n"));
524
525 IUnknown *pUnk = NULL;
526 CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (LPVOID*)pUnk);
527 if (pUnk)
528 {
529 IUnknown_Release(pUnk);
530 return NOERROR;
531 }
532 return DISP_E_MEMBERNOTFOUND;
533}
534
535
536
537/*************************************************************************
538 * ShellExecuteA [SHELL32.245]
539 */
540
541ODINFUNCTION6(HINSTANCE, ShellExecuteA, HWND, hWnd,
542 LPCSTR, lpOperation,
543 LPCSTR, lpFile,
544 LPCSTR, lpParameters,
545 LPCSTR, lpDirectory,
546 INT, iShowCmd )
547{ HINSTANCE retval=31;
548 char old_dir[1024];
549 char cmd[256];
550
551 if (lpFile==NULL) return 0; /* should not happen */
552 if (lpOperation==NULL) /* default is open */
553 lpOperation="open";
554
555 if (lpDirectory)
556 { GetCurrentDirectoryA( sizeof(old_dir), old_dir );
557 SetCurrentDirectoryA( lpDirectory );
558 }
559
560 cmd[0] = '\0';
561 retval = SHELL_FindExecutable( lpFile, lpOperation, cmd );
562
563 if (retval > 32) /* Found */
564 {
565 if (lpParameters)
566 {
567 strcat(cmd," ");
568 strcat(cmd,lpParameters);
569 }
570
571 dprintf(("starting %s\n",cmd));
572 retval = WinExec( cmd, iShowCmd );
573 }
574 else if(PathIsURLA((LPSTR)lpFile)) /* File not found, check for URL */
575 {
576 char lpstrProtocol[256];
577 LONG cmdlen = 512;
578 LPSTR lpstrRes;
579 INT iSize;
580
581 lpstrRes = strchr(lpFile,':');
582 iSize = lpstrRes - lpFile;
583
584 /* Looking for ...protocol\shell\lpOperation\command */
585 strncpy(lpstrProtocol,lpFile,iSize);
586 lpstrProtocol[iSize]='\0';
587 strcat( lpstrProtocol, "\\shell\\" );
588 strcat( lpstrProtocol, lpOperation );
589 strcat( lpstrProtocol, "\\command" );
590
591 /* Remove File Protocol from lpFile */
592 /* In the case file://path/file */
593 if(!strnicmp(lpFile,"file",iSize))
594 {
595 lpFile += iSize;
596 while(*lpFile == ':') lpFile++;
597 }
598
599
600 /* Get the application for the protocol and execute it */
601 if (RegQueryValueA( HKEY_CLASSES_ROOT, lpstrProtocol, cmd,
602 &cmdlen ) == ERROR_SUCCESS )
603 {
604 LPSTR tok;
605 LPSTR tmp;
606 char param[256] = "";
607 LONG paramlen = 256;
608
609 /* Get the parameters needed by the application
610 from the associated ddeexec key */
611 tmp = strstr(lpstrProtocol,"command");
612 tmp[0] = '\0';
613 strcat(lpstrProtocol,"ddeexec");
614
615 if(RegQueryValueA( HKEY_CLASSES_ROOT, lpstrProtocol, param,&paramlen ) == ERROR_SUCCESS)
616 {
617 strcat(cmd," ");
618 strcat(cmd,param);
619 cmdlen += paramlen;
620 }
621
622 /* Is there a replace() function anywhere? */
623 cmd[cmdlen]='\0';
624 tok=strstr( cmd, "%1" );
625 if (tok != NULL)
626 {
627 tok[0]='\0'; /* truncate string at the percent */
628 strcat( cmd, lpFile ); /* what if no dir in xlpFile? */
629 tok=strstr( cmd, "%1" );
630 if ((tok!=NULL) && (strlen(tok)>2))
631 {
632 strcat( cmd, &tok[2] );
633 }
634 }
635
636 retval = WinExec( cmd, iShowCmd );
637 }
638 }
639 /* Check if file specified is in the form www.??????.*** */
640 else if(!strnicmp(lpFile,"www",3))
641 {
642 /* if so, append lpFile http:// and call ShellExecute */
643 char lpstrTmpFile[256] = "http://" ;
644 strcat(lpstrTmpFile,lpFile);
645 retval = ShellExecuteA(hWnd,lpOperation,lpstrTmpFile,NULL,NULL,0);
646 }
647 /* Nothing was done yet, try to execute the cmdline directly,
648 maybe it's an OS/2 program */
649 else
650 {
651 strcpy(cmd,lpFile);
652 strcat(cmd,lpParameters ? lpParameters : "");
653 retval = WinExec( cmd, iShowCmd );
654 }
655
656 if (lpDirectory)
657 SetCurrentDirectoryA( old_dir );
658 return retval;
659}
660
661
662/*************************************************************************
663 * ShellExecuteW [SHELL32.294]
664 * from shellapi.h
665 * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation,
666 * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
667 */
668
669ODINFUNCTION6(HINSTANCE, ShellExecuteW, HWND, hWnd,
670 LPCWSTR, lpOperation,
671 LPCWSTR, lpFile,
672 LPCWSTR, lpParameters,
673 LPCWSTR, lpDirectory,
674 INT, iShowCmd )
675{
676 dprintf(("SHELL32:Shell32_Main:ShellExecuteW not implemented\n"));
677 return 0;
678}
679
680
681/*************************************************************************
682 * AboutDlgProc32 (internal)
683 */
684#define IDC_ODINLOGO 2001
685#define IDB_ODINLOGO 5555
686
687BOOL WINAPI AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam,
688 LPARAM lParam )
689{
690 HWND hWndCtl;
691 char Template[512], AppTitle[512];
692
693 switch(msg)
694 {
695 case WM_INITDIALOG:
696 {
697 ABOUT_INFO *info = (ABOUT_INFO *)lParam;
698 if(info)
699 {
700 const char* const *pstr = SHELL_People;
701
702 SendDlgItemMessageA(hWnd, stc1, STM_SETICON,info->hIcon, 0);
703 GetWindowTextA( hWnd, Template, sizeof(Template) );
704 sprintf( AppTitle, Template, info->szApp );
705 SetWindowTextA( hWnd, AppTitle );
706 SetWindowTextA( GetDlgItem(hWnd, IDC_STATIC_TEXT), info->szOtherStuff );
707
708 HWND hwndOdinLogo = GetDlgItem(hWnd, IDC_ODINLOGO);
709 if(hwndOdinLogo) {
710 HBITMAP hBitmap = LoadBitmapA(shell32_hInstance, MAKEINTRESOURCEA(IDB_ODINLOGO));
711 SendMessageA(hwndOdinLogo, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
712 }
713
714 hWndCtl = GetDlgItem(hWnd, IDC_LISTBOX);
715 SendMessageA( hWndCtl, WM_SETREDRAW, 0, 0 );
716#if 0 //CB: not used (hIconTitleFont not valid!!!), default font is ok
717 SendMessageA( hWndCtl, WM_SETFONT, hIconTitleFont, 0 );
718#endif
719 while (*pstr)
720 {
721 SendMessageA( hWndCtl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)*pstr );
722 pstr++;
723 }
724 SendMessageA( hWndCtl, WM_SETREDRAW, 1, 0 );
725 }
726 return 1;
727 }
728
729 case WM_PAINT:
730 {
731 RECT rect;
732 PAINTSTRUCT ps;
733 HDC hDC = BeginPaint( hWnd, &ps );
734
735 if( __get_dropline( hWnd, &rect ) ) {
736 SelectObject( hDC, GetStockObject( BLACK_PEN ) );
737 MoveToEx( hDC, rect.left, rect.top, NULL );
738 LineTo( hDC, rect.right, rect.bottom );
739 }
740 EndPaint( hWnd, &ps );
741 break;
742 }
743
744 case WM_LBTRACKPOINT:
745 hWndCtl = GetDlgItem(hWnd, IDC_LISTBOX);
746 if( (INT)GetKeyState( VK_CONTROL ) < 0 )
747 { if( DragDetect( hWndCtl, *((LPPOINT)&lParam) ) )
748 { INT idx = SendMessageA( hWndCtl, LB_GETCURSEL, 0, 0 );
749 if( idx != -1 )
750 { INT length = SendMessageA( hWndCtl, LB_GETTEXTLEN, (WPARAM)idx, 0 );
751 HGLOBAL hMemObj = GlobalAlloc( GMEM_MOVEABLE, length + 1 );
752 char* pstr = (char*)GlobalLock( hMemObj );
753
754 if( pstr )
755 { HCURSOR hCursor = LoadCursorA( 0, (LPCSTR)OCR_DRAGOBJECT );
756 SendMessageA( hWndCtl, LB_GETTEXT, (WPARAM)idx, (LPARAM)pstr );
757 SendMessageA( hWndCtl, LB_DELETESTRING, (WPARAM)idx, 0 );
758 UpdateWindow( hWndCtl );
759
760 if( !DragObject(hWnd, hWnd, DRAGOBJ_DATA, hMemObj, hCursor) )
761 SendMessageA( hWndCtl, LB_ADDSTRING, (WPARAM)-1, (LPARAM)pstr );
762 }
763 if( hMemObj )
764 GlobalFree( hMemObj );
765 }
766 }
767 }
768 break;
769
770 case WM_QUERYDROPOBJECT:
771 if( wParam == 0 )
772 { LPDRAGINFO lpDragInfo = (LPDRAGINFO)lParam;
773 if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA )
774 { RECT rect;
775 if( __get_dropline( hWnd, &rect ) )
776 { POINT pt;
777 pt.x=lpDragInfo->pt.x;
778 pt.x=lpDragInfo->pt.y;
779 rect.bottom += DROP_FIELD_HEIGHT;
780 if( PtInRect( &rect, pt ) )
781 { SetWindowLongA( hWnd, DWL_MSGRESULT, 1 );
782 return TRUE;
783 }
784 }
785 }
786 }
787 break;
788
789 case WM_DROPOBJECT:
790 if( wParam == hWnd )
791 { LPDRAGINFO lpDragInfo = (LPDRAGINFO)lParam;
792 if( lpDragInfo && lpDragInfo->wFlags == DRAGOBJ_DATA && lpDragInfo->hList )
793 { char* pstr = (char*)GlobalLock( (HGLOBAL)(lpDragInfo->hList) );
794 if( pstr )
795 { static char __appendix_str[] = " with";
796
797 hWndCtl = GetDlgItem( hWnd, IDC_ODIN_TEXT );
798 SendMessageA( hWndCtl, WM_GETTEXT, 512, (LPARAM)Template );
799 if( !strncmp( Template, "ODIN", 4 ) )
800 SetWindowTextA( GetDlgItem(hWnd, IDC_STATIC_TEXT), Template );
801 else
802 { char* pch = Template + strlen(Template) - strlen(__appendix_str);
803 *pch = '\0';
804 SendMessageA( GetDlgItem(hWnd, IDC_LISTBOX), LB_ADDSTRING,
805 (WPARAM)-1, (LPARAM)Template );
806 }
807
808 strcpy( Template, pstr );
809 strcat( Template, __appendix_str );
810 SetWindowTextA( hWndCtl, Template );
811 SetWindowLongA( hWnd, DWL_MSGRESULT, 1 );
812 return TRUE;
813 }
814 }
815 }
816 break;
817
818 case WM_COMMAND:
819 if (wParam == IDOK)
820 {
821 EndDialog(hWnd, TRUE);
822 return TRUE;
823 }
824 break;
825
826 case WM_CLOSE:
827 EndDialog(hWnd, TRUE);
828 break;
829 }
830 return 0;
831}
832
833
834/*************************************************************************
835 * ShellAboutA [SHELL32.243]
836 */
837
838ODINFUNCTION4(INT,ShellAboutA, HWND, hWnd,
839 LPCSTR, szApp,
840 LPCSTR, szOtherStuff,
841 HICON, hIcon )
842{ ABOUT_INFO info;
843 HRSRC hRes;
844 LPVOID dlgTemplate;
845
846 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA)))
847 return FALSE;
848 if(!(dlgTemplate = (LPVOID)LoadResource(shell32_hInstance, hRes)))
849 return FALSE;
850
851 info.szApp = szApp;
852 info.szOtherStuff = szOtherStuff;
853 info.hIcon = hIcon;
854 if (!hIcon) info.hIcon = LoadIconA( 0, MAKEINTRESOURCEA(OIC_ODINICON) );
855 return DialogBoxIndirectParamA( GetWindowLongA( hWnd, GWL_HINSTANCE ),
856 (DLGTEMPLATE*)dlgTemplate , hWnd, AboutDlgProc, (LPARAM)&info );
857}
858
859
860/*************************************************************************
861 * ShellAboutW [SHELL32.244]
862 */
863ODINFUNCTION4(INT,ShellAboutW, HWND, hWnd,
864 LPCWSTR, szApp,
865 LPCWSTR, szOtherStuff,
866 HICON, hIcon )
867{ INT ret;
868 ABOUT_INFO info;
869 HRSRC hRes;
870 LPVOID dlgTemplate;
871
872 if(!(hRes = FindResourceA(shell32_hInstance, "SHELL_ABOUT_MSGBOX", RT_DIALOGA)))
873 return FALSE;
874 if(!(dlgTemplate = (LPVOID)LoadResource(shell32_hInstance, hRes)))
875 return FALSE;
876
877 info.szApp = HEAP_strdupWtoA( GetProcessHeap(), 0, szApp );
878 info.szOtherStuff = HEAP_strdupWtoA( GetProcessHeap(), 0, szOtherStuff );
879 info.hIcon = hIcon;
880 if (!hIcon) info.hIcon = LoadIconA( 0, MAKEINTRESOURCEA(OIC_ODINICON) );
881 ret = DialogBoxIndirectParamA( GetWindowLongA( hWnd, GWL_HINSTANCE ),
882 (DLGTEMPLATE*)dlgTemplate, hWnd, AboutDlgProc, (LPARAM)&info );
883 HeapFree( GetProcessHeap(), 0, (LPSTR)info.szApp );
884 HeapFree( GetProcessHeap(), 0, (LPSTR)info.szOtherStuff );
885 return ret;
886}
887
888/*************************************************************************
889 * FreeIconList
890 */
891
892ODINPROCEDURE1(FreeIconList,DWORD,dw)
893{
894 dprintf(("SHELL32:Shell32_Main:FreeIconList not implemented.\n"));
895}
896
897/***********************************************************************
898 * DllGetVersion [COMCTL32.25]
899 *
900 * Retrieves version information of the 'SHELL32.DLL'
901 *
902 * PARAMS
903 * pdvi [O] pointer to version information structure.
904 *
905 * RETURNS
906 * Success: S_OK
907 * Failure: E_INVALIDARG
908 *
909 * NOTES
910 * Returns version of a shell32.dll from IE4.01 SP1.
911 */
912
913ODINFUNCTION1(HRESULT, SHELL32_DllGetVersion, DLLVERSIONINFO*, pdvi)
914{
915 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
916 { dprintf(("wrong DLLVERSIONINFO size from app\n"));
917 return E_INVALIDARG;
918 }
919
920 pdvi->dwMajorVersion = 4;
921 pdvi->dwMinorVersion = 72;
922 pdvi->dwBuildNumber = 3110;
923 pdvi->dwPlatformID = 1;
924
925 dprintf(("%lu.%lu.%lu.%lu\n",
926 pdvi->dwMajorVersion, pdvi->dwMinorVersion,
927 pdvi->dwBuildNumber, pdvi->dwPlatformID));
928
929 return S_OK;
930}
931/*************************************************************************
932 * global variables of the shell32.dll
933 * all are once per process
934 *
935 */
936void (WINAPI* pDLLInitComctl)(LPVOID);
937INT (WINAPI* pImageList_AddIcon) (HIMAGELIST himl, HICON hIcon);
938INT (WINAPI* pImageList_ReplaceIcon) (HIMAGELIST, INT, HICON);
939HIMAGELIST (WINAPI * pImageList_Create) (INT,INT,UINT,INT,INT);
940BOOL (WINAPI* pImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle);
941HICON (WINAPI * pImageList_GetIcon) (HIMAGELIST, INT, UINT);
942INT (WINAPI* pImageList_GetImageCount)(HIMAGELIST);
943COLORREF (WINAPI *pImageList_SetBkColor)(HIMAGELIST, COLORREF);
944
945LPVOID (WINAPI* pCOMCTL32_Alloc) (INT);
946BOOL (WINAPI* pCOMCTL32_Free) (LPVOID);
947
948HDPA (WINAPI* pDPA_Create) (INT);
949INT (WINAPI* pDPA_InsertPtr) (const HDPA, INT, LPVOID);
950BOOL (WINAPI* pDPA_Sort) (const HDPA, PFNDPACOMPARE, LPARAM);
951LPVOID (WINAPI* pDPA_GetPtr) (const HDPA, INT);
952BOOL (WINAPI* pDPA_Destroy) (const HDPA);
953INT (WINAPI *pDPA_Search) (const HDPA, LPVOID, INT, PFNDPACOMPARE, LPARAM, UINT);
954LPVOID (WINAPI *pDPA_DeletePtr) (const HDPA hdpa, INT i);
955
956/* user32 */
957HICON (WINAPI *pLookupIconIdFromDirectoryEx)(LPBYTE dir, BOOL bIcon, INT width, INT height, UINT cFlag);
958HICON (WINAPI *pCreateIconFromResourceEx)(LPBYTE bits,UINT cbSize, BOOL bIcon, DWORD dwVersion, INT width, INT height,UINT cFlag);
959
960
961static HINSTANCE hComctl32;
962static HINSTANCE hOle32;
963static INT shell32_RefCount = 0;
964
965LONG shell32_ObjCount = 0;
966HINSTANCE shell32_hInstance = 0;
967HMODULE huser32 = 0;
968HIMAGELIST ShellSmallIconList = 0;
969HIMAGELIST ShellBigIconList = 0;
970
971/*************************************************************************
972 * SHELL32 LibMain
973 *
974 * NOTES
975 * calling oleinitialize here breaks sone apps.
976 */
977
978static void Shell32ProcLoadHelper(LPVOID* pAddr,
979 HANDLE hModule,
980 LPCSTR lpstrName)
981{
982 *pAddr = (void*)GetProcAddress(hModule,lpstrName);
983
984 if (!pAddr)
985 dprintf(("Shell32: Shell32ProcLoadHelper(%08xh,%08xh,%s) failed!\n",
986 pAddr,
987 hModule,
988 lpstrName));
989}
990
991
992ODINFUNCTION3(BOOL, Shell32LibMain, HINSTANCE, hinstDLL,
993 DWORD, fdwReason,
994 LPVOID, fImpLoad)
995{
996 HMODULE hUser32;
997
998 switch (fdwReason)
999 {
1000 case DLL_PROCESS_ATTACH:
1001 shell32_RefCount++;
1002 if (shell32_hInstance)
1003 {
1004 dprintf(("shell32.dll instantiated twice in one address space!\n"));
1005 }
1006 else
1007 {
1008 /* we only want to call this the first time shell32 is instantiated */
1009 SHInitRestricted(NULL, NULL);
1010 }
1011
1012 shell32_hInstance = hinstDLL;
1013
1014 hComctl32 = LoadLibraryA("COMCTL32.DLL");
1015 hOle32 = LoadLibraryA("OLE32.DLL");
1016 hUser32 = GetModuleHandleA("USER32");
1017
1018 if (!hComctl32 || !hUser32 || !hOle32)
1019 {
1020 dprintf(("P A N I C SHELL32 loading failed\n"));
1021 return FALSE;
1022 }
1023
1024 /* comctl32 */
1025 Shell32ProcLoadHelper((LPVOID*)&pDLLInitComctl,hComctl32,"InitCommonControlsEx");
1026 Shell32ProcLoadHelper((LPVOID*)&pImageList_Create,hComctl32,"ImageList_Create");
1027 Shell32ProcLoadHelper((LPVOID*)&pImageList_AddIcon,hComctl32,"ImageList_AddIcon");
1028 Shell32ProcLoadHelper((LPVOID*)&pImageList_ReplaceIcon,hComctl32,"ImageList_ReplaceIcon");
1029 Shell32ProcLoadHelper((LPVOID*)&pImageList_GetIcon,hComctl32,"ImageList_GetIcon");
1030 Shell32ProcLoadHelper((LPVOID*)&pImageList_GetImageCount,hComctl32,"ImageList_GetImageCount");
1031 Shell32ProcLoadHelper((LPVOID*)&pImageList_Draw,hComctl32,"ImageList_Draw");
1032 Shell32ProcLoadHelper((LPVOID*)&pImageList_SetBkColor,hComctl32,"ImageList_SetBkColor");
1033 Shell32ProcLoadHelper((LPVOID*)&pCOMCTL32_Alloc,hComctl32, (LPCSTR)71L);
1034 Shell32ProcLoadHelper((LPVOID*)&pCOMCTL32_Free,hComctl32, (LPCSTR)73L);
1035 Shell32ProcLoadHelper((LPVOID*)&pDPA_Create,hComctl32, (LPCSTR)328L);
1036 Shell32ProcLoadHelper((LPVOID*)&pDPA_Destroy,hComctl32, (LPCSTR)329L);
1037 Shell32ProcLoadHelper((LPVOID*)&pDPA_GetPtr,hComctl32, (LPCSTR)332L);
1038 Shell32ProcLoadHelper((LPVOID*)&pDPA_InsertPtr,hComctl32, (LPCSTR)334L);
1039 Shell32ProcLoadHelper((LPVOID*)&pDPA_DeletePtr,hComctl32, (LPCSTR)336L);
1040 Shell32ProcLoadHelper((LPVOID*)&pDPA_Sort,hComctl32, (LPCSTR)338L);
1041 Shell32ProcLoadHelper((LPVOID*)&pDPA_Search,hComctl32, (LPCSTR)339L);
1042 /* user32 */
1043 Shell32ProcLoadHelper((LPVOID*)&pLookupIconIdFromDirectoryEx,hUser32,"LookupIconIdFromDirectoryEx");
1044 Shell32ProcLoadHelper((LPVOID*)&pCreateIconFromResourceEx,hUser32,"CreateIconFromResourceEx");
1045 /* ole2 */
1046 Shell32ProcLoadHelper((LPVOID*)&pOleInitialize,hOle32,"OleInitialize");
1047 Shell32ProcLoadHelper((LPVOID*)&pOleUninitialize,hOle32,"OleUninitialize");
1048 Shell32ProcLoadHelper((LPVOID*)&pDoDragDrop,hOle32,"DoDragDrop");
1049 Shell32ProcLoadHelper((LPVOID*)&pRegisterDragDrop,hOle32,"RegisterDragDrop");
1050 Shell32ProcLoadHelper((LPVOID*)&pRevokeDragDrop,hOle32,"RevokeDragDrop");
1051
1052 /* initialize the common controls */
1053 if (pDLLInitComctl)
1054 {
1055 pDLLInitComctl(NULL);
1056 }
1057
1058 SIC_Initialize();
1059 SYSTRAY_Init();
1060
1061 break;
1062
1063 case DLL_THREAD_ATTACH:
1064 shell32_RefCount++;
1065 break;
1066
1067 case DLL_THREAD_DETACH:
1068 shell32_RefCount--;
1069 break;
1070
1071 case DLL_PROCESS_DETACH:
1072 shell32_RefCount--;
1073
1074 if ( !shell32_RefCount )
1075 {
1076 shell32_hInstance = 0;
1077
1078 if (pdesktopfolder)
1079 {
1080 IShellFolder_Release(pdesktopfolder);
1081 pdesktopfolder = NULL;
1082 }
1083
1084 SIC_Destroy();
1085
1086 /* this one is here to check if AddRef/Release is balanced */
1087 if (shell32_ObjCount)
1088 {
1089 dprintf(("leaving with %u objects left (memory leak)\n", shell32_ObjCount));
1090 }
1091 }
1092
1093 FreeLibrary(hOle32);
1094 FreeLibrary(hComctl32);
1095
1096 dprintf(("refcount=%u objcount=%u \n", shell32_RefCount, shell32_ObjCount));
1097 break;
1098 }
1099 return TRUE;
1100}
1101
1102/*************************************************************************
1103 * DllInstall [SHELL32.202]
1104 *
1105 * PARAMETERS
1106 *
1107 * BOOL bInstall - TRUE for install, FALSE for uninstall
1108 * LPCWSTR pszCmdLine - command line (unused by shell32?)
1109 */
1110
1111HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
1112{
1113 FIXME("(%s, %s): stub!\n", bInstall ? "TRUE":"FALSE", debugstr_w(cmdline));
1114
1115 return S_OK; /* indicate success */
1116}
1117
Note: See TracBrowser for help on using the repository browser.