Commit 7dff8c19 authored by Andrey Turkin's avatar Andrey Turkin Committed by Alexandre Julliard

atl: Implement AtlAxCreateDialogA and AtlAxCreateDialogW.

parent 821aae4f
......@@ -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
......
......@@ -221,3 +221,209 @@ HRESULT WINAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUn
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;
}
......@@ -73,3 +73,7 @@ cpp_quote("DEFINE_GUID(CLSID_ATLRegistrar,0x44ec053a,0x400f,0x11d0,0x9d,0xcd,0x0
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");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment