comdlg32/tests: Add some IFileDialogEvents tests.

This commit is contained in:
David Hedberg 2014-08-31 18:47:14 +02:00 committed by Alexandre Julliard
parent 7cd7c069ad
commit 5f50864811
1 changed files with 272 additions and 68 deletions

View File

@ -25,6 +25,16 @@
#include "shlobj.h"
#include "wine/test.h"
#define IDT_CHANGEFILETYPE 500
#define IDT_CLOSEDIALOG 501
typedef enum {
IFDEVENT_TEST_NONE = 0,
IFDEVENT_TEST1 = 0x1,
IFDEVENT_TEST2 = 0x2,
IFDEVENT_TEST3 = 0x3
} FileDialogEventsTest;
static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
static HRESULT (WINAPI *pSHCreateItemFromParsingName)(PCWSTR,IBindCtx*,REFIID,void**);
@ -43,6 +53,62 @@ static void init_function_pointers(void)
#include <initguid.h>
DEFINE_GUID(IID_IFileDialogCustomizeAlt, 0x8016B7B3, 0x3D49, 0x4504, 0xA0,0xAA, 0x2A,0x37,0x49,0x4E,0x60,0x6F);
struct fw_arg {
LPCWSTR class, text;
HWND hwnd_res;
};
static BOOL CALLBACK find_window_callback(HWND hwnd, LPARAM lparam)
{
struct fw_arg *arg = (struct fw_arg*)lparam;
WCHAR buf[1024];
if(arg->class)
{
GetClassNameW(hwnd, buf, 1024);
if(lstrcmpW(buf, arg->class))
return TRUE;
}
if(arg->text)
{
GetWindowTextW(hwnd, buf, 1024);
if(lstrcmpW(buf, arg->text))
return TRUE;
}
arg->hwnd_res = hwnd;
return FALSE;
}
static HWND find_window(HWND parent, LPCWSTR class, LPCWSTR text)
{
struct fw_arg arg = {class, text, NULL};
EnumChildWindows(parent, find_window_callback, (LPARAM)&arg);
return arg.hwnd_res;
}
static HWND get_hwnd_from_ifiledialog(IFileDialog *pfd)
{
IOleWindow *pow;
HWND dlg_hwnd;
HRESULT hr;
hr = IFileDialog_QueryInterface(pfd, &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);
IOleWindow_Release(pow);
return dlg_hwnd;
}
static void test_customize_onfolderchange(IFileDialog *pfd);
static void filedialog_change_filetype(IFileDialog *pfd, HWND dlg_hwnd);
/**************************************************************************
* IFileDialogEvents implementation
*/
@ -55,7 +121,7 @@ typedef struct {
LONG OnOverwrite;
LPCWSTR set_filename;
BOOL set_filename_tried;
BOOL cfd_test1;
FileDialogEventsTest events_test;
} IFileDialogEventsImpl;
static inline IFileDialogEventsImpl *impl_from_IFileDialogEvents(IFileDialogEvents *iface)
@ -103,25 +169,39 @@ static HRESULT WINAPI IFileDialogEvents_fnOnFolderChanging(IFileDialogEvents *if
return S_OK;
}
static void test_customize_onfolderchange(IFileDialog *pfd);
static LRESULT CALLBACK test_customize_dlgproc(HWND hwnd, UINT message, LPARAM lparam, WPARAM wparam)
static LRESULT CALLBACK test_customize_dlgproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
WNDPROC oldwndproc = GetPropA(hwnd, "WT_OLDWC");
IFileDialog *pfd = GetPropA(hwnd, "WT_PFD");
BOOL br;
if(message == WM_USER+0x1234)
switch(message)
{
IFileDialog *pfd = (IFileDialog*)lparam;
case WM_USER+0x1234:
test_customize_onfolderchange(pfd);
break;
case WM_TIMER:
switch(wparam)
{
case IDT_CHANGEFILETYPE:
filedialog_change_filetype(pfd, hwnd);
KillTimer(hwnd, IDT_CHANGEFILETYPE);
SetTimer(hwnd, IDT_CLOSEDIALOG, 100, 0);
return TRUE;
case IDT_CLOSEDIALOG:
/* Calling IFileDialog_Close here does not work */
br = PostMessageW(hwnd, WM_COMMAND, IDCANCEL, 0);
ok(br, "Failed");
return TRUE;
}
}
return CallWindowProcW(oldwndproc, hwnd, message, lparam, wparam);
return CallWindowProcW(oldwndproc, hwnd, message, wparam, lparam);
}
static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *iface, IFileDialog *pfd)
{
IFileDialogEventsImpl *This = impl_from_IFileDialogEvents(iface);
IOleWindow *pow;
HWND dlg_hwnd;
HRESULT hr;
BOOL br;
@ -129,15 +209,9 @@ static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *ifac
if(This->set_filename)
{
hr = IFileDialog_QueryInterface(pfd, &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);
dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
ok(dlg_hwnd != NULL, "Got NULL.\n");
IOleWindow_Release(pow);
hr = IFileDialog_SetFileName(pfd, This->set_filename);
ok(hr == S_OK, "Got 0x%08x\n", hr);
@ -149,27 +223,35 @@ static HRESULT WINAPI IFileDialogEvents_fnOnFolderChange(IFileDialogEvents *ifac
}
}
if(This->cfd_test1)
if(This->events_test)
{
WNDPROC oldwndproc;
hr = IFileDialog_QueryInterface(pfd, &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, "Got NULL.\n");
IOleWindow_Release(pow);
dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
/* On Vista, the custom control area of the dialog is not
* fully set up when the first OnFolderChange event is
* issued. */
oldwndproc = (WNDPROC)GetWindowLongPtrW(dlg_hwnd, GWLP_WNDPROC);
SetPropA(dlg_hwnd, "WT_OLDWC", (HANDLE)oldwndproc);
SetPropA(dlg_hwnd, "WT_PFD", (HANDLE)pfd);
SetWindowLongPtrW(dlg_hwnd, GWLP_WNDPROC, (LPARAM)test_customize_dlgproc);
br = PostMessageW(dlg_hwnd, WM_USER+0x1234, (LPARAM)pfd, 0);
ok(br, "Failed\n");
switch(This->events_test)
{
case IFDEVENT_TEST1:
br = PostMessageW(dlg_hwnd, WM_USER+0x1234, 0, 0);
ok(br, "Failed\n");
break;
case IFDEVENT_TEST2:
SetTimer(dlg_hwnd, IDT_CLOSEDIALOG, 100, 0);
break;
case IFDEVENT_TEST3:
SetTimer(dlg_hwnd, IDT_CHANGEFILETYPE, 100, 0);
break;
default:
ok(FALSE, "Should not happen (%d)\n", This->events_test);
}
}
return S_OK;
@ -1008,6 +1090,168 @@ static void test_advise(void)
ok(!ref, "Got refcount %d, should have been released.\n", ref);
}
static void filedialog_change_filetype(IFileDialog *pfd, HWND dlg_hwnd)
{
HWND cb_filetype;
const WCHAR filetype1[] = {'f','n','a','m','e','1',0};
const WCHAR filetype1_broken[] = {'f','n','a','m','e','1',' ', '(','*','.','t','x','t',')',0};
cb_filetype = find_window(dlg_hwnd, NULL, filetype1);
ok(cb_filetype != NULL || broken(cb_filetype == NULL), "Could not find combobox on first attempt\n");
if(!cb_filetype)
{
/* Not sure when this happens. Some specific version?
* Seen on 32-bit English Vista */
trace("Didn't find combobox on first attempt, trying broken string..\n");
cb_filetype = find_window(dlg_hwnd, NULL, filetype1_broken);
ok(broken(cb_filetype != NULL), "Failed to find combobox on second attempt\n");
if(!cb_filetype)
return;
}
/* Making the combobox send a CBN_SELCHANGE */
SendMessageW( cb_filetype, CB_SHOWDROPDOWN, 1, 0 );
SendMessageW( cb_filetype, CB_SETCURSEL, 1, 0 );
SendMessageW( cb_filetype, WM_LBUTTONDOWN, 0, -1 );
SendMessageW( cb_filetype, WM_LBUTTONUP, 0, -1 );
}
static void test_events(void)
{
IFileDialog *pfd;
IFileDialogEventsImpl *pfdeimpl;
IFileDialogEvents *pfde;
DWORD cookie;
ULONG ref;
HRESULT hr;
const WCHAR fname1[] = {'f','n','a','m','e','1', 0};
const WCHAR fspec1[] = {'*','.','t','x','t',0};
const WCHAR fname2[] = {'f','n','a','m','e','2', 0};
const WCHAR fspec2[] = {'*','.','e','x','e',0};
COMDLG_FILTERSPEC filterspec[3] = {{fname1, fspec1}, {fname2, fspec2}};
/*
* 1. Show the dialog with no filetypes added
*/
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
&IID_IFileDialog, (void**)&pfd);
ok(hr == S_OK, "got 0x%08x.\n", hr);
pfde = IFileDialogEvents_Constructor();
pfdeimpl = impl_from_IFileDialogEvents(pfde);
pfdeimpl->events_test = IFDEVENT_TEST2;
hr = IFileDialog_Advise(pfd, pfde, &cookie);
ok(hr == S_OK, "got 0x%08x.\n", hr);
hr = IFileDialog_Show(pfd, NULL);
ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
pfdeimpl->OnFolderChanging = 0;
ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
pfdeimpl->OnFolderChange = 0;
/* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
pfdeimpl->OnSelectionChange = 0;
ok(pfdeimpl->OnTypeChange == 0, "Got %d\n", pfdeimpl->OnTypeChange);
pfdeimpl->OnTypeChange = 0;
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie);
ok(hr == S_OK, "got 0x%08x.\n", hr);
IFileDialogEvents_Release(pfde);
ref = IFileDialog_Release(pfd);
ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
/*
* 2. Show the dialog with filetypes added
*/
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
&IID_IFileDialog, (void**)&pfd);
ok(hr == S_OK, "got 0x%08x.\n", hr);
pfde = IFileDialogEvents_Constructor();
pfdeimpl = impl_from_IFileDialogEvents(pfde);
pfdeimpl->events_test = IFDEVENT_TEST2;
hr = IFileDialog_Advise(pfd, pfde, &cookie);
ok(hr == S_OK, "got 0x%08x.\n", hr);
hr = IFileDialog_SetFileTypes(pfd, 2, filterspec);
ok(hr == S_OK, "got 0x%08x.\n", hr);
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Show(pfd, NULL);
ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
pfdeimpl->OnFolderChanging = 0;
ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
pfdeimpl->OnFolderChange = 0;
/* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
pfdeimpl->OnSelectionChange = 0;
/* Called once just by showing the dialog */
todo_wine ok(pfdeimpl->OnTypeChange == 1, "Got %d\n", pfdeimpl->OnTypeChange);
pfdeimpl->OnTypeChange = 0;
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie);
ok(hr == S_OK, "got 0x%08x.\n", hr);
IFileDialogEvents_Release(pfde);
ref = IFileDialog_Release(pfd);
ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
/*
* 3. Show the dialog with filetypes added and simulate manual change of filetype
*/
hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
&IID_IFileDialog, (void**)&pfd);
ok(hr == S_OK, "got 0x%08x.\n", hr);
pfde = IFileDialogEvents_Constructor();
pfdeimpl = impl_from_IFileDialogEvents(pfde);
pfdeimpl->events_test = IFDEVENT_TEST3;
hr = IFileDialog_Advise(pfd, pfde, &cookie);
ok(hr == S_OK, "got 0x%08x.\n", hr);
hr = IFileDialog_SetFileTypes(pfd, 2, filterspec);
ok(hr == S_OK, "got 0x%08x.\n", hr);
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Show(pfd, NULL);
ok(hr == HRESULT_FROM_WIN32(ERROR_CANCELLED), "got 0x%08x.\n", hr);
ok(pfdeimpl->OnFolderChanging == 1, "Got %d\n", pfdeimpl->OnFolderChanging);
pfdeimpl->OnFolderChanging = 0;
ok(pfdeimpl->OnFolderChange == 1, "Got %d\n", pfdeimpl->OnFolderChange);
pfdeimpl->OnFolderChange = 0;
/* pfdeimpl->OnSelectionChange too unreliable to test. Can be 0, 1 or even 2. */
pfdeimpl->OnSelectionChange = 0;
/* Called once by showing the dialog and once again when changing the filetype */
todo_wine ok(pfdeimpl->OnTypeChange == 2, "Got %d\n", pfdeimpl->OnTypeChange);
pfdeimpl->OnTypeChange = 0;
ensure_zero_events(pfdeimpl);
hr = IFileDialog_Unadvise(pfd, cookie);
ok(hr == S_OK, "got 0x%08x.\n", hr);
IFileDialogEvents_Release(pfde);
ref = IFileDialog_Release(pfd);
ok(!ref || broken(ref /* win2008_64 (intermittently) */), "Got %d\n", ref);
}
static void touch_file(LPCWSTR filename)
{
HANDLE file;
@ -1269,57 +1513,16 @@ static const WCHAR visualgroup2W[] = {'v','i','s','u','a','l','g','r','o','u','p
static const WCHAR floatnotifysinkW[] = {'F','l','o','a','t','N','o','t','i','f','y','S','i','n','k',0};
static const WCHAR RadioButtonListW[] = {'R','a','d','i','o','B','u','t','t','o','n','L','i','s','t',0};
struct fw_arg {
LPCWSTR class, text;
HWND hwnd_res;
};
static BOOL CALLBACK find_window_callback(HWND hwnd, LPARAM lparam)
{
struct fw_arg *arg = (struct fw_arg*)lparam;
WCHAR buf[1024];
if(arg->class)
{
GetClassNameW(hwnd, buf, 1024);
if(lstrcmpW(buf, arg->class))
return TRUE;
}
if(arg->text)
{
GetWindowTextW(hwnd, buf, 1024);
if(lstrcmpW(buf, arg->text))
return TRUE;
}
arg->hwnd_res = hwnd;
return FALSE;
}
static HWND find_window(HWND parent, LPCWSTR class, LPCWSTR text)
{
struct fw_arg arg = {class, text, NULL};
EnumChildWindows(parent, find_window_callback, (LPARAM)&arg);
return arg.hwnd_res;
}
static void test_customize_onfolderchange(IFileDialog *pfd)
{
IOleWindow *pow;
HWND dlg_hwnd, item, item_parent;
HRESULT hr;
BOOL br;
WCHAR buf[1024];
buf[0] = '\0';
hr = IFileDialog_QueryInterface(pfd, &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);
dlg_hwnd = get_hwnd_from_ifiledialog(pfd);
ok(dlg_hwnd != NULL, "Got NULL.\n");
IOleWindow_Release(pow);
item = find_window(dlg_hwnd, NULL, checkbutton2W);
ok(item != NULL, "Failed to find item.\n");
@ -1665,7 +1868,7 @@ static void test_customize(void)
pfde = IFileDialogEvents_Constructor();
pfdeimpl = impl_from_IFileDialogEvents(pfde);
pfdeimpl->cfd_test1 = TRUE;
pfdeimpl->events_test = IFDEVENT_TEST1;
hr = IFileDialog_Advise(pfod, pfde, &cookie);
ok(hr == S_OK, "Got 0x%08x\n", hr);
@ -2053,6 +2256,7 @@ START_TEST(itemdlg)
{
test_basics();
test_advise();
test_events();
test_filename();
test_customize();
test_persistent_state();