Module: wine Branch: oldstable Commit: 7b4be95809569d0b41880ec08bc91432cc6ad3ca URL: https://source.winehq.org/git/wine.git/?a=commit;h=7b4be95809569d0b41880ec08...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Jan 19 11:24:00 2018 +0100
commdlg: Implement custom template support in 16-bit file dialogs.
Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 0e9cb103400c58480778894cb0e4a3d2dec9a3b4) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/commdlg.dll16/filedlg.c | 136 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 2 deletions(-)
diff --git a/dlls/commdlg.dll16/filedlg.c b/dlls/commdlg.dll16/filedlg.c index 7e2fda7..1238dc9 100644 --- a/dlls/commdlg.dll16/filedlg.c +++ b/dlls/commdlg.dll16/filedlg.c @@ -18,18 +18,120 @@ * 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 <assert.h> #include <stdarg.h> #include "windef.h" #include "winbase.h" #include "wine/winbase16.h" #include "wingdi.h" #include "winuser.h" +#include "winternl.h" #include "commdlg.h" #include "cdlg16.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
+ +static inline WORD get_word( const char **ptr ) +{ + WORD ret = *(WORD *)*ptr; + *ptr += sizeof(WORD); + return ret; +} + +static inline void copy_string( WORD **out, const char **in, DWORD maxlen ) +{ + DWORD len = MultiByteToWideChar( CP_ACP, 0, *in, -1, *out, maxlen ); + *in += strlen(*in) + 1; + *out += len; +} + +static inline void copy_dword( WORD **out, const char **in ) +{ + *(DWORD *)*out = *(DWORD *)*in; + *in += sizeof(DWORD); + *out += sizeof(DWORD) / sizeof(WORD); +} + +static LPDLGTEMPLATEA convert_dialog( const char *p, DWORD size ) +{ + LPDLGTEMPLATEA dlg; + WORD len, count, *out, *end; + + if (!(dlg = HeapAlloc( GetProcessHeap(), 0, size * 2 ))) return NULL; + out = (WORD *)dlg; + end = out + size; + copy_dword( &out, &p ); /* style */ + *out++ = 0; *out++ = 0; /* exstyle */ + *out++ = count = (BYTE)*p++; /* count */ + *out++ = get_word( &p ); /* x */ + *out++ = get_word( &p ); /* y */ + *out++ = get_word( &p ); /* cx */ + *out++ = get_word( &p ); /* cy */ + + if ((BYTE)*p == 0xff) /* menu */ + { + p++; + *out++ = 0xffff; + *out++ = get_word( &p ); + } + else copy_string( &out, &p, end - out ); + + copy_string( &out, &p, end - out ); /* class */ + copy_string( &out, &p, end - out ); /* caption */ + + if (dlg->style & DS_SETFONT) + { + *out++ = get_word( &p ); /* point size */ + copy_string( &out, &p, end - out ); /* face name */ + } + + /* controls */ + while (count--) + { + WORD x = get_word( &p ); + WORD y = get_word( &p ); + WORD cx = get_word( &p ); + WORD cy = get_word( &p ); + WORD id = get_word( &p ); + + out = (WORD *)(((UINT_PTR)out + 3) & ~3); + + copy_dword( &out, &p ); /* style */ + *out++ = 0; *out++ = 0; /* exstyle */ + *out++ = x; + *out++ = y; + *out++ = cx; + *out++ = cy; + *out++ = id; + + if (*p & 0x80) /* class */ + { + *out++ = 0xffff; + *out++ = (BYTE)*p++; + } + else copy_string( &out, &p, end - out ); + + if (*p & 0x80) /* window */ + { + *out++ = 0xffff; + *out++ = get_word( &p ); + } + else copy_string( &out, &p, end - out ); + + len = (BYTE)*p++; /* data */ + *out++ = (len + 1) & ~1; + memcpy( out, p, len ); + p += len; + out += (len + 1) / sizeof(WORD); + } + + assert( out <= end ); + return dlg; +} + static UINT_PTR CALLBACK dummy_hook( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) { return FALSE; @@ -68,6 +170,7 @@ BOOL16 CALLBACK FileSaveDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam, L BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) /* [in/out] address of structure with data*/ { LPOPENFILENAME16 lpofn = MapSL(ofn); + LPDLGTEMPLATEA template = NULL; OPENFILENAMEA ofn32; BOOL ret;
@@ -93,7 +196,20 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) /* [in/out] address of structure w ofn32.lpfnHook = dummy_hook; /* this is to force old 3.1 dialog style */
if (lpofn->Flags & OFN_ENABLETEMPLATE) - FIXME( "custom templates no longer supported, using default\n" ); + { + HRSRC16 res = FindResource16( lpofn->hInstance, MapSL(lpofn->lpTemplateName), (LPCSTR)RT_DIALOG ); + HGLOBAL16 handle = LoadResource16( lpofn->hInstance, res ); + DWORD size = SizeofResource16( lpofn->hInstance, res ); + void *ptr = LockResource16( handle ); + + if (ptr && (template = convert_dialog( ptr, size ))) + { + ofn32.hInstance = (HINSTANCE)template; + ofn32.Flags |= OFN_ENABLETEMPLATEHANDLE; + } + FreeResource16( handle ); + } + if (lpofn->Flags & OFN_ENABLEHOOK) FIXME( "custom hook %p no longer supported\n", lpofn->lpfnHook );
@@ -103,6 +219,7 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) /* [in/out] address of structure w lpofn->nFileOffset = ofn32.nFileOffset; lpofn->nFileExtension = ofn32.nFileExtension; } + HeapFree( GetProcessHeap(), 0, template ); return ret; }
@@ -121,6 +238,7 @@ BOOL16 WINAPI GetOpenFileName16( SEGPTR ofn ) /* [in/out] address of structure w BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn ) /* [in/out] address of structure with data*/ { LPOPENFILENAME16 lpofn = MapSL(ofn); + LPDLGTEMPLATEA template = NULL; OPENFILENAMEA ofn32; BOOL ret;
@@ -146,7 +264,20 @@ BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn ) /* [in/out] address of structure w ofn32.lpfnHook = dummy_hook; /* this is to force old 3.1 dialog style */
if (lpofn->Flags & OFN_ENABLETEMPLATE) - FIXME( "custom templates no longer supported, using default\n" ); + { + HRSRC16 res = FindResource16( lpofn->hInstance, MapSL(lpofn->lpTemplateName), (LPCSTR)RT_DIALOG ); + HGLOBAL16 handle = LoadResource16( lpofn->hInstance, res ); + DWORD size = SizeofResource16( lpofn->hInstance, res ); + void *ptr = LockResource16( handle ); + + if (ptr && (template = convert_dialog( ptr, size ))) + { + ofn32.hInstance = (HINSTANCE)template; + ofn32.Flags |= OFN_ENABLETEMPLATEHANDLE; + } + FreeResource16( handle ); + } + if (lpofn->Flags & OFN_ENABLEHOOK) FIXME( "custom hook %p no longer supported\n", lpofn->lpfnHook );
@@ -156,6 +287,7 @@ BOOL16 WINAPI GetSaveFileName16( SEGPTR ofn ) /* [in/out] address of structure w lpofn->nFileOffset = ofn32.nFileOffset; lpofn->nFileExtension = ofn32.nFileExtension; } + HeapFree( GetProcessHeap(), 0, template ); return ret; }