From 7e5129fcc0009e9bb8ae727920a16937778eee78 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 25 Nov 2005 23:49:10 +0000 Subject: [PATCH] Sync to Wine-0_9_2: Francois Gouget - Remove spaces before '\n' in traces. Dmitry Timoshkov - 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 - 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 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 - Hack around missing icons svn path=/trunk/; revision=19593 --- reactos/lib/shell32/brsfolder.c | 4 +- reactos/lib/shell32/iconcache.c | 98 +++++++++++++++++++++------- reactos/lib/shell32/shell32_main.c | 50 +++++++++++--- reactos/lib/shell32/shell32_main.h | 3 + reactos/lib/shell32/shellpath.c | 2 +- reactos/lib/shell32/shfldr_desktop.c | 43 ++++++------ reactos/lib/shell32/shfldr_mycomp.c | 45 +++++++------ 7 files changed, 168 insertions(+), 77 deletions(-) diff --git a/reactos/lib/shell32/brsfolder.c b/reactos/lib/shell32/brsfolder.c index 54a48b1c263..af65d66a225 100644 --- a/reactos/lib/shell32/brsfolder.c +++ b/reactos/lib/shell32/brsfolder.c @@ -679,11 +679,11 @@ LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi) 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; diff --git a/reactos/lib/shell32/iconcache.c b/reactos/lib/shell32/iconcache.c index 1d541966844..3efefcfbb21 100644 --- a/reactos/lib/shell32/iconcache.c +++ b/reactos/lib/shell32/iconcache.c @@ -96,6 +96,9 @@ static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam) return 0; } +/* declare SIC_LoadOverlayIcon() */ +static int SIC_LoadOverlayIcon(int idx); + /***************************************************************************** * SIC_OverlayShortcutImage [internal] * @@ -103,7 +106,7 @@ static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM lparam) * 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 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon) 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 @@ static INT SIC_LoadIcon (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags) 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 @@ void SIC_Destroy(void) 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 @@ BOOL PidlToSicIndex ( { 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 WINAPI SHMapPIDLToSystemImageListIndex( 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; diff --git a/reactos/lib/shell32/shell32_main.c b/reactos/lib/shell32/shell32_main.c index 82aaca16ab6..83b9c2d0629 100644 --- a/reactos/lib/shell32/shell32_main.c +++ b/reactos/lib/shell32/shell32_main.c @@ -297,6 +297,32 @@ static DWORD shgfi_get_exe_type(LPCWSTR szFullPath) 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 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, 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 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, } /* ### 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 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, &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 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, else { if (!(PidlToSicIndex(psfParent, pidlLast, !(flags & SHGFI_SMALLICON), - (flags & SHGFI_OPENICON)? GIL_OPENICON : 0, &(psfi->iIcon)))) + uGilFlags, &(psfi->iIcon)))) { ret = FALSE; } diff --git a/reactos/lib/shell32/shell32_main.h b/reactos/lib/shell32/shell32_main.h index a95d67ff6db..c67fa7fc7bf 100644 --- a/reactos/lib/shell32/shell32_main.h +++ b/reactos/lib/shell32/shell32_main.h @@ -227,4 +227,7 @@ extern const GUID CLSID_UnixDosFolder; /* Default shell folder value registration */ HRESULT SHELL_RegisterShellFolders(void); +/* Detect Shell Links */ +BOOL SHELL_IsShortcut(LPCITEMIDLIST); + #endif diff --git a/reactos/lib/shell32/shellpath.c b/reactos/lib/shell32/shellpath.c index 2064601c8c4..27a5b13de85 100644 --- a/reactos/lib/shell32/shellpath.c +++ b/reactos/lib/shell32/shellpath.c @@ -1586,7 +1586,7 @@ end: */ 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 */ diff --git a/reactos/lib/shell32/shfldr_desktop.c b/reactos/lib/shell32/shfldr_desktop.c index af7b5b2a698..800a857677d 100644 --- a/reactos/lib/shell32/shfldr_desktop.c +++ b/reactos/lib/shell32/shfldr_desktop.c @@ -271,36 +271,37 @@ static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags) 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); } } diff --git a/reactos/lib/shell32/shfldr_mycomp.c b/reactos/lib/shell32/shfldr_mycomp.c index ec137ce05e2..b9b51b7c05f 100644 --- a/reactos/lib/shell32/shfldr_mycomp.c +++ b/reactos/lib/shell32/shfldr_mycomp.c @@ -274,6 +274,7 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags) WCHAR wszDriveName[] = {'A', ':', '\\', '\0'}; DWORD dwDrivemap = GetLogicalDrives(); HKEY hkey; + UINT i; while (ret && wszDriveName[0]<='Z') { @@ -284,32 +285,34 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags) } 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; -- 2.17.1