- better error check when importing functions via GetProcAdress

- replaced SHGetSpecialFolderPath (not aviable in all shell32 versions)
- changed call order when browsing to different folder (crash with native shell)
- removed Move call since IShellview_CreateViewWindow creates it already in
  the right rect
This commit is contained in:
Juergen Schmied 2000-06-16 21:51:33 +00:00 committed by Alexandre Julliard
parent 3e56dbc9a4
commit 3de41ceb42
4 changed files with 108 additions and 129 deletions

View File

@ -110,7 +110,8 @@ extern DWORD (WINAPI *COMDLG32_SHGetFileInfoA)(LPCSTR,DWORD,SHFILEINFOA*,UINT,UI
extern LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
extern DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
extern HRESULT (WINAPI *COMDLG32_SHGetDataFromIDListA)(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len);
extern BOOL (WINAPI *COMDLG32_SHGetSpecialFolderPathA)(HWND hwndOwner,LPSTR szPath,DWORD csidl,BOOL bCreate);
extern BOOL (WINAPI *COMDLG32_SHGetFolderPathA)(HWND,int,HANDLE,DWORD,LPSTR);
/* PATH */
extern BOOL (WINAPI *COMDLG32_PathIsRootA)(LPCSTR x);

View File

@ -25,9 +25,10 @@ static int COMDLG32_Attach = 0;
HINSTANCE COMCTL32_hInstance = 0;
HINSTANCE SHELL32_hInstance = 0;
HINSTANCE SHLWAPI_hInstance = 0;
HINSTANCE SHFOLDER_hInstance = 0;
/* IMAGELIST */
BOOL (WINAPI* COMDLG32_ImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle);
BOOL (WINAPI* COMDLG32_ImageList_Draw) (HIMAGELIST himl, int i, HDC hdcDest, int x, int y, UINT fStyle);
/* ITEMIDLIST */
LPITEMIDLIST (WINAPI *COMDLG32_PIDL_ILClone) (LPCITEMIDLIST);
@ -46,7 +47,7 @@ DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
HRESULT (WINAPI *COMDLG32_SHGetDataFromIDListA)(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len);
HRESULT (WINAPI *COMDLG32_StrRetToBufA)(LPSTRRET,LPITEMIDLIST,LPSTR,DWORD);
HRESULT (WINAPI *COMDLG32_StrRetToBufW)(LPSTRRET,LPITEMIDLIST,LPWSTR,DWORD);
BOOL (WINAPI *COMDLG32_SHGetSpecialFolderPathA)(HWND hwndOwner,LPSTR szPath,DWORD csidl,BOOL bCreate);
BOOL (WINAPI *COMDLG32_SHGetFolderPathA)(HWND,int,HANDLE,DWORD,LPSTR);
/* PATH */
BOOL (WINAPI *COMDLG32_PathIsRootA)(LPCSTR x);
@ -71,6 +72,14 @@ BOOL (WINAPI *COMDLG32_PathAddExtensionA)(LPSTR pszPath,LPCSTR pszExtension);
* FALSE if sibling could not be loaded or instantiated twice, TRUE
* otherwise.
*/
static char * GPA_string = "Failed to get entry point %s for hinst = 0x%08x\n";
#define GPA(dest, hinst, name) \
if(!(dest = (void*)GetProcAddress(hinst,name)))\
{ \
ERR(GPA_string, debugres_a(name), hinst); \
return FALSE; \
}
BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
{
TRACE("(%08x, %08lx, %p)\n", hInstance, Reason, Reserved);
@ -115,28 +124,32 @@ BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Res
}
/* IMAGELIST */
COMDLG32_ImageList_Draw=(void*)GetProcAddress(COMCTL32_hInstance,"ImageList_Draw");
GPA(COMDLG32_ImageList_Draw, COMCTL32_hInstance,"ImageList_Draw");
/* ITEMISLIST */
COMDLG32_PIDL_ILIsEqual =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)21L);
COMDLG32_PIDL_ILCombine =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)25L);
COMDLG32_PIDL_ILGetNext =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)153L);
COMDLG32_PIDL_ILClone =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)18L);
COMDLG32_PIDL_ILRemoveLastID =(void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)17L);
/* ITEMIDLIST */
GPA(COMDLG32_PIDL_ILIsEqual, SHELL32_hInstance, (LPCSTR)21L);
GPA(COMDLG32_PIDL_ILCombine, SHELL32_hInstance, (LPCSTR)25L);
GPA(COMDLG32_PIDL_ILGetNext, SHELL32_hInstance, (LPCSTR)153L);
GPA(COMDLG32_PIDL_ILClone, SHELL32_hInstance, (LPCSTR)18L);
GPA(COMDLG32_PIDL_ILRemoveLastID, SHELL32_hInstance, (LPCSTR)17L);
/* SHELL */
COMDLG32_SHAlloc = (void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)196L);
COMDLG32_SHFree = (void*)GetProcAddress(SHELL32_hInstance, (LPCSTR)195L);
COMDLG32_SHGetSpecialFolderLocation = (void*)GetProcAddress(SHELL32_hInstance,"SHGetSpecialFolderLocation");
COMDLG32_SHGetPathFromIDListA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetPathFromIDListA");
COMDLG32_SHGetDesktopFolder = (void*)GetProcAddress(SHELL32_hInstance,"SHGetDesktopFolder");
COMDLG32_SHGetFileInfoA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFileInfoA");
COMDLG32_SHGetDataFromIDListA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetDataFromIDListA");
GPA(COMDLG32_SHAlloc, SHELL32_hInstance, (LPCSTR)196L);
GPA(COMDLG32_SHFree, SHELL32_hInstance, (LPCSTR)195L);
GPA(COMDLG32_SHGetSpecialFolderLocation, SHELL32_hInstance,"SHGetSpecialFolderLocation");
GPA(COMDLG32_SHGetPathFromIDListA, SHELL32_hInstance,"SHGetPathFromIDListA");
GPA(COMDLG32_SHGetDesktopFolder, SHELL32_hInstance,"SHGetDesktopFolder");
GPA(COMDLG32_SHGetFileInfoA, SHELL32_hInstance,"SHGetFileInfoA");
GPA(COMDLG32_SHGetDataFromIDListA, SHELL32_hInstance,"SHGetDataFromIDListA");
/* FIXME: we cant import SHGetSpecialFolderPathA from all versions of shell32 */
COMDLG32_SHGetSpecialFolderPathA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetSpecialFolderPathA");
/* for the first versions of shell32 SHGetFolderPathA is in SHFOLDER.DLL */
COMDLG32_SHGetFolderPathA = (void*)GetProcAddress(SHELL32_hInstance,"SHGetFolderPathA");
if (!COMDLG32_SHGetFolderPathA)
{
SHFOLDER_hInstance = LoadLibraryA("SHFOLDER.DLL");
GPA(COMDLG32_SHGetFolderPathA, SHFOLDER_hInstance,"SHGetFolderPathA");
}
/* ### WARINIG ###
We can't do a GetProcAddress to link to StrRetToBuf[A|W] sine not all
@ -146,18 +159,18 @@ BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Res
so it won't break the use of any combination of native and buildin dll's (jsch) */
/* PATH */
COMDLG32_PathMatchSpecW = (void*)GetProcAddress(SHLWAPI_hInstance,"PathMatchSpecW");
COMDLG32_PathIsRootA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathIsRootA");
COMDLG32_PathRemoveFileSpecA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathRemoveFileSpecA");
COMDLG32_PathFindFileNameA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathFindFileNameA");
COMDLG32_PathAddBackslashA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathAddBackslashA");
COMDLG32_PathCanonicalizeA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathCanonicalizeA");
COMDLG32_PathGetDriveNumberA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathGetDriveNumberA");
COMDLG32_PathIsRelativeA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathIsRelativeA");
COMDLG32_PathFindNextComponentA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathFindNextComponentA");
COMDLG32_PathAddBackslashW = (void*)GetProcAddress(SHLWAPI_hInstance,"PathAddBackslashW");
COMDLG32_PathFindExtensionA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathFindExtensionA");
COMDLG32_PathAddExtensionA = (void*)GetProcAddress(SHLWAPI_hInstance,"PathAddExtensionA");
GPA(COMDLG32_PathMatchSpecW, SHLWAPI_hInstance,"PathMatchSpecW");
GPA(COMDLG32_PathIsRootA, SHLWAPI_hInstance,"PathIsRootA");
GPA(COMDLG32_PathRemoveFileSpecA, SHLWAPI_hInstance,"PathRemoveFileSpecA");
GPA(COMDLG32_PathFindFileNameA, SHLWAPI_hInstance,"PathFindFileNameA");
GPA(COMDLG32_PathAddBackslashA, SHLWAPI_hInstance,"PathAddBackslashA");
GPA(COMDLG32_PathCanonicalizeA, SHLWAPI_hInstance,"PathCanonicalizeA");
GPA(COMDLG32_PathGetDriveNumberA, SHLWAPI_hInstance,"PathGetDriveNumberA");
GPA(COMDLG32_PathIsRelativeA, SHLWAPI_hInstance,"PathIsRelativeA");
GPA(COMDLG32_PathFindNextComponentA, SHLWAPI_hInstance,"PathFindNextComponentA");
GPA(COMDLG32_PathAddBackslashW, SHLWAPI_hInstance,"PathAddBackslashW");
GPA(COMDLG32_PathFindExtensionA, SHLWAPI_hInstance,"PathFindExtensionA");
GPA(COMDLG32_PathAddExtensionA, SHLWAPI_hInstance,"PathAddExtensionA");
break;
case DLL_PROCESS_DETACH:
@ -169,13 +182,15 @@ BOOL WINAPI COMDLG32_DllEntryPoint(HINSTANCE hInstance, DWORD Reason, LPVOID Res
COMDLG32_hInstance = 0;
if(COMDLG32_hInstance16)
FreeLibrary16(COMDLG32_hInstance16);
if(SHFOLDER_hInstance)
FreeLibrary(SHFOLDER_hInstance);
}
break;
}
return TRUE;
}
#undef GPA
/***********************************************************************
* COMDLG32_AllocMem (internal)

View File

@ -1036,7 +1036,7 @@ static LRESULT FILEDLG95_InitUI(HWND hwnd)
/* change Open to Save FIXME: use resources */
if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
{
SetDlgItemTextA(hwnd,IDOK,"Save");
SetDlgItemTextA(hwnd,IDOK,"&Save");
SetDlgItemTextA(hwnd,IDC_LOOKINSTATIC,"Save &in");
}
return 0;
@ -1178,8 +1178,11 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
if (!COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathAndFile))
{
/* we are in a special folder, default to desktop */
COMDLG32_SHGetSpecialFolderPathA(hwnd, lpstrPathAndFile, CSIDL_DESKTOPDIRECTORY, FALSE);
FIXME("special folder not handled, use desktop\n");
if(FAILED(COMDLG32_SHGetFolderPathA(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, 0, lpstrPathAndFile)))
{
/* last fallback */
GetCurrentDirectoryA(MAX_PATH, lpstrPathAndFile);
}
}
COMDLG32_PathAddBackslashA(lpstrPathAndFile);

View File

@ -108,8 +108,7 @@ IShellBrowser * IShellBrowserImpl_Construct(HWND hwndOwner)
sb->lpVtbl = &IShellBrowserImpl_Vtbl;
sb->lpVtbl2 = &IShellBrowserImpl_ICommDlgBrowser_Vtbl;
COMDLG32_SHGetSpecialFolderLocation(hwndOwner,
CSIDL_DESKTOP,
COMDLG32_SHGetSpecialFolderLocation(hwndOwner, CSIDL_DESKTOP,
&fodInfos->ShellInfos.pidlAbsCurrent);
TRACE("%p\n", sb);
@ -257,6 +256,9 @@ HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
IShellView *psvTmp;
FileOpenDlgInfos *fodInfos;
LPITEMIDLIST pidlTmp;
HWND hwndView;
HWND hDlgWnd;
BOOL bViewHasFocus;
ICOM_THIS(IShellBrowserImpl, iface);
@ -269,24 +271,19 @@ HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
{
/* SBSP_RELATIVE A relative pidl (relative from the current folder) */
hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
pidl,
NULL,
&IID_IShellFolder,
(LPVOID *)&psfTmp);
if(FAILED(hRes))
if(FAILED(hRes = IShellFolder_BindToObject(fodInfos->Shell.FOIShellFolder,
pidl, NULL, &IID_IShellFolder, (LPVOID *)&psfTmp)))
{
return hRes;
ERR("bind to object failed\n");
return hRes;
}
/* create an absolute pidl */
pidlTmp = COMDLG32_PIDL_ILCombine(fodInfos->ShellInfos.pidlAbsCurrent,
(LPITEMIDLIST)pidl);
}
else if(wFlags & SBSP_PARENT)
{
/* Browse the parent folder (ignores the pidl) */
pidlTmp = GetParentPidl(fodInfos->ShellInfos.pidlAbsCurrent);
psfTmp = GetShellFolderFromPidl(pidlTmp);
@ -298,11 +295,7 @@ HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
psfTmp = GetShellFolderFromPidl(pidlTmp);
}
/* Retrieve the IShellFolder interface of the pidl specified folder */
if(!psfTmp)
return E_FAIL;
if(!psfTmp) return E_FAIL;
/* If the pidl to browse to is equal to the actual pidl ...
do nothing and pretend you did it*/
@ -320,82 +313,55 @@ HRESULT WINAPI IShellBrowserImpl_BrowseObject(IShellBrowser *iface,
fodInfos->Shell.FOIDataObject = NULL;
}
/* Release the current fodInfos->Shell.FOIShellFolder and update its value */
/* Create the associated view */
if(FAILED(hRes = IShellFolder_CreateViewObject(psfTmp, fodInfos->ShellInfos.hwndOwner,
&IID_IShellView, (LPVOID *)&psvTmp))) return hRes;
/* Check if listview has focus */
bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus());
/* Get the foldersettings from the old view */
if(fodInfos->Shell.FOIShellView)
IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView, &fodInfos->ShellInfos.folderSettings);
/* Release the old fodInfos->Shell.FOIShellView and update its value.
We have to update this early since ShellView_CreateViewWindow of native
shell32 calls OnStateChange and needs the correct view here.*/
if(fodInfos->Shell.FOIShellView)
{
IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
IShellView_Release(fodInfos->Shell.FOIShellView);
}
fodInfos->Shell.FOIShellView = psvTmp;
/* Release old FOIShellFolder and update its value */
if (fodInfos->Shell.FOIShellFolder)
IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
fodInfos->Shell.FOIShellFolder = psfTmp;
/* Create the associated view */
if(SUCCEEDED(hRes = IShellFolder_CreateViewObject(psfTmp,
fodInfos->ShellInfos.hwndOwner,
&IID_IShellView,
(LPVOID *)&psvTmp)))
{
HWND hwndView;
HWND hDlgWnd;
BOOL bViewHasFocus;
/* Release old pidlAbsCurrent and update its value */
COMDLG32_SHFree((LPVOID)fodInfos->ShellInfos.pidlAbsCurrent);
fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
/* Check if listview has focus */
bViewHasFocus = IsChild(fodInfos->ShellInfos.hwndView,GetFocus());
/* Create the window */
TRACE("create view window\n");
if(FAILED(hRes = IShellView_CreateViewWindow(psvTmp, NULL,
&fodInfos->ShellInfos.folderSettings, fodInfos->Shell.FOIShellBrowser,
&fodInfos->ShellInfos.rectView, &hwndView))) return hRes;
/* Get the foldersettings from the old view */
if(fodInfos->Shell.FOIShellView)
{
IShellView_GetCurrentInfo(fodInfos->Shell.FOIShellView,
&fodInfos->ShellInfos.folderSettings);
}
/* Create the window */
if(SUCCEEDED(hRes = IShellView_CreateViewWindow(psvTmp,
NULL,
&fodInfos->ShellInfos.folderSettings,
fodInfos->Shell.FOIShellBrowser,
&fodInfos->ShellInfos.rectView,
&hwndView)))
{
/* Fit the created view in the appropriate RECT */
MoveWindow(hwndView,
fodInfos->ShellInfos.rectView.left,
fodInfos->ShellInfos.rectView.top,
fodInfos->ShellInfos.rectView.right-fodInfos->ShellInfos.rectView.left,
fodInfos->ShellInfos.rectView.bottom-fodInfos->ShellInfos.rectView.top,
FALSE);
/* Select the new folder in the Look In combo box of the Open file dialog */
FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,pidlTmp);
/* Release old pidlAbsCurrent memory and update its value */
COMDLG32_SHFree((LPVOID)fodInfos->ShellInfos.pidlAbsCurrent);
fodInfos->ShellInfos.pidlAbsCurrent = pidlTmp;
/* Release the current fodInfos->Shell.FOIShellView and update its value */
if(fodInfos->Shell.FOIShellView)
{
IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
IShellView_Release(fodInfos->Shell.FOIShellView);
}
#if 0
ShowWindow(fodInfos->ShellInfos.hwndView,SW_HIDE);
#endif
fodInfos->Shell.FOIShellView = psvTmp;
fodInfos->ShellInfos.hwndView = hwndView;
/* changes the tab order of the ListView to reflect the window's File Dialog */
hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN);
SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
/* Since we destroyed the old view if it had focus set focus
to the newly created view */
if (bViewHasFocus)
SetFocus(fodInfos->ShellInfos.hwndView);
return NOERROR;
}
}
fodInfos->ShellInfos.hwndView = hwndView;
/* Select the new folder in the Look In combo box of the Open file dialog */
FILEDLG95_LOOKIN_SelectItem(fodInfos->DlgInfos.hwndLookInCB,fodInfos->ShellInfos.pidlAbsCurrent);
/* changes the tab order of the ListView to reflect the window's File Dialog */
hDlgWnd = GetDlgItem(GetParent(hwndView), IDC_LOOKIN);
SetWindowPos(hwndView, hDlgWnd, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
/* Since we destroyed the old view if it had focus set focus to the newly created view */
if (bViewHasFocus)
SetFocus(fodInfos->ShellInfos.hwndView);
return hRes;
}
@ -693,7 +659,7 @@ HRESULT WINAPI IShellBrowserImpl_ICommDlgBrowser_OnStateChange(ICommDlgBrowser *
_ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
TRACE("(%p)\n", This);
TRACE("(%p shv=%p)\n", This, ppshv);
switch (uChange)
{
@ -809,8 +775,8 @@ HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IS
_ICOM_THIS_FromICommDlgBrowser(IShellBrowserImpl,iface);
fodInfos = (FileOpenDlgInfos *) GetPropA(This->hwndOwner,FileOpenDlgInfosStr);
TRACE("(%p)\n", This);
TRACE("(%p do=%p view=%p)\n", This, fodInfos->Shell.FOIDataObject, fodInfos->Shell.FOIShellView);
/* release old selections */
if (fodInfos->Shell.FOIDataObject)
IDataObject_Release(fodInfos->Shell.FOIDataObject);
@ -822,12 +788,6 @@ HRESULT IShellBrowserImpl_ICommDlgBrowser_OnSelChange(ICommDlgBrowser *iface, IS
FILEDLG95_FILENAME_FillFromSelection(This->hwndOwner);
if(fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Save");
else
SetDlgItemTextA(fodInfos->ShellInfos.hwndOwner,IDOK,"&Open");
/* fodInfos->DlgInfos.dwDlgProp |= FODPROP_USEVIEW; */
SendCustomDlgNotificationMessage(This->hwndOwner, CDN_SELCHANGE);
return S_OK;
}