mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Vitaliy Margolen <wine-patch@kievinfo.com>
- Michael Jung <mjung@iss.tu-darmstadt.de> Set all capability flags supported by the shellfolder, disregarding the flag mask given to GetAttributesOf. Unit tests to demonstrate this behaviour. Michael Jung <mjung@iss.tu-darmstadt.de> - Added some comments to document unixfs. - Fixed crash in unixfs shellfolder handling with winamp. - Implemented UnixFolder's IPersistPropertyBag::Load method. - Initialize COM prior to displaying the SHBrowseForFolder dialog. - More robust code for querying ShellFolder attributes (some ShellFolders ignore the flag mask in GetAttributesOf). - Remove iconcache pre-initialization hack, it's not necessary any more. - Move target folder initialization to a dedicated function. - Use this function in BindToObject (should be faster). - Special handling for FolderShortcut objects in Initialize method. - Removed a todo_wine from a no longer failing unit test. - Replaced tabs with spaces. Robert Shearman <rob@codeweavers.com> - Convert SHELL32_BindToChild to Unicode and fix up the callers. Vincent Bén <vberon@mecano.gme.usherb.ca> - Unicodify systray.c. - Move functions a bit to get rid of a static declaration. Dmitry Timoshkov <dmitry@codeweavers.com> - Correctly handle flags parameter in SHAddToRecentDocs. Martin Fuchs <martin-fuchs@gmx.net> - Correct WINAPI position for MSVC portability. Mike McCormack <mike@codeweavers.com> - Partially implement and test the shelllink object's IShellLinkDataList::CopyDataBlock and GetFlags methods. - Use advapi32.CommandLineFromMsiDescriptor to get msi component paths. - Pass the correct verb. Add a space between extra parameters. Wait for ShellExecute to complete. - Handle MSI advertised shortcuts in the shelllink object. - Implement IContextMenu::QueryContextMenu and IContextMenu::InvokeCommand. - Add the IObjectWithSite interface. - Invoke shortcuts through IContextMenu, rather than trying to access them directly. - Fix a problem spotted by Dmitry and another one stopping correctly formatted lnk files from being generated. svn path=/trunk/; revision=19356
This commit is contained in:
parent
e65d49b000
commit
4c62f96aad
26 changed files with 887 additions and 348 deletions
|
@ -21,6 +21,7 @@ HKCR,"lnkfile","NeverShowExt",0x00000000,""
|
|||
HKCR,"lnkfile","IsShortcut",0x00000000,"yes"
|
||||
HKCR,"lnkfile\CLSID","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
|
||||
HKCR,"lnkfile\shellex\IconHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
|
||||
HKCR,lnkfile\shellex\ContextMenuHandlers\{00021401-0000-0000-C000-000000000046},,,
|
||||
|
||||
; shell command files (e.g. "Show Desktop" in quicklaunch bar)
|
||||
HKCR,".scf","",0x00000000,"SHCmdFile"
|
||||
|
|
|
@ -43,4 +43,13 @@ DEFINE_GUID(IID_IPersistFolder3, 0xcef04fdf, 0xfe72, 0x11d2, 0x87,0xa5, 0x00,0xc
|
|||
/*** IShellExecuteHookW methods ***/
|
||||
#define IShellExecuteHookW_Execute(p,a) (p)->lpVtbl->Execute(p,a)
|
||||
|
||||
#ifdef COBJMACROS
|
||||
/*** IUnknown methods ***/
|
||||
#define IShellExtInit_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IShellExtInit_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IShellExtInit_Release(p) (p)->lpVtbl->Release(p)
|
||||
/*** IShellExtInit methods ***/
|
||||
#define IShellExtInit_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_SHOBJIDL_H */
|
||||
|
|
|
@ -6,7 +6,7 @@ VPATH = @srcdir@
|
|||
MODULE = shell32.dll
|
||||
IMPORTLIB = libshell32.$(IMPLIBEXT)
|
||||
IMPORTS = shlwapi comctl32 user32 gdi32 advapi32 kernel32 ntdll
|
||||
DELAYIMPORTS = ole32
|
||||
DELAYIMPORTS = ole32 oleaut32
|
||||
EXTRALIBS = -luuid $(LIBUNICODE)
|
||||
|
||||
C_SRCS = \
|
||||
|
|
|
@ -388,7 +388,7 @@ static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptv
|
|||
dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
|
||||
r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
|
||||
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
|
||||
if (FAILED(r) || !dwAttributes)
|
||||
if (FAILED(r) || !(dwAttributes & (SFGAO_FILESYSANCESTOR|SFGAO_FILESYSTEM)))
|
||||
bEnabled = FALSE;
|
||||
}
|
||||
if (lpBrowseInfo->ulFlags & BIF_RETURNONLYFSDIRS)
|
||||
|
@ -396,8 +396,11 @@ static void BrsFolder_CheckValidSelection( browse_info *info, LPTV_ITEMDATA lptv
|
|||
dwAttributes = SFGAO_FOLDER | SFGAO_FILESYSTEM;
|
||||
r = IShellFolder_GetAttributesOf(lptvid->lpsfParent, 1,
|
||||
(LPCITEMIDLIST*)&lptvid->lpi, &dwAttributes);
|
||||
if (FAILED(r) || (dwAttributes != (SFGAO_FOLDER | SFGAO_FILESYSTEM)))
|
||||
if (FAILED(r) ||
|
||||
((dwAttributes & (SFGAO_FOLDER|SFGAO_FILESYSTEM)) != (SFGAO_FOLDER|SFGAO_FILESYSTEM)))
|
||||
{
|
||||
bEnabled = FALSE;
|
||||
}
|
||||
}
|
||||
SendMessageW(info->hWnd, BFFM_ENABLEOK, 0, (LPARAM)bEnabled);
|
||||
}
|
||||
|
@ -662,21 +665,25 @@ LPITEMIDLIST WINAPI SHBrowseForFolderA (LPBROWSEINFOA lpbi)
|
|||
/*************************************************************************
|
||||
* SHBrowseForFolderW [SHELL32.@]
|
||||
*
|
||||
* NOTES:
|
||||
* NOTES
|
||||
* crashes when passed a null pointer
|
||||
*/
|
||||
LPITEMIDLIST WINAPI SHBrowseForFolderW (LPBROWSEINFOW lpbi)
|
||||
{
|
||||
browse_info info;
|
||||
DWORD r;
|
||||
HRESULT hr;
|
||||
|
||||
info.hWnd = 0;
|
||||
info.pidlRet = NULL;
|
||||
info.lpBrowseInfo = lpbi;
|
||||
info.hwndTreeView = NULL;
|
||||
|
||||
hr = CoInitialize(NULL);
|
||||
r = DialogBoxParamW( shell32_hInstance, swBrowseTemplateName, lpbi->hwndOwner,
|
||||
BrsFolderDlgProc, (LPARAM)&info );
|
||||
if (SUCCEEDED(hr))
|
||||
CoUninitialize();
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -410,7 +410,7 @@ static BOOL CreateCPanelEnumList(
|
|||
WIN32_FIND_DATAA wfd;
|
||||
HANDLE hFile;
|
||||
|
||||
TRACE("(%p)->(flags=0x%08lx) \n",iface,dwFlags);
|
||||
TRACE("(%p)->(flags=0x%08lx)\n", iface, dwFlags);
|
||||
|
||||
/* enumerate control panel folders folders */
|
||||
if (dwFlags & SHCONTF_FOLDERS)
|
||||
|
|
|
@ -116,7 +116,7 @@ BOOL CreateFolderEnumList(
|
|||
static const WCHAR dot[] = { '.',0 };
|
||||
static const WCHAR dotdot[] = { '.','.',0 };
|
||||
|
||||
TRACE("(%p)->(path=%s flags=0x%08lx) \n",list,debugstr_w(lpszPath),dwFlags);
|
||||
TRACE("(%p)->(path=%s flags=0x%08lx)\n", list, debugstr_w(lpszPath), dwFlags);
|
||||
|
||||
if(!lpszPath || !lpszPath[0]) return FALSE;
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
|
|||
|
||||
if ( INVALID_INDEX == index )
|
||||
{
|
||||
ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
|
||||
ret = SIC_LoadIcon (sSourceFile, dwSourceIndex, dwFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -378,15 +378,10 @@ INT SIC_GetIconIndex (LPCWSTR sSourceFile, INT dwSourceIndex, DWORD dwFlags )
|
|||
}
|
||||
/*****************************************************************************
|
||||
* SIC_Initialize [internal]
|
||||
*
|
||||
* NOTES
|
||||
* hack to load the resources from the shell32.dll under a different dll name
|
||||
* will be removed when the resource-compiler is ready
|
||||
*/
|
||||
BOOL SIC_Initialize(void)
|
||||
{
|
||||
HICON hSm, hLg;
|
||||
UINT index;
|
||||
int cx_small, cy_small;
|
||||
int cx_large, cy_large;
|
||||
|
||||
|
@ -407,28 +402,26 @@ BOOL SIC_Initialize(void)
|
|||
return(FALSE);
|
||||
}
|
||||
|
||||
ShellSmallIconList = ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,0,0x20);
|
||||
ShellBigIconList = ImageList_Create(32,32,ILC_COLOR32|ILC_MASK,0,0x20);
|
||||
ShellSmallIconList = ImageList_Create(cx_small,cy_small,ILC_COLOR32|ILC_MASK,0,0x20);
|
||||
ShellBigIconList = ImageList_Create(cx_large,cy_large,ILC_COLOR32|ILC_MASK,0,0x20);
|
||||
|
||||
ImageList_SetBkColor(ShellSmallIconList, CLR_NONE);
|
||||
ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
|
||||
ImageList_SetBkColor(ShellSmallIconList, CLR_NONE);
|
||||
ImageList_SetBkColor(ShellBigIconList, CLR_NONE);
|
||||
|
||||
/*
|
||||
* Wine will extract and cache all shell32 icons here. That's because
|
||||
* they are unable to extract resources from their built-in DLLs.
|
||||
* We don't need that, but we still want to make sure that the very
|
||||
* first icon in the image lists is icon 1 from shell32.dll, since
|
||||
* that's the default icon.
|
||||
*/
|
||||
index = 1;
|
||||
hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_small, cy_small, LR_SHARED);
|
||||
hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(index), IMAGE_ICON, cx_large, cy_large, LR_SHARED);
|
||||
/* Load the document icon, which is used as the default if an icon isn't found. */
|
||||
hSm = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
|
||||
IMAGE_ICON, cx_small, cy_small, LR_SHARED);
|
||||
hLg = (HICON)LoadImageA(shell32_hInstance, MAKEINTRESOURCEA(IDI_SHELL_DOCUMENT),
|
||||
IMAGE_ICON, cx_large, cy_large, LR_SHARED);
|
||||
|
||||
if(hSm)
|
||||
{
|
||||
SIC_IconAppend (swShell32Name, index - 1, hSm, hLg, 0);
|
||||
SIC_IconAppend (swShell32Name, -index, hSm, hLg, 0);
|
||||
}
|
||||
if (!hSm || !hLg)
|
||||
{
|
||||
FIXME("Failed to load IDI_SHELL_DOCUMENT icon!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SIC_IconAppend (swShell32Name, IDI_SHELL_DOCUMENT-1, hSm, hLg, 0);
|
||||
SIC_IconAppend (swShell32Name, -IDI_SHELL_DOCUMENT, hSm, hLg, 0);
|
||||
|
||||
TRACE("hIconSmall=%p hIconBig=%p\n",ShellSmallIconList, ShellBigIconList);
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
|
|||
DWORD len;
|
||||
LPITEMIDLIST pidlNew = NULL;
|
||||
|
||||
TRACE("pidl=%p \n",pidl);
|
||||
TRACE("pidl=%p\n", pidl);
|
||||
pdump(pidl);
|
||||
|
||||
if (pidl)
|
||||
|
@ -885,6 +885,9 @@ LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl, LPCITEMIDLIST item, BOOL bEnd)
|
|||
* PARAMS
|
||||
* pidl [I]
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing
|
||||
*
|
||||
* NOTES
|
||||
* exported by ordinal
|
||||
*/
|
||||
|
@ -903,6 +906,9 @@ void WINAPI ILFree(LPITEMIDLIST pidl)
|
|||
* PARAMS
|
||||
* pidl [I]
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing
|
||||
*
|
||||
* NOTES
|
||||
* exported by ordinal.
|
||||
*/
|
||||
|
@ -941,6 +947,8 @@ LPITEMIDLIST WINAPI ILCreateFromPathA (LPCSTR path)
|
|||
|
||||
/*************************************************************************
|
||||
* ILCreateFromPathW [SHELL32.190]
|
||||
*
|
||||
* See ILCreateFromPathA.
|
||||
*/
|
||||
LPITEMIDLIST WINAPI ILCreateFromPathW (LPCWSTR path)
|
||||
{
|
||||
|
@ -1238,6 +1246,8 @@ BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST pidl, LPSTR pszPath)
|
|||
|
||||
/*************************************************************************
|
||||
* SHGetPathFromIDListW [SHELL32.@]
|
||||
*
|
||||
* See SHGetPathFromIDListA.
|
||||
*/
|
||||
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
|
||||
{
|
||||
|
|
|
@ -335,12 +335,13 @@ SEGPTR WINAPI FindEnvironmentString16(LPSTR str)
|
|||
* from "DOS" environment. If it is not found the %KEYWORD% is left
|
||||
* intact. If the buffer is too small, str is not modified.
|
||||
*
|
||||
* str [I] '\0' terminated string with %keyword%.
|
||||
* PARAMS
|
||||
* str [I] '\0' terminated string with %keyword%.
|
||||
* [O] '\0' terminated string with %keyword% substituted.
|
||||
* length [I] size of str.
|
||||
* length [I] size of str.
|
||||
*
|
||||
* Return
|
||||
* str length in the LOWORD and 1 in HIWORD if subst was successful.
|
||||
* RETURNS
|
||||
* str length in the LOWORD and 1 in HIWORD if subst was successful.
|
||||
*/
|
||||
DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length)
|
||||
{
|
||||
|
@ -625,7 +626,7 @@ HINSTANCE16 WINAPI ShellExecute16( HWND16 hWnd, LPCSTR lpOperation,
|
|||
seiW.dwHotKey = 0;
|
||||
seiW.hProcess = hProcess;
|
||||
|
||||
SHELL_execute( &seiW, SHELL_Execute16, FALSE );
|
||||
SHELL_execute( &seiW, SHELL_Execute16 );
|
||||
|
||||
if (wVerb) SHFree(wVerb);
|
||||
if (wFile) SHFree(wFile);
|
||||
|
|
|
@ -213,7 +213,7 @@ inline static WCHAR * __SHCloneStrAtoW(WCHAR ** target, const char * source)
|
|||
typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
|
||||
LPSHELLEXECUTEINFOW sei, LPSHELLEXECUTEINFOW sei_out);
|
||||
|
||||
BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL unicode);
|
||||
BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc);
|
||||
|
||||
UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation,
|
||||
LPWSTR lpResult, int resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args);
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#include "shell32_main.h"
|
||||
#include "shlguid.h"
|
||||
#include "shlwapi.h"
|
||||
#include "msi.h"
|
||||
#include "appmgmt.h"
|
||||
|
||||
#include "initguid.h"
|
||||
|
||||
|
@ -120,6 +122,7 @@ static const IPersistStreamVtbl psvt;
|
|||
static const IShellLinkDataListVtbl dlvt;
|
||||
static const IShellExtInitVtbl eivt;
|
||||
static const IContextMenuVtbl cmvt;
|
||||
static const IObjectWithSiteVtbl owsvt;
|
||||
|
||||
/* IShellLink Implementation */
|
||||
|
||||
|
@ -132,6 +135,7 @@ typedef struct
|
|||
const IShellLinkDataListVtbl *lpvtblShellLinkDataList;
|
||||
const IShellExtInitVtbl *lpvtblShellExtInit;
|
||||
const IContextMenuVtbl *lpvtblContextMenu;
|
||||
const IObjectWithSiteVtbl *lpvtblObjectWithSite;
|
||||
|
||||
LONG ref;
|
||||
|
||||
|
@ -154,7 +158,9 @@ typedef struct
|
|||
LPWSTR sComponent;
|
||||
volume_info volume;
|
||||
|
||||
BOOL bDirty;
|
||||
BOOL bDirty;
|
||||
INT iIdOpen; /* id of the "Open" entry in the context menu */
|
||||
IUnknown *site;
|
||||
} IShellLinkImpl;
|
||||
|
||||
static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface )
|
||||
|
@ -187,6 +193,11 @@ static inline IShellLinkImpl *impl_from_IContextMenu( IContextMenu *iface )
|
|||
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblContextMenu));
|
||||
}
|
||||
|
||||
static inline IShellLinkImpl *impl_from_IObjectWithSite( IObjectWithSite *iface )
|
||||
{
|
||||
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblObjectWithSite));
|
||||
}
|
||||
|
||||
static HRESULT ShellLink_UpdatePath(LPWSTR sPathRel, LPCWSTR path, LPCWSTR sWorkDir, LPWSTR* psPath);
|
||||
|
||||
/* strdup on the process heap */
|
||||
|
@ -200,6 +211,16 @@ inline static LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
|
|||
return p;
|
||||
}
|
||||
|
||||
inline static LPWSTR strdupW( LPCWSTR src )
|
||||
{
|
||||
LPWSTR dest;
|
||||
if (!src) return NULL;
|
||||
dest = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(src)+1)*sizeof(WCHAR) );
|
||||
if (dest)
|
||||
lstrcpyW(dest, src);
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* ShellLink::QueryInterface implementation
|
||||
*/
|
||||
|
@ -237,6 +258,10 @@ static HRESULT ShellLink_QueryInterface( IShellLinkImpl *This, REFIID riid, LPV
|
|||
{
|
||||
*ppvObj = &(This->lpvtblContextMenu);
|
||||
}
|
||||
else if(IsEqualIID(riid, &IID_IObjectWithSite))
|
||||
{
|
||||
*ppvObj = &(This->lpvtblObjectWithSite);
|
||||
}
|
||||
|
||||
if(*ppvObj)
|
||||
{
|
||||
|
@ -280,6 +305,9 @@ static ULONG ShellLink_Release( IShellLinkImpl *This )
|
|||
HeapFree(GetProcessHeap(), 0, This->sDescription);
|
||||
HeapFree(GetProcessHeap(),0,This->sPath);
|
||||
|
||||
if (This->site)
|
||||
IUnknown_Release( This->site );
|
||||
|
||||
if (This->pPidl)
|
||||
ILFree(This->pPidl);
|
||||
|
||||
|
@ -986,20 +1014,29 @@ static HRESULT Stream_WriteLocationInfo( IStream* stm, LPCWSTR path,
|
|||
return IStream_Write( stm, loc, total_size, &count );
|
||||
}
|
||||
|
||||
static EXP_DARWIN_LINK* shelllink_build_darwinid( LPCWSTR string, DWORD magic )
|
||||
{
|
||||
EXP_DARWIN_LINK *buffer;
|
||||
|
||||
buffer = LocalAlloc( LMEM_ZEROINIT, sizeof *buffer );
|
||||
buffer->dbh.cbSize = sizeof *buffer;
|
||||
buffer->dbh.dwSignature = magic;
|
||||
lstrcpynW( buffer->szwDarwinID, string, MAX_PATH );
|
||||
WideCharToMultiByte(CP_ACP, 0, string, -1, buffer->szDarwinID, MAX_PATH, NULL, NULL );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static HRESULT Stream_WriteAdvertiseInfo( IStream* stm, LPCWSTR string, DWORD magic )
|
||||
{
|
||||
EXP_DARWIN_LINK *buffer;
|
||||
ULONG count;
|
||||
EXP_DARWIN_LINK buffer;
|
||||
|
||||
TRACE("%p\n",stm);
|
||||
|
||||
memset( &buffer, 0, sizeof buffer );
|
||||
buffer.dbh.cbSize = sizeof buffer;
|
||||
buffer.dbh.dwSignature = magic;
|
||||
lstrcpynW( buffer.szwDarwinID, string, MAX_PATH );
|
||||
WideCharToMultiByte(CP_ACP, 0, string, -1, buffer.szDarwinID, MAX_PATH, NULL, NULL );
|
||||
buffer = shelllink_build_darwinid( string, magic );
|
||||
|
||||
return IStream_Write( stm, &buffer, buffer.dbh.cbSize, &count );
|
||||
return IStream_Write( stm, buffer, buffer->dbh.cbSize, &count );
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -1075,7 +1112,7 @@ static HRESULT WINAPI IPersistStream_fnSave(
|
|||
return r;
|
||||
}
|
||||
|
||||
TRACE("Writing pidl \n");
|
||||
TRACE("Writing pidl\n");
|
||||
|
||||
/* write the PIDL to the shortcut */
|
||||
if( This->pPidl )
|
||||
|
@ -1172,8 +1209,11 @@ HRESULT WINAPI IShellLink_Constructor( IUnknown *pUnkOuter,
|
|||
sl->lpvtblShellLinkDataList = &dlvt;
|
||||
sl->lpvtblShellExtInit = &eivt;
|
||||
sl->lpvtblContextMenu = &cmvt;
|
||||
sl->lpvtblObjectWithSite = &owsvt;
|
||||
sl->iShowCmd = SW_SHOWNORMAL;
|
||||
sl->bDirty = FALSE;
|
||||
sl->iIdOpen = -1;
|
||||
sl->site = NULL;
|
||||
|
||||
TRACE("(%p)->()\n",sl);
|
||||
|
||||
|
@ -2215,8 +2255,32 @@ ShellLink_AddDataBlock( IShellLinkDataList* iface, void* pDataBlock )
|
|||
static HRESULT WINAPI
|
||||
ShellLink_CopyDataBlock( IShellLinkDataList* iface, DWORD dwSig, void** ppDataBlock )
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
|
||||
LPVOID block = NULL;
|
||||
HRESULT r = E_FAIL;
|
||||
|
||||
TRACE("%p %08lx %p\n", iface, dwSig, ppDataBlock );
|
||||
|
||||
switch (dwSig)
|
||||
{
|
||||
case EXP_DARWIN_ID_SIG:
|
||||
if (!This->sComponent)
|
||||
break;
|
||||
block = shelllink_build_darwinid( This->sComponent, dwSig );
|
||||
r = S_OK;
|
||||
break;
|
||||
case EXP_SZ_LINK_SIG:
|
||||
case NT_CONSOLE_PROPS_SIG:
|
||||
case NT_FE_CONSOLE_PROPS_SIG:
|
||||
case EXP_SPECIAL_FOLDER_SIG:
|
||||
case EXP_SZ_ICON_SIG:
|
||||
FIXME("valid but unhandled datablock %08lx\n", dwSig);
|
||||
break;
|
||||
default:
|
||||
ERR("unknown datablock %08lx\n", dwSig);
|
||||
}
|
||||
*ppDataBlock = block;
|
||||
return r;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
@ -2229,8 +2293,26 @@ ShellLink_RemoveDataBlock( IShellLinkDataList* iface, DWORD dwSig )
|
|||
static HRESULT WINAPI
|
||||
ShellLink_GetFlags( IShellLinkDataList* iface, DWORD* pdwFlags )
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
|
||||
DWORD flags = 0;
|
||||
|
||||
FIXME("%p %p\n", This, pdwFlags );
|
||||
|
||||
/* FIXME: add more */
|
||||
if (This->sArgs)
|
||||
flags |= SLDF_HAS_ARGS;
|
||||
if (This->sComponent)
|
||||
flags |= SLDF_HAS_DARWINID;
|
||||
if (This->sIcoPath)
|
||||
flags |= SLDF_HAS_ICONLOCATION;
|
||||
if (This->sProduct)
|
||||
flags |= SLDF_HAS_LOGO3ID;
|
||||
if (This->pPidl)
|
||||
flags |= SLDF_HAS_ID_LIST;
|
||||
|
||||
*pdwFlags = flags;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
@ -2358,21 +2440,139 @@ ShellLink_QueryContextMenu( IContextMenu* iface, HMENU hmenu, UINT indexMenu,
|
|||
UINT idCmdFirst, UINT idCmdLast, UINT uFlags )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IContextMenu(iface);
|
||||
static const WCHAR szOpen[] = { 'O','p','e','n',0 };
|
||||
MENUITEMINFOW mii;
|
||||
int id = 1;
|
||||
|
||||
FIXME("%p %p %u %u %u %u\n", This,
|
||||
TRACE("%p %p %u %u %u %u\n", This,
|
||||
hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags );
|
||||
|
||||
return E_NOTIMPL;
|
||||
if ( !hmenu )
|
||||
return E_INVALIDARG;
|
||||
|
||||
memset( &mii, 0, sizeof mii );
|
||||
mii.cbSize = sizeof mii;
|
||||
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
|
||||
mii.dwTypeData = (LPWSTR)szOpen;
|
||||
mii.cch = strlenW( mii.dwTypeData );
|
||||
mii.wID = idCmdFirst + id++;
|
||||
mii.fState = MFS_DEFAULT | MFS_ENABLED;
|
||||
mii.fType = MFT_STRING;
|
||||
if (!InsertMenuItemW( hmenu, indexMenu, TRUE, &mii ))
|
||||
return E_FAIL;
|
||||
This->iIdOpen = 0;
|
||||
|
||||
return MAKE_HRESULT( SEVERITY_SUCCESS, 0, id );
|
||||
}
|
||||
|
||||
static LPWSTR
|
||||
shelllink_get_msi_component_path( LPWSTR component )
|
||||
{
|
||||
LPWSTR path = NULL;
|
||||
DWORD r, sz = 0;
|
||||
|
||||
r = CommandLineFromMsiDescriptor( component, NULL, &sz );
|
||||
if (r != ERROR_SUCCESS)
|
||||
return path;
|
||||
|
||||
sz++;
|
||||
path = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
|
||||
r = CommandLineFromMsiDescriptor( component, path, &sz );
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
TRACE("returning %s\n", debugstr_w( path ) );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
ShellLink_InvokeCommand( IContextMenu* iface, LPCMINVOKECOMMANDINFO lpici )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IContextMenu(iface);
|
||||
static const WCHAR szOpen[] = { 'O','p','e','n',0 };
|
||||
SHELLEXECUTEINFOW sei;
|
||||
HWND hwnd = NULL; /* FIXME: get using interface set from IObjectWithSite */
|
||||
LPWSTR args = NULL;
|
||||
LPWSTR path = NULL;
|
||||
HRESULT r;
|
||||
|
||||
FIXME("%p %p\n", This, lpici );
|
||||
TRACE("%p %p\n", This, lpici );
|
||||
|
||||
return E_NOTIMPL;
|
||||
if ( lpici->cbSize < sizeof (CMINVOKECOMMANDINFO) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
if ( lpici->lpVerb != MAKEINTRESOURCEA(This->iIdOpen) )
|
||||
{
|
||||
ERR("Unknown id %d != %d\n", (INT)lpici->lpVerb, This->iIdOpen );
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
r = IShellLinkW_Resolve( (IShellLinkW*)&(This->lpvtblw), hwnd, 0 );
|
||||
if ( FAILED( r ) )
|
||||
return r;
|
||||
|
||||
if ( This->sComponent )
|
||||
{
|
||||
path = shelllink_get_msi_component_path( This->sComponent );
|
||||
if (!path)
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
path = strdupW( This->sPath );
|
||||
|
||||
if ( lpici->cbSize == sizeof (CMINVOKECOMMANDINFOEX) &&
|
||||
( lpici->fMask & CMIC_MASK_UNICODE ) )
|
||||
{
|
||||
LPCMINVOKECOMMANDINFOEX iciex = (LPCMINVOKECOMMANDINFOEX) lpici;
|
||||
DWORD len = 2;
|
||||
|
||||
if ( This->sArgs )
|
||||
len += lstrlenW( This->sArgs );
|
||||
if ( iciex->lpParametersW )
|
||||
len += lstrlenW( iciex->lpParametersW );
|
||||
|
||||
args = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
|
||||
args[0] = 0;
|
||||
if ( This->sArgs )
|
||||
lstrcatW( args, This->sArgs );
|
||||
if ( iciex->lpParametersW )
|
||||
{
|
||||
static const WCHAR space[] = { ' ', 0 };
|
||||
lstrcatW( args, space );
|
||||
lstrcatW( args, iciex->lpParametersW );
|
||||
}
|
||||
}
|
||||
|
||||
memset( &sei, 0, sizeof sei );
|
||||
sei.cbSize = sizeof sei;
|
||||
sei.fMask = SEE_MASK_UNICODE | SEE_MASK_NOCLOSEPROCESS;
|
||||
sei.lpFile = path;
|
||||
sei.nShow = This->iShowCmd;
|
||||
sei.lpIDList = This->pPidl;
|
||||
sei.lpDirectory = This->sWorkDir;
|
||||
sei.lpParameters = args;
|
||||
sei.lpVerb = szOpen;
|
||||
|
||||
if( ShellExecuteExW( &sei ) )
|
||||
{
|
||||
if ( sei.hProcess )
|
||||
{
|
||||
WaitForSingleObject( sei.hProcess, 10000 );
|
||||
CloseHandle( sei.hProcess );
|
||||
}
|
||||
r = S_OK;
|
||||
}
|
||||
else
|
||||
r = E_FAIL;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, args );
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
|
@ -2396,3 +2596,59 @@ static const IContextMenuVtbl cmvt =
|
|||
ShellLink_InvokeCommand,
|
||||
ShellLink_GetCommandString
|
||||
};
|
||||
|
||||
static HRESULT WINAPI
|
||||
ShellLink_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IObjectWithSite(iface);
|
||||
return ShellLink_QueryInterface( This, riid, ppvObject );
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
ShellLink_ObjectWithSite_AddRef( IObjectWithSite* iface )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IObjectWithSite(iface);
|
||||
return ShellLink_AddRef( This );
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
ShellLink_ObjectWithSite_Release( IObjectWithSite* iface )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IObjectWithSite(iface);
|
||||
return ShellLink_Release( This );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
ShellLink_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IObjectWithSite(iface);
|
||||
|
||||
TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
|
||||
|
||||
if ( !This->site )
|
||||
return E_FAIL;
|
||||
return IUnknown_QueryInterface( This->site, iid, ppvSite );
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
ShellLink_SetSite( IObjectWithSite *iface, IUnknown *punk )
|
||||
{
|
||||
IShellLinkImpl *This = impl_from_IObjectWithSite(iface);
|
||||
|
||||
TRACE("%p %p\n", iface, punk);
|
||||
|
||||
if ( punk )
|
||||
IUnknown_AddRef( punk );
|
||||
This->site = punk;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IObjectWithSiteVtbl owsvt =
|
||||
{
|
||||
ShellLink_ObjectWithSite_QueryInterface,
|
||||
ShellLink_ObjectWithSite_AddRef,
|
||||
ShellLink_ObjectWithSite_Release,
|
||||
ShellLink_SetSite,
|
||||
ShellLink_GetSite,
|
||||
};
|
||||
|
|
|
@ -689,8 +689,8 @@ BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p)
|
|||
}
|
||||
|
||||
/*************************************************************************
|
||||
* DragQueryFile [SHELL32.@]
|
||||
* DragQueryFileA [SHELL32.@]
|
||||
* DragQueryFile [SHELL32.@]
|
||||
*/
|
||||
UINT WINAPI DragQueryFileA(
|
||||
HDROP hDrop,
|
||||
|
|
|
@ -622,12 +622,17 @@ static INT SHADD_create_add_mru_data(HANDLE mruhandle, LPSTR doc_name, LPSTR new
|
|||
/*************************************************************************
|
||||
* SHAddToRecentDocs [SHELL32.@]
|
||||
*
|
||||
* Modify (add/clear) Shell's list of recently used documents.
|
||||
*
|
||||
* PARAMETERS
|
||||
* uFlags [IN] SHARD_PATH or SHARD_PIDL
|
||||
* uFlags [IN] SHARD_PATHA, SHARD_PATHW or SHARD_PIDL
|
||||
* pv [IN] string or pidl, NULL clears the list
|
||||
*
|
||||
* NOTES
|
||||
* exported by name
|
||||
*
|
||||
* FIXME
|
||||
* convert to unicode
|
||||
*/
|
||||
void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
|
||||
{
|
||||
|
@ -652,6 +657,8 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
|
|||
INT ret;
|
||||
DWORD data[64], datalen, type;
|
||||
|
||||
TRACE("%04x %p\n", uFlags, pv);
|
||||
|
||||
/*FIXME: Document:
|
||||
* RecentDocs MRU data structure seems to be:
|
||||
* +0h document file name w/ terminating 0h
|
||||
|
@ -732,7 +739,7 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
|
|||
* DeleteFileA(old_lnk_name);
|
||||
* }
|
||||
*/
|
||||
FIXME("should delete all files in %s\\ \n", link_dir);
|
||||
FIXME("should delete all files in %s\\\n", link_dir);
|
||||
|
||||
/* clear MRU list
|
||||
*/
|
||||
|
@ -757,15 +764,28 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
|
|||
|
||||
/* Get the pure document name from the input
|
||||
*/
|
||||
if (uFlags & SHARD_PIDL) {
|
||||
switch (uFlags)
|
||||
{
|
||||
case SHARD_PIDL:
|
||||
SHGetPathFromIDListA((LPCITEMIDLIST) pv, doc_name);
|
||||
break;
|
||||
|
||||
case SHARD_PATHA:
|
||||
lstrcpynA(doc_name, (LPCSTR)pv, MAX_PATH);
|
||||
break;
|
||||
|
||||
case SHARD_PATHW:
|
||||
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pv, -1, doc_name, MAX_PATH, NULL, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unsupported flags: %u\n", uFlags);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
lstrcpyA(doc_name, (LPCSTR) pv);
|
||||
}
|
||||
TRACE("full document name %s\n", doc_name);
|
||||
|
||||
TRACE("full document name %s\n", debugstr_a(doc_name));
|
||||
PathStripPathA(doc_name);
|
||||
TRACE("stripped document name %s\n", doc_name);
|
||||
TRACE("stripped document name %s\n", debugstr_a(doc_name));
|
||||
|
||||
|
||||
/* *** JOB 1: Update registry for ...\Explorer\RecentDocs list *** */
|
||||
|
@ -902,7 +922,7 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
|
|||
}
|
||||
|
||||
/* Set the document path or pidl */
|
||||
if (uFlags & SHARD_PIDL) {
|
||||
if (uFlags == SHARD_PIDL) {
|
||||
hres = IShellLinkA_SetIDList(psl, (LPCITEMIDLIST) pv);
|
||||
} else {
|
||||
hres = IShellLinkA_SetPath(psl, (LPCSTR) pv);
|
||||
|
@ -955,6 +975,12 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
|
|||
/*************************************************************************
|
||||
* SHCreateShellFolderViewEx [SHELL32.174]
|
||||
*
|
||||
* Create a new instance of the default Shell folder view object.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: error value
|
||||
*
|
||||
* NOTES
|
||||
* see IShellFolder::CreateViewObject
|
||||
*/
|
||||
|
@ -1125,7 +1151,7 @@ BOOL WINAPI ReadCabinetState(CABINETSTATE *cs, int length)
|
|||
HKEY hkey = 0;
|
||||
DWORD type, r;
|
||||
|
||||
TRACE("%p %d \n",cs,length);
|
||||
TRACE("%p %d\n", cs, length);
|
||||
|
||||
if( (cs == NULL) || (length < (int)sizeof(*cs)) )
|
||||
return FALSE;
|
||||
|
@ -1319,10 +1345,11 @@ BOOL WINAPI SHWaitForFileToOpen(
|
|||
/************************************************************************
|
||||
* @ [SHELL32.654]
|
||||
*
|
||||
* NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState)
|
||||
* second one could be a size (0x0c). The size is the same as the structure saved to
|
||||
* HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
|
||||
* I'm (js) guessing: this one is just ReadCabinetState ;-)
|
||||
* NOTES
|
||||
* first parameter seems to be a pointer (same as passed to WriteCabinetState)
|
||||
* second one could be a size (0x0c). The size is the same as the structure saved to
|
||||
* HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
|
||||
* I'm (js) guessing: this one is just ReadCabinetState ;-)
|
||||
*/
|
||||
HRESULT WINAPI shell32_654 (CABINETSTATE *cs, int length)
|
||||
{
|
||||
|
@ -1357,11 +1384,12 @@ HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
|
|||
* from environment. If it is not found the %KEYWORD% is left
|
||||
* intact. If the buffer is too small, str is not modified.
|
||||
*
|
||||
* pszString [I] '\0' terminated string with %keyword%.
|
||||
* PARAMS
|
||||
* pszString [I] '\0' terminated string with %keyword%.
|
||||
* [O] '\0' terminated string with %keyword% substituted.
|
||||
* cchString [I] size of str.
|
||||
* cchString [I] size of str.
|
||||
*
|
||||
* Return
|
||||
* RETURNS
|
||||
* cchString length in the HIWORD;
|
||||
* TRUE in LOWORD if subst was successful and FALSE in other case
|
||||
*/
|
||||
|
@ -1388,6 +1416,7 @@ DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString)
|
|||
/************************************************************************
|
||||
* DoEnvironmentSubstW [SHELL32.@]
|
||||
*
|
||||
* See DoEnvironmentSubstA.
|
||||
*/
|
||||
DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
|
||||
{
|
||||
|
@ -1398,6 +1427,7 @@ DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
|
|||
/************************************************************************
|
||||
* DoEnvironmentSubst [SHELL32.53]
|
||||
*
|
||||
* See DoEnvironmentSubstA.
|
||||
*/
|
||||
DWORD WINAPI DoEnvironmentSubstAW(LPVOID x, UINT y)
|
||||
{
|
||||
|
@ -1563,6 +1593,9 @@ BOOL WINAPI SHFindFiles( LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidlSaveFile )
|
|||
* uFlags [I] Flags determining the icon attributes. See notes.
|
||||
* iImageIndex [I] Index of the icon in the system image list.
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing
|
||||
*
|
||||
* NOTES
|
||||
* uFlags can be one or more of the following flags:
|
||||
* GIL_NOTFILENAME - pszHashItem is not a file name.
|
||||
|
@ -1573,6 +1606,11 @@ void WINAPI SHUpdateImageW(LPCWSTR pszHashItem, int iIndex, UINT uFlags, int iIm
|
|||
FIXME("%s, %d, 0x%x, %d - stub\n", debugstr_w(pszHashItem), iIndex, uFlags, iImageIndex);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHUpdateImageA (SHELL32.191)
|
||||
*
|
||||
* See SHUpdateImageW.
|
||||
*/
|
||||
VOID WINAPI SHUpdateImageA(LPCSTR pszHashItem, INT iIndex, UINT uFlags, INT iImageIndex)
|
||||
{
|
||||
FIXME("%s, %d, 0x%x, %d - stub\n", debugstr_a(pszHashItem), iIndex, uFlags, iImageIndex);
|
||||
|
|
|
@ -1562,8 +1562,14 @@ end:
|
|||
/*************************************************************************
|
||||
* SHGetFolderPathW [SHELL32.@]
|
||||
*
|
||||
* Convert nFolder to path.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: standard HRESULT error codes.
|
||||
*
|
||||
* NOTES
|
||||
* Converts nFolder to path. Most values can be overridden in either
|
||||
* Most values can be overridden in either
|
||||
* HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
|
||||
* or in the same location in HKLM.
|
||||
* The registry usage is explained by the following tech note:
|
||||
|
@ -1577,13 +1583,13 @@ end:
|
|||
* http://www.microsoft.com/windows2000/techinfo/reskit/en-us/default.asp?url=/windows2000/techinfo/reskit/en-us/regentry/36276.asp
|
||||
* the HKCU paths take precedence over the HKLM paths.
|
||||
*
|
||||
**********************************************************************/
|
||||
*/
|
||||
HRESULT WINAPI SHGetFolderPathW(
|
||||
HWND hwndOwner,
|
||||
int nFolder,
|
||||
HANDLE hToken,
|
||||
DWORD dwFlags,
|
||||
LPWSTR pszPath)
|
||||
HWND hwndOwner, /* [I] owner window */
|
||||
int nFolder, /* [I] CSIDL identifing the folder */
|
||||
HANDLE hToken, /* [I] access token */
|
||||
DWORD dwFlags, /* [I] which path to return */
|
||||
LPWSTR pszPath) /* [O] converted path */
|
||||
{
|
||||
HRESULT hr;
|
||||
WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
|
||||
|
@ -1689,6 +1695,8 @@ end:
|
|||
|
||||
/*************************************************************************
|
||||
* SHGetFolderPathA [SHELL32.@]
|
||||
*
|
||||
* See SHGetFolderPathW.
|
||||
*/
|
||||
HRESULT WINAPI SHGetFolderPathA(
|
||||
HWND hwndOwner,
|
||||
|
@ -1928,11 +1936,7 @@ BOOL WINAPI SHGetSpecialFolderPathAW (
|
|||
/*************************************************************************
|
||||
* SHGetFolderLocation [SHELL32.@]
|
||||
*
|
||||
* NOTES
|
||||
* Gets the folder locations from the registry and creates a pidl.
|
||||
* Creates missing reg keys and directories.
|
||||
* Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
|
||||
* virtual folders that are handled here.
|
||||
*
|
||||
* PARAMS
|
||||
* hwndOwner [I]
|
||||
|
@ -1942,7 +1946,14 @@ BOOL WINAPI SHGetSpecialFolderPathAW (
|
|||
* dwReserved [I] must be zero
|
||||
* ppidl [O] PIDL of a special folder
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
|
||||
*
|
||||
* NOTES
|
||||
* Creates missing reg keys and directories.
|
||||
* Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
|
||||
* virtual folders that are handled here.
|
||||
*/
|
||||
HRESULT WINAPI SHGetFolderLocation(
|
||||
HWND hwndOwner,
|
||||
|
|
|
@ -260,7 +260,7 @@ static const WCHAR strEscapedChars[] = {' ','"',',',';','^',0};
|
|||
/*************************************************************************
|
||||
* CheckEscapesW [SHELL32.@]
|
||||
*
|
||||
* see CheckEscapesA
|
||||
* See CheckEscapesA.
|
||||
*/
|
||||
DWORD WINAPI CheckEscapesW(
|
||||
LPWSTR string,
|
||||
|
|
|
@ -43,7 +43,7 @@ HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl,
|
|||
DWORD dwOutLen);
|
||||
|
||||
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
|
||||
LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
|
||||
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
|
||||
|
||||
HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
|
||||
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);
|
||||
|
|
|
@ -265,7 +265,7 @@ static BOOL CreateDesktopEnumList(IEnumIDList *list, DWORD dwFlags)
|
|||
BOOL ret = TRUE;
|
||||
WCHAR szPath[MAX_PATH];
|
||||
|
||||
TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
|
||||
TRACE("(%p)->(flags=0x%08lx)\n", list, dwFlags);
|
||||
|
||||
/* enumerate the root folders */
|
||||
if (dwFlags & SHCONTF_FOLDERS)
|
||||
|
@ -338,14 +338,11 @@ static HRESULT WINAPI ISF_Desktop_fnBindToObject (IShellFolder2 * iface,
|
|||
LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
|
||||
{
|
||||
IGenericSFImpl *This = (IGenericSFImpl *)iface;
|
||||
char szPath[MAX_PATH];
|
||||
|
||||
TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
|
||||
This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
|
||||
|
||||
WideCharToMultiByte( CP_ACP, 0, This->sPathTarget, -1,
|
||||
szPath, MAX_PATH, NULL, NULL );
|
||||
return SHELL32_BindToChild( This->pidlRoot, szPath, pidl, riid, ppvOut );
|
||||
return SHELL32_BindToChild( This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
|
@ -481,11 +481,13 @@ IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl,
|
|||
LPBC pbc, REFIID riid, LPVOID * ppvOut)
|
||||
{
|
||||
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
|
||||
WCHAR szPath[MAX_PATH];
|
||||
|
||||
TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc,
|
||||
shdebugstr_guid (riid), ppvOut);
|
||||
|
||||
return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid,
|
||||
MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath, MAX_PATH);
|
||||
return SHELL32_BindToChild (This->pidlRoot, szPath, pidl, riid,
|
||||
ppvOut);
|
||||
}
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ static BOOL CreateMyCompEnumList(IEnumIDList *list, DWORD dwFlags)
|
|||
{
|
||||
BOOL ret = TRUE;
|
||||
|
||||
TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
|
||||
TRACE("(%p)->(flags=0x%08lx)\n", list, dwFlags);
|
||||
|
||||
/* enumerate the folders */
|
||||
if (dwFlags & SHCONTF_FOLDERS)
|
||||
|
|
|
@ -266,70 +266,6 @@ HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR pszPath, U
|
|||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHELL_ResolveShortCutW [Internal]
|
||||
* read shortcut file at 'wcmd'
|
||||
*/
|
||||
static HRESULT SHELL_ResolveShortCutW(LPWSTR wcmd, LPWSTR wargs, LPWSTR wdir, HWND hwnd, LPCWSTR lpVerb, int* pshowcmd, LPITEMIDLIST* ppidl)
|
||||
{
|
||||
IShellFolder* psf;
|
||||
|
||||
HRESULT hr = SHGetDesktopFolder(&psf);
|
||||
|
||||
*ppidl = NULL;
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
LPITEMIDLIST pidl;
|
||||
ULONG l;
|
||||
|
||||
hr = IShellFolder_ParseDisplayName(psf, 0, 0, wcmd, &l, &pidl, 0);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
IShellLinkW* psl;
|
||||
|
||||
hr = IShellFolder_GetUIObjectOf(psf, NULL, 1, (LPCITEMIDLIST*)&pidl, &IID_IShellLinkW, NULL, (LPVOID*)&psl);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = IShellLinkW_Resolve(psl, hwnd, 0);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = IShellLinkW_GetPath(psl, wcmd, MAX_PATH, NULL, SLGP_UNCPRIORITY);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (!*wcmd) {
|
||||
/* We could not translate the PIDL in the shell link into a valid file system path - so return the PIDL instead. */
|
||||
hr = IShellLinkW_GetIDList(psl, ppidl);
|
||||
|
||||
if (SUCCEEDED(hr) && *ppidl) {
|
||||
/* We got a PIDL instead of a file system path - try to translate it. */
|
||||
if (SHGetPathFromIDListW(*ppidl, wcmd)) {
|
||||
SHFree(*ppidl);
|
||||
*ppidl = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
/* get command line arguments, working directory and display mode if available */
|
||||
IShellLinkW_GetWorkingDirectory(psl, wdir, MAX_PATH);
|
||||
IShellLinkW_GetArguments(psl, wargs, MAX_PATH);
|
||||
IShellLinkW_GetShowCmd(psl, pshowcmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IShellLinkW_Release(psl);
|
||||
}
|
||||
|
||||
SHFree(pidl);
|
||||
}
|
||||
|
||||
IShellFolder_Release(psf);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHELL_ExecuteW [Internal]
|
||||
*
|
||||
|
@ -772,8 +708,7 @@ static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv,
|
|||
static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
|
||||
const WCHAR* lpFile, WCHAR *env,
|
||||
LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc,
|
||||
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out,
|
||||
BOOL unicode)
|
||||
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
|
||||
{
|
||||
static const WCHAR wApplication[] = {'\\','a','p','p','l','i','c','a','t','i','o','n',0};
|
||||
static const WCHAR wTopic[] = {'\\','t','o','p','i','c',0};
|
||||
|
@ -787,6 +722,7 @@ static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
|
|||
HCONV hConv;
|
||||
HDDEDATA hDdeData;
|
||||
unsigned ret = 31;
|
||||
BOOL unicode = !(GetVersion() & 0x80000000);
|
||||
|
||||
strcpyW(endkey, wApplication);
|
||||
applen = sizeof(app);
|
||||
|
@ -883,8 +819,7 @@ static unsigned dde_connect(WCHAR* key, WCHAR* start, WCHAR* ddeexec,
|
|||
*/
|
||||
static UINT_PTR execute_from_key(LPWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR szCommandline,
|
||||
SHELL_ExecuteW32 execfunc,
|
||||
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out,
|
||||
BOOL unicode)
|
||||
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
|
||||
{
|
||||
WCHAR cmd[1024];
|
||||
LONG cmdlen = sizeof(cmd);
|
||||
|
@ -912,7 +847,7 @@ static UINT_PTR execute_from_key(LPWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR
|
|||
if (RegQueryValueW(HKEY_CLASSES_ROOT, key, param, ¶mlen) == ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("Got ddeexec %s => %s\n", debugstr_w(key), debugstr_w(param));
|
||||
retval = dde_connect(key, cmd, param, lpFile, env, szCommandline, psei->lpIDList, execfunc, psei, psei_out, unicode);
|
||||
retval = dde_connect(key, cmd, param, lpFile, env, szCommandline, psei->lpIDList, execfunc, psei, psei_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -983,17 +918,272 @@ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpR
|
|||
return (HINSTANCE)retval;
|
||||
}
|
||||
|
||||
/* FIXME: is this already implemented somewhere else? */
|
||||
static HKEY ShellExecute_GetClassKey( LPSHELLEXECUTEINFOW sei )
|
||||
{
|
||||
LPCWSTR ext = NULL, lpClass = NULL;
|
||||
LPWSTR cls = NULL;
|
||||
DWORD type = 0, sz = 0;
|
||||
HKEY hkey = 0;
|
||||
LONG r;
|
||||
|
||||
if (sei->fMask & SEE_MASK_CLASSALL)
|
||||
return sei->hkeyClass;
|
||||
|
||||
if (sei->fMask & SEE_MASK_CLASSNAME)
|
||||
lpClass = sei->lpClass;
|
||||
else
|
||||
{
|
||||
ext = PathFindExtensionW( sei->lpFile );
|
||||
TRACE("ext = %s\n", debugstr_w( ext ) );
|
||||
if (!ext)
|
||||
return hkey;
|
||||
|
||||
r = RegOpenKeyW( HKEY_CLASSES_ROOT, ext, &hkey );
|
||||
if (r != ERROR_SUCCESS )
|
||||
return hkey;
|
||||
|
||||
r = RegQueryValueExW( hkey, NULL, 0, &type, NULL, &sz );
|
||||
if ( r == ERROR_SUCCESS && type == REG_SZ )
|
||||
{
|
||||
sz += sizeof (WCHAR);
|
||||
cls = HeapAlloc( GetProcessHeap(), 0, sz );
|
||||
cls[0] = 0;
|
||||
RegQueryValueExW( hkey, NULL, 0, &type, (LPBYTE) cls, &sz );
|
||||
}
|
||||
|
||||
RegCloseKey( hkey );
|
||||
lpClass = cls;
|
||||
}
|
||||
|
||||
TRACE("class = %s\n", debugstr_w(lpClass) );
|
||||
|
||||
hkey = 0;
|
||||
if ( lpClass )
|
||||
RegOpenKeyW( HKEY_CLASSES_ROOT, lpClass, &hkey );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, cls );
|
||||
|
||||
return hkey;
|
||||
}
|
||||
|
||||
static IDataObject *shellex_get_dataobj( LPSHELLEXECUTEINFOW sei )
|
||||
{
|
||||
LPCITEMIDLIST pidllast = NULL;
|
||||
IDataObject *dataobj = NULL;
|
||||
IShellFolder *shf = NULL;
|
||||
LPITEMIDLIST pidl = NULL;
|
||||
HRESULT r;
|
||||
|
||||
if (sei->fMask & SEE_MASK_CLASSALL)
|
||||
pidl = sei->lpIDList;
|
||||
else
|
||||
{
|
||||
WCHAR fullpath[MAX_PATH];
|
||||
|
||||
fullpath[0] = 0;
|
||||
r = GetFullPathNameW( sei->lpFile, MAX_PATH, fullpath, NULL );
|
||||
if (!r)
|
||||
goto end;
|
||||
|
||||
pidl = ILCreateFromPathW( fullpath );
|
||||
}
|
||||
|
||||
r = SHBindToParent( pidl, &IID_IShellFolder, (LPVOID*)&shf, &pidllast );
|
||||
if ( FAILED( r ) )
|
||||
goto end;
|
||||
|
||||
IShellFolder_GetUIObjectOf( shf, NULL, 1, &pidllast,
|
||||
&IID_IDataObject, NULL, (LPVOID*) &dataobj );
|
||||
|
||||
end:
|
||||
if ( pidl != sei->lpIDList )
|
||||
ILFree( pidl );
|
||||
if ( shf )
|
||||
IShellFolder_Release( shf );
|
||||
return dataobj;
|
||||
}
|
||||
|
||||
static HRESULT shellex_run_context_menu_default( IShellExtInit *obj,
|
||||
LPSHELLEXECUTEINFOW sei )
|
||||
{
|
||||
IContextMenu *cm = NULL;
|
||||
CMINVOKECOMMANDINFOEX ici;
|
||||
MENUITEMINFOW info;
|
||||
WCHAR string[0x80];
|
||||
INT i, n, def = -1;
|
||||
HMENU hmenu = 0;
|
||||
HRESULT r;
|
||||
|
||||
TRACE("%p %p\n", obj, sei );
|
||||
|
||||
r = IShellExtInit_QueryInterface( obj, &IID_IContextMenu, (LPVOID*) &cm );
|
||||
if ( FAILED( r ) )
|
||||
return r;
|
||||
|
||||
hmenu = CreateMenu();
|
||||
if ( !hmenu )
|
||||
goto end;
|
||||
|
||||
/* the number of the last menu added is returned in r */
|
||||
r = IContextMenu_QueryContextMenu( cm, hmenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY );
|
||||
if ( FAILED( r ) )
|
||||
goto end;
|
||||
|
||||
n = GetMenuItemCount( hmenu );
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
memset( &info, 0, sizeof info );
|
||||
info.cbSize = sizeof info;
|
||||
info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_DATA | MIIM_ID;
|
||||
info.dwTypeData = string;
|
||||
info.cch = sizeof string;
|
||||
string[0] = 0;
|
||||
GetMenuItemInfoW( hmenu, i, TRUE, &info );
|
||||
|
||||
TRACE("menu %d %s %08x %08lx %08x %08x\n", i, debugstr_w(string),
|
||||
info.fState, info.dwItemData, info.fType, info.wID );
|
||||
if ( ( !sei->lpVerb && (info.fState & MFS_DEFAULT) ) ||
|
||||
( sei->lpVerb && !lstrcmpiW( sei->lpVerb, string ) ) )
|
||||
{
|
||||
def = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = E_FAIL;
|
||||
if ( def == -1 )
|
||||
goto end;
|
||||
|
||||
memset( &ici, 0, sizeof ici );
|
||||
ici.cbSize = sizeof ici;
|
||||
ici.fMask = CMIC_MASK_UNICODE;
|
||||
ici.nShow = sei->nShow;
|
||||
ici.lpVerb = MAKEINTRESOURCEA( def );
|
||||
ici.hwnd = sei->hwnd;
|
||||
ici.lpParametersW = sei->lpParameters;
|
||||
|
||||
r = IContextMenu_InvokeCommand( cm, (LPCMINVOKECOMMANDINFO) &ici );
|
||||
|
||||
TRACE("invoke command returned %08lx\n", r );
|
||||
|
||||
end:
|
||||
if ( hmenu )
|
||||
DestroyMenu( hmenu );
|
||||
if ( cm )
|
||||
IContextMenu_Release( cm );
|
||||
return r;
|
||||
}
|
||||
|
||||
static HRESULT shellex_load_object_and_run( HKEY hkey, LPCGUID guid, LPSHELLEXECUTEINFOW sei )
|
||||
{
|
||||
IDataObject *dataobj = NULL;
|
||||
IObjectWithSite *ows = NULL;
|
||||
IShellExtInit *obj = NULL;
|
||||
HRESULT r;
|
||||
|
||||
TRACE("%p %s %p\n", hkey, debugstr_guid( guid ), sei );
|
||||
|
||||
r = CoInitialize( NULL );
|
||||
if ( FAILED( r ) )
|
||||
goto end;
|
||||
|
||||
r = CoCreateInstance( guid, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IShellExtInit, (LPVOID*)&obj );
|
||||
if ( FAILED( r ) )
|
||||
{
|
||||
ERR("failed %08lx\n", r );
|
||||
goto end;
|
||||
}
|
||||
|
||||
dataobj = shellex_get_dataobj( sei );
|
||||
if ( !dataobj )
|
||||
{
|
||||
ERR("failed to get data object\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
r = IShellExtInit_Initialize( obj, NULL, dataobj, hkey );
|
||||
if ( FAILED( r ) )
|
||||
goto end;
|
||||
|
||||
r = IShellExtInit_QueryInterface( obj, &IID_IObjectWithSite, (LPVOID*) &ows );
|
||||
if ( FAILED( r ) )
|
||||
goto end;
|
||||
|
||||
IObjectWithSite_SetSite( ows, NULL );
|
||||
|
||||
r = shellex_run_context_menu_default( obj, sei );
|
||||
|
||||
end:
|
||||
if ( ows )
|
||||
IObjectWithSite_Release( ows );
|
||||
if ( dataobj )
|
||||
IDataObject_Release( dataobj );
|
||||
if ( obj )
|
||||
IShellExtInit_Release( obj );
|
||||
CoUninitialize();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* ShellExecute_FromContextMenu [Internal]
|
||||
*/
|
||||
static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei )
|
||||
{
|
||||
static const WCHAR szcm[] = { 's','h','e','l','l','e','x','\\',
|
||||
'C','o','n','t','e','x','t','M','e','n','u','H','a','n','d','l','e','r','s',0 };
|
||||
HKEY hkey, hkeycm = 0;
|
||||
WCHAR szguid[39];
|
||||
HRESULT hr;
|
||||
GUID guid;
|
||||
DWORD i;
|
||||
LONG r;
|
||||
|
||||
TRACE("%s\n", debugstr_w(sei->lpFile) );
|
||||
|
||||
hkey = ShellExecute_GetClassKey( sei );
|
||||
if ( !hkey )
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
r = RegOpenKeyW( hkey, szcm, &hkeycm );
|
||||
if ( r == ERROR_SUCCESS )
|
||||
{
|
||||
i = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
r = RegEnumKeyW( hkeycm, i++, szguid, 39 );
|
||||
if ( r != ERROR_SUCCESS )
|
||||
break;
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
hr = CLSIDFromString( szguid, &guid );
|
||||
if ( FAILED( hr ) )
|
||||
break;
|
||||
r = ERROR_SUCCESS;
|
||||
/* stop at the first one that succeeds in running */
|
||||
hr = shellex_load_object_and_run( hkey, &guid, sei );
|
||||
if ( SUCCEEDED( hr ) )
|
||||
break;
|
||||
}
|
||||
RegCloseKey( hkeycm );
|
||||
}
|
||||
|
||||
if ( hkey != sei->hkeyClass )
|
||||
RegCloseKey( hkey );
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHELL_execute [Internal]
|
||||
*/
|
||||
BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL unicode )
|
||||
BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
|
||||
{
|
||||
static const WCHAR wQuote[] = {'"',0};
|
||||
static const WCHAR wSpace[] = {' ',0};
|
||||
static const WCHAR wWww[] = {'w','w','w',0};
|
||||
static const WCHAR wFile[] = {'f','i','l','e',0};
|
||||
static const WCHAR wHttp[] = {'h','t','t','p',':','/','/',0};
|
||||
static const WCHAR wExtLnk[] = {'.','l','n','k',0};
|
||||
static const WCHAR wExplorer[] = {'e','x','p','l','o','r','e','r','.','e','x','e',0};
|
||||
static const DWORD unsupportedFlags =
|
||||
SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
|
||||
|
@ -1010,7 +1200,6 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
|
|||
UINT_PTR retval = 31;
|
||||
WCHAR wcmd[1024];
|
||||
WCHAR buffer[MAX_PATH];
|
||||
const WCHAR* ext;
|
||||
BOOL done;
|
||||
|
||||
/* make a local copy of the LPSHELLEXECUTEINFO structure and work with this from now on */
|
||||
|
@ -1077,12 +1266,16 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
wszApplicationName[0] = '"';
|
||||
SHGetPathFromIDListW(sei_tmp.lpIDList, wszApplicationName+1);
|
||||
strcatW(wszApplicationName, wQuote);
|
||||
SHGetPathFromIDListW(sei_tmp.lpIDList, wszApplicationName);
|
||||
TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName));
|
||||
}
|
||||
|
||||
if ( ERROR_SUCCESS == ShellExecute_FromContextMenu( &sei_tmp ) )
|
||||
{
|
||||
sei->hInstApp = (HINSTANCE) 33;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (sei_tmp.fMask & SEE_MASK_CLASSALL)
|
||||
{
|
||||
/* launch a document by fileclass like 'WordPad.Document.1' */
|
||||
|
@ -1111,78 +1304,6 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* resolve shell shortcuts */
|
||||
ext = PathFindExtensionW(sei_tmp.lpFile);
|
||||
|
||||
if (ext && !strncmpiW(ext, wExtLnk, sizeof(wExtLnk) / sizeof(WCHAR) - 1) &&
|
||||
(ext[sizeof(wExtLnk) / sizeof(WCHAR) - 1] == '\0' ||
|
||||
(sei_tmp.lpFile[0] == '"' && ext[sizeof(wExtLnk) / sizeof(WCHAR) - 1] == '"'))) /* or check for: shell_attribs & SFGAO_LINK */
|
||||
{
|
||||
HRESULT hr;
|
||||
BOOL Quoted;
|
||||
|
||||
if (wszApplicationName[0] == '"')
|
||||
{
|
||||
if (wszApplicationName[strlenW(wszApplicationName) - 1] == '"')
|
||||
{
|
||||
wszApplicationName[strlenW(wszApplicationName) - 1] = '\0';
|
||||
Quoted = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Quoted = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Quoted = FALSE;
|
||||
}
|
||||
/* expand paths before reading shell link */
|
||||
if (ExpandEnvironmentStringsW(Quoted ? sei_tmp.lpFile + 1 : sei_tmp.lpFile, buffer, MAX_PATH))
|
||||
lstrcpyW(Quoted ? wszApplicationName + 1 : wszApplicationName/*sei_tmp.lpFile*/, buffer);
|
||||
|
||||
if (*sei_tmp.lpParameters)
|
||||
if (ExpandEnvironmentStringsW(sei_tmp.lpParameters, buffer, MAX_PATH))
|
||||
lstrcpyW(wszParameters/*sei_tmp.lpParameters*/, buffer);
|
||||
|
||||
hr = SHELL_ResolveShortCutW((LPWSTR)(Quoted ? sei_tmp.lpFile + 1 : sei_tmp.lpFile),
|
||||
(LPWSTR)sei_tmp.lpParameters, (LPWSTR)sei_tmp.lpDirectory,
|
||||
sei_tmp.hwnd, sei_tmp.lpVerb?sei_tmp.lpVerb:wszEmpty, &sei_tmp.nShow, (LPITEMIDLIST*)&sei_tmp.lpIDList);
|
||||
if (Quoted)
|
||||
{
|
||||
wszApplicationName[strlenW(wszApplicationName) + 1] = '\0';
|
||||
wszApplicationName[strlenW(wszApplicationName)] = '"';
|
||||
}
|
||||
|
||||
if (sei->lpIDList)
|
||||
sei->fMask |= SEE_MASK_IDLIST;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
/* repeat IDList processing if needed */
|
||||
if (sei_tmp.fMask & SEE_MASK_IDLIST)
|
||||
{
|
||||
IShellExecuteHookW* pSEH;
|
||||
|
||||
HRESULT hr = SHBindToParent(sei_tmp.lpIDList, &IID_IShellExecuteHookW, (LPVOID*)&pSEH, NULL);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = IShellExecuteHookW_Execute(pSEH, &sei_tmp);
|
||||
|
||||
IShellExecuteHookW_Release(pSEH);
|
||||
|
||||
if (hr == S_OK)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TRACE("-- idlist=%p (%s)\n", debugstr_w(sei_tmp.lpIDList), debugstr_w(sei_tmp.lpFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Has the IDList not yet been translated? */
|
||||
if (sei_tmp.fMask & SEE_MASK_IDLIST)
|
||||
{
|
||||
|
@ -1314,7 +1435,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
|
|||
}
|
||||
TRACE("%s/%s => %s/%s\n", debugstr_w(wszApplicationName), debugstr_w(sei_tmp.lpVerb), debugstr_w(wszQuotedCmd), debugstr_w(lpstrProtocol));
|
||||
if (*lpstrProtocol)
|
||||
retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei_tmp.lpParameters, execfunc, &sei_tmp, sei, unicode);
|
||||
retval = execute_from_key(lpstrProtocol, wszApplicationName, env, sei_tmp.lpParameters, execfunc, &sei_tmp, sei);
|
||||
else
|
||||
retval = execfunc(wszQuotedCmd, env, FALSE, &sei_tmp, sei);
|
||||
HeapFree( GetProcessHeap(), 0, env );
|
||||
|
@ -1347,7 +1468,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc, BOOL uni
|
|||
lpFile += iSize;
|
||||
while (*lpFile == ':') lpFile++;
|
||||
}
|
||||
retval = execute_from_key(lpstrProtocol, lpFile, NULL, sei_tmp.lpParameters, execfunc, &sei_tmp, sei, unicode);
|
||||
retval = execute_from_key(lpstrProtocol, lpFile, NULL, sei_tmp.lpParameters, execfunc, &sei_tmp, sei);
|
||||
}
|
||||
/* Check if file specified is in the form www.??????.*** */
|
||||
else if (!strncmpiW(lpFile, wWww, 3))
|
||||
|
@ -1432,7 +1553,7 @@ BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
|
|||
else
|
||||
seiW.lpClass = NULL;
|
||||
|
||||
ret = SHELL_execute( &seiW, SHELL_ExecuteW, FALSE );
|
||||
ret = SHELL_execute( &seiW, SHELL_ExecuteW );
|
||||
|
||||
sei->hInstApp = seiW.hInstApp;
|
||||
|
||||
|
@ -1454,7 +1575,7 @@ BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
|
|||
*/
|
||||
BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
|
||||
{
|
||||
return SHELL_execute( sei, SHELL_ExecuteW, TRUE );
|
||||
return SHELL_execute( sei, SHELL_ExecuteW );
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1483,6 +1604,6 @@ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile,
|
|||
sei.dwHotKey = 0;
|
||||
sei.hProcess = 0;
|
||||
|
||||
SHELL_execute( &sei, SHELL_ExecuteW, TRUE );
|
||||
SHELL_execute( &sei, SHELL_ExecuteW );
|
||||
return sei.hInstApp;
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ BOOL SHELL_DeleteFileW(LPCWSTR pszFile, BOOL bShowUI)
|
|||
* RETURNS
|
||||
* TRUE if successful, FALSE otherwise
|
||||
*
|
||||
* NOTES:
|
||||
* NOTES
|
||||
* Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
|
||||
* This is Unicode on NT/2000
|
||||
*/
|
||||
|
@ -290,7 +290,7 @@ BOOL WINAPI Win32CreateDirectoryAW(LPCVOID path, LPSECURITY_ATTRIBUTES sec)
|
|||
* RETURNS
|
||||
* TRUE if successful, FALSE otherwise
|
||||
*
|
||||
* NOTES:
|
||||
* NOTES
|
||||
* Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
|
||||
* This is Unicode on NT/2000
|
||||
*/
|
||||
|
@ -354,7 +354,7 @@ BOOL WINAPI Win32RemoveDirectoryAW(LPCVOID path)
|
|||
* RETURNS
|
||||
* TRUE if successful, FALSE otherwise
|
||||
*
|
||||
* NOTES:
|
||||
* NOTES
|
||||
* Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
|
||||
* This is Unicode on NT/2000
|
||||
*/
|
||||
|
@ -560,6 +560,8 @@ int WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES se
|
|||
|
||||
/*************************************************************************
|
||||
* SHCreateDirectoryExW [SHELL32.@]
|
||||
*
|
||||
* See SHCreateDirectoryExA.
|
||||
*/
|
||||
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
|
||||
{
|
||||
|
@ -792,6 +794,10 @@ DWORD SHNameTranslate(LPWSTR* wString, LPCWSTR* pWToFrom, BOOL more)
|
|||
* PARAMS
|
||||
* lpFileOp [I/O] pointer to a structure containing all the necessary information
|
||||
*
|
||||
* RETURNS
|
||||
* Success: zero
|
||||
* Failure: nonzero
|
||||
*
|
||||
* NOTES
|
||||
* exported by name
|
||||
*/
|
||||
|
@ -998,7 +1004,7 @@ static DWORD shfileops_get_parent_attr(LPWSTR pFile,LPWSTR pTemp)
|
|||
/*************************************************************************
|
||||
* SHFileOperationW [SHELL32.@]
|
||||
*
|
||||
* See SHFileOperationA
|
||||
* See SHFileOperationA.
|
||||
*/
|
||||
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
|
||||
{
|
||||
|
@ -1394,6 +1400,8 @@ shfileop_end:
|
|||
* PARAMS
|
||||
* hNameMapping [I] handle to the name mappings used during renaming of files
|
||||
*
|
||||
* RETURNS
|
||||
* Nothing
|
||||
*/
|
||||
void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
|
||||
{
|
||||
|
|
|
@ -192,12 +192,12 @@ HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
|
|||
* pathRoot can be NULL for Folders beeing a drive.
|
||||
* In this case the absolute path is build from pidlChild (eg. C:)
|
||||
*/
|
||||
HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot,
|
||||
static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
|
||||
LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID riid, LPVOID * ppvOut)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
TRACE ("%p %s %p\n", pidlRoot, pathRoot, pidlChild);
|
||||
TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild);
|
||||
|
||||
if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, clsid, NULL, riid, ppvOut)))) {
|
||||
LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
|
||||
|
@ -208,31 +208,28 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot,
|
|||
SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf)))
|
||||
{
|
||||
PERSIST_FOLDER_TARGET_INFO ppfti;
|
||||
char szDestPath[MAX_PATH];
|
||||
|
||||
ZeroMemory (&ppfti, sizeof (ppfti));
|
||||
|
||||
/* build path */
|
||||
if (pathRoot) {
|
||||
lstrcpyA (szDestPath, pathRoot);
|
||||
PathAddBackslashA(szDestPath); /* FIXME: why have drives a backslash here ? */
|
||||
} else {
|
||||
szDestPath[0] = '\0';
|
||||
}
|
||||
|
||||
if (pidlChild) {
|
||||
LPSTR pszChild = _ILGetTextPointer(pidlChild);
|
||||
|
||||
if (pszChild)
|
||||
lstrcatA (szDestPath, pszChild);
|
||||
else
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
/* fill the PERSIST_FOLDER_TARGET_INFO */
|
||||
ppfti.dwAttributes = -1;
|
||||
ppfti.csidl = -1;
|
||||
MultiByteToWideChar (CP_ACP, 0, szDestPath, -1, ppfti.szTargetParsingName, MAX_PATH);
|
||||
|
||||
/* build path */
|
||||
if (pathRoot) {
|
||||
lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
|
||||
PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */
|
||||
}
|
||||
|
||||
if (pidlChild) {
|
||||
LPCSTR pszChild = _ILGetTextPointer(pidlChild);
|
||||
int len = lstrlenW(ppfti.szTargetParsingName);
|
||||
|
||||
if (pszChild)
|
||||
MultiByteToWideChar (CP_ACP, 0, pszChild, -1, ppfti.szTargetParsingName + len, MAX_PATH - len);
|
||||
else
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti);
|
||||
IPersistFolder3_Release (ppf);
|
||||
|
@ -265,7 +262,7 @@ HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCSTR pathRoot,
|
|||
* means you probably can't use it for your IShellFolder implementation.
|
||||
*/
|
||||
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
|
||||
LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
|
||||
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
|
||||
{
|
||||
GUID const *clsid;
|
||||
IShellFolder *pSF;
|
||||
|
@ -290,10 +287,10 @@ HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
|
|||
|
||||
/* see if folder CLSID should be overridden by desktop.ini file */
|
||||
if (pathRoot) {
|
||||
MultiByteToWideChar(CP_ACP, 0, pathRoot, -1, wszFolderPath, MAX_PATH);
|
||||
lstrcpynW(wszFolderPath, pathRoot, MAX_PATH);
|
||||
pwszPathTail = PathAddBackslashW(wszFolderPath);
|
||||
}
|
||||
MultiByteToWideChar(CP_ACP, 0, _ILGetTextPointer(pidlChild), -1, pwszPathTail, MAX_PATH);
|
||||
MultiByteToWideChar(CP_ACP, 0, _ILGetTextPointer(pidlChild), -1, pwszPathTail, MAX_PATH - (int)(pwszPathTail - wszFolderPath));
|
||||
if (SHELL32_GetCustomFolderAttributeFromPath (wszFolderPath,
|
||||
wszDotShellClassInfo, wszCLSID, wszCLSIDValue, CHARS_IN_GUID))
|
||||
CLSIDFromString (wszCLSIDValue, &clsidFolder);
|
||||
|
@ -421,16 +418,23 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO
|
|||
} else if (_ILGetDataPointer (pidl)) {
|
||||
dwAttributes = _ILGetFileAttributes (pidl, NULL, 0);
|
||||
|
||||
if ((SFGAO_FILESYSANCESTOR & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
*pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
|
||||
/* Set common attributes */
|
||||
*pdwAttributes |= SFGAO_FILESYSTEM | SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANDELETE |
|
||||
SFGAO_CANRENAME | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANCOPY;
|
||||
|
||||
if ((SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
*pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
|
||||
if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
*pdwAttributes |= (SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
|
||||
else
|
||||
*pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR);
|
||||
|
||||
if ((SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
|
||||
if (dwAttributes & FILE_ATTRIBUTE_HIDDEN)
|
||||
*pdwAttributes |= SFGAO_HIDDEN;
|
||||
else
|
||||
*pdwAttributes &= ~SFGAO_HIDDEN;
|
||||
|
||||
if ((SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
if (dwAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
*pdwAttributes |= SFGAO_READONLY;
|
||||
else
|
||||
*pdwAttributes &= ~SFGAO_READONLY;
|
||||
|
||||
if (SFGAO_LINK & *pdwAttributes) {
|
||||
|
|
|
@ -818,6 +818,8 @@ void WINAPI FileMenu_AbortInitMenu (void)
|
|||
/*************************************************************************
|
||||
* SHFind_InitMenuPopup [SHELL32.149]
|
||||
*
|
||||
* Get the IContextMenu instance for the submenu of options displayed
|
||||
* for the Search entry in the Classic style Start menu.
|
||||
*
|
||||
* PARAMETERS
|
||||
* hMenu [in] handle of menu previously created
|
||||
|
|
|
@ -46,15 +46,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
|||
typedef struct SystrayItem {
|
||||
HWND hWnd;
|
||||
HWND hWndToolTip;
|
||||
NOTIFYICONDATAA notifyIcon;
|
||||
NOTIFYICONDATAW notifyIcon;
|
||||
struct SystrayItem *nextTrayItem;
|
||||
} SystrayItem;
|
||||
|
||||
static SystrayItem *systray=NULL;
|
||||
static int firstSystray=TRUE; /* defer creation of window class until first systray item is created */
|
||||
|
||||
static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid);
|
||||
|
||||
|
||||
#define ICON_SIZE GetSystemMetrics(SM_CXSMICON)
|
||||
/* space around icon (forces icon to center of KDE systray area) */
|
||||
|
@ -62,13 +60,47 @@ static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid);
|
|||
|
||||
|
||||
|
||||
static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAA pnid1, PNOTIFYICONDATAA pnid2)
|
||||
static BOOL SYSTRAY_ItemIsEqual(PNOTIFYICONDATAW pnid1, PNOTIFYICONDATAW pnid2)
|
||||
{
|
||||
if (pnid1->hWnd != pnid2->hWnd) return FALSE;
|
||||
if (pnid1->uID != pnid2->uID) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void SYSTRAY_ItemTerm(SystrayItem *ptrayItem)
|
||||
{
|
||||
if(ptrayItem->notifyIcon.hIcon)
|
||||
DestroyIcon(ptrayItem->notifyIcon.hIcon);
|
||||
if(ptrayItem->hWndToolTip)
|
||||
DestroyWindow(ptrayItem->hWndToolTip);
|
||||
if(ptrayItem->hWnd)
|
||||
DestroyWindow(ptrayItem->hWnd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static BOOL SYSTRAY_Delete(PNOTIFYICONDATAW pnid)
|
||||
{
|
||||
SystrayItem **ptrayItem = &systray;
|
||||
|
||||
while (*ptrayItem) {
|
||||
if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon)) {
|
||||
SystrayItem *next = (*ptrayItem)->nextTrayItem;
|
||||
TRACE("%p: %p %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd, debugstr_w((*ptrayItem)->notifyIcon.szTip));
|
||||
SYSTRAY_ItemTerm(*ptrayItem);
|
||||
|
||||
HeapFree(GetProcessHeap(),0,*ptrayItem);
|
||||
*ptrayItem = next;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
ptrayItem = &((*ptrayItem)->nextTrayItem);
|
||||
}
|
||||
|
||||
return FALSE; /* not found */
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
|
@ -120,7 +152,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
msg.pt.x = LOWORD(GetMessagePos ());
|
||||
msg.pt.y = HIWORD(GetMessagePos ());
|
||||
|
||||
SendMessageA(ptrayItem->hWndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
|
||||
SendMessageW(ptrayItem->hWndToolTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
|
||||
}
|
||||
ptrayItem = ptrayItem->nextTrayItem;
|
||||
}
|
||||
|
@ -136,7 +168,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
while (ptrayItem) {
|
||||
if (ptrayItem->hWnd == hWnd) {
|
||||
if (ptrayItem->notifyIcon.hWnd && ptrayItem->notifyIcon.uCallbackMessage) {
|
||||
if (!PostMessageA(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
|
||||
if (!PostMessageW(ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.uCallbackMessage,
|
||||
(WPARAM)ptrayItem->notifyIcon.uID, (LPARAM)message)) {
|
||||
ERR("PostMessage(SystrayWindow %p) failed -> removing SystrayItem %p\n", hWnd, ptrayItem);
|
||||
SYSTRAY_Delete(&ptrayItem->notifyIcon);
|
||||
|
@ -150,7 +182,7 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
break;
|
||||
|
||||
default:
|
||||
return (DefWindowProcA(hWnd, message, wParam, lParam));
|
||||
return (DefWindowProcW(hWnd, message, wParam, lParam));
|
||||
}
|
||||
return (0);
|
||||
|
||||
|
@ -159,7 +191,8 @@ static LRESULT CALLBACK SYSTRAY_WndProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||
|
||||
static BOOL SYSTRAY_RegisterClass(void)
|
||||
{
|
||||
WNDCLASSA wc;
|
||||
WNDCLASSW wc;
|
||||
static const WCHAR WineSystrayW[] = { 'W','i','n','e','S','y','s','t','r','a','y',0 };
|
||||
|
||||
wc.style = CS_SAVEBITS|CS_DBLCLKS;
|
||||
wc.lpfnWndProc = SYSTRAY_WndProc;
|
||||
|
@ -167,12 +200,12 @@ static BOOL SYSTRAY_RegisterClass(void)
|
|||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = 0;
|
||||
wc.hIcon = 0;
|
||||
wc.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
|
||||
wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "WineSystray";
|
||||
wc.lpszClassName = WineSystrayW;
|
||||
|
||||
if (!RegisterClassA(&wc)) {
|
||||
if (!RegisterClassW(&wc)) {
|
||||
ERR("RegisterClass(WineSystray) failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -183,6 +216,8 @@ static BOOL SYSTRAY_RegisterClass(void)
|
|||
static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
|
||||
{
|
||||
RECT rect;
|
||||
static const WCHAR WineSystrayW[] = { 'W','i','n','e','S','y','s','t','r','a','y',0 };
|
||||
static const WCHAR Wine_SystrayW[] = { 'W','i','n','e','-','S','y','s','t','r','a','y',0 };
|
||||
|
||||
/* Register the class if this is our first tray item. */
|
||||
if ( firstSystray ) {
|
||||
|
@ -201,8 +236,8 @@ static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
|
|||
|
||||
ZeroMemory( ptrayItem, sizeof(SystrayItem) );
|
||||
/* Create tray window for icon. */
|
||||
ptrayItem->hWnd = CreateWindowExA( WS_EX_TRAYWINDOW,
|
||||
"WineSystray", "Wine-Systray",
|
||||
ptrayItem->hWnd = CreateWindowExW( WS_EX_TRAYWINDOW,
|
||||
WineSystrayW, Wine_SystrayW,
|
||||
WS_VISIBLE,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
rect.right-rect.left, rect.bottom-rect.top,
|
||||
|
@ -213,7 +248,7 @@ static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
|
|||
}
|
||||
|
||||
/* Create tooltip for icon. */
|
||||
ptrayItem->hWndToolTip = CreateWindowA( TOOLTIPS_CLASSA,NULL,TTS_ALWAYSTIP,
|
||||
ptrayItem->hWndToolTip = CreateWindowW( TOOLTIPS_CLASSW,NULL,TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
ptrayItem->hWnd, 0, 0, 0 );
|
||||
|
@ -225,18 +260,6 @@ static BOOL SYSTRAY_ItemInit(SystrayItem *ptrayItem)
|
|||
}
|
||||
|
||||
|
||||
static void SYSTRAY_ItemTerm(SystrayItem *ptrayItem)
|
||||
{
|
||||
if(ptrayItem->notifyIcon.hIcon)
|
||||
DestroyIcon(ptrayItem->notifyIcon.hIcon);
|
||||
if(ptrayItem->hWndToolTip)
|
||||
DestroyWindow(ptrayItem->hWndToolTip);
|
||||
if(ptrayItem->hWnd)
|
||||
DestroyWindow(ptrayItem->hWnd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void SYSTRAY_ItemSetMessage(SystrayItem *ptrayItem, UINT uCallbackMessage)
|
||||
{
|
||||
ptrayItem->notifyIcon.uCallbackMessage = uCallbackMessage;
|
||||
|
@ -252,13 +275,13 @@ static void SYSTRAY_ItemSetIcon(SystrayItem *ptrayItem, HICON hIcon)
|
|||
}
|
||||
|
||||
|
||||
static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
|
||||
static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, const WCHAR* szTip, int modify)
|
||||
{
|
||||
TTTOOLINFOA ti;
|
||||
TTTOOLINFOW ti;
|
||||
|
||||
lstrcpynA(ptrayItem->notifyIcon.szTip, szTip, sizeof(ptrayItem->notifyIcon.szTip));
|
||||
lstrcpynW(ptrayItem->notifyIcon.szTip, szTip, sizeof(ptrayItem->notifyIcon.szTip)/sizeof(WCHAR));
|
||||
|
||||
ti.cbSize = sizeof(TTTOOLINFOA);
|
||||
ti.cbSize = sizeof(TTTOOLINFOW);
|
||||
ti.uFlags = 0;
|
||||
ti.hwnd = ptrayItem->hWnd;
|
||||
ti.hinst = 0;
|
||||
|
@ -270,15 +293,16 @@ static void SYSTRAY_ItemSetTip(SystrayItem *ptrayItem, CHAR* szTip, int modify)
|
|||
ti.rect.bottom = ICON_SIZE+2*ICON_BORDER;
|
||||
|
||||
if(modify)
|
||||
SendMessageA(ptrayItem->hWndToolTip, TTM_UPDATETIPTEXTA, 0, (LPARAM)&ti);
|
||||
SendMessageW(ptrayItem->hWndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti);
|
||||
else
|
||||
SendMessageA(ptrayItem->hWndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
|
||||
SendMessageW(ptrayItem->hWndToolTip, TTM_ADDTOOLW, 0, (LPARAM)&ti);
|
||||
}
|
||||
|
||||
|
||||
static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
|
||||
static BOOL SYSTRAY_Add(PNOTIFYICONDATAW pnid)
|
||||
{
|
||||
SystrayItem **ptrayItem = &systray;
|
||||
static const WCHAR emptyW[] = { 0 };
|
||||
|
||||
/* Find last element. */
|
||||
while( *ptrayItem ) {
|
||||
|
@ -295,15 +319,15 @@ static BOOL SYSTRAY_Add(PNOTIFYICONDATAA pnid)
|
|||
(*ptrayItem)->notifyIcon.hWnd = pnid->hWnd; /* only needed for callback message */
|
||||
SYSTRAY_ItemSetIcon (*ptrayItem, (pnid->uFlags&NIF_ICON) ?pnid->hIcon :0);
|
||||
SYSTRAY_ItemSetMessage(*ptrayItem, (pnid->uFlags&NIF_MESSAGE)?pnid->uCallbackMessage:0);
|
||||
SYSTRAY_ItemSetTip (*ptrayItem, (pnid->uFlags&NIF_TIP) ?pnid->szTip :"", FALSE);
|
||||
SYSTRAY_ItemSetTip (*ptrayItem, (pnid->uFlags&NIF_TIP) ?pnid->szTip :emptyW, FALSE);
|
||||
|
||||
TRACE("%p: %p %s\n", (*ptrayItem), (*ptrayItem)->notifyIcon.hWnd,
|
||||
(*ptrayItem)->notifyIcon.szTip);
|
||||
debugstr_w((*ptrayItem)->notifyIcon.szTip));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
|
||||
static BOOL SYSTRAY_Modify(PNOTIFYICONDATAW pnid)
|
||||
{
|
||||
SystrayItem *ptrayItem = systray;
|
||||
|
||||
|
@ -316,7 +340,7 @@ static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
|
|||
if (pnid->uFlags & NIF_TIP)
|
||||
SYSTRAY_ItemSetTip(ptrayItem, pnid->szTip, TRUE);
|
||||
|
||||
TRACE("%p: %p %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd, ptrayItem->notifyIcon.szTip);
|
||||
TRACE("%p: %p %s\n", ptrayItem, ptrayItem->notifyIcon.hWnd, debugstr_w(ptrayItem->notifyIcon.szTip));
|
||||
return TRUE;
|
||||
}
|
||||
ptrayItem = ptrayItem->nextTrayItem;
|
||||
|
@ -325,27 +349,6 @@ static BOOL SYSTRAY_Modify(PNOTIFYICONDATAA pnid)
|
|||
}
|
||||
|
||||
|
||||
static BOOL SYSTRAY_Delete(PNOTIFYICONDATAA pnid)
|
||||
{
|
||||
SystrayItem **ptrayItem = &systray;
|
||||
|
||||
while (*ptrayItem) {
|
||||
if (SYSTRAY_ItemIsEqual(pnid, &(*ptrayItem)->notifyIcon)) {
|
||||
SystrayItem *next = (*ptrayItem)->nextTrayItem;
|
||||
TRACE("%p: %p %s\n", *ptrayItem, (*ptrayItem)->notifyIcon.hWnd, (*ptrayItem)->notifyIcon.szTip);
|
||||
SYSTRAY_ItemTerm(*ptrayItem);
|
||||
|
||||
HeapFree(GetProcessHeap(),0,*ptrayItem);
|
||||
*ptrayItem = next;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
ptrayItem = &((*ptrayItem)->nextTrayItem);
|
||||
}
|
||||
|
||||
return FALSE; /* not found */
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
*/
|
||||
|
@ -355,10 +358,9 @@ BOOL SYSTRAY_Init(void)
|
|||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Shell_NotifyIcon [SHELL32.296]
|
||||
* Shell_NotifyIconA [SHELL32.297]
|
||||
* Shell_NotifyIconW [SHELL32.298]
|
||||
*/
|
||||
BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
|
||||
BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW pnid )
|
||||
{
|
||||
BOOL flag=FALSE;
|
||||
TRACE("enter %p %d %ld\n", pnid->hWnd, pnid->uID, dwMessage);
|
||||
|
@ -378,18 +380,19 @@ BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid )
|
|||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Shell_NotifyIconW [SHELL32.298]
|
||||
* Shell_NotifyIconA [SHELL32.297]
|
||||
* Shell_NotifyIcon [SHELL32.296]
|
||||
*/
|
||||
BOOL WINAPI Shell_NotifyIconW (DWORD dwMessage, PNOTIFYICONDATAW pnid )
|
||||
BOOL WINAPI Shell_NotifyIconA (DWORD dwMessage, PNOTIFYICONDATAA pnid )
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
PNOTIFYICONDATAA p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAA));
|
||||
memcpy(p, pnid, sizeof(NOTIFYICONDATAA));
|
||||
WideCharToMultiByte( CP_ACP, 0, pnid->szTip, -1, p->szTip, sizeof(p->szTip), NULL, NULL );
|
||||
p->szTip[sizeof(p->szTip)-1] = 0;
|
||||
PNOTIFYICONDATAW p = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFYICONDATAW));
|
||||
memcpy(p, pnid, sizeof(NOTIFYICONDATAW));
|
||||
MultiByteToWideChar( CP_ACP, 0, pnid->szTip, -1, p->szTip, sizeof(p->szTip)/sizeof(WCHAR) );
|
||||
p->szTip[sizeof(p->szTip)/sizeof(WCHAR)-1] = 0;
|
||||
|
||||
ret = Shell_NotifyIconA(dwMessage, p );
|
||||
ret = Shell_NotifyIconW(dwMessage, p );
|
||||
|
||||
HeapFree(GetProcessHeap(),0,p);
|
||||
return ret;
|
||||
|
|
45
reactos/w32api/include/appmgmt.h
Normal file
45
reactos/w32api/include/appmgmt.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2005 Mike McCormack
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _APPMGMT_H
|
||||
#define _APPMGMT_H
|
||||
|
||||
typedef struct _MANAGEDAPPLICATION
|
||||
{
|
||||
LPWSTR pszPackageName;
|
||||
LPWSTR pszPublisher;
|
||||
DWORD dwVersionHi;
|
||||
DWORD dwVersionLo;
|
||||
DWORD dwRevision;
|
||||
GUID GpoId;
|
||||
LPWSTR pszPolicyName;
|
||||
GUID ProductId;
|
||||
LANGID Language;
|
||||
LPWSTR pszOwner;
|
||||
LPWSTR pszCompany;
|
||||
LPWSTR pszComments;
|
||||
LPWSTR pszContact;
|
||||
LPWSTR pszSupportUrl;
|
||||
DWORD dwPathType;
|
||||
BOOL bInstalled;
|
||||
} MANAGEDAPPLICATION, *PMANAGEDAPPLICATION;
|
||||
|
||||
DWORD WINAPI CommandLineFromMsiDescriptor(WCHAR*,WCHAR*,DWORD*);
|
||||
DWORD WINAPI GetManagedApplications(GUID*,DWORD,DWORD,LPDWORD,PMANAGEDAPPLICATION*);
|
||||
|
||||
#endif /* _APPMGMT_H */
|
|
@ -51,7 +51,13 @@ extern "C" {
|
|||
#endif
|
||||
#define DVASPECT_SHORTNAME 2
|
||||
#define SHARD_PIDL 1
|
||||
#define SHARD_PATH 2
|
||||
#define SHARD_PATHA 2
|
||||
#define SHARD_PATHW 3
|
||||
#ifdef UNICODE
|
||||
#define SHARD_PATH SHARD_PATHW
|
||||
#else
|
||||
#define SHARD_PATH SHARD_PATHA
|
||||
#endif
|
||||
#define SHCNE_RENAMEITEM 1
|
||||
#define SHCNE_CREATE 2
|
||||
#define SHCNE_DELETE 4
|
||||
|
@ -282,6 +288,7 @@ extern "C" {
|
|||
#define CMIC_MASK_HOTKEY SEE_MASK_HOTKEY
|
||||
#define CMIC_MASK_ICON SEE_MASK_ICON
|
||||
#define CMIC_MASK_FLAG_NO_UI SEE_MASK_FLAG_NO_UI
|
||||
#define CMIC_MASK_UNICODE SEE_MASK_UNICODE
|
||||
#define CMIC_MASK_MODAL 0x80000000
|
||||
#define CMIC_VALID_SEE_FLAGS SEE_VALID_CMIC_FLAGS
|
||||
#define GIL_OPENICON 1
|
||||
|
@ -458,6 +465,23 @@ typedef struct _CMInvokeCommandInfo {
|
|||
DWORD dwHotKey;
|
||||
HANDLE hIcon;
|
||||
} CMINVOKECOMMANDINFO,*LPCMINVOKECOMMANDINFO;
|
||||
typedef struct _CMInvokeCommandInfoEx {
|
||||
DWORD cbSize;
|
||||
DWORD fMask;
|
||||
HWND hwnd;
|
||||
LPCSTR lpVerb;
|
||||
LPCSTR lpParameters;
|
||||
LPCSTR lpDirectory;
|
||||
INT nShow;
|
||||
DWORD dwHotKey;
|
||||
HANDLE hIcon;
|
||||
LPCSTR lpTitle;
|
||||
LPCWSTR lpVerbW;
|
||||
LPCWSTR lpParametersW;
|
||||
LPCWSTR lpDirectoryW;
|
||||
LPCWSTR lpTitleW;
|
||||
POINT ptInvoke;
|
||||
} CMINVOKECOMMANDINFOEX, *LPCMINVOKECOMMANDINFOEX;
|
||||
typedef struct _DROPFILES {
|
||||
DWORD pFiles;
|
||||
POINT pt;
|
||||
|
@ -1788,6 +1812,13 @@ LPITEMIDLIST WINAPI ILAppendID(LPITEMIDLIST, LPCSHITEMID, BOOL);
|
|||
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST);
|
||||
LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST);
|
||||
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST, LPCITEMIDLIST);
|
||||
LPITEMIDLIST WINAPI ILCreateFromPathA(LPCSTR);
|
||||
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR);
|
||||
#ifdef UNICODE
|
||||
#define ILCreateFromPath ILCreateFromPathW
|
||||
#else
|
||||
#define ILCreateFromPath ILCreateFromPathA
|
||||
#endif
|
||||
LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST, LPCITEMIDLIST);
|
||||
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST);
|
||||
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST);
|
||||
|
|
Loading…
Reference in a new issue