bug 246616 - moz-icon should be able to draw special virtual namespace icons for Desktop and My Documents, r=mscott

This commit is contained in:
ben%bengoodger.com 2004-06-22 22:36:40 +00:00
parent cefa77d7c2
commit d69e125618
2 changed files with 56 additions and 3 deletions

View File

@ -99,7 +99,7 @@ EXTRA_DSO_LDOPTS += \
LOCAL_INCLUDES = -I$(srcdir)/$(PLATFORM)
ifeq ($(OS_ARCH),WINNT)
OS_LIBS += $(call EXPAND_LIBNAME,shell32 gdi32)
OS_LIBS += $(call EXPAND_LIBNAME,shell32 gdi32 comctl32)
endif
include $(topsrcdir)/config/rules.mk

View File

@ -23,6 +23,7 @@
* Contributor(s):
* Scott MacGregor <mscott@netscape.com>
* Neil Rashbrook <neil@parkwaycc.co.uk>
* Ben Goodger <ben@mozilla.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -55,10 +56,12 @@
#include "nsIFileURL.h"
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
#include "nsDirectoryServiceDefs.h"
// we need windows.h to read out registry information...
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
struct ICONFILEHEADER {
PRUint16 ifhReserved;
@ -234,6 +237,40 @@ NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports
return rv;
}
static DWORD GetSpecialFolderIcon(nsIFile* aFile, int aFolder, SHFILEINFO* aSFI, UINT aInfoFlags)
{
DWORD shellResult = 0;
if (!aFile)
return shellResult;
char fileNativePath[MAX_PATH];
nsCAutoString fileNativePathStr;
aFile->GetNativePath(fileNativePathStr);
::GetShortPathName(fileNativePathStr.get(), fileNativePath, sizeof(fileNativePath));
char specialNativePath[MAX_PATH];
::SHGetSpecialFolderPath(NULL, specialNativePath, aFolder, FALSE);
::GetShortPathName(specialNativePath, specialNativePath, sizeof(specialNativePath));
if (nsDependentCString(fileNativePath).EqualsIgnoreCase(specialNativePath)) {
LPITEMIDLIST idList;
HRESULT hr = ::SHGetSpecialFolderLocation(NULL, aFolder, &idList);
if (SUCCEEDED(hr)) {
aInfoFlags |= (SHGFI_PIDL | SHGFI_SYSICONINDEX);
shellResult = ::SHGetFileInfo((LPCTSTR)(LPCITEMIDLIST)idList, 0, aSFI,
sizeof(SHFILEINFO), aInfoFlags);
IMalloc* pMalloc;
hr = ::SHGetMalloc(&pMalloc);
if (SUCCEEDED(hr)) {
pMalloc->Free(idList);
pMalloc->Release();
}
}
}
return shellResult;
}
nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBlocking)
{
nsXPIDLCString contentType;
@ -279,8 +316,24 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc
}
rv = NS_ERROR_NOT_AVAILABLE;
// (1) get an hIcon for the file
if (SHGetFileInfo(filePath.get(), FILE_ATTRIBUTE_ARCHIVE, &sfi, sizeof(sfi), infoFlags) && sfi.hIcon)
// Is this the "Desktop" folder?
DWORD shellResult = GetSpecialFolderIcon(localFile, CSIDL_DESKTOP, &sfi, infoFlags);
if (!shellResult) {
// Is this the "My Documents" folder?
shellResult = GetSpecialFolderIcon(localFile, CSIDL_PERSONAL, &sfi, infoFlags);
}
// There are other "Special Folders" and Namespace entities that we are not
// fetching icons for, see:
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp
// If we ever need to get them, code to do so would be inserted here.
// Not a special folder, or something else failed above.
if (!shellResult)
shellResult = ::SHGetFileInfo(filePath.get(), FILE_ATTRIBUTE_ARCHIVE, &sfi, sizeof(sfi), infoFlags);
if (shellResult && sfi.hIcon)
{
// we got a handle to an icon. Now we want to get a bitmap for the icon using GetIconInfo....
ICONINFO iconInfo;