atl: Implement AtlAxCreateDialogA and AtlAxCreateDialogW.
This commit is contained in:
parent
821aae4f9f
commit
7dff8c19ee
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue