Andrey Turkin : atl: Implement AtlAxCreateDialogA and AtlAxCreateDialogW.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Nov 2 15:48:05 CST 2006


Module: wine
Branch: master
Commit: 7dff8c19ee1948fe5373fd70d2ef69604905c3d0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7dff8c19ee1948fe5373fd70d2ef69604905c3d0

Author: Andrey Turkin <pancha at mail.nnov.ru>
Date:   Mon Oct 30 21:48:24 2006 +0300

atl: Implement AtlAxCreateDialogA and AtlAxCreateDialogW.

---

 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 1170cb8..bb393f1 100644
--- a/dlls/atl/atl_ax.c
+++ b/dlls/atl/atl_ax.c
@@ -221,3 +221,209 @@ HRESULT WINAPI AtlAxAttachControl(IUnkno
     FIXME( "(%p %p %p) - stub\n", pControl, hWnd, ppUnkContainer );
     return E_NOTIMPL;
 }
+
+/**********************************************************************
+ * Helper function for AX_ConvertDialogTemplate
+ */
+static inline BOOL 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
+ */
+static LPDLGTEMPLATEW 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");




More information about the wine-cvs mailing list