Sync to Wine-0_9_2: Francois Gouget fgouget@free.fr - Remove spaces before '\n' in traces. Dmitry Timoshkov dmitry@codeweavers.com - Unconditionally fall back to ANSI DDE APIs in ShellExecute if current emulated Windows version is Win9x, Excel refuses to communicate with a unicode client in win9x mode. Martin Fuchs martin-fuchs@gmx.net - SHGetFileInfoW(): handle SHGFI_LINKOVERLAY and SHGFI_OVERLAYINDEX. - SHMapPIDLToSystemImageListIndex(): determine overlay flag for PidlToSicIndex() and return -1 in error cases. - Read shell overlay icon settings from registry to allow icon overrides. Markus Amsler markus.amsler@oribi.org - Markus Amsler markus.amsler@oribi.org Improve c2man Documented-Total count. Changes: - add missing description - add missing returns section - complete missing A/W pairs - reformate comments, to match c2man requirements Ge van Geldorp gvg@reactos.org - Hack around missing icons Modified: trunk/reactos/lib/shell32/brsfolder.c Modified: trunk/reactos/lib/shell32/iconcache.c Modified: trunk/reactos/lib/shell32/shell32_main.c Modified: trunk/reactos/lib/shell32/shell32_main.h Modified: trunk/reactos/lib/shell32/shellpath.c Modified: trunk/reactos/lib/shell32/shfldr_desktop.c Modified: trunk/reactos/lib/shell32/shfldr_mycomp.c _____
Modified: trunk/reactos/lib/shell32/brsfolder.c --- trunk/reactos/lib/shell32/brsfolder.c 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/brsfolder.c 2005-11-25 23:49:10 UTC (rev 19593) @@ -679,11 +679,11 @@
info.lpBrowseInfo = lpbi; info.hwndTreeView = NULL;
- hr = CoInitialize(NULL); + hr = OleInitialize(NULL); r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner, BrsFolderDlgProc, (LPARAM)&info ); if (SUCCEEDED(hr)) - CoUninitialize(); + OleUninitialize(); if (!r) return NULL;
_____
Modified: trunk/reactos/lib/shell32/iconcache.c --- trunk/reactos/lib/shell32/iconcache.c 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/iconcache.c 2005-11-25 23:49:10 UTC (rev 19593) @@ -96,6 +96,9 @@
return 0; }
+/* declare SIC_LoadOverlayIcon() */ +static int SIC_LoadOverlayIcon(int idx); +
/*********************************************************************** ****** * SIC_OverlayShortcutImage [internal] * @@ -103,7 +106,7 @@ * Creates a new icon as a copy of the passed-in icon, overlayed with a * shortcut image. */ -static HICON SIC_OverlayShortcutImage(HICON SourceIcon) +static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large) { ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo; HICON ShortcutIcon, TargetIcon; BITMAP SourceBitmapInfo, ShortcutBitmapInfo; @@ -115,15 +118,28 @@ OldShortcutBitmap = NULL, OldTargetBitmap = NULL;
+ static int s_imgListIdx = -1; + /* Get information about the source icon and shortcut overlay */ if (! GetIconInfo(SourceIcon, &SourceIconInfo) || 0 == GetObjectW(SourceIconInfo.hbmColor, sizeof(BITMAP), &SourceBitmapInfo)) { return NULL; } - ShortcutIcon = LoadImageW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_SHORTCUT), - IMAGE_ICON, SourceBitmapInfo.bmWidth, SourceBitmapInfo.bmWidth, - LR_SHARED); + + /* search for the shortcut icon only once */ + if (s_imgListIdx == -1) + s_imgListIdx = SIC_LoadOverlayIcon(-IDI_SHELL_SHORTCUT); + + if (s_imgListIdx != -1) + { + if (large) + ShortcutIcon = ImageList_GetIcon(ShellBigIconList, s_imgListIdx, ILD_TRANSPARENT); + else + ShortcutIcon = ImageList_GetIcon(ShellSmallIconList, s_imgListIdx, ILD_TRANSPARENT); + } else + ShortcutIcon = NULL; + if (NULL == ShortcutIcon || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo) || 0 == GetObjectW(ShortcutIconInfo.hbmColor, sizeof(BITMAP), &ShortcutBitmapInfo)) @@ -313,8 +329,8 @@
if (0 != (dwFlags & GIL_FORSHORTCUT)) { - hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge); - hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall); + hiconLargeShortcut = SIC_OverlayShortcutImage(hiconLarge, TRUE); + hiconSmallShortcut = SIC_OverlayShortcutImage(hiconSmall, FALSE); if (NULL != hiconLargeShortcut && NULL != hiconSmallShortcut) { hiconLarge = hiconLargeShortcut; @@ -456,6 +472,52 @@ LeaveCriticalSection(&SHELL32_SicCS); }
+/********************************************************************** ******* + * SIC_LoadOverlayIcon [internal] + * + * Load a shell overlay icon and return its icon cache index. + */ +static int SIC_LoadOverlayIcon(int idx) +{ + WCHAR buffer[1024], wszIdx[8]; + HKEY hKeyShellIcons; + LPCWSTR iconPath; + int iconIdx; + + static const WCHAR wszShellIcons[] = { + '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','\', + 'E','x','p','l','o','r','e','r','\','S','h','e','l','l',' ','I','c','o','n','s',0 + }; + static const WCHAR wszNumFmt[] = {'%','d',0}; + + iconPath = swShell32Name; /* default: load icon from shell32.dll */ + iconIdx = idx; + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszShellIcons, 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS) + { + DWORD count = sizeof(buffer); + + sprintfW(wszIdx, wszNumFmt, idx); + + /* read icon path and index */ + if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS) + { + LPWSTR p = strchrW(buffer, ','); + + if (p) + *p++ = 0; + + iconPath = buffer; + iconIdx = atoiW(p); + } + + RegCloseKey(hKeyShellIcons); + } + + return SIC_LoadIcon(iconPath, iconIdx, 0); +} +
/*********************************************************************** ** * Shell_GetImageList [SHELL32.71] * @@ -494,29 +556,15 @@ { IExtractIconW *ei; WCHAR szIconFile[MAX_PATH]; /* file containing the icon */ - char szTemp[MAX_PATH]; INT iSourceIndex; /* index or resID(negated) in this file */ BOOL ret = FALSE; UINT dwFlags = 0; - HKEY keyCls; int iShortcutDefaultIndex = INVALID_INDEX;
TRACE("sf=%p pidl=%p %s\n", sh, pidl, bBigIcon?"Big":"Small");
if (SUCCEEDED (IShellFolder_GetUIObjectOf(sh, 0, 1, &pidl, &IID_IExtractIconW, 0, (void **)&ei))) { - if (_ILGetExtension(pidl, szTemp, MAX_PATH) && - HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE)) - { - if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls)) - { - if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL)) - { - uFlags |= GIL_FORSHORTCUT; - } - RegCloseKey(keyCls); - } - } if (SUCCEEDED(IExtractIconW_GetIconLocation(ei, uFlags, szIconFile, MAX_PATH, &iSourceIndex, &dwFlags))) { *pIndex = SIC_GetIconIndex(szIconFile, iSourceIndex, uFlags); @@ -560,15 +608,19 @@ int *pIndex) { int Index; + UINT uGilFlags = 0;
TRACE("(SF=%p,pidl=%p,%p)\n",sh,pidl,pIndex); pdump(pidl);
+ if (SHELL_IsShortcut(pidl)) + uGilFlags |= GIL_FORSHORTCUT; + if (pIndex) - if (!PidlToSicIndex ( sh, pidl, 1, 0, pIndex)) - *pIndex = -1; + if (!PidlToSicIndex ( sh, pidl, 1, uGilFlags, pIndex)) + *pIndex = -1;
- if (!PidlToSicIndex ( sh, pidl, 0, 0, &Index)) + if (!PidlToSicIndex ( sh, pidl, 0, uGilFlags, &Index)) return -1;
return Index; _____
Modified: trunk/reactos/lib/shell32/shell32_main.c --- trunk/reactos/lib/shell32/shell32_main.c 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/shell32_main.c 2005-11-25 23:49:10 UTC (rev 19593) @@ -297,6 +297,32 @@
return 0; }
+/********************************************************************** *** + * SHELL_IsShortcut [internal] + * + * Decide if an item id list points to a shell shortcut + */ +BOOL SHELL_IsShortcut(LPCITEMIDLIST pidlLast) +{ + char szTemp[MAX_PATH]; + HKEY keyCls; + BOOL ret = FALSE; + + if (_ILGetExtension(pidlLast, szTemp, MAX_PATH) && + HCR_MapTypeToValueA(szTemp, szTemp, MAX_PATH, TRUE)) + { + if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_CLASSES_ROOT, szTemp, 0, KEY_QUERY_VALUE, &keyCls)) + { + if (ERROR_SUCCESS == RegQueryValueExA(keyCls, "IsShortcut", NULL, NULL, NULL, NULL)) + ret = TRUE; + + RegCloseKey(keyCls); + } + } + + return ret; +} + #define SHGFI_KNOWN_FLAGS \ (SHGFI_SMALLICON | SHGFI_OPENICON | SHGFI_SHELLICONSIZE | SHGFI_PIDL | \ SHGFI_USEFILEATTRIBUTES | SHGFI_ADDOVERLAYS | SHGFI_OVERLAYINDEX | \ @@ -320,6 +346,7 @@ LPITEMIDLIST pidlLast = NULL, pidl = NULL; HRESULT hr = S_OK; BOOL IconNotYetLoaded=TRUE; + UINT uGilFlags = 0;
TRACE("%s fattr=0x%lx sfi=%p(attr=0x%08lx) size=0x%x flags=0x%x\n", (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes, @@ -458,15 +485,21 @@ }
/* ### icons ###*/ - if (flags & SHGFI_ADDOVERLAYS) - FIXME("SHGFI_ADDOVERLAYS unhandled\n"); + if (flags & SHGFI_OPENICON) + uGilFlags |= GIL_OPENICON;
+ if (flags & SHGFI_LINKOVERLAY) + uGilFlags |= GIL_FORSHORTCUT; + else if ((flags&SHGFI_ADDOVERLAYS) || + (flags&(SHGFI_ICON|SHGFI_SMALLICON))==SHGFI_ICON) + { + if (SHELL_IsShortcut(pidlLast)) + uGilFlags |= GIL_FORSHORTCUT; + } + if (flags & SHGFI_OVERLAYINDEX) FIXME("SHGFI_OVERLAYINDEX unhandled\n");
- if (flags & SHGFI_LINKOVERLAY) - FIXME("set icon to link, stub\n"); - if (flags & SHGFI_SELECTED) FIXME("set icon to selected, stub\n");
@@ -483,12 +516,11 @@ &uDummy, (LPVOID*)&pei); if (SUCCEEDED(hr)) { - hr = IExtractIconW_GetIconLocation(pei, - (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, + hr = IExtractIconW_GetIconLocation(pei, uGilFlags, szLocation, MAX_PATH, &iIndex, &uFlags); psfi->iIcon = iIndex;
- if (uFlags != GIL_NOTFILENAME) + if (!(uFlags & GIL_NOTFILENAME)) lstrcpyW (psfi->szDisplayName, szLocation); else ret = FALSE; @@ -550,7 +582,7 @@ else { if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON), - (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon)))) + uGilFlags, &(psfi->iIcon)))) { ret = FALSE; } _____
Modified: trunk/reactos/lib/shell32/shell32_main.h --- trunk/reactos/lib/shell32/shell32_main.h 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/shell32_main.h 2005-11-25 23:49:10 UTC (rev 19593) @@ -227,4 +227,7 @@
/* Default shell folder value registration */ HRESULT SHELL_RegisterShellFolders(void);
+/* Detect Shell Links */ +BOOL SHELL_IsShortcut(LPCITEMIDLIST); + #endif _____
Modified: trunk/reactos/lib/shell32/shellpath.c --- trunk/reactos/lib/shell32/shellpath.c 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/shellpath.c 2005-11-25 23:49:10 UTC (rev 19593) @@ -1586,7 +1586,7 @@
*/ HRESULT WINAPI SHGetFolderPathW( HWND hwndOwner, /* [I] owner window */ - int nFolder, /* [I] CSIDL identifing the folder */ + int nFolder, /* [I] CSIDL identifying the folder */ HANDLE hToken, /* [I] access token */ DWORD dwFlags, /* [I] which path to return */ LPWSTR pszPath) /* [O] converted path */ _____
Modified: trunk/reactos/lib/shell32/shfldr_desktop.c --- trunk/reactos/lib/shell32/shfldr_desktop.c 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/shfldr_desktop.c 2005-11-25 23:49:10 UTC (rev 19593) @@ -271,36 +271,37 @@
if (dwFlags & SHCONTF_FOLDERS) { HKEY hkey; - LONG r; + UINT i;
/* create the pidl for This item */ ret = AddToEnumList(list, _ILCreateMyComputer());
- r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW, - 0, KEY_READ, &hkey); - if (ret && ERROR_SUCCESS == r) - { - WCHAR iid[50]; - int i=0; - BOOL moreKeys = TRUE; - - while (ret && moreKeys) + for (i=0; i<2; i++) { + if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, + Desktop_NameSpaceW, 0, KEY_READ, &hkey)) { - DWORD size; + WCHAR iid[50]; + int i=0;
- size = sizeof (iid); - r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL); - if (ERROR_SUCCESS == r) + while (ret) { - ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid)); - i++; + DWORD size; + LONG r; + + size = sizeof (iid); + r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL); + if (ERROR_SUCCESS == r) + { + ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid)); + i++; + } + else if (ERROR_NO_MORE_ITEMS == r) + break; + else + ret = FALSE; } - else if (ERROR_NO_MORE_ITEMS == r) - moreKeys = FALSE; - else - ret = FALSE; + RegCloseKey(hkey); } - RegCloseKey(hkey); } }
_____
Modified: trunk/reactos/lib/shell32/shfldr_mycomp.c --- trunk/reactos/lib/shell32/shfldr_mycomp.c 2005-11-25 23:36:32 UTC (rev 19592) +++ trunk/reactos/lib/shell32/shfldr_mycomp.c 2005-11-25 23:49:10 UTC (rev 19593) @@ -274,6 +274,7 @@
WCHAR wszDriveName[] = {'A', ':', '\', '\0'}; DWORD dwDrivemap = GetLogicalDrives(); HKEY hkey; + UINT i;
while (ret && wszDriveName[0]<='Z') { @@ -284,32 +285,34 @@ }
TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n",list); - if (ret && !RegOpenKeyExW(HKEY_LOCAL_MACHINE, MyComputer_NameSpaceW, - 0, KEY_READ, &hkey)) - { - WCHAR iid[50]; - int i=0; - - while (ret) + for (i=0; i<2; i++) { + if (ret && !RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, + MyComputer_NameSpaceW, 0, KEY_READ, &hkey)) { - DWORD size; - LONG r; + WCHAR iid[50]; + int i=0;
- size = sizeof(iid) / sizeof(iid[0]); - r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL); - if (ERROR_SUCCESS == r) + while (ret) { - /* FIXME: shell extensions, shouldn't the type be - * PT_SHELLEXT? */ - ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid)); - i++; + DWORD size; + LONG r; + + size = sizeof(iid) / sizeof(iid[0]); + r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL); + if (ERROR_SUCCESS == r) + { + /* FIXME: shell extensions, shouldn't the type be + * PT_SHELLEXT? */ + ret = AddToEnumList(list, _ILCreateGuidFromStrW(iid)); + i++; + } + else if (ERROR_NO_MORE_ITEMS == r) + break; + else + ret = FALSE; } - else if (ERROR_NO_MORE_ITEMS == r) - break; - else - ret = FALSE; + RegCloseKey(hkey); } - RegCloseKey(hkey); } } return ret;