From c58779606486044224cf2445c535f650575a0bcc Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 3 Feb 2005 19:39:26 +0000 Subject: [PATCH] Make GetOpenFileNameW with an old style open file dialog work with the original OPENFILENAMEW structure, making sure that all changes are passed back to the caller. --- dlls/commdlg/filedlg.c | 46 +++++++++++++++++++++++++++------------- dlls/commdlg/filedlg16.c | 8 +++---- dlls/commdlg/filedlg31.c | 44 +++++++++++++++++++------------------- dlls/commdlg/filedlg31.h | 3 ++- 4 files changed, 59 insertions(+), 42 deletions(-) diff --git a/dlls/commdlg/filedlg.c b/dlls/commdlg/filedlg.c index 031a2a412f5..e1216f08960 100644 --- a/dlls/commdlg/filedlg.c +++ b/dlls/commdlg/filedlg.c @@ -3377,7 +3377,7 @@ static void MemFree(void *mem) */ static BOOL FD32_GetTemplate(PFD31_DATA lfs) { - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; HANDLE hDlgTmpl; @@ -3445,9 +3445,9 @@ static BOOL CALLBACK FD32_Init(LPARAM lParam, PFD31_DATA lfs, DWORD data) if (NULL == lfs->private1632) return FALSE; if (IsUnicode) { - lfs->ofnW = *((LPOPENFILENAMEW) lParam); - if (lfs->ofnW.Flags & OFN_ENABLEHOOK) - if (lfs->ofnW.lpfnHook) + lfs->ofnW = (LPOPENFILENAMEW) lParam; + if (lfs->ofnW->Flags & OFN_ENABLEHOOK) + if (lfs->ofnW->lpfnHook) lfs->hook = TRUE; } else @@ -3456,7 +3456,8 @@ static BOOL CALLBACK FD32_Init(LPARAM lParam, PFD31_DATA lfs, DWORD data) if (priv->ofnA->Flags & OFN_ENABLEHOOK) if (priv->ofnA->lpfnHook) lfs->hook = TRUE; - FD31_MapOfnStructA(priv->ofnA, &lfs->ofnW, lfs->open); + lfs->ofnW = HeapAlloc(GetProcessHeap(), 0, sizeof(*lfs->ofnW)); + FD31_MapOfnStructA(priv->ofnA, lfs->ofnW, lfs->open); } if (! FD32_GetTemplate(lfs)) return FALSE; @@ -3472,18 +3473,25 @@ static BOOL CALLBACK FD32_Init(LPARAM lParam, PFD31_DATA lfs, DWORD data) BOOL CALLBACK FD32_CallWindowProc(PFD31_DATA lfs, UINT wMsg, WPARAM wParam, LPARAM lParam) { + BOOL ret; PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; if (priv->ofnA) { - return (BOOL) CallWindowProcA( - (WNDPROC)priv->ofnA->lpfnHook, lfs->hwnd, - wMsg, wParam, lParam); + TRACE("Call hookA %p (%p, %04x, %08x, %08lx)\n", + priv->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + ret = priv->ofnA->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); + TRACE("ret hookA %p (%p, %04x, %08x, %08lx)\n", + priv->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + return ret; } - return (BOOL) CallWindowProcW( - (WNDPROC)lfs->ofnW.lpfnHook, lfs->hwnd, - wMsg, wParam, lParam); + TRACE("Call hookW %p (%p, %04x, %08x, %08lx)\n", + lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + ret = lfs->ofnW->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); + TRACE("Ret hookW %p (%p, %04x, %08x, %08lx)\n", + lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); + return ret; } /*********************************************************************** @@ -3493,7 +3501,7 @@ BOOL CALLBACK FD32_CallWindowProc(PFD31_DATA lfs, UINT wMsg, WPARAM wParam, static void CALLBACK FD32_UpdateResult(PFD31_DATA lfs) { PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; if (priv->ofnA) { @@ -3513,7 +3521,7 @@ static void CALLBACK FD32_UpdateResult(PFD31_DATA lfs) static void CALLBACK FD32_UpdateFileTitle(PFD31_DATA lfs) { PFD32_PRIVATE priv = (PFD32_PRIVATE) lfs->private1632; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; if (priv->ofnA) { @@ -3544,7 +3552,10 @@ static void CALLBACK FD32_Destroy(PFD31_DATA lfs) /* if ofnW has been allocated, have to free everything in it */ if (NULL != priv && NULL != priv->ofnA) - FD31_FreeOfnW(&lfs->ofnW); + { + FD31_FreeOfnW(lfs->ofnW); + HeapFree(GetProcessHeap(), 0, lfs->ofnW); + } } static void FD32_SetupCallbacks(PFD31_CALLBACKS callbacks) @@ -3676,7 +3687,8 @@ static BOOL GetFileName31W(LPOPENFILENAMEW lpofn, /* addess of structure with da FD31_DestroyPrivate(lfs); } - TRACE("return lpstrFile=%s !\n", debugstr_w(lpofn->lpstrFile)); + TRACE("file %s, file offset %d, ext offset %d\n", + debugstr_w(lpofn->lpstrFile), lpofn->nFileOffset, lpofn->nFileExtension); return bRet; } @@ -3697,6 +3709,10 @@ BOOL WINAPI GetOpenFileNameA( { BOOL win16look = FALSE; + /* OFN_FILEMUSTEXIST implies OFN_PATHMUSTEXIST */ + if (ofn->Flags & OFN_FILEMUSTEXIST) + ofn->Flags |= OFN_PATHMUSTEXIST; + if (ofn->Flags & (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE)) win16look = (ofn->Flags & OFN_EXPLORER) ? FALSE : TRUE; diff --git a/dlls/commdlg/filedlg16.c b/dlls/commdlg/filedlg16.c index 475896c2b9a..380f7164a4f 100644 --- a/dlls/commdlg/filedlg16.c +++ b/dlls/commdlg/filedlg16.c @@ -170,7 +170,7 @@ static BOOL CALLBACK FD16_Init(LPARAM lParam, PFD31_DATA lfs, DWORD data) if (priv->ofn16->lpfnHook) lfs->hook = TRUE; - FD16_MapOfnStruct16(priv->ofn16, &lfs->ofnW, lfs->open); + FD16_MapOfnStruct16(priv->ofn16, lfs->ofnW, lfs->open); if (! FD16_GetTemplate(lfs)) return FALSE; @@ -204,7 +204,7 @@ BOOL CALLBACK FD16_CallWindowProc(PFD31_DATA lfs, UINT wMsg, WPARAM wParam, static void CALLBACK FD16_UpdateResult(PFD31_DATA lfs) { PFD16_PRIVATE priv = (PFD16_PRIVATE) lfs->private1632; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; if (priv->ofn16) { /* we have to convert to short (8.3) path */ @@ -240,7 +240,7 @@ static void CALLBACK FD16_UpdateResult(PFD31_DATA lfs) static void CALLBACK FD16_UpdateFileTitle(PFD31_DATA lfs) { PFD16_PRIVATE priv = (PFD16_PRIVATE) lfs->private1632; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; if (priv->ofn16) { @@ -279,7 +279,7 @@ static void CALLBACK FD16_Destroy(PFD31_DATA lfs) GlobalUnlock16(priv->hGlobal16); GlobalFree16(priv->hGlobal16); } - FD31_FreeOfnW(&lfs->ofnW); + FD31_FreeOfnW(lfs->ofnW); } } diff --git a/dlls/commdlg/filedlg31.c b/dlls/commdlg/filedlg31.c index 5fa41dcc92d..735e4252b65 100644 --- a/dlls/commdlg/filedlg31.c +++ b/dlls/commdlg/filedlg31.c @@ -38,6 +38,7 @@ #include "cderr.h" #include "winreg.h" #include "winternl.h" +#include "shlwapi.h" WINE_DEFAULT_DEBUG_CHANNEL(commdlg); @@ -305,9 +306,9 @@ LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, void FD31_UpdateResult(PFD31_DATA lfs, WCHAR *tmpstr) { int lenstr2; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; WCHAR tmpstr2[BUFFILE]; - WCHAR *bs; + WCHAR *p; TRACE("%s\n", debugstr_w(tmpstr)); if(ofnW->Flags & OFN_NOVALIDATE) @@ -320,17 +321,18 @@ void FD31_UpdateResult(PFD31_DATA lfs, WCHAR *tmpstr) lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2); if (ofnW->lpstrFile) lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile); - if((bs = strrchrW(tmpstr2, '\\')) != NULL) - ofnW->nFileOffset = bs - tmpstr2 +1; - else - ofnW->nFileOffset = 0; - ofnW->nFileExtension = 0; - while(tmpstr2[ofnW->nFileExtension] != '.' && tmpstr2[ofnW->nFileExtension] != '\0') - ofnW->nFileExtension++; - if (tmpstr2[ofnW->nFileExtension] == '\0') - ofnW->nFileExtension = 0; - else - ofnW->nFileExtension++; + + /* set filename offset */ + p = PathFindFileNameW(ofnW->lpstrFile); + ofnW->nFileOffset = (p - ofnW->lpstrFile); + + /* set extension offset */ + p = PathFindExtensionW(ofnW->lpstrFile); + ofnW->nFileExtension = (*p) ? (p - ofnW->lpstrFile) + 1 : 0; + + TRACE("file %s, file offset %d, ext offset %d\n", + debugstr_w(ofnW->lpstrFile), ofnW->nFileOffset, ofnW->nFileExtension); + /* update the real client structures if any */ lfs->callbacks->UpdateResult(lfs); } @@ -342,7 +344,7 @@ void FD31_UpdateResult(PFD31_DATA lfs, WCHAR *tmpstr) void FD31_UpdateFileTitle(PFD31_DATA lfs) { LONG lRet; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; if (ofnW->lpstrFileTitle != NULL) { lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); @@ -447,14 +449,14 @@ static LRESULT FD31_TestPath( PFD31_DATA lfs, LPWSTR path ) else { strcpyW(tmpstr2, path); - if(!(lfs->ofnW.Flags & OFN_NOVALIDATE)) + if(!(lfs->ofnW->Flags & OFN_NOVALIDATE)) *path = 0; } TRACE("path=%s, tmpstr2=%s\n", debugstr_w(path), debugstr_w(tmpstr2)); SetDlgItemTextW( hWnd, edt1, tmpstr2 ); FD31_ScanDir(hWnd, path); - return (lfs->ofnW.Flags & OFN_NOVALIDATE) ? TRUE : FALSE; + return (lfs->ofnW->Flags & OFN_NOVALIDATE) ? TRUE : FALSE; } /* no wildcards, we might have a directory or a filename */ @@ -501,7 +503,7 @@ static LRESULT FD31_Validate( PFD31_DATA lfs, LPWSTR path, UINT control, INT ite LONG lRet; HWND hWnd = lfs->hwnd; OPENFILENAMEW ofnsav; - LPOPENFILENAMEW ofnW = &lfs->ofnW; + LPOPENFILENAMEW ofnW = lfs->ofnW; WCHAR filename[BUFFILE]; ofnsav = *ofnW; /* for later restoring */ @@ -610,9 +612,7 @@ LRESULT FD31_WMCommand(HWND hWnd, LPARAM lParam, UINT notification, FD31_StripEditControl(hWnd); if (notification == LBN_DBLCLK) { - if (FD31_Validate( lfs, NULL, control, 0, FALSE )) - EndDialog(hWnd, TRUE); - return TRUE; + return SendMessageW(hWnd, WM_COMMAND, IDOK, 0); } else if (notification == LBN_SELCHANGE) return FD31_FileListSelect( lfs ); @@ -700,7 +700,7 @@ static LPWSTR FD31_DupToW(LPCSTR str, DWORD size) * FD31_MapOfnStructA [internal] * map a 32 bits Ansi structure to an Unicode one */ -void FD31_MapOfnStructA(LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open) +void FD31_MapOfnStructA(const LPOPENFILENAMEA ofnA, LPOPENFILENAMEW ofnW, BOOL open) { UNICODE_STRING usBuffer; @@ -828,7 +828,7 @@ LONG FD31_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) if (!lfs) return FALSE; SetPropA(hWnd, FD31_OFN_PROP, (HANDLE)lfs); lfs->hwnd = hWnd; - ofn = &lfs->ofnW; + ofn = lfs->ofnW; TRACE("flags=%lx initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir)); diff --git a/dlls/commdlg/filedlg31.h b/dlls/commdlg/filedlg31.h index f646cb80db0..2506a7d8fc0 100644 --- a/dlls/commdlg/filedlg31.h +++ b/dlls/commdlg/filedlg31.h @@ -44,7 +44,8 @@ typedef struct tagFD31_DATA LPARAM lParam; /* save original lparam */ LPCVOID template; /* template for 32 bits resource */ BOOL open; /* TRUE if open dialog, FALSE if save dialog */ - OPENFILENAMEW ofnW; /* copy of original structure or work struct */ + LPOPENFILENAMEW ofnW; /* pointer either to the original structure or + a W copy for A/16 API */ LPVOID private1632; /* 16/32 bit caller private data */ PFD31_CALLBACKS callbacks; /* callbacks to handle 16/32 bit differences */ } FD31_DATA;