comdlg32: Add a container for custom controls.
This commit is contained in:
parent
ac65f31ae6
commit
44e7cda419
|
@ -98,6 +98,8 @@ typedef struct FileDialogImpl {
|
|||
LPWSTR custom_okbutton;
|
||||
LPWSTR custom_cancelbutton;
|
||||
LPWSTR custom_filenamelabel;
|
||||
|
||||
HWND cctrls_hwnd;
|
||||
} FileDialogImpl;
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -485,6 +487,104 @@ static void ctrl_resize(HWND hctrl, UINT min_width, UINT max_width)
|
|||
HeapFree(GetProcessHeap(), 0, text);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Container functions.
|
||||
*/
|
||||
static UINT ctrl_container_resize(FileDialogImpl *This, UINT container_width)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ctrl_container_reparent(FileDialogImpl *This, HWND parent)
|
||||
{
|
||||
LONG wndstyle;
|
||||
|
||||
if(parent)
|
||||
{
|
||||
wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
|
||||
wndstyle &= ~(WS_POPUP);
|
||||
wndstyle |= WS_CHILD;
|
||||
SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle);
|
||||
|
||||
SetParent(This->cctrls_hwnd, parent);
|
||||
ShowWindow(This->cctrls_hwnd, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowWindow(This->cctrls_hwnd, FALSE);
|
||||
|
||||
wndstyle = GetWindowLongW(This->cctrls_hwnd, GWL_STYLE);
|
||||
wndstyle &= ~(WS_CHILD);
|
||||
wndstyle |= WS_POPUP;
|
||||
SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, wndstyle);
|
||||
|
||||
SetParent(This->cctrls_hwnd, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT ctrl_container_on_create(HWND hwnd, CREATESTRUCTW *crs)
|
||||
{
|
||||
FileDialogImpl *This = crs->lpCreateParams;
|
||||
TRACE("%p\n", This);
|
||||
|
||||
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LPARAM)This);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LRESULT ctrl_container_on_wm_destroy(FileDialogImpl *This)
|
||||
{
|
||||
TRACE("%p", This);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK ctrl_container_wndproc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
FileDialogImpl *This = (FileDialogImpl*)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
||||
|
||||
switch(umessage)
|
||||
{
|
||||
case WM_NCCREATE: return ctrl_container_on_create(hwnd, (CREATESTRUCTW*)lparam);
|
||||
case WM_DESTROY: return ctrl_container_on_wm_destroy(This);
|
||||
default: return DefWindowProcW(hwnd, umessage, wparam, lparam);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HRESULT init_custom_controls(FileDialogImpl *This)
|
||||
{
|
||||
WNDCLASSW wc;
|
||||
static const WCHAR ctrl_container_classname[] =
|
||||
{'i','d','l','g','_','c','o','n','t','a','i','n','e','r','_','p','a','n','e',0};
|
||||
|
||||
if( !GetClassInfoW(COMDLG32_hInstance, ctrl_container_classname, &wc) )
|
||||
{
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = ctrl_container_wndproc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = COMDLG32_hInstance;
|
||||
wc.hIcon = 0;
|
||||
wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = ctrl_container_classname;
|
||||
|
||||
if(!RegisterClassW(&wc)) return E_FAIL;
|
||||
}
|
||||
|
||||
This->cctrls_hwnd = CreateWindowExW(0, ctrl_container_classname, NULL,
|
||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||
0, 0, 0, 0, NULL, 0,
|
||||
COMDLG32_hInstance, (void*)This);
|
||||
if(!This->cctrls_hwnd)
|
||||
return E_FAIL;
|
||||
|
||||
SetWindowLongW(This->cctrls_hwnd, GWL_STYLE, WS_TABSTOP);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Window related functions.
|
||||
*/
|
||||
|
@ -495,7 +595,7 @@ static SIZE update_layout(FileDialogImpl *This)
|
|||
RECT dialog_rc;
|
||||
RECT cancel_rc, open_rc;
|
||||
RECT filetype_rc, filename_rc, filenamelabel_rc;
|
||||
RECT toolbar_rc, ebrowser_rc;
|
||||
RECT toolbar_rc, ebrowser_rc, customctrls_rc;
|
||||
int missing_width, missing_height;
|
||||
static const UINT vspacing = 4, hspacing = 4;
|
||||
SIZE ret;
|
||||
|
@ -606,22 +706,35 @@ static SIZE update_layout(FileDialogImpl *This)
|
|||
MapWindowPoints(NULL, This->dlg_hwnd, (POINT*)&toolbar_rc, 2);
|
||||
}
|
||||
|
||||
/* The custom controls */
|
||||
customctrls_rc.left = dialog_rc.left + vspacing;
|
||||
customctrls_rc.right = dialog_rc.right - vspacing;
|
||||
customctrls_rc.bottom = filename_rc.top - hspacing;
|
||||
customctrls_rc.top = customctrls_rc.bottom -
|
||||
ctrl_container_resize(This, customctrls_rc.right - customctrls_rc.left);
|
||||
|
||||
/* The ExplorerBrowser control. */
|
||||
ebrowser_rc.left = dialog_rc.left + vspacing;
|
||||
ebrowser_rc.top = toolbar_rc.bottom + vspacing;
|
||||
ebrowser_rc.right = dialog_rc.right - hspacing;
|
||||
ebrowser_rc.bottom = filename_rc.top - hspacing;
|
||||
ebrowser_rc.bottom = customctrls_rc.top - hspacing;
|
||||
|
||||
/****
|
||||
* Move everything to the right place.
|
||||
*/
|
||||
|
||||
/* FIXME: The Save Dialog uses a slightly different layout. */
|
||||
hdwp = BeginDeferWindowPos(6);
|
||||
hdwp = BeginDeferWindowPos(7);
|
||||
|
||||
if(hdwp && This->peb)
|
||||
IExplorerBrowser_SetRect(This->peb, &hdwp, ebrowser_rc);
|
||||
|
||||
if(hdwp && This->cctrls_hwnd)
|
||||
DeferWindowPos(hdwp, This->cctrls_hwnd, NULL,
|
||||
customctrls_rc.left, customctrls_rc.top,
|
||||
customctrls_rc.right - customctrls_rc.left, customctrls_rc.bottom - customctrls_rc.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
/* The default controls */
|
||||
if(hdwp && (hwnd = GetDlgItem(This->dlg_hwnd, IDC_FILETYPE)) )
|
||||
DeferWindowPos(hdwp, hwnd, NULL, filetype_rc.left, filetype_rc.top, 0, 0,
|
||||
|
@ -797,6 +910,7 @@ static LRESULT on_wm_initdialog(HWND hwnd, LPARAM lParam)
|
|||
(hitem = GetDlgItem(This->dlg_hwnd, IDC_FILENAME)) )
|
||||
SendMessageW(hitem, WM_SETTEXT, 0, (LPARAM)This->set_filename);
|
||||
|
||||
ctrl_container_reparent(This, This->dlg_hwnd);
|
||||
init_explorerbrowser(This);
|
||||
init_toolbar(This, hwnd);
|
||||
update_control_text(This);
|
||||
|
@ -834,6 +948,7 @@ static LRESULT on_wm_destroy(FileDialogImpl *This)
|
|||
This->peb = NULL;
|
||||
}
|
||||
|
||||
ctrl_container_reparent(This, NULL);
|
||||
This->dlg_hwnd = NULL;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1055,6 +1170,8 @@ static ULONG WINAPI IFileDialog2_fnRelease(IFileDialog2 *iface)
|
|||
}
|
||||
HeapFree(GetProcessHeap(), 0, This->filterspecs);
|
||||
|
||||
DestroyWindow(This->cctrls_hwnd);
|
||||
|
||||
if(This->psi_defaultfolder) IShellItem_Release(This->psi_defaultfolder);
|
||||
if(This->psi_setfolder) IShellItem_Release(This->psi_setfolder);
|
||||
if(This->psi_folder) IShellItem_Release(This->psi_folder);
|
||||
|
@ -2736,6 +2853,14 @@ static HRESULT FileDialog_constructor(IUnknown *pUnkOuter, REFIID riid, void **p
|
|||
SHGetItemFromObject((IUnknown*)psf, &IID_IShellItem, (void**)&fdimpl->psi_defaultfolder);
|
||||
IShellFolder_Release(psf);
|
||||
|
||||
hr = init_custom_controls(fdimpl);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to initialize custom controls (0x%08x).\n", hr);
|
||||
IUnknown_Release((IUnknown*)fdimpl);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
hr = IUnknown_QueryInterface((IUnknown*)fdimpl, riid, ppv);
|
||||
IUnknown_Release((IUnknown*)fdimpl);
|
||||
return hr;
|
||||
|
|
|
@ -1200,6 +1200,38 @@ static void test_filename(void)
|
|||
DeleteFileW(filename_ext2W);
|
||||
}
|
||||
|
||||
static void test_customize(void)
|
||||
{
|
||||
IFileDialog *pfod;
|
||||
IFileDialogCustomize *pfdc;
|
||||
IOleWindow *pow;
|
||||
LONG ref;
|
||||
HWND dlg_hwnd;
|
||||
HRESULT hr;
|
||||
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IFileDialog, (void**)&pfod);
|
||||
ok(hr == S_OK, "got 0x%08x.\n", hr);
|
||||
|
||||
hr = IFileOpenDialog_QueryInterface(pfod, &IID_IFileDialogCustomize, (void**)&pfdc);
|
||||
ok(hr == S_OK, "got 0x%08x.\n", hr);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
skip("Skipping IFileDialogCustomize tests.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IFileDialog_QueryInterface(pfod, &IID_IOleWindow, (void**)&pow);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
hr = IOleWindow_GetWindow(pow, &dlg_hwnd);
|
||||
ok(hr == S_OK, "Got 0x%08x\n", hr);
|
||||
ok(dlg_hwnd == NULL, "NULL\n");
|
||||
IOleWindow_Release(pow);
|
||||
|
||||
IFileDialogCustomize_Release(pfdc);
|
||||
ref = IFileOpenDialog_Release(pfod);
|
||||
ok(!ref, "Refcount not zero (%d).\n", ref);
|
||||
}
|
||||
|
||||
START_TEST(itemdlg)
|
||||
{
|
||||
OleInitialize(NULL);
|
||||
|
@ -1210,6 +1242,7 @@ START_TEST(itemdlg)
|
|||
test_basics();
|
||||
test_advise();
|
||||
test_filename();
|
||||
test_customize();
|
||||
}
|
||||
else
|
||||
skip("Skipping all Item Dialog tests.\n");
|
||||
|
|
Loading…
Reference in New Issue