atl: implement AtlAxCreateDialogA and AtlAxCreateDialogW
Andrey Turkin
pancha at mail.nnov.ru
Mon Oct 30 12:48:24 CST 2006
This patch implements AtlAxCreateDialogA and AtlAxCreateDialogW (these
functions reparse dialog template to catch ActiveX controls and change
their classnames to AtlAxWin).
ChangeLog:
Implement AtlAxCreateDialogA and AtlAxCreateDialogW
-------------- next part --------------
dlls/atl/atl.spec | 4 -
dlls/atl/atl_ax.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++
dlls/atl/atliface.idl | 4 +
3 files changed, 212 insertions(+), 2 deletions(-)
diff --git a/dlls/atl/atl.spec b/dlls/atl/atl.spec
index db9ca9a..12d5a19 100644
--- a/dlls/atl/atl.spec
+++ b/dlls/atl/atl.spec
@@ -28,8 +28,8 @@
34 stub AtlGetVersion
35 stub AtlAxDialogBoxW
36 stub AtlAxDialogBoxA
-37 stub AtlAxCreateDialogW
-38 stub AtlAxCreateDialogA
+37 stdcall AtlAxCreateDialogW(long wstr long ptr long)
+38 stdcall AtlAxCreateDialogA(long str long ptr long)
39 stdcall AtlAxCreateControl(ptr ptr ptr ptr)
40 stdcall AtlAxCreateControlEx(ptr ptr ptr ptr ptr ptr ptr)
41 stub AtlAxAttachControl
diff --git a/dlls/atl/atl_ax.c b/dlls/atl/atl_ax.c
index 79e2435..7a45f3b 100644
--- a/dlls/atl/atl_ax.c
+++ b/dlls/atl/atl_ax.c
@@ -221,3 +221,209 @@ HRESULT WINAPI AtlAxAttachControl(IUnkno
FIXME( "(%p %x %p) - stub\n", pControl, hWnd, ppUnkContainer );
return E_NOTIMPL;
}
+
+/**********************************************************************
+ * Helper function for AX_ConvertDialogTemplate
+ */
+BOOL static inline advance_array(WORD **pptr, DWORD *palloc, DWORD *pfilled, const WORD *data, DWORD size)
+{
+ if ( (*pfilled + size) > *palloc )
+ {
+ *palloc = ((*pfilled+size) + 0xFF) & ~0xFF;
+ *pptr = HeapReAlloc( GetProcessHeap(), 0, *pptr, *palloc * sizeof(WORD) );
+ if (!*pptr)
+ return FALSE;
+ }
+ RtlMoveMemory( *pptr+*pfilled, data, size * sizeof(WORD) );
+ *pfilled += size;
+ return TRUE;
+}
+
+/**********************************************************************
+ * Convert ActiveX control templates to AtlAxWin class instances
+ */
+LPDLGTEMPLATEW static AX_ConvertDialogTemplate(LPCDLGTEMPLATEW src_tmpl)
+{
+#define GET_WORD(x) (*(const WORD *)(x))
+#define GET_DWORD(x) (*(const DWORD *)(x))
+#define PUT_BLOCK(x,y) do {if (!advance_array(&output, &allocated, &filled, (x), (y))) return NULL;} while (0)
+#define PUT_WORD(x) do {WORD w = (x);PUT_BLOCK(&w, 1);} while(0)
+#define PUT_DWORD(x) do {DWORD w = (x);PUT_BLOCK(&w, 2);} while(0)
+ const WORD *tmp, *src = (const WORD *)src_tmpl;
+ WORD *output;
+ DWORD allocated, filled; /* in WORDs */
+ BOOL ext;
+ WORD signature, dlgver, rescount;
+ DWORD style;
+
+ filled = 0; allocated = 256;
+ output = HeapAlloc( GetProcessHeap(), 0, allocated * sizeof(WORD) );
+ if (!output)
+ return NULL;
+
+ /* header */
+ tmp = src;
+ signature = GET_WORD(src);
+ dlgver = GET_WORD(src + 1);
+ if (signature == 1 && dlgver == 0xFFFF)
+ {
+ ext = TRUE;
+ src += 6;
+ style = GET_DWORD(src);
+ src += 2;
+ rescount = GET_WORD(src++);
+ src += 4;
+ if ( GET_WORD(src) == 0xFFFF ) /* menu */
+ src += 2;
+ else
+ src += strlenW(src) + 1;
+ if ( GET_WORD(src) == 0xFFFF ) /* class */
+ src += 2;
+ else
+ src += strlenW(src) + 1;
+ src += strlenW(src) + 1; /* title */
+ if ( style & (DS_SETFONT | DS_SHELLFONT) )
+ {
+ src += 3;
+ src += strlenW(src) + 1;
+ }
+ } else {
+ ext = FALSE;
+ style = GET_DWORD(src);
+ src += 4;
+ rescount = GET_WORD(src++);
+ src += 4;
+ if ( GET_WORD(src) == 0xFFFF ) /* menu */
+ src += 2;
+ else
+ src += strlenW(src) + 1;
+ if ( GET_WORD(src) == 0xFFFF ) /* class */
+ src += 2;
+ else
+ src += strlenW(src) + 1;
+ src += strlenW(src) + 1; /* title */
+ if ( style & DS_SETFONT )
+ {
+ src++;
+ src += strlenW(src) + 1;
+ }
+ }
+ PUT_BLOCK(tmp, src-tmp);
+
+ while(rescount--)
+ {
+ src = (const WORD *)( ( ((ULONG)src) + 3) & ~3); /* align on DWORD boundary */
+ filled = (filled + 1) & ~1; /* depends on DWORD-aligned allocation unit */
+
+ tmp = src;
+ if (ext)
+ src += 11;
+ else
+ src += 9;
+ PUT_BLOCK(tmp, src-tmp);
+
+ tmp = src;
+ if ( GET_WORD(src) == 0xFFFF ) /* class */
+ {
+ src += 2;
+ } else
+ {
+ src += strlenW(src) + 1;
+ }
+ src += strlenW(src) + 1; /* title */
+ if ( GET_WORD(tmp) == '{' ) /* all this mess created because of this line */
+ {
+ const WCHAR AtlAxWin[9]={'A','t','l','A','x','W','i','n',0};
+ PUT_BLOCK(AtlAxWin, sizeof(AtlAxWin)/sizeof(WORD));
+ PUT_BLOCK(tmp, strlenW(tmp)+1);
+ } else
+ PUT_BLOCK(tmp, src-tmp);
+
+ if ( GET_WORD(src) )
+ {
+ WORD size = (GET_WORD(src)+sizeof(WORD)-1) / sizeof(WORD); /* quite ugly :( Maybe use BYTE* instead of WORD* everywhere ? */
+ PUT_BLOCK(src, size);
+ src+=size;
+ }
+ else
+ {
+ PUT_WORD(0);
+ src++;
+ }
+ }
+ return (LPDLGTEMPLATEW) output;
+}
+
+/***********************************************************************
+ * AtlAxCreateDialogA [ATL.@]
+ *
+ * Creates a dialog window
+ *
+ * PARAMS
+ * hInst [I] Application instance
+ * name [I] Dialog box template name
+ * owner [I] Dialog box parent HWND
+ * dlgProc [I] Dialog box procedure
+ * param [I] This value will be passed to dlgProc as WM_INITDIALOG's message lParam
+ *
+ * RETURNS
+ * Window handle of dialog window.
+ */
+HWND WINAPI AtlAxCreateDialogA(HINSTANCE hInst, LPCSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param)
+{
+ HWND res = NULL;
+ int length;
+ WCHAR *nameW;
+
+ if ( HIWORD(name) == 0 )
+ return AtlAxCreateDialogW( hInst, (LPCWSTR) name, owner, dlgProc, param );
+
+ length = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
+ nameW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
+ if (nameW)
+ {
+ MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, length );
+ res = AtlAxCreateDialogW( hInst, nameW, owner, dlgProc, param );
+ HeapFree( GetProcessHeap(), 0, nameW );
+ }
+ return res;
+}
+
+/***********************************************************************
+ * AtlAxCreateDialogW [ATL.@]
+ *
+ * See AtlAxCreateDialogA
+ *
+ */
+HWND WINAPI AtlAxCreateDialogW(HINSTANCE hInst, LPCWSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param)
+{
+ HRSRC hrsrc;
+ HGLOBAL hgl;
+ LPCDLGTEMPLATEW ptr;
+ LPDLGTEMPLATEW newptr;
+ HWND res;
+
+ FIXME("(%p %s %p %p %lx) - not tested\n", hInst, debugstr_w(name), owner, dlgProc, param);
+
+ hrsrc = FindResourceW( hInst, name, (LPWSTR)RT_DIALOG );
+ if ( !hrsrc )
+ return NULL;
+ hgl = LoadResource (hInst, hrsrc);
+ if ( !hgl )
+ return NULL;
+ ptr = (LPCDLGTEMPLATEW)LockResource ( hgl );
+ if (!ptr)
+ {
+ FreeResource( hgl );
+ return NULL;
+ }
+ newptr = AX_ConvertDialogTemplate( ptr );
+ if ( newptr )
+ {
+ res = CreateDialogIndirectParamW( hInst, newptr, owner, dlgProc, param );
+ HeapFree( GetProcessHeap(), 0, newptr );
+ } else
+ res = NULL;
+ FreeResource ( hrsrc );
+ return res;
+}
diff --git a/dlls/atl/atliface.idl b/dlls/atl/atliface.idl
index 884d187..bb5cb2e 100644
--- a/dlls/atl/atliface.idl
+++ b/dlls/atl/atliface.idl
@@ -73,3 +73,7 @@ cpp_quote("DEFINE_GUID(CLSID_ATLRegistra
cpp_quote("HRESULT WINAPI AtlAxCreateControl(LPCOLESTR,HWND,IStream*,IUnknown**);")
cpp_quote("HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR,HWND,IStream*,IUnknown**,IUnknown**,REFIID,IUnknown*);")
cpp_quote("BOOL WINAPI AtlAxWinInit(void);")
+
+cpp_quote("HWND WINAPI AtlAxCreateDialogW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM);");
+cpp_quote("HWND WINAPI AtlAxCreateDialogA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM);");
+cpp_quote("#define AtlAxCreateDialog WINELIB_NAME_AW(AtlAxCreateDialog");
--
1.4.2.4
More information about the wine-patches
mailing list