diff --git a/dlls/commdlg/cdlg.h b/dlls/commdlg/cdlg.h index 8ad3972437d..22b556bb86f 100644 --- a/dlls/commdlg/cdlg.h +++ b/dlls/commdlg/cdlg.h @@ -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); diff --git a/dlls/commdlg/cdlg32.c b/dlls/commdlg/cdlg32.c index e0041bd8e2a..c0d5981a480 100644 --- a/dlls/commdlg/cdlg32.c +++ b/dlls/commdlg/cdlg32.c @@ -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) diff --git a/dlls/commdlg/filedlg95.c b/dlls/commdlg/filedlg95.c index 640446ff8f8..e636f5d32fd 100644 --- a/dlls/commdlg/filedlg95.c +++ b/dlls/commdlg/filedlg95.c @@ -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); diff --git a/dlls/commdlg/filedlgbrowser.c b/dlls/commdlg/filedlgbrowser.c index a3b7e01200d..1a3512f6332 100644 --- a/dlls/commdlg/filedlgbrowser.c +++ b/dlls/commdlg/filedlgbrowser.c @@ -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; }