📄 filedlgbrowser.c
字号:
/*
* Implementation of IShellBrowser for the File Open common dialog
*
* Copyright 1999 Francois Boisvert
* Copyright 1999, 2000 Juergen Schmied
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
#include "filedlgbrowser.h"
#include "cdlg.h"
#include "shlguid.h"
#include "servprov.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
typedef struct
{
const IShellBrowserVtbl *lpVtbl;
const ICommDlgBrowserVtbl *lpVtblCommDlgBrowser;
const IServiceProviderVtbl *lpVtblServiceProvider;
LONG ref; /* Reference counter */
HWND hwndOwner; /* Owner dialog of the interface */
} IShellBrowserImpl;
static inline IShellBrowserImpl *impl_from_ICommDlgBrowser( ICommDlgBrowser *iface )
{
return (IShellBrowserImpl *)((char*)iface - FIELD_OFFSET(IShellBrowserImpl, lpVtblCommDlgBrowser));
}
static inline IShellBrowserImpl *impl_from_IServiceProvider( IServiceProvider *iface )
{
return (IShellBrowserImpl *)((char*)iface - FIELD_OFFSET(IShellBrowserImpl, lpVtblServiceProvider));
}
/**************************************************************************
* vtable
*/
static const IShellBrowserVtbl IShellBrowserImpl_Vtbl;
static const ICommDlgBrowserVtbl IShellBrowserImpl_ICommDlgBrowser_Vtbl;
static const IServiceProviderVtbl IShellBrowserImpl_IServiceProvider_Vtbl;
/**************************************************************************
* Local Prototypes
*/
static HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, const IShellView *ppshv);
/*
* Helper functions
*/
#define add_flag(a) if (flags & a) {strcat(str, #a );strcat(str," ");}
static void COMDLG32_DumpSBSPFlags(UINT uflags)
{
if (TRACE_ON(commdlg))
{
unsigned int i;
static const struct {
DWORD mask;
const char *name;
} flags[] = {
#define FE(x) { x, #x}
/* SBSP_DEFBROWSER == 0 */
FE(SBSP_SAMEBROWSER),
FE(SBSP_NEWBROWSER),
/* SBSP_DEFMODE == 0 */
FE(SBSP_OPENMODE),
FE(SBSP_EXPLOREMODE),
FE(SBSP_HELPMODE),
FE(SBSP_NOTRANSFERHIST),
/* SBSP_ABSOLUTE == 0 */
FE(SBSP_RELATIVE),
FE(SBSP_PARENT),
FE(SBSP_NAVIGATEBACK),
FE(SBSP_NAVIGATEFORWARD),
FE(SBSP_ALLOW_AUTONAVIGATE),
FE(SBSP_NOAUTOSELECT),
FE(SBSP_WRITENOHISTORY),
FE(SBSP_REDIRECT),
FE(SBSP_INITIATEDBYHLINKFRAME),
};
#undef FE
DPRINTF("SBSP Flags: %08x =", uflags);
for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)
if (flags[i].mask & uflags)
DPRINTF("%s ", flags[i].name);
DPRINTF("\n");
}
}
static void COMDLG32_UpdateCurrentDir(const FileOpenDlgInfos *fodInfos)
{
LPSHELLFOLDER psfDesktop;
STRRET strret;
HRESULT res;
res = SHGetDesktopFolder(&psfDesktop);
if (FAILED(res))
return;
res = IShellFolder_GetDisplayNameOf(psfDesktop, fodInfos->ShellInfos.pidlAbsCurrent,
SHGDN_FORPARSING, &strret);
if (SUCCEEDED(res)) {
WCHAR wszCurrentDir[MAX_PATH];
res = StrRetToBufW(&strret, fodInfos->ShellInfos.pidlAbsCurrent, wszCurrentDir, MAX_PATH);
if (SUCCEEDED(res))
SetCurrentDirectoryW(wszCurrentDir);
}
IShellFolder_Release(psfDesktop);
}
/* copied from shell32 to avoid linking to it */
static HRESULT COMDLG32_StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, LPCITEMIDLIST pidl)
{
TRACE("dest=%p len=0x%x strret=%p pidl=%p stub\n",dest,len,src,pidl);
switch (src->uType)
{
case STRRET_WSTR:
lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
COMDLG32_SHFree(src->u.pOleStr);
break;
case STRRET_CSTR:
if (len && !MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, (LPWSTR)dest, len ))
((LPWSTR)dest)[len-1] = 0;
break;
case STRRET_OFFSET:
if (pidl)
{
if (len && !MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset,
-1, (LPWSTR)dest, len ))
((LPWSTR)dest)[len-1] = 0;
}
break;
default:
FIXME("unknown type!\n");
if (len)
{ *(LPWSTR)dest = '\0';
}
return(FALSE);
}
return S_OK;
}
/*
* IShellBrowser
*/
/**************************************************************************
* IShellBrowserImpl_Construct
*/
IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
{
IShellBrowserImpl *sb;
FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndOwner,FileOpenDlgInfosStr);
sb=(IShellBrowserImpl*)COMDLG32_SHAlloc(sizeof(IShellBrowserImpl));
/* Initialisation of the member variables */
sb->ref=1;
sb->hwndOwner = hwndOwner;
/* Initialisation of the vTables */
sb->lpVtbl = &IShellBrowserImpl_Vtbl;
sb->lpVtblCommDlgBrowser = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
sb->lpVtblServiceProvider = &IShellBrowserImpl_IServiceProvider_Vtbl;
SHGetSpecialFolderLocation(hwndOwner, CSIDL_DESKTOP,
&fodInfos->ShellInfos.pidlAbsCurrent);
TRACE("%p\n", sb);
return (IShellBrowser *) sb;
}
/***************************************************************************
* IShellBrowserImpl_QueryInterface
*/
static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
REFIID riid,
LPVOID *ppvObj)
{
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
TRACE("(%p)\n\t%s\n", This, debugstr_guid(riid));
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
{ *ppvObj = This;
}
else if(IsEqualIID(riid, &IID_IOleWindow)) /*IOleWindow*/
{ *ppvObj = (IOleWindow*)This;
}
else if(IsEqualIID(riid, &IID_IShellBrowser)) /*IShellBrowser*/
{ *ppvObj = (IShellBrowser*)This;
}
else if(IsEqualIID(riid, &IID_ICommDlgBrowser)) /*ICommDlgBrowser*/
{ *ppvObj = (ICommDlgBrowser*) &(This->lpVtblCommDlgBrowser);
}
else if(IsEqualIID(riid, &IID_IServiceProvider)) /* IServiceProvider */
{ *ppvObj = (ICommDlgBrowser*) &(This->lpVtblServiceProvider);
}
if(*ppvObj)
{ IUnknown_AddRef( (IShellBrowser*) *ppvObj);
return S_OK;
}
FIXME("Unknown interface requested\n");
return E_NOINTERFACE;
}
/**************************************************************************
* IShellBrowser::AddRef
*/
static ULONG WINAPI IShellBrowserImpl_AddRef(IShellBrowser * iface)
{
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p,%u)\n", This, ref - 1);
return ref;
}
/**************************************************************************
* IShellBrowserImpl_Release
*/
static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
{
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p,%u)\n", This, ref + 1);
if (!ref)
{
COMDLG32_SHFree(This);
TRACE("-- destroyed\n");
return 0;
}
return ref;
}
/*
* IOleWindow
*/
/**************************************************************************
* IShellBrowserImpl_GetWindow (IOleWindow)
*
* Inherited from IOleWindow::GetWindow
*
* See Windows documentation for more details
*
* Note : We will never be window less in the File Open dialog
*
*/
static HRESULT WINAPI IShellBrowserImpl_GetWindow(IShellBrowser * iface,
HWND * phwnd)
{
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
TRACE("(%p)\n", This);
if(!This->hwndOwner)
return E_FAIL;
*phwnd = This->hwndOwner;
return (*phwnd) ? S_OK : E_UNEXPECTED;
}
/**************************************************************************
* IShellBrowserImpl_ContextSensitiveHelp
*/
static HRESULT WINAPI IShellBrowserImpl_ContextSensitiveHelp(IShellBrowser * iface,
BOOL fEnterMode)
{
IShellBrowserImpl *This = (IShellBrowserImpl *)iface;
TRACE("(%p)\n", This);
/* Feature not implemented */
return E_NOTIMPL;
}
/*
* IShellBrowser
*/
/**************************************************************************
* IShellBrowserImpl_BrowseObject
*
* See Windows documentation on IShellBrowser::BrowseObject for more details
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -