Ge van Geldorp <gvg(a)reactos.com>
- Overlay icons for .lnk files with a small arrow in the lower left
corner.
Alexandre Julliard <julliard(a)winehq.org>
- Added rules for building import libraries in the individual dll
makefiles, and added support for building a .def.a static import
library too.
- Removed unnecessary code in the 16-bit DllEntryPoint function of some
dlls, and also fixed its ordinal in a few places.
- Comment out stub WEP entry points so that we can call WEP for builtin
dlls too.
Juan Lang <juan_lang(a)yahoo.com>
- Fixes to IShellFolder::GetAttributesOf implementations, spotted by
silverblade_:
- a count of zero is allowed to GetAttributesOf if apidl is NULL
- SFGAO_VALIDATE must be cleared upon return
- only log unsupported flags in ShellExecute
- environment variables are expanded, so SEE_MASK_DOENVSUBST is
supported
Michael Jung <mjung(a)iss.tu-darmstadt.de>
- Add a new CLSID for UnixDosFolder, which is identical to UnixFolder,
but does unix <-> dos path conversion for GetDisplayNameOf and
ParseDisplayName.
- Make the root of the shell extension map to the root of the unix
filesystem.
- More robustly query the SHGDN_FORPARSING flag in the shell32's folders
GetDisplayNameOf methods.
- Fixed GetDisplayNameOf method to not depend on incorrect behaviour
regarding the SHGDN_INFOLDER flag.
- Fixed MyComputer's GetDisplayNameOf method.
- Return a cloned PIDL by SHBrowseForFolder to avoid heap corruption.
- Fixed incorrect IShellFolder::EnumOjects API usage.
- Support for regular files (as opposed to directories).
- Display a drive icon for the unix root directory.
- Consider only the GIL_FORSHORTCUT flag in SIC_CompareEntries.
Stefan Doesinger <stefandoesinger(a)gmx.at>
- Handle cidl==0 in shfldr_desktop, shfldr_fs and shfldr_mycomp.
- Remove the dwAttributes member from the IGenericSFImpl class, it's
not needed and can't be initialised in Initialize and InitializeEx.
Mike McCormack <mike(a)codeweavers.com>
- Split SHGetFileInfoW into two functions.
- Remove static variables in SHBrowseForFolder implementation.
- Split up the window procedure.
- Remove some unused include files.
- MSI advertised shortcuts don't require a product ID.
Peter Berg Larsen <pebl(a)math.ku.dk>
- Rewritten DoEnvironmentSubst16.
Kouji Sasaki <taro-x(a)justsystem.co.jp>
- Added the processing for determination of SFGAO_HASSUBFOLDER flag in
SHELL32_GetItemAttribute function.
Francois Gouget <fgouget(a)free.fr>
- Assorted spelling fixes.
Huw Davies <huw(a)codeweavers.com>
- It makes no sense to have a left pointing arrow as the desktop icon.
Replace it with something more appropiate.
Mike Hearn <mh(a)codeweavers.com>
- Fix SHELL_GetPathFromIDList[AW] to return the desktop path given an
empty PIDL.
Modified: trunk/reactos/lib/shell32/Makefile.in
Modified: trunk/reactos/lib/shell32/brsfolder.c
Modified: trunk/reactos/lib/shell32/cpanelfolder.c
Modified: trunk/reactos/lib/shell32/folders.c
Modified: trunk/reactos/lib/shell32/iconcache.c
Modified: trunk/reactos/lib/shell32/pidl.c
Modified: trunk/reactos/lib/shell32/regsvr.c
Modified: trunk/reactos/lib/shell32/shell.c
Modified: trunk/reactos/lib/shell32/shell.spec
Modified: trunk/reactos/lib/shell32/shell32_De.rc
Modified: trunk/reactos/lib/shell32/shell32_En.rc
Modified: trunk/reactos/lib/shell32/shell32_main.c
Modified: trunk/reactos/lib/shell32/shell32_main.h
Modified: trunk/reactos/lib/shell32/shelllink.c
Modified: trunk/reactos/lib/shell32/shfldr_desktop.c
Modified: trunk/reactos/lib/shell32/shfldr_fs.c
Modified: trunk/reactos/lib/shell32/shfldr_mycomp.c
Modified: trunk/reactos/lib/shell32/shlexec.c
Modified: trunk/reactos/lib/shell32/shlfileop.c
Modified: trunk/reactos/lib/shell32/shlfolder.c
Modified: trunk/reactos/lib/shell32/shres.rc
Modified: trunk/reactos/lib/shell32/shresdef.h
_____
Modified: trunk/reactos/lib/shell32/Makefile.in
--- trunk/reactos/lib/shell32/Makefile.in 2005-05-28 21:30:02 UTC
(rev 15616)
+++ trunk/reactos/lib/shell32/Makefile.in 2005-05-28 21:30:32 UTC
(rev 15617)
@@ -4,6 +4,7 @@
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = shell32.dll
+IMPORTLIB = libshell32.$(IMPLIBEXT)
IMPORTS = shlwapi comctl32 user32 gdi32 advapi32 kernel32
DELAYIMPORTS = ole32
EXTRALIBS = -luuid $(LIBUNICODE)
@@ -63,7 +64,8 @@
netdrive.ico \
netdrive2.ico \
printer.ico \
- ramdisk.ico
+ ramdisk.ico \
+ shortcut.ico
C_SRCS16 = shell.c
RC_SRCS16 = version16.rc
_____
Modified: trunk/reactos/lib/shell32/brsfolder.c
--- trunk/reactos/lib/shell32/brsfolder.c 2005-05-28 21:30:02 UTC
(rev 15616)
+++ trunk/reactos/lib/shell32/brsfolder.c 2005-05-28 21:30:32 UTC
(rev 15617)
@@ -37,12 +37,21 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-static HWND hwndTreeView;
-static LPBROWSEINFOW lpBrowseInfo;
-static LPITEMIDLIST pidlRet;
+typedef struct tagbrowse_info
+{
+ HWND hWnd;
+ HWND hwndTreeView;
+ LPBROWSEINFOW lpBrowseInfo;
+ LPITEMIDLIST pidlRet;
+} browse_info;
-static void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq,
HTREEITEM hParent, IEnumIDList* lpe);
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST
pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM
hParent);
+typedef struct tagTV_ITEMDATA
+{
+ LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
+ LPITEMIDLIST lpi; /* PIDL relativ to parent */
+ LPITEMIDLIST lpifq; /* Fully qualified PIDL */
+ IEnumIDList* pEnumIL; /* Children iterator */
+} TV_ITEMDATA, *LPTV_ITEMDATA;
#define SUPPORTEDFLAGS (BIF_STATUSTEXT | \
BIF_BROWSEFORCOMPUTER | \
@@ -50,11 +59,30 @@
BIF_RETURNONLYFSDIRS | \
BIF_BROWSEINCLUDEFILES)
+static void FillTreeView(browse_info*, LPSHELLFOLDER,
+ LPITEMIDLIST, HTREEITEM, IEnumIDList*);
+static HTREEITEM InsertTreeViewItem( browse_info*, IShellFolder *,
+ LPCITEMIDLIST, LPCITEMIDLIST, IEnumIDList*, HTREEITEM);
+
+const WCHAR szBrowseFolderInfo[] = {
+ '_','_','W','I','N','E','_',
+
'B','R','S','F','O','L','D','E','R','D','L','G','_',
+ 'I','N','F','O',0
+};
+
static inline DWORD BrowseFlagsToSHCONTF(UINT ulFlags)
{
return SHCONTF_FOLDERS | (ulFlags & BIF_BROWSEINCLUDEFILES ?
SHCONTF_NONFOLDERS : 0);
}
+static void browsefolder_callback( LPBROWSEINFOW lpBrowseInfo, HWND
hWnd,
+ UINT msg, LPARAM param )
+{
+ if (!lpBrowseInfo->lpfn)
+ return;
+ lpBrowseInfo->lpfn( hWnd, BFFM_INITIALIZED, param,
lpBrowseInfo->lParam );
+}
+
/***********************************************************************
*******
* InitializeTreeView [Internal]
*
@@ -64,25 +92,23 @@
* hwndParent [I] The BrowseForFolder dialog
* root [I] ITEMIDLIST of the root shell folder
*/
-static void InitializeTreeView(HWND hwndParent, LPCITEMIDLIST root)
+static void InitializeTreeView( browse_info *info )
{
LPITEMIDLIST pidlParent, pidlChild;
HIMAGELIST hImageList;
HRESULT hr;
IShellFolder *lpsfParent, *lpsfRoot;
IEnumIDList * pEnumChildren = NULL;
+ HTREEITEM item;
+ DWORD flags;
+ LPCITEMIDLIST root = info->lpBrowseInfo->pidlRoot;
- TRACE("dlg=%p tree=%p\n", hwndParent, hwndTreeView );
+ TRACE("%p\n", info );
- hwndTreeView = GetDlgItem (hwndParent, IDD_TREEVIEW);
- if (!hwndTreeView) {
- FIXME("Could not get handle to treeview control! Error:
%08lx\n", GetLastError());
- return;
- }
Shell_GetImageList(NULL, &hImageList);
if (hImageList)
- TreeView_SetImageList(hwndTreeView, hImageList, 0);
+ TreeView_SetImageList( info->hwndTreeView, hImageList, 0 );
/* We want to call InsertTreeViewItem down the code, in order to
insert
* the root item of the treeview. Due to InsertTreeViewItem's
signature,
@@ -131,7 +157,8 @@
return;
}
- hr = IShellFolder_EnumObjects(lpsfRoot, hwndParent,
BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumChildren);
+ flags = BrowseFlagsToSHCONTF( info->lpBrowseInfo->ulFlags );
+ hr = IShellFolder_EnumObjects( lpsfRoot, info->hWnd, flags,
&pEnumChildren );
if (!SUCCEEDED(hr)) {
WARN("Could not get child iterator! hr = %08lx\n", hr);
IShellFolder_Release(lpsfParent);
@@ -139,8 +166,10 @@
return;
}
- TreeView_DeleteAllItems(hwndTreeView);
- TreeView_Expand(hwndTreeView, InsertTreeViewItem(lpsfParent,
pidlChild, pidlParent, pEnumChildren, TVI_ROOT), TVE_EXPAND);
+ TreeView_DeleteAllItems( info->hwndTreeView );
+ item = InsertTreeViewItem( info, lpsfParent, pidlChild,
+ pidlParent, pEnumChildren, TVI_ROOT );
+ TreeView_Expand( info->hwndTreeView, item, TVE_EXPAND );
IShellFolder_Release(lpsfRoot);
IShellFolder_Release(lpsfParent);
@@ -148,40 +177,34 @@
static int GetIcon(LPITEMIDLIST lpi, UINT uFlags)
{
- SHFILEINFOW sfi;
- SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW),
uFlags);
- return sfi.iIcon;
+ SHFILEINFOW sfi;
+ SHGetFileInfoW((LPCWSTR)lpi, 0 ,&sfi, sizeof(SHFILEINFOW), uFlags);
+ return sfi.iIcon;
}
static void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEMW
lpTV_ITEM)
{
- LPITEMIDLIST pidlDesktop = NULL;
+ LPITEMIDLIST pidlDesktop = NULL;
+ DWORD flags;
- TRACE("%p %p\n",lpifq, lpTV_ITEM);
+ TRACE("%p %p\n",lpifq, lpTV_ITEM);
- if (!lpifq)
- {
- pidlDesktop = _ILCreateDesktop();
- lpifq = pidlDesktop;
- }
+ if (!lpifq)
+ {
+ pidlDesktop = _ILCreateDesktop();
+ lpifq = pidlDesktop;
+ }
- lpTV_ITEM->iImage = GetIcon(lpifq, SHGFI_PIDL |
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
- lpTV_ITEM->iSelectedImage = GetIcon(lpifq, SHGFI_PIDL |
SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON);
+ flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON;
+ lpTV_ITEM->iImage = GetIcon( lpifq, flags );
- if (pidlDesktop)
- ILFree(pidlDesktop);
+ flags = SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON |
SHGFI_OPENICON;
+ lpTV_ITEM->iSelectedImage = GetIcon( lpifq, flags );
- return;
+ if (pidlDesktop)
+ ILFree( pidlDesktop );
}
-typedef struct tagID
-{
- LPSHELLFOLDER lpsfParent; /* IShellFolder of the parent */
- LPITEMIDLIST lpi; /* PIDL relativ to parent */
- LPITEMIDLIST lpifq; /* Fully qualified PIDL */
- IEnumIDList* pEnumIL; /* Children iterator */
-} TV_ITEMDATA, *LPTV_ITEMDATA;
-
/***********************************************************************
*******
* GetName [Internal]
*
@@ -221,6 +244,7 @@
* InsertTreeViewItem [Internal]
*
* PARAMS
+ * info [I] data for the dialog
* lpsf [I] IShellFolder interface of the item's parent shell
folder
* pidl [I] ITEMIDLIST of the child to insert, relativ to parent
* pidlParent [I] ITEMIDLIST of the parent shell folder
@@ -231,8 +255,9 @@
* Success: Handle to the created and inserted treeview-item
* Failure: NULL
*/
-static HTREEITEM InsertTreeViewItem(IShellFolder * lpsf, LPCITEMIDLIST
pidl,
- LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL, HTREEITEM hParent)
+static HTREEITEM InsertTreeViewItem( browse_info *info, IShellFolder *
lpsf,
+ LPCITEMIDLIST pidl, LPCITEMIDLIST pidlParent, IEnumIDList* pEnumIL,
+ HTREEITEM hParent)
{
TVITEMW tvi;
TVINSERTSTRUCTW tvins;
@@ -244,7 +269,8 @@
tvi.cChildren= pEnumIL ? 1 : 0;
tvi.mask |= TVIF_CHILDREN;
- if (!(lptvid = (LPTV_ITEMDATA)SHAlloc(sizeof(TV_ITEMDATA))))
+ lptvid = SHAlloc( sizeof(TV_ITEMDATA) );
+ if (!lptvid)
return NULL;
if (!GetName(lpsf, pidl, SHGDN_NORMAL, szBuff))
@@ -265,7 +291,7 @@
tvins.hInsertAfter = NULL;
tvins.hParent = hParent;
- return (HTREEITEM)TreeView_InsertItemW(hwndTreeView, &tvins);
+ return (HTREEITEM)TreeView_InsertItemW( info->hwndTreeView,
&tvins );
}
/***********************************************************************
*******
@@ -275,26 +301,28 @@
* lpsf and whose PIDL is pidl, insert a treeview-item right under
hParent
*
* PARAMS
+ * info [I] data for the dialog
* lpsf [I] IShellFolder interface of the parent shell folder
* pidl [I] ITEMIDLIST of the parent shell folder
* hParent [I] The treeview item that represents the parent shell
folder
* lpe [I] An iterator for the children of the parent shell folder
*/
-static void FillTreeView(IShellFolder * lpsf, LPITEMIDLIST pidl,
HTREEITEM hParent, IEnumIDList* lpe)
+static void FillTreeView( browse_info *info, IShellFolder * lpsf,
+ LPITEMIDLIST pidl, HTREEITEM hParent, IEnumIDList*
lpe)
{
HTREEITEM hPrev = 0;
LPITEMIDLIST pidlTemp = 0;
ULONG ulFetched;
HRESULT hr;
- HWND hwnd=GetParent(hwndTreeView);
+ HWND hwnd = GetParent( info->hwndTreeView );
TRACE("%p %p %x %p\n",lpsf, pidl, (INT)hParent, lpe);
/* No IEnumIDList -> No children */
if (!lpe) return;
- SetCapture(GetParent(hwndTreeView));
- SetCursor(LoadCursorA(0, (LPSTR)IDC_WAIT));
+ SetCapture( hwnd );
+ SetCursor( LoadCursorA( 0, (LPSTR)IDC_WAIT ) );
while (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched))
{
@@ -307,10 +335,12 @@
hr =
IShellFolder_BindToObject(lpsf,pidlTemp,NULL,&IID_IShellFolder,(LPVOID*)
&pSFChild);
if (SUCCEEDED(hr))
{
- hr = IShellFolder_EnumObjects(pSFChild, hwnd,
BrowseFlagsToSHCONTF(lpBrowseInfo->ulFlags), &pEnumIL);
- if (SUCCEEDED(hr))
+ DWORD flags =
BrowseFlagsToSHCONTF(info->lpBrowseInfo->ulFlags);
+ hr = IShellFolder_EnumObjects(pSFChild, hwnd, flags,
&pEnumIL);
+ if (hr == S_OK)
{
- if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) ||
FAILED(IEnumIDList_Reset(pEnumIL)))
+ if ((IEnumIDList_Skip(pEnumIL, 1) != S_OK) ||
+ FAILED(IEnumIDList_Reset(pEnumIL)))
{
IEnumIDList_Release(pEnumIL);
pEnumIL = NULL;
@@ -320,13 +350,13 @@
}
}
- if (!(hPrev = InsertTreeViewItem(lpsf, pidlTemp, pidl,
pEnumIL, hParent)))
- goto Done;
+ if (!(hPrev = InsertTreeViewItem(info, lpsf, pidlTemp, pidl,
pEnumIL, hParent)))
+ goto done;
SHFree(pidlTemp); /* Finally, free the pidl that the shell
gave us... */
pidlTemp=NULL;
}
-Done:
+done:
ReleaseCapture();
SetCursor(LoadCursorW(0, (LPWSTR)IDC_ARROW));
@@ -342,182 +372,238 @@
return (data->type == type);
}
-static void BrsFolder_CheckValidSelection(HWND hWndTree, LPTV_ITEMDATA
lptvid)
+static void BrsFolder_CheckValidSelection( browse_info *info,
LPTV_ITEMDATA lptvid )
{
+ LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
LPCITEMIDLIST pidl = lptvid->lpi;
BOOL bEnabled = TRUE;
DWORD dwAttributes;
+ HRESULT r;
+
if ((lpBrowseInfo->ulFlags & BIF_BROWSEFORCOMPUTER) &&
!PIDLIsType(pidl, PT_COMP))
bEnabled = FALSE;
if (lpBrowseInfo->ulFlags & BIF_RETURNFSANCESTORS)
{
dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
- if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) ||
- !dwAttributes)
+ r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
+ (LPCITEMIDLIST*)&lptvid->lpi,
&dwAttributes);
+ if (FAILED(r) || !dwAttributes)
bEnabled = FALSE;
}
if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
{
dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
- if (FAILED(IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes)) ||
- (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
+ r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
+ (LPCITEMIDLIST*)&lptvid->lpi,
&dwAttributes);
+ if (FAILED(r) || (dwAttributes != (SFGAO_FOLDER |
SFGAO_FILESYSTEM)))
bEnabled = FALSE;
}
- SendMessageW(hWndTree, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
+ SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
}
-static LRESULT MsgNotify(HWND hWnd, UINT CtlID, LPNMHDR lpnmh)
+static LRESULT BrsFolder_Treeview_Delete( browse_info *info,
NMTREEVIEWW *pnmtv )
{
- NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
- LPTV_ITEMDATA lptvid; /* Long pointer to TreeView item data
*/
- IShellFolder * lpsf2=0;
+ LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA)pnmtv->itemOld.lParam;
+ TRACE("TVN_DELETEITEMA/W %p\n", lptvid);
- TRACE("%p %x %p msg=%x\n", hWnd, CtlID, lpnmh,
pnmtv->hdr.code);
+ IShellFolder_Release(lptvid->lpsfParent);
+ if (lptvid->pEnumIL)
+ IEnumIDList_Release(lptvid->pEnumIL);
+ SHFree(lptvid->lpi);
+ SHFree(lptvid->lpifq);
+ SHFree(lptvid);
+ return 0;
+}
- switch (pnmtv->hdr.idFrom)
- { case IDD_TREEVIEW:
- switch (pnmtv->hdr.code)
- {
- case TVN_DELETEITEMA:
- case TVN_DELETEITEMW:
- TRACE("TVN_DELETEITEMA/W\n");
- lptvid=(LPTV_ITEMDATA)pnmtv->itemOld.lParam;
- IShellFolder_Release(lptvid->lpsfParent);
- if (lptvid->pEnumIL)
- IEnumIDList_Release(lptvid->pEnumIL);
- SHFree(lptvid->lpi);
- SHFree(lptvid->lpifq);
- SHFree(lptvid);
- break;
+static LRESULT BrsFolder_Treeview_Expand( browse_info *info,
NMTREEVIEWW *pnmtv )
+{
+ IShellFolder *lpsf2 = NULL;
+ LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
+ HRESULT r;
- case TVN_ITEMEXPANDINGA:
- case TVN_ITEMEXPANDINGW:
- {
- TRACE("TVN_ITEMEXPANDINGA/W\n");
- if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
- break;
+ TRACE("TVN_ITEMEXPANDINGA/W\n");
- lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
- if
(SUCCEEDED(IShellFolder_BindToObject(lptvid->lpsfParent,
lptvid->lpi,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
- { FillTreeView( lpsf2, lptvid->lpifq,
pnmtv->itemNew.hItem, lptvid->pEnumIL);
- }
- /* My Computer is already sorted and trying to do a
simple text
- * sort will only mess things up */
- if (!_ILIsMyComputer(lptvid->lpi))
- TreeView_SortChildren(hwndTreeView,
pnmtv->itemNew.hItem, FALSE);
- }
- break;
- case TVN_SELCHANGEDA:
- case TVN_SELCHANGEDW:
- lptvid=(LPTV_ITEMDATA)pnmtv->itemNew.lParam;
- pidlRet = lptvid->lpifq;
- if (lpBrowseInfo->lpfn)
- (lpBrowseInfo->lpfn)(hWnd, BFFM_SELCHANGED,
(LPARAM)pidlRet, lpBrowseInfo->lParam);
- BrsFolder_CheckValidSelection(hWnd, lptvid);
- break;
+ if ((pnmtv->itemNew.state & TVIS_EXPANDEDONCE))
+ return 0;
- default:
- WARN("unhandled (%d)\n", pnmtv->hdr.code);
- break;
- }
- break;
+ r = IShellFolder_BindToObject( lptvid->lpsfParent, lptvid->lpi, 0,
+ (REFIID)&IID_IShellFolder, (LPVOID
*)&lpsf2 );
+ if (SUCCEEDED(r))
+ FillTreeView( info, lpsf2, lptvid->lpifq, pnmtv->itemNew.hItem,
lptvid->pEnumIL);
- default:
- break;
- }
+ /* My Computer is already sorted and trying to do a simple text
+ * sort will only mess things up */
+ if (!_ILIsMyComputer(lptvid->lpi))
+ TreeView_SortChildren(info->hwndTreeView, pnmtv->itemNew.hItem,
FALSE);
- return 0;
+ return 0;
}
+static HRESULT BrsFolder_Treeview_Changed( browse_info *info,
NMTREEVIEWW *pnmtv )
+{
+ LPTV_ITEMDATA lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
+ lptvid = (LPTV_ITEMDATA) pnmtv->itemNew.lParam;
+ info->pidlRet = lptvid->lpifq;
+ browsefolder_callback( info->lpBrowseInfo, info->hWnd,
BFFM_SELCHANGED,
+ (LPARAM)info->pidlRet );
+ BrsFolder_CheckValidSelection( info, lptvid );
+ return 0;
+}
+
+static LRESULT BrsFolder_OnNotify( browse_info *info, UINT CtlID,
LPNMHDR lpnmh )
+{
+ NMTREEVIEWW *pnmtv = (NMTREEVIEWW *)lpnmh;
+
+ TRACE("%p %x %p msg=%x\n", info, CtlID, lpnmh, pnmtv->hdr.code);
+
+ if (pnmtv->hdr.idFrom != IDD_TREEVIEW)
+ return 0;
+
+ switch (pnmtv->hdr.code)
+ {
+ case TVN_DELETEITEMA:
+ case TVN_DELETEITEMW:
+ return BrsFolder_Treeview_Delete( info, pnmtv );
+
+ case TVN_ITEMEXPANDINGA:
+ case TVN_ITEMEXPANDINGW:
+ return BrsFolder_Treeview_Expand( info, pnmtv );
+
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ return BrsFolder_Treeview_Changed( info, pnmtv );
+
+ default:
+ WARN("unhandled (%d)\n", pnmtv->hdr.code);
+ break;
+ }
+
+ return 0;
+}
+
+
+static BOOL BrsFolder_OnCreate( HWND hWnd, browse_info *info )
+{
+ LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
+ info->hWnd = hWnd;
+ SetPropW( hWnd, szBrowseFolderInfo, info );
+
+ if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
+ FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags &
~SUPPORTEDFLAGS);
+
+ if (lpBrowseInfo->lpszTitle)
+ SetWindowTextW( GetDlgItem(hWnd, IDD_TITLE),
lpBrowseInfo->lpszTitle );
+ else
+ ShowWindow( GetDlgItem(hWnd, IDD_TITLE), SW_HIDE );
+
+ if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
+ ShowWindow( GetDlgItem(hWnd, IDD_STATUS), SW_HIDE );
+
+ info->hwndTreeView = GetDlgItem( hWnd, IDD_TREEVIEW );
+ if (info->hwndTreeView)
+ InitializeTreeView( info );
+ else
+ ERR("treeview control missing!\n");
+
+ browsefolder_callback( info->lpBrowseInfo, hWnd, BFFM_INITIALIZED,
0 );
+
+ return TRUE;
+}
+
+static BOOL BrsFolder_OnCommand( browse_info *info, UINT id )
+{
+ LPBROWSEINFOW lpBrowseInfo = info->lpBrowseInfo;
+
+ switch (id)
+ {
+ case IDOK:
+ info->pidlRet = ILClone(info->pidlRet); /* The original pidl
will be free'd. */
+ pdump( info->pidlRet );
+ if (lpBrowseInfo->pszDisplayName)
+ SHGetPathFromIDListW( info->pidlRet,
lpBrowseInfo->pszDisplayName );
+ EndDialog( info->hWnd, 1 );
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog( info->hWnd, 0 );
+ return TRUE;
+ }
+ return FALSE;
+}
+
/***********************************************************************
**
* BrsFolderDlgProc32 (not an exported API function)
*/
-static INT_PTR CALLBACK BrsFolderDlgProc(HWND hWnd, UINT msg, WPARAM
wParam,
- LPARAM lParam )
+static INT_PTR CALLBACK BrsFolderDlgProc( HWND hWnd, UINT msg, WPARAM
wParam,
+ LPARAM lParam )
{
- TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd, msg, wParam,
lParam );
+ browse_info *info;
- switch(msg)
- { case WM_INITDIALOG:
- pidlRet = NULL;
- lpBrowseInfo = (LPBROWSEINFOW) lParam;
- if (lpBrowseInfo->ulFlags & ~SUPPORTEDFLAGS)
- FIXME("flags %x not implemented\n", lpBrowseInfo->ulFlags
& ~SUPPORTEDFLAGS);
- if (lpBrowseInfo->lpszTitle) {
- SetWindowTextW(GetDlgItem(hWnd, IDD_TITLE),
lpBrowseInfo->lpszTitle);
- } else {
- ShowWindow(GetDlgItem(hWnd, IDD_TITLE), SW_HIDE);
- }
- if (!(lpBrowseInfo->ulFlags & BIF_STATUSTEXT))
- ShowWindow(GetDlgItem(hWnd, IDD_STATUS), SW_HIDE);
+ TRACE("hwnd=%p msg=%04x 0x%08x 0x%08lx\n", hWnd, msg, wParam,
lParam );
- InitializeTreeView(hWnd, lpBrowseInfo->pidlRoot);
+ if (msg == WM_INITDIALOG)
+ return BrsFolder_OnCreate( hWnd, (browse_info*) lParam );
- if (lpBrowseInfo->lpfn)
- (lpBrowseInfo->lpfn)(hWnd, BFFM_INITIALIZED, 0,
lpBrowseInfo->lParam);
+ info = (browse_info*) GetPropW( hWnd, szBrowseFolderInfo );
- return TRUE;
+ switch (msg)
+ {
+ case WM_NOTIFY:
+ return BrsFolder_OnNotify( info, (UINT)wParam,
(LPNMHDR)lParam);
- case WM_NOTIFY:
- MsgNotify( hWnd, (UINT)wParam, (LPNMHDR)lParam);
- break;
+ case WM_COMMAND:
+ return BrsFolder_OnCommand( info, wParam );
- case WM_COMMAND:
- switch (wParam)
- { case IDOK:
- pdump ( pidlRet );
- if (lpBrowseInfo->pszDisplayName)
- SHGetPathFromIDListW(pidlRet,
lpBrowseInfo->pszDisplayName);
- EndDialog(hWnd, (DWORD) ILClone(pidlRet));
- return TRUE;
+ case BFFM_SETSTATUSTEXTA:
+ TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
+ SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
+ break;
- case IDCANCEL:
- EndDialog(hWnd, 0);
- return TRUE;
- }
- break;
- case BFFM_SETSTATUSTEXTA:
- TRACE("Set status %s\n", debugstr_a((LPSTR)lParam));
- SetWindowTextA(GetDlgItem(hWnd, IDD_STATUS), (LPSTR)lParam);
- break;
- case BFFM_SETSTATUSTEXTW:
- TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
- SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
- break;
- case BFFM_ENABLEOK:
- TRACE("Enable %ld\n", lParam);
- EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
- break;
- case BFFM_SETOKTEXT: /* unicode only */
- TRACE("Set OK text %s\n", debugstr_w((LPWSTR)wParam));
- SetWindowTextW(GetDlgItem(hWnd, 1), (LPWSTR)wParam);
- break;
- case BFFM_SETSELECTIONA:
- if (wParam)
- FIXME("Set selection %s\n", debugstr_a((LPSTR)lParam));
- else
- FIXME("Set selection %p\n", (void*)lParam);
- break;
- case BFFM_SETSELECTIONW:
- if (wParam)
- FIXME("Set selection %s\n", debugstr_w((LPWSTR)lParam));
- else
- FIXME("Set selection %p\n", (void*)lParam);
- break;
- case BFFM_SETEXPANDED: /* unicode only */
- if (wParam)
- FIXME("Set expanded %s\n", debugstr_w((LPWSTR)lParam));
- else
- FIXME("Set expanded %p\n", (void*)lParam);
- break;
- }
- return FALSE;
+ case BFFM_SETSTATUSTEXTW:
+ TRACE("Set status %s\n", debugstr_w((LPWSTR)lParam));
+ SetWindowTextW(GetDlgItem(hWnd, IDD_STATUS), (LPWSTR)lParam);
+ break;
+
+ case BFFM_ENABLEOK:
+ TRACE("Enable %ld\n", lParam);
+ EnableWindow(GetDlgItem(hWnd, 1), (lParam)?TRUE:FALSE);
+ break;
+
+ case BFFM_SETOKTEXT: /* unicode only */
+ TRACE("Set OK text %s\n", debugstr_w((LPWSTR)wParam));
+ SetWindowTextW(GetDlgItem(hWnd, 1), (LPWSTR)wParam);
+ break;
+
+ case BFFM_SETSELECTIONA:
+ if (wParam)
+ FIXME("Set selection %s\n", debugstr_a((LPSTR)lParam));
+ else
+ FIXME("Set selection %p\n", (void*)lParam);
+ break;
+
+ case BFFM_SETSELECTIONW:
+ if (wParam)
+ FIXME("Set selection %s\n", debugstr_w((LPWSTR)lParam));
+ else
+ FIXME("Set selection %p\n", (void*)lParam);
+ break;
+
+ case BFFM_SETEXPANDED: /* unicode only */
+ if (wParam)
+ FIXME("Set expanded %s\n", debugstr_w((LPWSTR)lParam));
+ else
+ FIXME("Set expanded %p\n", (void*)lParam);
+ break;
+ }
+ return FALSE;
}
-static const WCHAR swBrowseTempName[] =
{'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G'
,'B','O','X',0};
+static const WCHAR swBrowseTemplateName[] = {
+
'S','H','B','R','S','F','O','R','F','O','L','D','E','R','_','M','S','G',
'B','O','X',0};
/***********************************************************************
**
* SHBrowseForFolderA [SHELL32.@]
@@ -525,66 +611,69 @@
*/
LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
{
- BROWSEINFOW bi;
- LPITEMIDLIST lpid;
- INT len;
-
- TRACE("(%p{lpszTitle=%s,owner=%p})\n", lpbi,
- lpbi ? debugstr_a(lpbi->lpszTitle) : NULL, lpbi ?
lpbi->hwndOwner : NULL);
+ BROWSEINFOW bi;
+ LPITEMIDLIST lpid;
+ INT len;
+
+ TRACE("%p\n", lpbi);
- if (!lpbi)
- return NULL;
+ bi.hwndOwner = lpbi->hwndOwner;
+ bi.pidlRoot = lpbi->pidlRoot;
+ if (lpbi->pszDisplayName)
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1,
NULL, 0 );
+ bi.pszDisplayName = HeapAlloc( GetProcessHeap(), 0, len *
sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, lpbi->pszDisplayName, -1,
bi.pszDisplayName, len );
+ }
+ else
+ bi.pszDisplayName = NULL;
- bi.hwndOwner = lpbi->hwndOwner;
- bi.pidlRoot = lpbi->pidlRoot;
- if (lpbi->pszDisplayName)
- {
- /*lpbi->pszDisplayName is assumed to be MAX_PATH (MSDN) */
- bi.pszDisplayName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH *
sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpbi->pszDisplayName, -1,
bi.pszDisplayName, MAX_PATH);
- }
- else
- bi.pszDisplayName = NULL;
+ if (lpbi->lpszTitle)
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1,
NULL, 0 );
+ bi.lpszTitle = HeapAlloc( GetProcessHeap(), 0, len *
sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, lpbi->lpszTitle, -1,
(LPWSTR)bi.lpszTitle, len );
+ }
+ else
+ bi.lpszTitle = NULL;
- if (lpbi->lpszTitle)
- {
- len = MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1,
NULL, 0);
- bi.lpszTitle = HeapAlloc(GetProcessHeap(), 0, len *
sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, lpbi->lpszTitle, -1,
(LPWSTR)bi.lpszTitle, len);
- }
- else
- bi.lpszTitle = NULL;
-
- bi.ulFlags = lpbi->ulFlags;
- bi.lpfn = lpbi->lpfn;
- bi.lParam = lpbi->lParam;
- bi.iImage = lpbi->iImage;
- lpid = (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
- swBrowseTempName,
lpbi->hwndOwner,
- BrsFolderDlgProc,
(INT)&bi);
- if (bi.pszDisplayName)
- {
- WideCharToMultiByte(CP_ACP, 0, bi.pszDisplayName, -1,
lpbi->pszDisplayName, MAX_PATH, 0, NULL);
- HeapFree(GetProcessHeap(), 0, bi.pszDisplayName);
- }
- HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
- lpbi->iImage = bi.iImage;
- return lpid;
+ bi.ulFlags = lpbi->ulFlags;
+ bi.lpfn = lpbi->lpfn;
+ bi.lParam = lpbi->lParam;
+ bi.iImage = lpbi->iImage;
+ lpid = SHBrowseForFolderW( &bi );
+ if (bi.pszDisplayName)
+ {
+ WideCharToMultiByte( CP_ACP, 0, bi.pszDisplayName, -1,
+ lpbi->pszDisplayName, MAX_PATH, 0, NULL);
+ HeapFree( GetProcessHeap(), 0, bi.pszDisplayName );
+ }
+ HeapFree(GetProcessHeap(), 0, (LPVOID)bi.lpszTitle);
+ lpbi->iImage = bi.iImage;
+ return lpid;
}
/***********************************************************************
**
* SHBrowseForFolderW [SHELL32.@]
+ *
+ * NOTES:
+ * crashes when passed a null pointer
*/
LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
{
- TRACE("((%p->{lpszTitle=%s,owner=%p})\n", lpbi,
- lpbi ? debugstr_w(lpbi->lpszTitle) : NULL, lpbi ?
lpbi->hwndOwner : 0);
+ browse_info info;
+ DWORD r;
- if (!lpbi)
- return NULL;
+ info.hWnd = 0;
+ info.pidlRet = NULL;
+ info.lpBrowseInfo = lpbi;
+ info.hwndTreeView = NULL;
- return (LPITEMIDLIST) DialogBoxParamW(shell32_hInstance,
- swBrowseTempName,
lpbi->hwndOwner,
- BrsFolderDlgProc,
(INT)lpbi);
+ r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName,
lpbi->hwndOwner,
+ BrsFolderDlgProc, (LPARAM)&info );
+ if (!r)
+ return NULL;
+
+ return info.pidlRet;
}
_____
Modified: trunk/reactos/lib/shell32/cpanelfolder.c
--- trunk/reactos/lib/shell32/cpanelfolder.c 2005-05-28 21:30:02 UTC
(rev 15616)
+++ trunk/reactos/lib/shell32/cpanelfolder.c 2005-05-28 21:30:32 UTC
(rev 15617)
@@ -552,10 +552,13 @@
HRESULT hr = S_OK;
- TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n", This, cidl, apidl,
*rgfInOut);
+ TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
+ This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
- if ((!cidl) ||(!apidl) ||(!rgfInOut))
- return E_INVALIDARG;
+ if (!rgfInOut)
+ return E_INVALIDARG;
+ if (cidl && !apidl)
+ return E_INVALIDARG;
if (*rgfInOut == 0)
*rgfInOut = ~0;
@@ -566,6 +569,8 @@
apidl++;
cidl--;
}
+ /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
+ *rgfInOut &= ~SFGAO_VALIDATE;
TRACE("-- result=0x%08lx\n", *rgfInOut);
return hr;
_____
Modified: trunk/reactos/lib/shell32/folders.c
--- trunk/reactos/lib/shell32/folders.c 2005-05-28 21:30:02 UTC (rev
15616)
+++ trunk/reactos/lib/shell32/folders.c 2005-05-28 21:30:32 UTC (rev
15617)
@@ -383,7 +383,7 @@
FIXME("(%p) (file=%p index=%d %p %p size=%08x) semi-stub\n",
This, debugstr_w(pszFile), (signed)nIconIndex,
phiconLarge, phiconSmall, nIconSize);
- index = SIC_GetIconIndex(pszFile, nIconIndex);
+ index = SIC_GetIconIndex(pszFile, nIconIndex, 0);
if (phiconLarge)
*phiconLarge = ImageList_GetIcon(ShellBigIconList, index,
ILD_TRANSPARENT);
_____
Modified: trunk/reactos/lib/shell32/iconcache.c
--- trunk/reactos/lib/shell32/iconcache.c 2005-05-28 21:30:02 UTC
(rev 15616)
+++ trunk/reactos/lib/shell32/iconcache.c 2005-05-28 21:30:32 UTC
(rev 15617)
@@ -43,6 +43,7 @@
#include "pidl.h"
#include "shell32_main.h"
#include "undocshell.h"
+#include "shresdef.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -77,23 +78,165 @@
* Callback for DPA_Search
*/
static INT CALLBACK SIC_CompareEntries( LPVOID p1, LPVOID p2, LPARAM
lparam)
-{ TRACE("%p %p %8lx\n", p1, p2, lparam);
+{ LPSIC_ENTRY e1 = (LPSIC_ENTRY)p1, e2 = (LPSIC_ENTRY)p2;
+
+ TRACE("%p %p %8lx\n", p1, p2, lparam);
- if (((LPSIC_ENTRY)p1)->dwSourceIndex !=
((LPSIC_ENTRY)p2)->dwSourceIndex) /* first the faster one*/
+ /* Icons in the cache are keyed by the name of the file they are
+ * loaded from, their resource index and the fact if they have a
shortcut
+ * icon overlay or not.
+ */
+ if (e1->dwSourceIndex != e2->dwSourceIndex || /* first the
faster one */
+ (e1->dwFlags & GIL_FORSHORTCUT) != (e2->dwFlags &
GIL_FORSHORTCUT))
return 1;
- if
(strcmpiW(((LPSIC_ENTRY)p1)->sSourceFile,((LPSIC_ENTRY)p2)->sSourceFile)
)
+ if (strcmpiW(e1->sSourceFile,e2->sSourceFile))
return 1;
return 0;
}
+
/***********************************************************************
******
+ * SIC_OverlayShortcutImage [internal]
+ *
+ * NOTES
+ * Creates a new icon as a copy of the passed-in icon, overlayed with
a
+ * shortcut image.
+ */
+static HICON SIC_OverlayShortcutImage(HICON SourceIcon)
+{ ICONINFO SourceIconInfo, ShortcutIconInfo, TargetIconInfo;
+ HICON ShortcutIcon, TargetIcon;
+ BITMAP SourceBitmapInfo, ShortcutBitmapInfo;
+ HDC SourceDC = NULL,
+ ShortcutDC = NULL,
+ TargetDC = NULL,
+ ScreenDC = NULL;
+ HBITMAP OldSourceBitmap = NULL,
+ OldShortcutBitmap = NULL,
+ OldTargetBitmap = NULL;
+
+ /* 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);
+ if (NULL == ShortcutIcon
+ || ! GetIconInfo(ShortcutIcon, &ShortcutIconInfo)
+ || 0 == GetObjectW(ShortcutIconInfo.hbmColor,
sizeof(BITMAP), &ShortcutBitmapInfo))
+ {
+ return NULL;
+ }
+
+ TargetIconInfo = SourceIconInfo;
+ TargetIconInfo.hbmMask = NULL;
+ TargetIconInfo.hbmColor = NULL;
+
+ /* Setup the source, shortcut and target masks */
+ SourceDC = CreateCompatibleDC(NULL);
+ if (NULL == SourceDC) goto fail;
+ OldSourceBitmap = SelectObject(SourceDC,
SourceIconInfo.hbmMask);
+ if (NULL == OldSourceBitmap) goto fail;
+
+ ShortcutDC = CreateCompatibleDC(NULL);
+ if (NULL == ShortcutDC) goto fail;
+ OldShortcutBitmap = SelectObject(ShortcutDC,
ShortcutIconInfo.hbmMask);
+ if (NULL == OldShortcutBitmap) goto fail;
+
+ TargetDC = CreateCompatibleDC(NULL);
+ if (NULL == TargetDC) goto fail;
+ TargetIconInfo.hbmMask = CreateCompatibleBitmap(TargetDC,
SourceBitmapInfo.bmWidth,
+
SourceBitmapInfo.bmHeight);
+ if (NULL == TargetIconInfo.hbmMask) goto fail;
+ ScreenDC = GetDC(NULL);
+ if (NULL == ScreenDC) goto fail;
+ TargetIconInfo.hbmColor = CreateCompatibleBitmap(ScreenDC,
SourceBitmapInfo.bmWidth,
+
SourceBitmapInfo.bmHeight);
+ ReleaseDC(NULL, ScreenDC);
+ if (NULL == TargetIconInfo.hbmColor) goto fail;
+ OldTargetBitmap = SelectObject(TargetDC,
TargetIconInfo.hbmMask);
+ if (NULL == OldTargetBitmap) goto fail;
+
+ /* Create the target mask by ANDing the source and shortcut
masks */
+ if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth,
SourceBitmapInfo.bmHeight,
+ SourceDC, 0, 0, SRCCOPY) ||
+ ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight -
ShortcutBitmapInfo.bmHeight,
+ ShortcutBitmapInfo.bmWidth,
ShortcutBitmapInfo.bmHeight,
+ ShortcutDC, 0, 0, SRCAND))
+ {
+ goto fail;
+ }
+
+ /* Setup the source and target xor bitmap */
+ if (NULL == SelectObject(SourceDC, SourceIconInfo.hbmColor) ||
+ NULL == SelectObject(TargetDC, TargetIconInfo.hbmColor))
+ {
+ goto fail;
+ }
+
+ /* Copy the source xor bitmap to the target and clear out part
of it by using
+ the shortcut mask */
+ if (! BitBlt(TargetDC, 0, 0, SourceBitmapInfo.bmWidth,
SourceBitmapInfo.bmHeight,
+ SourceDC, 0, 0, SRCCOPY) ||
+ ! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight -
ShortcutBitmapInfo.bmHeight,
+ ShortcutBitmapInfo.bmWidth,
ShortcutBitmapInfo.bmHeight,
+ ShortcutDC, 0, 0, SRCAND))
+ {
+ goto fail;
+ }
+
+ if (NULL == SelectObject(ShortcutDC, ShortcutIconInfo.hbmColor))
goto fail;
+
+ /* Now put in the shortcut xor mask */
+ if (! BitBlt(TargetDC, 0, SourceBitmapInfo.bmHeight -
ShortcutBitmapInfo.bmHeight,
+ ShortcutBitmapInfo.bmWidth,
ShortcutBitmapInfo.bmHeight,
+ ShortcutDC, 0, 0, SRCINVERT))
+ {
+ goto fail;
+ }
+
+ /* Clean up, we're not goto'ing to 'fail' after this so we can
be lazy and not set
+ handles to NULL */
+ SelectObject(TargetDC, OldTargetBitmap);
+ DeleteObject(TargetDC);
+ SelectObject(ShortcutDC, OldShortcutBitmap);
+ DeleteObject(ShortcutDC);
+ SelectObject(SourceDC, OldSourceBitmap);
+ DeleteObject(SourceDC);
+
+ /* Create the icon using the bitmaps prepared earlier */
+ TargetIcon = CreateIconIndirect(&TargetIconInfo);
+
+ /* CreateIconIndirect copies the bitmaps, so we can release our
bitmaps now */
+ DeleteObject(TargetIconInfo.hbmColor);
+ DeleteObject(TargetIconInfo.hbmMask);
+
+ return TargetIcon;
+
+fail:
+ /* Clean up scratch resources we created */
+ if (NULL != OldTargetBitmap) SelectObject(TargetDC,
OldTargetBitmap);
+ if (NULL != TargetIconInfo.hbmColor)
DeleteObject(TargetIconInfo.hbmColor);
+ if (NULL != TargetIconInfo.hbmMask)
DeleteObject(TargetIconInfo.hbmMask);
+ if (NULL != TargetDC) DeleteObject(TargetDC);
+ if (NULL != OldShortcutBitmap) SelectObject(ShortcutDC,
OldShortcutBitmap);
+ if (NULL != ShortcutDC) DeleteObject(ShortcutDC);
[truncated at 1000 lines; 1448 more skipped]