diff --git a/rostests/winetests/comdlg32/comdlg32.rbuild b/rostests/winetests/comdlg32/comdlg32.rbuild
index d24dc1bd3c8..2d5dec28046 100644
--- a/rostests/winetests/comdlg32/comdlg32.rbuild
+++ b/rostests/winetests/comdlg32/comdlg32.rbuild
@@ -5,11 +5,13 @@
.
filedlg.c
+ fontdlg.c
printdlg.c
testlist.c
rsrc.rc
wine
comdlg32
+ winspool
user32
gdi32
ntdll
diff --git a/rostests/winetests/comdlg32/filedlg.c b/rostests/winetests/comdlg32/filedlg.c
index 9714dda1fe3..71f7d2a2595 100644
--- a/rostests/winetests/comdlg32/filedlg.c
+++ b/rostests/winetests/comdlg32/filedlg.c
@@ -29,6 +29,32 @@
/* ##### */
+static int resizesupported = TRUE;
+
+static void toolbarcheck( HWND hDlg)
+{
+ /* test toolbar properties */
+ /* bug #10532 */
+ int maxtextrows;
+ HWND ctrl;
+ DWORD ret;
+ char classname[20];
+
+ for( ctrl = GetWindow( hDlg, GW_CHILD);
+ ctrl ; ctrl = GetWindow( ctrl, GW_HWNDNEXT)) {
+ GetClassName( ctrl, classname, 10);
+ classname[7] = '\0';
+ if( !strcmp( classname, "Toolbar")) break;
+ }
+ ok( ctrl != NULL, "could not get the toolbar control\n");
+ ret = SendMessage( ctrl, TB_ADDSTRING, 0, (LPARAM)"winetestwinetest\0\0");
+ ok( ret == 0, "addstring returned %d (expected 0)\n", ret);
+ maxtextrows = SendMessage( ctrl, TB_GETTEXTROWS, 0, 0);
+ ok( maxtextrows == 0 || broken(maxtextrows == 1), /* Win2k and below */
+ "Get(Max)TextRows returned %d (expected 0)\n", maxtextrows);
+}
+
+
static UINT_PTR CALLBACK OFNHookProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
LPNMHDR nmh;
@@ -49,6 +75,7 @@ static UINT_PTR CALLBACK OFNHookProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM
ok(ret > 0, "CMD_GETFOLDERIDLIST not implemented\n");
if (ret > 5)
ok(buf[0] == 0x66 && buf[1] == 0x66, "CMD_GETFOLDERIDLIST: The buffer was touched on failure\n");
+ toolbarcheck( GetParent(hDlg));
}
}
@@ -78,26 +105,26 @@ static void test_DialogCancel(void)
ofn.lpstrInitialDir = szInitialDir;
PrintDlgA(NULL);
- ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n",
- CDERR_INITIALIZATION, CommDlgExtendedError());
+ ok(CDERR_INITIALIZATION == CommDlgExtendedError(),
+ "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError());
result = GetOpenFileNameA(&ofn);
- ok(0 == result, "expected %d, got %d\n", 0, result);
- ok(0 == CommDlgExtendedError(), "expected %d, got %d\n", 0,
+ ok(0 == result, "expected 0, got %d\n", result);
+ ok(0 == CommDlgExtendedError(), "expected 0, got %d\n",
CommDlgExtendedError());
PrintDlgA(NULL);
- ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n",
- CDERR_INITIALIZATION, CommDlgExtendedError());
+ ok(CDERR_INITIALIZATION == CommDlgExtendedError(),
+ "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError());
result = GetSaveFileNameA(&ofn);
- ok(0 == result, "expected %d, got %d\n", 0, result);
- ok(0 == CommDlgExtendedError(), "expected %d, got %d\n", 0,
+ ok(0 == result, "expected 0, got %d\n", result);
+ ok(0 == CommDlgExtendedError(), "expected 0, got %d\n",
CommDlgExtendedError());
PrintDlgA(NULL);
- ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n",
- CDERR_INITIALIZATION, CommDlgExtendedError());
+ ok(CDERR_INITIALIZATION == CommDlgExtendedError(),
+ "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError());
/* Before passing the ofn to Unicode functions, remove the ANSI strings */
ofn.lpstrFilter = NULL;
@@ -105,8 +132,8 @@ static void test_DialogCancel(void)
ofn.lpstrDefExt = NULL;
PrintDlgA(NULL);
- ok(CDERR_INITIALIZATION == CommDlgExtendedError(), "expected %d, got %d\n",
- CDERR_INITIALIZATION, CommDlgExtendedError());
+ ok(CDERR_INITIALIZATION == CommDlgExtendedError(),
+ "expected CDERR_INITIALIZATION, got %d\n", CommDlgExtendedError());
SetLastError(0xdeadbeef);
result = GetOpenFileNameW((LPOPENFILENAMEW) &ofn);
@@ -114,11 +141,10 @@ static void test_DialogCancel(void)
win_skip("GetOpenFileNameW is not implemented\n");
else
{
- ok(0 == result, "expected %d, got %d\n", 0, result);
+ ok(0 == result, "expected 0, got %d\n", result);
ok(0 == CommDlgExtendedError() ||
- CDERR_INITIALIZATION == CommDlgExtendedError(), /* win9x */
- "expected %d or %d, got %d\n", 0, CDERR_INITIALIZATION,
- CommDlgExtendedError());
+ broken(CDERR_INITIALIZATION == CommDlgExtendedError()), /* win9x */
+ "expected 0, got %d\n", CommDlgExtendedError());
}
SetLastError(0xdeadbeef);
@@ -127,11 +153,10 @@ static void test_DialogCancel(void)
win_skip("GetSaveFileNameW is not implemented\n");
else
{
- ok(0 == result, "expected %d, got %d\n", 0, result);
+ ok(0 == result, "expected 0, got %d\n", result);
ok(0 == CommDlgExtendedError() ||
- CDERR_INITIALIZATION == CommDlgExtendedError(), /* win9x */
- "expected %d or %d, got %d\n", 0, CDERR_INITIALIZATION,
- CommDlgExtendedError());
+ broken(CDERR_INITIALIZATION == CommDlgExtendedError()), /* win9x */
+ "expected 0, got %d\n", CommDlgExtendedError());
}
}
@@ -177,12 +202,19 @@ static UINT_PTR CALLBACK create_view_window2_hook(HWND dlg, UINT msg, WPARAM wPa
view_params.hwndView = NULL;
hr = IShellView2_CreateViewWindow2(shell_view2, &view_params);
+ if (hr == E_FAIL)
+ {
+ win_skip("CreateViewWindow2 is broken on Vista/W2K8\n");
+ goto cleanup;
+ }
ok(SUCCEEDED(hr), "CreateViewWindow2 returned %#x\n", hr);
if (FAILED(hr)) goto cleanup;
hr = IShellView2_GetCurrentInfo(shell_view2, &folder_settings);
ok(SUCCEEDED(hr), "GetCurrentInfo returned %#x\n", hr);
- ok(folder_settings.ViewMode == FVM_LIST, "view mode is %d, expected %d\n", folder_settings.ViewMode, FVM_LIST);
+ ok(folder_settings.ViewMode == FVM_LIST,
+ "view mode is %d, expected FVM_LIST\n",
+ folder_settings.ViewMode);
hr = IShellView2_DestroyViewWindow(shell_view2);
ok(SUCCEEDED(hr), "DestroyViewWindow returned %#x\n", hr);
@@ -201,7 +233,8 @@ static UINT_PTR CALLBACK create_view_window2_hook(HWND dlg, UINT msg, WPARAM wPa
ok(SUCCEEDED(hr), "GetCurrentInfo returned %#x\n", hr);
ok(folder_settings.ViewMode == FVM_DETAILS ||
broken(folder_settings.ViewMode == FVM_LIST), /* Win9x */
- "view mode is %d, expected %d\n", folder_settings.ViewMode, FVM_DETAILS);
+ "view mode is %d, expected FVM_DETAILS\n",
+ folder_settings.ViewMode);
cleanup:
if (shell_view2) IShellView2_Release(shell_view2);
@@ -241,7 +274,7 @@ static void test_create_view_window2(void)
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = filename;
- ofn.nMaxFile = 1042;
+ ofn.nMaxFile = 1024;
ofn.lpfnHook = create_view_window2_hook;
ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER;
ret = GetOpenFileNameA(&ofn);
@@ -258,7 +291,7 @@ static void test_create_view_template(void)
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = filename;
- ofn.nMaxFile = 1042;
+ ofn.nMaxFile = 1024;
ofn.lpfnHook = (LPOFNHOOKPROC)template_hook;
ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE;
ofn.hInstance = GetModuleHandleA(NULL);
@@ -270,9 +303,694 @@ static void test_create_view_template(void)
ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
}
+/* test cases for resizing of the file dialog */
+struct {
+ DWORD flags;
+ int resize_folderchange;/* change in CDN_FOLDERCHANGE handler */
+ int resize_timer1; /* change in first WM_TIMER handler */
+ int resize_check; /* expected change (in second WM_TIMER handler) */
+ BOOL todo; /* mark that test todo_wine */
+ BOOL testcontrols; /* test resizing and moving of the controls */
+} resize_testcases[] = {
+ { 0 , 10, 10, 20,FALSE,FALSE}, /* 0 */
+ { 0 ,-10,-10,-20,FALSE,FALSE},
+ { OFN_ENABLESIZING , 0, 0, 0,FALSE,FALSE},
+ { OFN_ENABLESIZING , 0,-10, 0,FALSE,FALSE},
+ { OFN_ENABLESIZING , 0, 10, 10,FALSE, TRUE},
+ { OFN_ENABLESIZING ,-10, 0, 10,FALSE,FALSE}, /* 5 */
+ { OFN_ENABLESIZING , 10, 0, 10,FALSE,FALSE},
+ { OFN_ENABLESIZING , 0, 10, 20,FALSE,FALSE},
+ /* mark the end */
+ { 0xffffffff }
+};
+
+static LONG_PTR WINAPI resize_template_hook(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static RECT initrc, rc;
+ static int index, count;
+ static int gotSWP_bottom, gotShowWindow;
+ HWND parent = GetParent( dlg);
+ int resize;
+#define MAXNRCTRLS 30
+ static RECT ctrlrcs[MAXNRCTRLS];
+ static int ctrlids[MAXNRCTRLS];
+ static HWND ctrls[MAXNRCTRLS];
+ static int nrctrls;
+
+ switch( msg)
+ {
+ case WM_INITDIALOG:
+ {
+ DWORD style;
+
+ index = ((OPENFILENAME*)lParam)->lCustData;
+ count = 0;
+ gotSWP_bottom = gotShowWindow = 0;
+ /* test style */
+ style = GetWindowLong( parent, GWL_STYLE);
+ if( resize_testcases[index].flags & OFN_ENABLESIZING)
+ if( !(style & WS_SIZEBOX)) {
+ win_skip( "OFN_ENABLESIZING flag not supported.\n");
+ resizesupported = FALSE;
+ PostMessage( parent, WM_COMMAND, IDCANCEL, 0);
+ } else
+ ok( style & WS_SIZEBOX,
+ "testid %d: dialog should have a WS_SIZEBOX style.\n", index);
+ else
+ ok( !(style & WS_SIZEBOX),
+ "testid %d: dialog should not have a WS_SIZEBOX style.\n", index);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ if(( (LPNMHDR)lParam)->code == CDN_FOLDERCHANGE){
+ GetWindowRect( parent, &initrc);
+ if( (resize = resize_testcases[index].resize_folderchange)){
+ MoveWindow( parent, initrc.left,initrc.top, initrc.right - initrc.left + resize,
+ initrc.bottom - initrc.top + resize, TRUE);
+ }
+ SetTimer( dlg, 0, 100, 0);
+ }
+ break;
+ }
+ case WM_TIMER:
+ {
+ if( count == 0){
+ /* store the control rectangles */
+ if( resize_testcases[index].testcontrols) {
+ HWND ctrl;
+ int i;
+ for( i = 0, ctrl = GetWindow( parent, GW_CHILD);
+ i < MAXNRCTRLS && ctrl;
+ i++, ctrl = GetWindow( ctrl, GW_HWNDNEXT)) {
+ ctrlids[i] = GetDlgCtrlID( ctrl);
+ GetWindowRect( ctrl, &ctrlrcs[i]);
+ MapWindowPoints( NULL, parent, (LPPOINT) &ctrlrcs[i], 2);
+ ctrls[i] = ctrl;
+ }
+ nrctrls = i;
+ }
+ if( (resize = resize_testcases[index].resize_timer1)){
+ GetWindowRect( parent, &rc);
+ MoveWindow( parent, rc.left,rc.top, rc.right - rc.left + resize,
+ rc.bottom - rc.top + resize, TRUE);
+ }
+ } else if( count == 1){
+ resize = resize_testcases[index].resize_check;
+ GetWindowRect( parent, &rc);
+ if( resize_testcases[index].todo){
+ todo_wine {
+ ok( resize == rc.right - rc.left - initrc.right + initrc.left,
+ "testid %d size-x change %d expected %d\n", index,
+ rc.right - rc.left - initrc.right + initrc.left, resize);
+ ok( resize == rc.bottom - rc.top - initrc.bottom + initrc.top,
+ "testid %d size-y change %d expected %d\n", index,
+ rc.bottom - rc.top - initrc.bottom + initrc.top, resize);
+ }
+ }else{
+ ok( resize == rc.right - rc.left - initrc.right + initrc.left,
+ "testid %d size-x change %d expected %d\n", index,
+ rc.right - rc.left - initrc.right + initrc.left, resize);
+ ok( resize == rc.bottom - rc.top - initrc.bottom + initrc.top,
+ "testid %d size-y change %d expected %d\n", index,
+ rc.bottom - rc.top - initrc.bottom + initrc.top, resize);
+ }
+ if( resize_testcases[index].testcontrols) {
+ int i;
+ RECT rc;
+ for( i = 0; i < nrctrls; i++) {
+ GetWindowRect( ctrls[i], &rc);
+ MapWindowPoints( NULL, parent, (LPPOINT) &rc, 2);
+ switch( ctrlids[i]){
+
+/* test if RECT R1, moved and sized result in R2 */
+#define TESTRECTS( R1, R2, Mx, My, Sx, Sy) \
+ ((R1).left + (Mx) ==(R2).left \
+ &&(R1).top + (My) ==(R2).top \
+ &&(R1).right + (Mx) + (Sx) == (R2).right \
+ &&(R1).bottom + (My) + (Sy) ==(R2).bottom)
+
+ /* sized horizontal and moved vertical */
+ case cmb1:
+ case edt1:
+ ok( TESTRECTS( ctrlrcs[i], rc, 0, 10, 10, 0) ||
+ broken(TESTRECTS( ctrlrcs[i], rc, 0, 10, 0, 0)),/*win98*/
+ "control id %03x should have sized horizontally and moved vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* sized horizontal and vertical */
+ case lst2:
+ ok( TESTRECTS( ctrlrcs[i], rc, 0, 0, 10, 10),
+ "control id %03x should have sized horizontally and vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* moved horizontal and vertical */
+ case IDCANCEL:
+ case pshHelp:
+ ok( TESTRECTS( ctrlrcs[i], rc, 10, 10, 0, 0) ||
+ broken(TESTRECTS( ctrlrcs[i], rc, 0, 10, 0, 0)),/*win98*/
+ "control id %03x should have moved horizontally and vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* moved vertically */
+ case chx1:
+ case stc2:
+ case stc3:
+ ok( TESTRECTS( ctrlrcs[i], rc, 0, 10, 0, 0),
+ "control id %03x should have moved vertically, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* resized horizontal */
+ case cmb2: /* aka IDC_LOOKIN */
+ ok( TESTRECTS( ctrlrcs[i], rc, 0, 0, 10, 0)||
+ TESTRECTS( ctrlrcs[i], rc, 0, 0, 0, 0), /* Vista and higher */
+ "control id %03x should have resized horizontally, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* non moving non sizing controls */
+ case stc4:
+ ok( TESTRECTS( rc, ctrlrcs[i], 0, 0, 0, 0),
+ "control id %03x was moved/resized, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* todo_wine: non moving non sizing controls */
+ case lst1:
+todo_wine
+ ok( TESTRECTS( rc, ctrlrcs[i], 0, 0, 0, 0),
+ "control id %03x was moved/resized, before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+ break;
+ /* don't test: id is not unique */
+ case IDOK:
+ case stc1:
+ case 0:
+ case -1:
+ break;
+ default:
+ trace("untested control id %03x before %d,%d-%d,%d after %d,%d-%d,%d\n",
+ ctrlids[i], ctrlrcs[i].left, ctrlrcs[i].top,
+ ctrlrcs[i].right, ctrlrcs[i].bottom,
+ rc.left, rc.top, rc.right, rc.bottom);
+#undef TESTRECTS
+#undef MAXNRCTRLS
+ }
+ }
+ }
+ KillTimer( dlg, 0);
+ PostMessage( parent, WM_COMMAND, IDCANCEL, 0);
+ }
+ count++;
+ }
+ break;
+ case WM_WINDOWPOSCHANGING:
+ {
+ WINDOWPOS *pwp = (WINDOWPOS *)lParam;
+ if( !index && pwp->hwndInsertAfter == HWND_BOTTOM){
+ gotSWP_bottom = 1;
+ ok( gotShowWindow == 0, "The WM_WINDOWPOSCHANGING message came after a WM_SHOWWINDOW message\n");
+ }
+ }
+ break;
+ case WM_SHOWWINDOW:
+ {
+ if( !index){
+ gotShowWindow = 1;
+ ok( gotSWP_bottom == 1, "No WM_WINDOWPOSCHANGING message came before a WM_SHOWWINDOW message\n");
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+static void test_resize(void)
+{
+ OPENFILENAME ofn = { sizeof(OPENFILENAME)};
+ char filename[1024] = {0};
+ DWORD ret;
+ int i;
+
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = 1024;
+ ofn.lpfnHook = (LPOFNHOOKPROC) resize_template_hook;
+ ofn.hInstance = GetModuleHandle(NULL);
+ ofn.lpTemplateName = "template_sz";
+ for( i = 0; resize_testcases[i].flags != 0xffffffff; i++) {
+ ofn.lCustData = i;
+ ofn.Flags = resize_testcases[i].flags |
+ OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE | OFN_SHOWHELP ;
+ ret = GetOpenFileName(&ofn);
+ ok(!ret, "GetOpenFileName returned %#x\n", ret);
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ }
+}
+
+/* test cases for control message IDOK */
+/* Show case for bug #19079 */
+static struct {
+ int retval; /* return code of the message handler */
+ BOOL setmsgresult; /* set the result in the DWLP_MSGRESULT */
+ BOOL usemsgokstr; /* use the FILEOKSTRING message instead of WM_NOTIFY:CDN_FILEOK */
+ BOOL do_subclass; /* subclass the dialog hook procedure */
+ BOOL expclose; /* is the dialog expected to close ? */
+ BOOL actclose; /* has the dialog actually closed ? */
+} ok_testcases[] = {
+ { 0, FALSE, FALSE, FALSE, TRUE},
+ { 0, TRUE, FALSE, FALSE, TRUE},
+ { 0, FALSE, FALSE, TRUE, TRUE},
+ { 0, TRUE, FALSE, TRUE, TRUE},
+ { 1, FALSE, FALSE, FALSE, TRUE},
+ { 1, TRUE, FALSE, FALSE, FALSE},
+ { 1, FALSE, FALSE, TRUE, FALSE},
+ { 1, TRUE, FALSE, TRUE, FALSE},
+ /* FILEOKSTRING tests */
+ { 1, TRUE, TRUE, FALSE, FALSE},
+ { 1, FALSE, TRUE, TRUE, FALSE},
+ /* mark the end */
+ { -1 }
+};
+
+/* test_ok_wndproc can be used as hook procedure or a subclass
+ * window proc for the file dialog */
+static LONG_PTR WINAPI test_ok_wndproc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HWND parent = GetParent( dlg);
+ static int index;
+ static UINT msgFILEOKSTRING;
+ if (msg == WM_INITDIALOG)
+ {
+ index = ((OPENFILENAME*)lParam)->lCustData;
+ ok_testcases[index].actclose = TRUE;
+ msgFILEOKSTRING = RegisterWindowMessageA( FILEOKSTRING);
+ }
+ if( msg == WM_NOTIFY) {
+ if(((LPNMHDR)lParam)->code == CDN_FOLDERCHANGE) {
+ SetTimer( dlg, 0, 100, 0);
+ PostMessage( parent, WM_COMMAND, IDOK, 0);
+ return FALSE;
+ } else if(((LPNMHDR)lParam)->code == CDN_FILEOK) {
+ if( ok_testcases[index].usemsgokstr)
+ return FALSE;
+ if( ok_testcases[index].setmsgresult)
+ SetWindowLongPtrA( dlg, DWLP_MSGRESULT, ok_testcases[index].retval);
+ return ok_testcases[index].retval;
+ }
+ }
+ if( msg == msgFILEOKSTRING) {
+ if( !ok_testcases[index].usemsgokstr)
+ return FALSE;
+ if( ok_testcases[index].setmsgresult)
+ SetWindowLongPtrA( dlg, DWLP_MSGRESULT, ok_testcases[index].retval);
+ return ok_testcases[index].retval;
+ }
+ if( msg == WM_TIMER) {
+ /* the dialog did not close automatically */
+ ok_testcases[index].actclose = FALSE;
+ KillTimer( dlg, 0);
+ PostMessage( parent, WM_COMMAND, IDCANCEL, 0);
+ return FALSE;
+ }
+ if( ok_testcases[index].do_subclass)
+ return DefWindowProc( dlg, msg, wParam, lParam);
+ return FALSE;
+}
+
+static LONG_PTR WINAPI ok_template_hook(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (msg == WM_SETFONT)
+ SetWindowLongPtrA( dlg, GWLP_WNDPROC, (LONG_PTR) test_ok_wndproc);
+ return FALSE;
+}
+
+static void test_ok(void)
+{
+ OPENFILENAME ofn = { sizeof(OPENFILENAME)};
+ char filename[1024] = {0};
+ char tmpfilename[ MAX_PATH];
+ char curdir[MAX_PATH];
+ int i;
+ DWORD ret;
+
+ ok(GetCurrentDirectoryA(sizeof(curdir), curdir) != 0, "Failed to get current dir err %d\n", GetLastError());
+ if (!GetTempFileNameA(".", "txt", 0, tmpfilename)) {
+ skip("Failed to create a temporary file name\n");
+ return;
+ }
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = 1024;
+ ofn.hInstance = GetModuleHandle(NULL);
+ ofn.lpTemplateName = "template1";
+ ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATE ;
+ for( i = 0; ok_testcases[i].retval != -1; i++) {
+ strcpy( filename, tmpfilename);
+ ofn.lCustData = i;
+ ofn.lpfnHook = ok_testcases[i].do_subclass
+ ? (LPOFNHOOKPROC) ok_template_hook
+ : (LPOFNHOOKPROC) test_ok_wndproc;
+ ret = GetOpenFileNameA(&ofn);
+ ok( ok_testcases[i].expclose == ok_testcases[i].actclose,
+ "testid %d: Open File dialog should %shave closed.\n", i,
+ ok_testcases[i].expclose ? "" : "NOT ");
+ ok(ret == ok_testcases[i].expclose, "testid %d: GetOpenFileName returned %#x\n", i, ret);
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ ok(SetCurrentDirectoryA(curdir), "Failed to restore current dir err %d\n", GetLastError());
+ }
+ ret = DeleteFileA( tmpfilename);
+ ok( ret, "Failed to delete temporary file %s err %d\n", tmpfilename, GetLastError());
+}
+
+/* test arranging with a custom template */
+typedef struct {
+ int x, y; /* left, top coordinates */
+ int cx, cy; /* width and height */
+} posz;
+static struct {
+ int nrcontrols; /* 0: no controls, 1: just the stc32 control 2: with button */
+ posz poszDlg;
+ posz poszStc32;
+ posz poszBtn;
+ DWORD ofnflags;
+} arrange_tests[] = {
+ /* do not change the first two cases: used to get the uncustomized sizes */
+ { 0, {0},{0},{0},0 },
+ { 0, {0},{0},{0}, OFN_SHOWHELP},
+ /* two tests with just a subdialog, no controls */
+ { 0, {0, 0, 316, 76},{0},{0},0 },
+ { 0, {0, 0, 100, 76},{0},{0}, OFN_SHOWHELP},
+ /* now with a control with id stc32 */
+ { 1, {0, 0, 316, 76} ,{0, 0, 204, 76,},{0},0 }, /* bug #17748*/
+ { 1, {0, 0, 316, 76} ,{0, 0, 204, 76,},{0}, OFN_SHOWHELP}, /* bug #17748*/
+ /* tests with size of the stc32 control higher or wider then the standard dialog */
+ { 1, {0, 0, 316, 170} ,{0, 0, 204, 170,},{0},0 },
+ { 1, {0, 0, 316, 165} ,{0, 0, 411, 165,},{0}, OFN_SHOWHELP },
+ /* move the stc32 control around */
+ { 1, {0, 0, 300, 100} ,{73, 17, 50, 50,},{0},0 },
+ /* add control */
+ { 2, {0, 0, 280, 100} ,{0, 0, 50, 50,},{300,20,30,30},0 },
+ /* enable resizing should make the dialog bigger */
+ { 0, {0},{0},{0}, OFN_SHOWHELP|OFN_ENABLESIZING},
+ /* mark the end */
+ { -1 }
+};
+
+static LONG_PTR WINAPI template_hook_arrange(HWND dlgChild, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int index, fixhelp;
+ static posz posz0[2];
+ static RECT clrcParent, clrcChild, rcStc32;
+ static HWND hwndStc32;
+ HWND dlgParent;
+
+ dlgParent = GetParent( dlgChild);
+ if (msg == WM_INITDIALOG) {
+ index = ((OPENFILENAME*)lParam)->lCustData;
+ /* get the positions before rearrangement */
+ GetClientRect( dlgParent, &clrcParent);
+ GetClientRect( dlgChild, &clrcChild);
+ hwndStc32 = GetDlgItem( dlgChild, stc32);
+ if( hwndStc32) GetWindowRect( hwndStc32, &rcStc32);
+ }
+ if (msg == WM_NOTIFY && ((LPNMHDR)lParam)->code == CDN_FOLDERCHANGE) {
+ RECT wrcParent;
+
+ GetWindowRect( dlgParent, &wrcParent);
+ /* the fist two "tests" just save the dialogs position, with and without
+ * help button */
+ if( index == 0) {
+ posz0[0].x = wrcParent.left;
+ posz0[0].y = wrcParent.top;
+ posz0[0].cx = wrcParent.right - wrcParent.left;
+ posz0[0].cy = wrcParent.bottom - wrcParent.top;
+ } else if( index == 1) {
+ posz0[1].x = wrcParent.left;
+ posz0[1].y = wrcParent.top;
+ posz0[1].cx = wrcParent.right - wrcParent.left;
+ posz0[1].cy = wrcParent.bottom - wrcParent.top;
+ fixhelp = posz0[1].cy - posz0[0].cy;
+ } else {
+ /* the real tests */
+ int withhelp;
+ int expectx, expecty;
+ DWORD style;
+
+ withhelp = (arrange_tests[index].ofnflags & OFN_SHOWHELP) != 0;
+ GetWindowRect( dlgParent, &wrcParent);
+ if( !hwndStc32) {
+ /* case with no custom subitem with stc32:
+ * default to all custom controls below the standard */
+ expecty = posz0[withhelp].cy + clrcChild.bottom;
+ expectx = posz0[withhelp].cx;
+ } else {
+ /* special case: there is a control with id stc32 */
+ /* expected height */
+ expecty = posz0[withhelp].cy;
+ if( rcStc32.bottom - rcStc32.top > clrcParent.bottom) {
+ expecty += clrcChild.bottom - clrcParent.bottom;
+ if( !withhelp) expecty += fixhelp;
+ }
+ else
+ expecty += clrcChild.bottom - ( rcStc32.bottom - rcStc32.top) ;
+ /* expected width */
+ expectx = posz0[withhelp].cx;
+ if( rcStc32.right - rcStc32.left > clrcParent.right) {
+ expectx += clrcChild.right - clrcParent.right;
+ }
+ else
+ expectx += clrcChild.right - ( rcStc32.right - rcStc32.left) ;
+ }
+ style = GetWindowLong( dlgParent, GWL_STYLE);
+ if( !(style & WS_SIZEBOX)) {
+ /* without the OFN_ENABLESIZING flag */
+ ok( wrcParent.bottom - wrcParent.top == expecty,
+ "Wrong height of dialog %d, expected %d\n",
+ wrcParent.bottom - wrcParent.top, expecty);
+ ok( wrcParent.right - wrcParent.left == expectx,
+ "Wrong width of dialog %d, expected %d\n",
+ wrcParent.right - wrcParent.left, expectx);
+ } else todo_wine {
+ /* with the OFN_ENABLESIZING flag */
+ ok( wrcParent.bottom - wrcParent.top > expecty,
+ "Wrong height of dialog %d, expected more than %d\n",
+ wrcParent.bottom - wrcParent.top, expecty);
+ ok( wrcParent.right - wrcParent.left > expectx,
+ "Wrong width of dialog %d, expected more than %d\n",
+ wrcParent.right - wrcParent.left, expectx);
+ }
+
+ }
+ PostMessage( dlgParent, WM_COMMAND, IDCANCEL, 0);
+ }
+ return 0;
+}
+
+static void test_arrange(void)
+{
+ OPENFILENAMEA ofn = {0};
+ char filename[1024] = {0};
+ DWORD ret;
+ HRSRC hRes;
+ HANDLE hDlgTmpl;
+ LPBYTE pv;
+ DLGTEMPLATE *template;
+ DLGITEMTEMPLATE *itemtemplateStc32, *itemtemplateBtn;
+ int i;
+
+ /* load subdialog template into memory */
+ hRes = FindResource( GetModuleHandle(NULL), "template_stc32", (LPSTR)RT_DIALOG);
+ hDlgTmpl = LoadResource( GetModuleHandle(NULL), hRes );
+ /* get pointers to the structures for the dialog and the controls */
+ pv = LockResource( hDlgTmpl );
+ template = (DLGTEMPLATE*)pv;
+ if( template->x != 11111) {
+ win_skip("could not find the dialog template\n");
+ return;
+ }
+ /* skip dialog template, menu, class and title */
+ pv += sizeof(DLGTEMPLATE);
+ pv += 3 * sizeof(WORD);
+ /* skip font info */
+ while( *(WORD*)pv)
+ pv += sizeof(WORD);
+ pv += sizeof(WORD);
+ /* align on 32 bit boundaries */
+ pv = (LPBYTE)(((UINT_PTR)pv + 3 ) & ~3);
+ itemtemplateStc32 = (DLGITEMTEMPLATE*)pv;
+ if( itemtemplateStc32->x != 22222) {
+ win_skip("could not find the first item template\n");
+ return;
+ }
+ /* skip itemtemplate, class, title and creation data */
+ pv += sizeof(DLGITEMTEMPLATE);
+ pv += 4 * sizeof(WORD);
+ /* align on 32 bit boundaries */
+ pv = (LPBYTE)(((UINT_PTR)pv + 3 ) & ~3);
+ itemtemplateBtn = (DLGITEMTEMPLATE*)pv;
+ if( itemtemplateBtn->x != 12345) {
+ win_skip("could not find the second item template\n");
+ return;
+ }
+
+ ofn.lStructSize = sizeof(ofn);
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = 1024;
+ ofn.lpfnHook = (LPOFNHOOKPROC)template_hook_arrange;
+ ofn.hInstance = hDlgTmpl;
+ ofn.lpstrFilter="text\0*.txt\0All\0*\0\0";
+ for( i = 0; arrange_tests[i].nrcontrols != -1; i++) {
+ ofn.lCustData = i;
+ ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER| OFN_ENABLETEMPLATEHANDLE | OFN_HIDEREADONLY |
+ arrange_tests[i].ofnflags;
+ template->cdit = arrange_tests[i].nrcontrols;
+ template->x = arrange_tests[i].poszDlg.x;
+ template->y = arrange_tests[i].poszDlg.y;
+ template->cx = arrange_tests[i].poszDlg.cx;
+ template->cy = arrange_tests[i].poszDlg.cy;
+ itemtemplateStc32->x = arrange_tests[i].poszStc32.x;
+ itemtemplateStc32->y = arrange_tests[i].poszStc32.y;
+ itemtemplateStc32->cx = arrange_tests[i].poszStc32.cx;
+ itemtemplateStc32->cy = arrange_tests[i].poszStc32.cy;
+ itemtemplateBtn->x = arrange_tests[i].poszBtn.x;
+ itemtemplateBtn->y = arrange_tests[i].poszBtn.y;
+ itemtemplateBtn->cx = arrange_tests[i].poszBtn.cx;
+ itemtemplateBtn->cy = arrange_tests[i].poszBtn.cy;
+ ret = GetOpenFileNameA(&ofn);
+ ok(!ret, "GetOpenFileNameA returned %#x\n", ret);
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ }
+}
+
+static CHAR SYSDIR[MAX_PATH];
+
+static UINT_PTR CALLBACK path_hook_proc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ LPNMHDR nmh;
+
+ if( msg == WM_NOTIFY)
+ {
+ nmh = (LPNMHDR) lParam;
+ if( nmh->code == CDN_INITDONE)
+ {
+ PostMessage( GetParent(hDlg), WM_COMMAND, IDCANCEL, FALSE);
+ }
+ else if ( nmh->code == CDN_FOLDERCHANGE)
+ {
+ char buf[1024];
+ int ret;
+
+ memset(buf, 0x66, sizeof(buf));
+ ret = SendMessageA( GetParent(hDlg), CDM_GETFOLDERPATH, sizeof(buf), (LPARAM)buf);
+ ok(!lstrcmpiA(SYSDIR, buf), "Expected '%s', got '%s'\n", SYSDIR, buf);
+ ok(lstrlenA(SYSDIR) + 1 == ret, "Expected %d, got %d\n", lstrlenA(SYSDIR) + 1, ret);
+ }
+ }
+
+ return 0;
+}
+
+static void test_getfolderpath(void)
+{
+ OPENFILENAMEA ofn;
+ BOOL result;
+ char szFileName[MAX_PATH] = "";
+ char szInitialDir[MAX_PATH];
+
+ /* We need to pick a different directory as the other tests because of new
+ * Windows 7 behavior.
+ */
+ GetSystemDirectory(szInitialDir, MAX_PATH);
+ lstrcpyA(SYSDIR, szInitialDir);
+
+ ZeroMemory(&ofn, sizeof(ofn));
+
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = NULL;
+ ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
+ ofn.lpstrFile = szFileName;
+ ofn.nMaxFile = MAX_PATH;
+ ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLEHOOK;
+ ofn.lpstrDefExt = "txt";
+ ofn.lpfnHook = path_hook_proc;
+ ofn.lpstrInitialDir = szInitialDir;
+
+ result = GetOpenFileNameA(&ofn);
+ ok(0 == result, "expected 0, got %d\n", result);
+ ok(0 == CommDlgExtendedError(), "expected 0, got %d\n",
+ CommDlgExtendedError());
+
+ result = GetSaveFileNameA(&ofn);
+ ok(0 == result, "expected 0, got %d\n", result);
+ ok(0 == CommDlgExtendedError(), "expected 0, got %d\n",
+ CommDlgExtendedError());
+}
+
+static void test_resizable2(void)
+{
+ OPENFILENAMEA ofn = {0};
+ char filename[1024] = "pls press Enter if sizable, Esc otherwise";
+ DWORD ret;
+
+ /* interactive because there is no hook function */
+ if( !winetest_interactive) {
+ skip( "some interactive resizable dialog tests (set WINETEST_INTERACTIVE=1)\n");
+ return;
+ }
+ ofn.lStructSize = sizeof(ofn);
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = 1024;
+ ofn.lpfnHook = NULL;
+ ofn.hInstance = GetModuleHandleA(NULL);
+ ofn.lpTemplateName = "template1";
+ ofn.Flags = OFN_EXPLORER;
+#define ISSIZABLE 1
+ ret = GetOpenFileNameA(&ofn);
+ ok( ret == ISSIZABLE, "File Dialog should have been sizable\n");
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ ofn.Flags = OFN_EXPLORER | OFN_ENABLETEMPLATE;
+ ret = GetOpenFileNameA(&ofn);
+ ok( ret != ISSIZABLE, "File Dialog should NOT have been sizable\n");
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ ofn.Flags = OFN_EXPLORER | OFN_ENABLETEMPLATEHANDLE;
+ ofn.hInstance = LoadResource( GetModuleHandle(NULL), FindResource( GetModuleHandle(NULL), "template1", (LPSTR)RT_DIALOG));
+ ofn.lpTemplateName = NULL;
+ ret = GetOpenFileNameA(&ofn);
+ ok( ret != ISSIZABLE, "File Dialog should NOT have been sizable\n");
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+ ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK;
+ ret = GetOpenFileNameA(&ofn);
+ ok( ret != ISSIZABLE, "File Dialog should NOT have been sizable\n");
+ ret = CommDlgExtendedError();
+ ok(!ret, "CommDlgExtendedError returned %#x\n", ret);
+#undef ISSIZABLE
+}
+
START_TEST(filedlg)
{
test_DialogCancel();
test_create_view_window2();
test_create_view_template();
+ test_arrange();
+ test_resize();
+ test_ok();
+ test_getfolderpath();
+ if( resizesupported) test_resizable2();
}
diff --git a/rostests/winetests/comdlg32/fontdlg.c b/rostests/winetests/comdlg32/fontdlg.c
new file mode 100644
index 00000000000..57c1d908214
--- /dev/null
+++ b/rostests/winetests/comdlg32/fontdlg.c
@@ -0,0 +1,150 @@
+/*
+ * Unit test suite for comdlg32 API functions: font dialogs
+ *
+ * Copyright 2009 Vincent Povirk for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ */
+
+#include
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wingdi.h"
+#include "winspool.h"
+#include "winuser.h"
+#include "objbase.h"
+
+#include "commdlg.h"
+
+#include "wine/test.h"
+
+static int get_dpiy(void)
+{
+ HDC hdc;
+ int result;
+
+ hdc = GetDC(0);
+ result = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(0, hdc);
+
+ return result;
+}
+
+static HDC get_printer_ic(void)
+{
+ PRINTER_INFO_2A *info;
+ DWORD info_size, num_printers=0;
+ BOOL ret;
+ HDC result=NULL;
+
+ EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &info_size, &num_printers);
+
+ if (info_size == 0)
+ return NULL;
+
+ info = HeapAlloc(GetProcessHeap(), 0, info_size);
+
+ ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)info, info_size, &info_size, &num_printers);
+
+ if (ret)
+ result = CreateICA(info->pDriverName, info->pPrinterName, NULL, NULL);
+
+ HeapFree(GetProcessHeap(), 0, info);
+
+ return result;
+}
+
+static UINT_PTR CALLBACK CFHookProcOK(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ PostMessageA(hdlg, WM_COMMAND, IDOK, FALSE);
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static void test_ChooseFontA(void)
+{
+ LOGFONTA lfa;
+ CHOOSEFONTA cfa;
+ BOOL ret;
+ int dpiy = get_dpiy();
+ int expected_pointsize, expected_lfheight;
+ HDC printer_ic;
+
+ memset(&lfa, 0, sizeof(LOGFONTA));
+ lfa.lfHeight = -16;
+ lfa.lfWeight = FW_NORMAL;
+ strcpy(lfa.lfFaceName, "Symbol");
+
+ memset(&cfa, 0, sizeof(CHOOSEFONTA));
+ cfa.lStructSize = sizeof(cfa);
+ cfa.lpLogFont = &lfa;
+ cfa.Flags = CF_ENABLEHOOK|CF_INITTOLOGFONTSTRUCT|CF_SCREENFONTS;
+ cfa.lpfnHook = CFHookProcOK;
+
+ ret = ChooseFontA(&cfa);
+
+ expected_pointsize = MulDiv(16, 72, dpiy) * 10;
+ expected_lfheight = -MulDiv(expected_pointsize, dpiy, 720);
+
+ ok(ret == TRUE, "ChooseFontA returned FALSE\n");
+ ok(cfa.iPointSize == expected_pointsize, "Expected %i, got %i\n", expected_pointsize, cfa.iPointSize);
+ ok(lfa.lfHeight == expected_lfheight, "Expected %i, got %i\n", expected_lfheight, lfa.lfHeight);
+ ok(lfa.lfWeight == FW_NORMAL, "Expected FW_NORMAL, got %i\n", lfa.lfWeight);
+ ok(strcmp(lfa.lfFaceName, "Symbol") == 0, "Expected Symbol, got %s\n", lfa.lfFaceName);
+
+ printer_ic = get_printer_ic();
+ if (!printer_ic)
+ skip("can't get a DC for a local printer\n");
+ else
+ {
+ memset(&lfa, 0, sizeof(LOGFONTA));
+ lfa.lfHeight = -16;
+ lfa.lfWeight = FW_NORMAL;
+ strcpy(lfa.lfFaceName, "Symbol");
+
+ memset(&cfa, 0, sizeof(CHOOSEFONTA));
+ cfa.lStructSize = sizeof(cfa);
+ cfa.lpLogFont = &lfa;
+ cfa.Flags = CF_ENABLEHOOK|CF_INITTOLOGFONTSTRUCT|CF_PRINTERFONTS;
+ cfa.hDC = printer_ic;
+ cfa.lpfnHook = CFHookProcOK;
+
+ ret = ChooseFontA(&cfa);
+
+ expected_pointsize = MulDiv(16, 72, dpiy) * 10;
+ expected_lfheight = -MulDiv(expected_pointsize, dpiy, 720);
+
+ ok(ret == TRUE, "ChooseFontA returned FALSE\n");
+ ok(cfa.iPointSize == expected_pointsize, "Expected %i, got %i\n", expected_pointsize, cfa.iPointSize);
+ ok(lfa.lfHeight == expected_lfheight, "Expected %i, got %i\n", expected_lfheight, lfa.lfHeight);
+ ok(lfa.lfWeight == FW_NORMAL, "Expected FW_NORMAL, got %i\n", lfa.lfWeight);
+ ok(strcmp(lfa.lfFaceName, "Symbol") == 0, "Expected Symbol, got %s\n", lfa.lfFaceName);
+
+ DeleteDC(printer_ic);
+ }
+}
+
+START_TEST(fontdlg)
+{
+ test_ChooseFontA();
+}
diff --git a/rostests/winetests/comdlg32/printdlg.c b/rostests/winetests/comdlg32/printdlg.c
index ec63da9a6c7..f021b019299 100644
--- a/rostests/winetests/comdlg32/printdlg.c
+++ b/rostests/winetests/comdlg32/printdlg.c
@@ -246,6 +246,11 @@ static void test_PrintDlgExW(void)
PrintDlg(NULL);
SetLastError(0xdeadbeef);
res = pPrintDlgExW(NULL);
+ if(res == E_NOTIMPL)
+ {
+ win_skip("PrintDlgExW returns not implemented\n");
+ return;
+ }
ok( (res == E_INVALIDARG),
"got 0x%x with %u and %u (expected 'E_INVALIDARG')\n",
res, GetLastError(), CommDlgExtendedError());
@@ -318,6 +323,8 @@ static void test_abort_proc(void)
ok(DeleteFileA(filename), "Failed to delete temporary file\n");
return;
}
+ GlobalFree(pd.hDevMode);
+ GlobalFree(pd.hDevNames);
ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n");
if (!(print_dc = pd.hDC))
@@ -346,25 +353,19 @@ static void test_abort_proc(void)
goto end;
}
- ok(abort_proc_called, "AbortProc didn't get called by StartDoc.\n");
- abort_proc_called = FALSE;
+ /* StartDoc may or may not call abort proc */
+ abort_proc_called = FALSE;
ok(StartPage(print_dc) > 0, "StartPage failed\n");
ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n");
abort_proc_called = FALSE;
+ /* following functions sometimes call abort proc too */
ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n");
- ok(!abort_proc_called, "AbortProc got called unexpectedly by StretchBlt.\n");
- abort_proc_called = FALSE;
-
ok(EndPage(print_dc) > 0, "EndPage failed\n");
- ok(!abort_proc_called, "AbortProc got called unexpectedly by EndPage.\n");
- abort_proc_called = FALSE;
-
ok(EndDoc(print_dc) > 0, "EndDoc failed\n");
- ok(!abort_proc_called, "AbortProc got called unexpectedly by EndDoc.\n");
- abort_proc_called = FALSE;
+ abort_proc_called = FALSE;
ok(DeleteDC(print_dc), "DeleteDC failed\n");
ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n");
abort_proc_called = FALSE;
diff --git a/rostests/winetests/comdlg32/rsrc.rc b/rostests/winetests/comdlg32/rsrc.rc
index 51415fddb26..65e7972ffa4 100644
--- a/rostests/winetests/comdlg32/rsrc.rc
+++ b/rostests/winetests/comdlg32/rsrc.rc
@@ -32,3 +32,28 @@ FONT 8, "MS Shell Dlg"
LTEXT "",-1,28,16,204,31
EDITTEXT 56,65,2,200,12,ES_AUTOHSCROLL
}
+
+/* Used by the resize file dialog tests.
+ * Keep this template small or get failures
+ * resizing on small desk tops.
+ * This will work with 640x480 pixels
+ */
+TEMPLATE_SZ DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 300, 40
+STYLE WS_CHILD | WS_CLIPSIBLINGS
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Path:",-1,28,4,36,8
+ LTEXT "Text1",-1,4,16,20,40
+ LTEXT "Text2",-1,232,20,65,8
+ LTEXT "",-1,28,16,204,31
+ EDITTEXT 56,65,2,200,12,ES_AUTOHSCROLL
+}
+
+/* note: the test program will modify coordinates and nr of controls in this template */
+TEMPLATE_STC32 DIALOG LOADONCALL MOVEABLE DISCARDABLE 11111, 0, 316, 76
+STYLE WS_CHILD | WS_CLIPSIBLINGS
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "", 1119, 22222, 0, 204, 76
+ PUSHBUTTON "TEST", -1, 12345, 0, 20, 20
+}
diff --git a/rostests/winetests/crypt32/chain.c b/rostests/winetests/crypt32/chain.c
index a626b82c4fe..f9ccaed78b1 100644
--- a/rostests/winetests/crypt32/chain.c
+++ b/rostests/winetests/crypt32/chain.c
@@ -58,6 +58,8 @@ static VOID (WINAPI *pCertFreeCertificateChain)(PCCERT_CHAIN_CONTEXT);
static VOID (WINAPI *pCertFreeCertificateChainEngine)(HCERTCHAINENGINE);
static BOOL (WINAPI *pCertVerifyCertificateChainPolicy)(LPCSTR,PCCERT_CHAIN_CONTEXT,PCERT_CHAIN_POLICY_PARA,PCERT_CHAIN_POLICY_STATUS);
+#define IS_INTOID(x) (((ULONG_PTR)(x) >> 16) == 0)
+
static void testCreateCertChainEngine(void)
{
@@ -3883,19 +3885,19 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
if (check->todo & TODO_POLICY)
todo_wine ok(ret,
"%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex, GetLastError());
else
{
if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
{
skip("%d: missing policy %s, skipping test\n", testIndex,
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)));
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy);
pCertFreeCertificateChain(chain);
return;
}
ok(ret, "%s[%d]: CertVerifyCertificateChainPolicy failed: %08x\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)), testIndex,
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy, testIndex,
GetLastError());
}
if (ret)
@@ -3906,7 +3908,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
(check->brokenStatus && broken(policyStatus.dwError ==
check->brokenStatus->dwError)),
"%s[%d]: expected %08x, got %08x\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex, check->status.dwError, policyStatus.dwError);
else
ok(policyStatus.dwError == check->status.dwError ||
@@ -3914,12 +3916,12 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
(check->brokenStatus && broken(policyStatus.dwError ==
check->brokenStatus->dwError)),
"%s[%d]: expected %08x, got %08x\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex, check->status.dwError, policyStatus.dwError);
if (policyStatus.dwError != check->status.dwError)
{
skip("%s[%d]: error %08x doesn't match expected %08x, not checking indexes\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex, policyStatus.dwError, check->status.dwError);
pCertFreeCertificateChain(chain);
return;
@@ -3930,7 +3932,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
(check->brokenStatus && broken(policyStatus.lChainIndex ==
check->brokenStatus->lChainIndex)),
"%s[%d]: expected %d, got %d\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex, check->status.lChainIndex,
policyStatus.lChainIndex);
else
@@ -3938,7 +3940,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
(check->brokenStatus && broken(policyStatus.lChainIndex ==
check->brokenStatus->lChainIndex)),
"%s[%d]: expected %d, got %d\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex,
check->status.lChainIndex, policyStatus.lChainIndex);
if (check->todo & TODO_ELEMENTS)
@@ -3947,7 +3949,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
(check->brokenStatus && broken(policyStatus.lElementIndex ==
check->brokenStatus->lElementIndex)),
"%s[%d]: expected %d, got %d\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex,
check->status.lElementIndex, policyStatus.lElementIndex);
else
@@ -3955,7 +3957,7 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check,
(check->brokenStatus && broken(policyStatus.lElementIndex ==
check->brokenStatus->lElementIndex)),
"%s[%d]: expected %d, got %d\n",
- HIWORD(policy) ? policy : num_to_str(LOWORD(policy)),
+ IS_INTOID(policy) ? num_to_str(LOWORD(policy)) : policy,
testIndex,
check->status.lElementIndex, policyStatus.lElementIndex);
}
diff --git a/rostests/winetests/crypt32/main.c b/rostests/winetests/crypt32/main.c
index 9b622bbbd08..7c11e8e2ee3 100644
--- a/rostests/winetests/crypt32/main.c
+++ b/rostests/winetests/crypt32/main.c
@@ -254,10 +254,8 @@ static void test_cryptTls(void)
ret = pI_CryptFreeTls(index, 0);
ok(ret, "I_CryptFreeTls failed: %08x\n", GetLastError());
ret = pI_CryptFreeTls(index, 0);
- /* Not sure if this fails because TlsFree should fail, so leave as
- * todo for now.
- */
- todo_wine ok(!ret && GetLastError() == E_INVALIDARG,
+ ok(!ret, "I_CryptFreeTls succeeded\n");
+ ok(GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
}
/* Similar pass, check I_CryptDetachTls */
diff --git a/rostests/winetests/crypt32/msg.c b/rostests/winetests/crypt32/msg.c
index 8ab5625fd8e..39662ebe8f2 100644
--- a/rostests/winetests/crypt32/msg.c
+++ b/rostests/winetests/crypt32/msg.c
@@ -2572,8 +2572,8 @@ static void test_decode_msg_get_param(void)
sizeof(signedKeyIdEmptyContent), TRUE);
if (!ret && GetLastError() == OSS_DATA_ERROR)
{
- /* Subsequent tests crashes on some Win9x, so bail out */
CryptMsgClose(msg);
+ win_skip("Subsequent tests crash on some Win9x\n");
return;
}
ok(ret, "CryptMsgUpdate failed: %08x\n", GetLastError());
diff --git a/rostests/winetests/gdiplus/brush.c b/rostests/winetests/gdiplus/brush.c
index 0ee4dd485a2..0effcf40fd6 100644
--- a/rostests/winetests/gdiplus/brush.c
+++ b/rostests/winetests/gdiplus/brush.c
@@ -646,6 +646,61 @@ static void test_linelinearblend(void)
expect(Ok, status);
}
+static void test_gradientsurroundcolorcount(void)
+{
+ GpStatus status;
+ GpPathGradient *grad;
+ ARGB *color;
+ INT count = 3;
+
+ status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad);
+ expect(Ok, status);
+
+ color = GdipAlloc(sizeof(ARGB[3]));
+
+ status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
+ expect(InvalidParameter, status);
+ GdipFree(color);
+
+ count = 2;
+
+ color = GdipAlloc(sizeof(ARGB[2]));
+
+ color[0] = 0x00ff0000;
+ color[1] = 0x0000ff00;
+
+ status = GdipSetPathGradientSurroundColorsWithCount(NULL, color, &count);
+ expect(InvalidParameter, status);
+
+ status = GdipSetPathGradientSurroundColorsWithCount(grad, NULL, &count);
+ expect(InvalidParameter, status);
+
+ /* WinXP crashes on this test */
+ if(0)
+ {
+ status = GdipSetPathGradientSurroundColorsWithCount(grad, color, NULL);
+ expect(InvalidParameter, status);
+ }
+
+ status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
+ todo_wine expect(Ok, status);
+ expect(2, count);
+
+ status = GdipGetPathGradientSurroundColorCount(NULL, &count);
+ expect(InvalidParameter, status);
+
+ status = GdipGetPathGradientSurroundColorCount(grad, NULL);
+ expect(InvalidParameter, status);
+
+ count = 0;
+ status = GdipGetPathGradientSurroundColorCount(grad, &count);
+ todo_wine expect(Ok, status);
+ todo_wine expect(2, count);
+
+ GdipFree(color);
+ GdipDeleteBrush((GpBrush*)grad);
+}
+
START_TEST(brush)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -669,6 +724,7 @@ START_TEST(brush)
test_gradientgetrect();
test_lineblend();
test_linelinearblend();
+ test_gradientsurroundcolorcount();
GdiplusShutdown(gdiplusToken);
}
diff --git a/rostests/winetests/gdiplus/font.c b/rostests/winetests/gdiplus/font.c
index 7b95d4c55ab..80f11bc0032 100644
--- a/rostests/winetests/gdiplus/font.c
+++ b/rostests/winetests/gdiplus/font.c
@@ -18,11 +18,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include
+
#include "windows.h"
#include "gdiplus.h"
#include "wine/test.h"
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
+#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
static const WCHAR arial[] = {'A','r','i','a','l','\0'};
static const WCHAR nonexistent[] = {'T','h','i','s','F','o','n','t','s','h','o','u','l','d','N','o','t','E','x','i','s','t','\0'};
@@ -189,12 +192,9 @@ static void test_fontfamily (void)
expect (FontFamilyNotFound, stat);
/* Bitmap fonts are not found */
-todo_wine
-{
stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
expect (FontFamilyNotFound, stat);
if(stat == Ok) GdipDeleteFontFamily(family);
-}
stat = GdipCreateFontFamilyFromName (arial, NULL, &family);
if(stat == FontFamilyNotFound)
@@ -345,6 +345,78 @@ static void test_installedfonts (void)
ok (collection != NULL, "got NULL font collection\n");
}
+static void test_heightgivendpi(void)
+{
+ GpStatus stat;
+ GpFont* font = NULL;
+ GpFontFamily* fontfamily = NULL;
+ REAL height;
+
+ stat = GdipCreateFontFamilyFromName(arial, NULL, &fontfamily);
+ if(stat == FontFamilyNotFound)
+ {
+ skip("Arial not installed\n");
+ return;
+ }
+ expect(Ok, stat);
+
+ stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
+ expect(Ok, stat);
+
+ stat = GdipGetFontHeightGivenDPI(NULL, 96, &height);
+ expect(InvalidParameter, stat);
+
+ stat = GdipGetFontHeightGivenDPI(font, 96, NULL);
+ expect(InvalidParameter, stat);
+
+ stat = GdipGetFontHeightGivenDPI(font, 96, &height);
+ expect(Ok, stat);
+ expectf((REAL)34.497070, height);
+ GdipDeleteFont(font);
+
+ height = 12345;
+ stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitWorld, &font);
+ expect(Ok, stat);
+ stat = GdipGetFontHeightGivenDPI(font, 96, &height);
+ expect(Ok, stat);
+ expectf((REAL)34.497070, height);
+ GdipDeleteFont(font);
+
+ height = 12345;
+ stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPoint, &font);
+ expect(Ok, stat);
+ stat = GdipGetFontHeightGivenDPI(font, 96, &height);
+ expect(Ok, stat);
+ expectf((REAL)45.996094, height);
+ GdipDeleteFont(font);
+
+ height = 12345;
+ stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitInch, &font);
+ expect(Ok, stat);
+ stat = GdipGetFontHeightGivenDPI(font, 96, &height);
+ expect(Ok, stat);
+ expectf((REAL)3311.718750, height);
+ GdipDeleteFont(font);
+
+ height = 12345;
+ stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitDocument, &font);
+ expect(Ok, stat);
+ stat = GdipGetFontHeightGivenDPI(font, 96, &height);
+ expect(Ok, stat);
+ expectf((REAL)11.039062, height);
+ GdipDeleteFont(font);
+
+ height = 12345;
+ stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitMillimeter, &font);
+ expect(Ok, stat);
+ stat = GdipGetFontHeightGivenDPI(font, 96, &height);
+ expect(Ok, stat);
+ expectf((REAL)130.382614, height);
+ GdipDeleteFont(font);
+
+ GdipDeleteFontFamily(fontfamily);
+}
+
START_TEST(font)
{
struct GdiplusStartupInput gdiplusStartupInput;
@@ -363,6 +435,7 @@ START_TEST(font)
test_fontfamily_properties();
test_getgenerics();
test_installedfonts();
+ test_heightgivendpi();
GdiplusShutdown(gdiplusToken);
}
diff --git a/rostests/winetests/gdiplus/graphics.c b/rostests/winetests/gdiplus/graphics.c
index b2dc9b299fb..57ce638093c 100644
--- a/rostests/winetests/gdiplus/graphics.c
+++ b/rostests/winetests/gdiplus/graphics.c
@@ -25,14 +25,17 @@
#include
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
-#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
+#define expectf_(expected, got, precision) ok(fabs(expected - got) < precision, "Expected %.2f, got %.2f\n", expected, got)
+#define expectf(expected, got) expectf_(expected, got, 0.0001)
#define TABLE_LEN (23)
+static HWND hwnd;
+
static void test_constructor_destructor(void)
{
GpStatus stat;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
stat = GdipCreateFromHDC(NULL, &graphics);
expect(OutOfMemory, stat);
@@ -56,7 +59,7 @@ static void test_constructor_destructor(void)
stat = GdipDeleteGraphics(NULL);
expect(InvalidParameter, stat);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
typedef struct node{
@@ -115,7 +118,7 @@ static void test_save_restore(void)
InterpolationMode mode;
GpGraphics *graphics1, *graphics2;
node * state_log = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
state_a = state_b = state_c = 0xdeadbeef;
/* Invalid saving. */
@@ -224,7 +227,7 @@ static void test_save_restore(void)
todo_wine
check_no_duplicates(state_log);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawArc(void)
@@ -232,7 +235,7 @@ static void test_GdipDrawArc(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
/* make a graphics object and pen object */
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -268,7 +271,7 @@ static void test_GdipDrawArc(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawArcI(void)
@@ -276,7 +279,7 @@ static void test_GdipDrawArcI(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
/* make a graphics object and pen object */
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -312,7 +315,7 @@ static void test_GdipDrawArcI(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_BeginContainer2(void)
@@ -334,7 +337,7 @@ static void test_BeginContainer2(void)
GpStatus status;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -497,7 +500,7 @@ static void test_BeginContainer2(void)
expect(Ok, status);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawBezierI(void)
@@ -505,7 +508,7 @@ static void test_GdipDrawBezierI(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
/* make a graphics object and pen object */
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -535,7 +538,7 @@ static void test_GdipDrawBezierI(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawCurve3(void)
@@ -543,7 +546,7 @@ static void test_GdipDrawCurve3(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPointF points[3];
points[0].X = 0;
@@ -615,7 +618,7 @@ static void test_GdipDrawCurve3(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawCurve3I(void)
@@ -623,7 +626,7 @@ static void test_GdipDrawCurve3I(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPoint points[3];
points[0].X = 0;
@@ -695,7 +698,7 @@ static void test_GdipDrawCurve3I(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawCurve2(void)
@@ -703,7 +706,7 @@ static void test_GdipDrawCurve2(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPointF points[3];
points[0].X = 0;
@@ -762,7 +765,7 @@ static void test_GdipDrawCurve2(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawCurve2I(void)
@@ -770,7 +773,7 @@ static void test_GdipDrawCurve2I(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPoint points[3];
points[0].X = 0;
@@ -829,7 +832,7 @@ static void test_GdipDrawCurve2I(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawCurve(void)
@@ -837,7 +840,7 @@ static void test_GdipDrawCurve(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPointF points[3];
points[0].X = 0;
@@ -890,7 +893,7 @@ static void test_GdipDrawCurve(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawCurveI(void)
@@ -898,7 +901,7 @@ static void test_GdipDrawCurveI(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPoint points[3];
points[0].X = 0;
@@ -951,7 +954,7 @@ static void test_GdipDrawCurveI(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawLineI(void)
@@ -959,7 +962,7 @@ static void test_GdipDrawLineI(void)
GpStatus status;
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
/* make a graphics object and pen object */
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -989,7 +992,7 @@ static void test_GdipDrawLineI(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawLinesI(void)
@@ -998,7 +1001,7 @@ static void test_GdipDrawLinesI(void)
GpGraphics *graphics = NULL;
GpPen *pen = NULL;
GpPoint *ptf = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
/* make a graphics object and pen object */
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -1041,7 +1044,7 @@ static void test_GdipDrawLinesI(void)
GdipDeletePen(pen);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_Get_Release_DC(void)
@@ -1051,7 +1054,7 @@ static void test_Get_Release_DC(void)
GpPen *pen;
GpSolidFill *brush;
GpPath *path;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
HDC retdc;
REAL r;
CompositingQuality quality;
@@ -1345,14 +1348,14 @@ static void test_Get_Release_DC(void)
GdipDeleteMatrix(m);
DeleteObject(hrgn);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_transformpoints(void)
{
GpStatus status;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpPointF ptf[2];
GpPoint pt[2];
@@ -1465,14 +1468,14 @@ static void test_transformpoints(void)
expect(18, pt[1].Y);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_get_set_clip(void)
{
GpStatus status;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpRegion *clip;
GpRectF rect;
BOOL res;
@@ -1544,14 +1547,14 @@ static void test_get_set_clip(void)
GdipDeleteRegion(clip);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_isempty(void)
{
GpStatus status;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpRegion *clip;
BOOL res;
@@ -1578,7 +1581,7 @@ static void test_isempty(void)
GdipDeleteRegion(clip);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_clear(void)
@@ -1592,7 +1595,7 @@ static void test_clear(void)
static void test_textcontrast(void)
{
GpStatus status;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpGraphics *graphics;
UINT contrast;
@@ -1608,7 +1611,7 @@ static void test_textcontrast(void)
expect(4, contrast);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipDrawString(void)
@@ -1620,7 +1623,7 @@ static void test_GdipDrawString(void)
GpStringFormat *format;
GpBrush *brush;
LOGFONTA logfont;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
static const WCHAR string[] = {'T','e','s','t',0};
memset(&logfont,0,sizeof(logfont));
@@ -1658,7 +1661,7 @@ static void test_GdipDrawString(void)
GdipDeleteFont(fnt);
GdipDeleteStringFormat(format);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipGetVisibleClipBounds_screen(void)
@@ -1758,36 +1761,10 @@ static void test_GdipGetVisibleClipBounds_window(void)
GpGraphics *graphics = NULL;
GpRectF rectf, window, exp, clipr;
GpRect recti;
- HWND hwnd;
- WNDCLASSA class;
HDC hdc;
PAINTSTRUCT ps;
- HINSTANCE hInstance = GetModuleHandle(NULL);
RECT wnd_rect;
- window.X = 0;
- window.Y = 0;
- window.Width = 200;
- window.Height = 300;
-
- class.lpszClassName = "ClipBoundsTestClass";
- class.style = CS_HREDRAW | CS_VREDRAW;
- class.lpfnWndProc = DefWindowProcA;
- class.hInstance = hInstance;
- class.hIcon = LoadIcon(0, IDI_APPLICATION);
- class.hCursor = LoadCursor(NULL, IDC_ARROW);
- class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- class.lpszMenuName = 0;
- class.cbClsExtra = 0;
- class.cbWndExtra = 0;
- RegisterClass(&class);
-
- hwnd = CreateWindow(class.lpszClassName, "ClipboundsTest",
- WS_OVERLAPPEDWINDOW, window.X, window.Y, window.Width, window.Height,
- NULL, NULL, hInstance, NULL);
-
- ok(hwnd != NULL, "Expected window to be created\n");
-
/* get client area size */
ok(GetClientRect(hwnd, &wnd_rect), "GetClientRect should have succeeded\n");
window.X = wnd_rect.left;
@@ -1870,7 +1847,6 @@ static void test_GdipGetVisibleClipBounds_window(void)
GdipDeleteGraphics(graphics);
EndPaint(hwnd, &ps);
- DestroyWindow(hwnd);
}
static void test_GdipGetVisibleClipBounds(void)
@@ -1878,7 +1854,7 @@ static void test_GdipGetVisibleClipBounds(void)
GpGraphics* graphics = NULL;
GpRectF rectf;
GpRect rect;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
GpStatus status;
status = GdipCreateFromHDC(hdc, &graphics);
@@ -1899,7 +1875,7 @@ static void test_GdipGetVisibleClipBounds(void)
expect(InvalidParameter, status);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
test_GdipGetVisibleClipBounds_screen();
test_GdipGetVisibleClipBounds_window();
@@ -1933,7 +1909,7 @@ static void test_GdipIsVisiblePoint(void)
{
GpStatus status;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
REAL x, y;
BOOL val;
@@ -2105,14 +2081,14 @@ static void test_GdipIsVisiblePoint(void)
ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipIsVisibleRect(void)
{
GpStatus status;
GpGraphics *graphics = NULL;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
REAL x, y, width, height;
BOOL val;
@@ -2267,7 +2243,7 @@ static void test_GdipIsVisibleRect(void)
ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
GdipDeleteGraphics(graphics);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
}
static void test_GdipGetNearestColor(void)
@@ -2276,7 +2252,7 @@ static void test_GdipGetNearestColor(void)
GpGraphics *graphics;
GpBitmap *bitmap;
ARGB color = 0xdeadbeef;
- HDC hdc = GetDC(0);
+ HDC hdc = GetDC( hwnd );
/* create a graphics object */
ok(hdc != NULL, "Expected HDC to be initialized\n");
@@ -2415,17 +2391,269 @@ static void test_GdipGetNearestColor(void)
expect(Ok, status);
status = GdipGetNearestColor(graphics, &color);
expect(Ok, status);
- todo_wine expect(0xffa8b8e8, color);
+ todo_wine
+ ok(color == 0xffa8b8e8 ||
+ broken(color == 0xffa0b8e0), /* Win98/WinMe */
+ "Expected ffa8b8e8, got %.8x\n", color);
GdipDeleteGraphics(graphics);
GdipDisposeImage((GpImage*)bitmap);
- ReleaseDC(0, hdc);
+ ReleaseDC(hwnd, hdc);
+}
+
+static void test_string_functions(void)
+{
+ GpStatus status;
+ GpGraphics *graphics;
+ GpFontFamily *family;
+ GpFont *font;
+ RectF rc, char_bounds, bounds;
+ GpBrush *brush;
+ ARGB color = 0xff000000;
+ HDC hdc = GetDC( hwnd );
+ const WCHAR fontname[] = {'C','o','u','r','i','e','r',' ','N','e','w',0};
+ const WCHAR fontname2[] = {'C','o','u','r','i','e','r',0};
+ const WCHAR teststring[] = {'o','o',' ','o','\n','o',0};
+ REAL char_width, char_height;
+ INT codepointsfitted, linesfilled;
+ GpStringFormat *format;
+ CharacterRange ranges[3] = {{0, 1}, {1, 3}, {5, 1}};
+ GpRegion *regions[4] = {0};
+ BOOL region_isempty[4];
+ int i;
+
+ ok(hdc != NULL, "Expected HDC to be initialized\n");
+ status = GdipCreateFromHDC(hdc, &graphics);
+ expect(Ok, status);
+ ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+ status = GdipCreateFontFamilyFromName(fontname, NULL, &family);
+
+ if (status != Ok)
+ {
+ /* Wine doesn't have Courier New? */
+ todo_wine expect(Ok, status);
+ status = GdipCreateFontFamilyFromName(fontname2, NULL, &family);
+ }
+
+ expect(Ok, status);
+
+ status = GdipCreateFont(family, 10.0, FontStyleRegular, UnitPixel, &font);
+ expect(Ok, status);
+
+ status = GdipCreateSolidFill(color, (GpSolidFill**)&brush);
+ expect(Ok, status);
+
+ status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
+ expect(Ok, status);
+
+ rc.X = 0;
+ rc.Y = 0;
+ rc.Width = 100.0;
+ rc.Height = 100.0;
+
+ status = GdipDrawString(NULL, teststring, 6, font, &rc, NULL, brush);
+ expect(InvalidParameter, status);
+
+ status = GdipDrawString(graphics, NULL, 6, font, &rc, NULL, brush);
+ expect(InvalidParameter, status);
+
+ status = GdipDrawString(graphics, teststring, 6, NULL, &rc, NULL, brush);
+ expect(InvalidParameter, status);
+
+ status = GdipDrawString(graphics, teststring, 6, font, NULL, NULL, brush);
+ expect(InvalidParameter, status);
+
+ status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, NULL);
+ expect(InvalidParameter, status);
+
+ status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, brush);
+ expect(Ok, status);
+
+ status = GdipMeasureString(NULL, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureString(graphics, NULL, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureString(graphics, teststring, 6, NULL, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureString(graphics, teststring, 6, font, NULL, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, NULL, &codepointsfitted, &linesfilled);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, NULL, &linesfilled);
+ expect(Ok, status);
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, NULL);
+ expect(Ok, status);
+
+ status = GdipMeasureString(graphics, teststring, 1, font, &rc, NULL, &char_bounds, &codepointsfitted, &linesfilled);
+ expect(Ok, status);
+ expectf(0.0, char_bounds.X);
+ expectf(0.0, char_bounds.Y);
+ ok(char_bounds.Width > 0, "got %0.2f\n", bounds.Width);
+ ok(char_bounds.Height > 0, "got %0.2f\n", bounds.Height);
+ expect(1, codepointsfitted);
+ expect(1, linesfilled);
+
+ status = GdipMeasureString(graphics, teststring, 2, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(Ok, status);
+ expectf(0.0, bounds.X);
+ expectf(0.0, bounds.Y);
+ ok(bounds.Width > char_bounds.Width, "got %0.2f, expected at least %0.2f\n", bounds.Width, char_bounds.Width);
+ expectf(char_bounds.Height, bounds.Height);
+ expect(2, codepointsfitted);
+ expect(1, linesfilled);
+ char_width = bounds.Width - char_bounds.Width;
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(Ok, status);
+ expectf(0.0, bounds.X);
+ expectf(0.0, bounds.Y);
+ expectf_(char_bounds.Width + char_width * 3, bounds.Width, 0.01);
+ ok(bounds.Height > char_bounds.Height, "got %0.2f, expected at least %0.2f\n", bounds.Height, char_bounds.Height);
+ expect(6, codepointsfitted);
+ expect(2, linesfilled);
+ char_height = bounds.Height - char_bounds.Height;
+
+ /* Cut off everything after the first space. */
+ rc.Width = char_bounds.Width + char_width * 2.5;
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(Ok, status);
+ expectf(0.0, bounds.X);
+ expectf(0.0, bounds.Y);
+ expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
+ expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
+ expect(6, codepointsfitted);
+ expect(3, linesfilled);
+
+ /* Cut off everything including the first space. */
+ rc.Width = char_bounds.Width + char_width * 1.5;
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(Ok, status);
+ expectf(0.0, bounds.X);
+ expectf(0.0, bounds.Y);
+ expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
+ expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
+ expect(6, codepointsfitted);
+ expect(3, linesfilled);
+
+ /* Cut off everything after the first character. */
+ rc.Width = char_bounds.Width + char_width * 0.5;
+
+ status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
+ expect(Ok, status);
+ expectf(0.0, bounds.X);
+ expectf(0.0, bounds.Y);
+ expectf_(char_bounds.Width, bounds.Width, 0.01);
+ todo_wine expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05);
+ expect(6, codepointsfitted);
+ todo_wine expect(4, linesfilled);
+
+ status = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges);
+ expect(Ok, status);
+
+ rc.Width = 100.0;
+
+ for (i=0; i<4; i++)
+ {
+ status = GdipCreateRegion(®ions[i]);
+ expect(Ok, status);
+ }
+
+ status = GdipMeasureCharacterRanges(NULL, teststring, 6, font, &rc, format, 3, regions);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions);
+ expect(InvalidParameter, status);
+
+ if (0)
+ {
+ /* Crashes on Windows XP */
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions);
+ expect(InvalidParameter, status);
+ }
+
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, NULL);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions);
+ expect(InvalidParameter, status);
+
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions);
+ expect(Ok, status);
+
+ for (i=0; i<4; i++)
+ {
+ status = GdipIsEmptyRegion(regions[i], graphics, ®ion_isempty[i]);
+ expect(Ok, status);
+ }
+
+ ok(!region_isempty[0], "region shouldn't be empty\n");
+ ok(!region_isempty[1], "region shouldn't be empty\n");
+ ok(!region_isempty[2], "region shouldn't be empty\n");
+ ok(!region_isempty[3], "region shouldn't be empty\n");
+
+ /* Cut off everything after the first space, and the second line. */
+ rc.Width = char_bounds.Width + char_width * 2.5;
+ rc.Height = char_bounds.Height + char_height * 0.5;
+
+ status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
+ expect(Ok, status);
+
+ for (i=0; i<4; i++)
+ {
+ status = GdipIsEmptyRegion(regions[i], graphics, ®ion_isempty[i]);
+ expect(Ok, status);
+ }
+
+ ok(!region_isempty[0], "region shouldn't be empty\n");
+ ok(!region_isempty[1], "region shouldn't be empty\n");
+ ok(region_isempty[2], "region should be empty\n");
+ ok(!region_isempty[3], "region shouldn't be empty\n");
+
+ for (i=0; i<4; i++)
+ GdipDeleteRegion(regions[i]);
+
+ GdipDeleteStringFormat(format);
+ GdipDeleteBrush(brush);
+ GdipDeleteFont(font);
+ GdipDeleteFontFamily(family);
+ GdipDeleteGraphics(graphics);
+
+ ReleaseDC(hwnd, hdc);
}
START_TEST(graphics)
{
struct GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
+ WNDCLASSA class;
+
+ memset( &class, 0, sizeof(class) );
+ class.lpszClassName = "gdiplus_test";
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = DefWindowProcA;
+ class.hInstance = GetModuleHandleA(0);
+ class.hIcon = LoadIcon(0, IDI_APPLICATION);
+ class.hCursor = LoadCursor(NULL, IDC_ARROW);
+ class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ RegisterClassA( &class );
+ hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, 0, 0, GetModuleHandleA(0), 0 );
+ ok(hwnd != NULL, "Expected window to be created\n");
gdiplusStartupInput.GdiplusVersion = 1;
gdiplusStartupInput.DebugEventCallback = NULL;
@@ -2460,6 +2688,8 @@ START_TEST(graphics)
test_clear();
test_textcontrast();
test_fromMemoryBitmap();
+ test_string_functions();
GdiplusShutdown(gdiplusToken);
+ DestroyWindow( hwnd );
}
diff --git a/rostests/winetests/gdiplus/image.c b/rostests/winetests/gdiplus/image.c
index 9085ef2cf2d..74e6ee1db23 100644
--- a/rostests/winetests/gdiplus/image.c
+++ b/rostests/winetests/gdiplus/image.c
@@ -226,10 +226,23 @@ static void test_GdipImageGetFrameDimensionsCount(void)
stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
expect(InvalidParameter, stat);
+ stat = GdipImageGetFrameCount(NULL, &dimension, &count);
+ expect(InvalidParameter, stat);
+
+ /* WinXP crashes on this test */
+ if(0)
+ {
+ stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
+ expect(InvalidParameter, stat);
+ }
+
+ stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count);
+ expect(Ok, stat);
+
count = 12345;
stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
- todo_wine expect(Ok, stat);
- todo_wine expect(1, count);
+ expect(Ok, stat);
+ expect(1, count);
GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
@@ -793,6 +806,26 @@ static const unsigned char jpgimage[285] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
};
+/* 1x1 pixel tiff */
+static const unsigned char tiffimage[] = {
+0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
+0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
+0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
+0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
+0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
+0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
+0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
+0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
+0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
+0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
+0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
+0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
+0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
+0x00,0x00,0x00,0x01
+};
/* 320x320 twip wmf */
static const unsigned char wmfimage[180] = {
0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
@@ -814,6 +847,7 @@ static void test_getrawformat(void)
test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE);
test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE);
test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
+ test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
}
@@ -828,6 +862,7 @@ static void test_loadwmf(void)
GpRectF bounds;
GpUnit unit;
REAL res = 12345.0;
+ MetafileHeader header;
hglob = GlobalAlloc (0, sizeof(wmfimage));
data = GlobalLock (hglob);
@@ -863,6 +898,27 @@ static void test_loadwmf(void)
expect(Ok, stat);
todo_wine expectf(1440.0, res);
+ memset(&header, 0, sizeof(header));
+ stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
+ expect(Ok, stat);
+ if (stat == Ok)
+ {
+ todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
+ todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
+ todo_wine expect(0x300, header.Version);
+ expect(0, header.EmfPlusFlags);
+ todo_wine expectf(1440.0, header.DpiX);
+ todo_wine expectf(1440.0, header.DpiY);
+ expect(0, header.X);
+ expect(0, header.Y);
+ todo_wine expect(320, header.Width);
+ todo_wine expect(320, header.Height);
+ todo_wine expect(1, U(header).WmfHeader.mtType);
+ expect(0, header.EmfPlusHeaderSize);
+ expect(0, header.LogicalDpiX);
+ expect(0, header.LogicalDpiY);
+ }
+
GdipDisposeImage(img);
}
@@ -874,6 +930,7 @@ static void test_createfromwmf(void)
GpRectF bounds;
GpUnit unit;
REAL res = 12345.0;
+ MetafileHeader header;
hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
wmfimage+sizeof(WmfPlaceableFileHeader));
@@ -885,11 +942,11 @@ static void test_createfromwmf(void)
stat = GdipGetImageBounds(img, &bounds, &unit);
expect(Ok, stat);
- todo_wine expect(UnitPixel, unit);
+ expect(UnitPixel, unit);
expectf(0.0, bounds.X);
expectf(0.0, bounds.Y);
- todo_wine expectf(320.0, bounds.Width);
- todo_wine expectf(320.0, bounds.Height);
+ expectf(320.0, bounds.Width);
+ expectf(320.0, bounds.Height);
stat = GdipGetImageHorizontalResolution(img, &res);
expect(Ok, stat);
@@ -899,6 +956,27 @@ static void test_createfromwmf(void)
expect(Ok, stat);
expectf(1440.0, res);
+ memset(&header, 0, sizeof(header));
+ stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
+ expect(Ok, stat);
+ if (stat == Ok)
+ {
+ todo_wine expect(MetafileTypeWmfPlaceable, header.Type);
+ todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
+ todo_wine expect(0x300, header.Version);
+ expect(0, header.EmfPlusFlags);
+ todo_wine expectf(1440.0, header.DpiX);
+ todo_wine expectf(1440.0, header.DpiY);
+ expect(0, header.X);
+ expect(0, header.Y);
+ todo_wine expect(320, header.Width);
+ todo_wine expect(320, header.Height);
+ todo_wine expect(1, U(header).WmfHeader.mtType);
+ expect(0, header.EmfPlusHeaderSize);
+ expect(0, header.LogicalDpiX);
+ expect(0, header.LogicalDpiY);
+ }
+
GdipDisposeImage(img);
}
@@ -1544,7 +1622,7 @@ static void test_multiframegif(void)
count = 12345;
stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
- todo_wine expect(Ok, stat);
+ expect(Ok, stat);
todo_wine expect(2, count);
/* SelectActiveFrame overwrites our current data */
@@ -1618,8 +1696,8 @@ static void test_multiframegif(void)
count = 12345;
stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
- todo_wine expect(Ok, stat);
- todo_wine expect(1, count);
+ expect(Ok, stat);
+ expect(1, count);
GdipDisposeImage((GpImage*)bmp);
IStream_Release(stream);
@@ -1641,30 +1719,30 @@ static void test_rotateflip(void)
expect(Ok, stat);
stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone);
- todo_wine expect(Ok, stat);
+ expect(Ok, stat);
stat = GdipGetImageWidth(bitmap, &width);
expect(Ok, stat);
stat = GdipGetImageHeight(bitmap, &height);
expect(Ok, stat);
- todo_wine expect(2, width);
- todo_wine expect(3, height);
+ expect(2, width);
+ expect(3, height);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xff00ffff, color);
+ expect(0xff00ffff, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xffff0000, color);
+ expect(0xffff0000, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color);
- todo_wine expect(Ok, stat);
- todo_wine expect(0xffffff00, color);
+ expect(Ok, stat);
+ expect(0xffffff00, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color);
- todo_wine expect(Ok, stat);
- todo_wine expect(0xff0000ff, color);
+ expect(Ok, stat);
+ expect(0xff0000ff, color);
expect(0, bits[0]);
expect(0, bits[1]);
@@ -1677,7 +1755,7 @@ static void test_rotateflip(void)
expect(Ok, stat);
stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX);
- todo_wine expect(Ok, stat);
+ expect(Ok, stat);
stat = GdipGetImageWidth(bitmap, &width);
expect(Ok, stat);
@@ -1688,19 +1766,19 @@ static void test_rotateflip(void)
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xff0000ff, color);
+ expect(0xff0000ff, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xffff0000, color);
+ expect(0xffff0000, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
expect(Ok, stat);
- todo_wine expect(0xffffff00, color);
+ expect(0xffffff00, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
expect(Ok, stat);
- todo_wine expect(0xff00ffff, color);
+ expect(0xff00ffff, color);
expect(0, bits[0]);
expect(0, bits[1]);
@@ -1713,7 +1791,7 @@ static void test_rotateflip(void)
expect(Ok, stat);
stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY);
- todo_wine expect(Ok, stat);
+ expect(Ok, stat);
stat = GdipGetImageWidth(bitmap, &width);
expect(Ok, stat);
@@ -1724,19 +1802,19 @@ static void test_rotateflip(void)
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xff00ffff, color);
+ expect(0xff00ffff, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xffffff00, color);
+ expect(0xffffff00, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color);
expect(Ok, stat);
- todo_wine expect(0xffff0000, color);
+ expect(0xffff0000, color);
stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color);
expect(Ok, stat);
- todo_wine expect(0xff0000ff, color);
+ expect(0xff0000ff, color);
expect(0, bits[0]);
expect(0, bits[1]);
@@ -1801,7 +1879,7 @@ static void test_remaptable(void)
stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
expect(Ok, stat);
- todo_wine ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
+ ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
GdipDeleteGraphics(graphics);
GdipDisposeImage((GpImage*)bitmap1);
diff --git a/rostests/winetests/inetcomm/mimeintl.c b/rostests/winetests/inetcomm/mimeintl.c
index 563943f663b..f64d7d93d23 100644
--- a/rostests/winetests/inetcomm/mimeintl.c
+++ b/rostests/winetests/inetcomm/mimeintl.c
@@ -156,7 +156,7 @@ static void test_charset(void)
hr = MimeOleGetInternat(&internat);
ok(hr == S_OK, "ret %08x\n", hr);
- hr = IMimeInternational_FindCharset(internat, "non-existent", &hcs);
+ hr = IMimeInternational_FindCharset(internat, "nonexistent", &hcs);
ok(hr == MIME_E_NOT_FOUND, "got %08x\n", hr);
hr = IMimeInternational_FindCharset(internat, "windows-1252", &hcs_windows_1252);
diff --git a/rostests/winetests/jscript/regexp.js b/rostests/winetests/jscript/regexp.js
index fac111227fe..7b74cb11421 100644
--- a/rostests/winetests/jscript/regexp.js
+++ b/rostests/winetests/jscript/regexp.js
@@ -113,6 +113,7 @@ ok(typeof(m) === "object", "typeof m is not object");
ok(m.length === 2, "m.length is not 2");
ok(m["0"] === "ab", "m[0] is not \"ab\"");
ok(m["1"] === "ab", "m[1] is not \"ab\"");
+/* ok(m.input === "abcabc", "m.input = " + m.input); */
m = "abcabc".match(/Ab/g);
ok(typeof(m) === "object", "typeof m is not object");
@@ -167,6 +168,32 @@ ok(m["0"] === "ab", "m[0] is not \"ab\"");
m = "abcabc".match();
ok(m === null, "m is not null");
+m = "abcabc".match(/(a)(b)cabc/);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 3, "m.length is not 3");
+ok(m[0] === "abcabc", "m[0] is not \"abc\"");
+ok(m[1] === "a", "m[1] is not \"a\"");
+ok(m[2] === "b", "m[2] is not \"b\"");
+
+re = /(a)bcabc/;
+re.lastIndex = -3;
+m = "abcabc".match(re);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length = " + m.length + "expected 3");
+ok(m[0] === "abcabc", "m[0] is not \"abc\"");
+ok(m[1] === "a", "m[1] is not \"a\"");
+ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
+
+re = /(a)bcabc/;
+re.lastIndex = 2;
+m = "abcabcxxx".match(re);
+ok(typeof(m) === "object", "typeof m is not object");
+ok(m.length === 2, "m.length = " + m.length + "expected 3");
+ok(m[0] === "abcabc", "m[0] is not \"abc\"");
+ok(m[1] === "a", "m[1] is not \"a\"");
+ok(m.input === "abcabcxxx", "m.input = " + m.input);
+ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
+
r = "- [test] -".replace(re = /\[([^\[]+)\]/g, "success");
ok(r === "- success -", "r = " + r + " expected '- success -'");
ok(re.lastIndex === 8, "re.lastIndex = " + re.lastIndex);
@@ -410,6 +437,19 @@ m = re.exec(" ");
ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
ok(m === null, "m = " + m + " expected null");
+re = /a/;
+re.lastIndex = -3;
+ok(re.lastIndex === -3, "re.lastIndex = " + re.lastIndex + " expected -3");
+m = re.exec(" a a ");
+ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 0");
+ok(m.index === 1, "m = " + m + " expected 1");
+
+re.lastIndex = -1;
+ok(re.lastIndex === -1, "re.lastIndex = " + re.lastIndex + " expected -1");
+m = re.exec(" ");
+ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
+ok(m === null, "m = " + m + " expected null");
+
re = /aa/g;
i = 'baacd'.search(re);
ok(i === 1, "'baacd'.search(re) = " + i);
diff --git a/rostests/winetests/msctf/inputprocessor.c b/rostests/winetests/msctf/inputprocessor.c
index 7ba9140573a..c445b41b01e 100644
--- a/rostests/winetests/msctf/inputprocessor.c
+++ b/rostests/winetests/msctf/inputprocessor.c
@@ -38,15 +38,28 @@ static ITfDocumentMgr *g_dm = NULL;
static TfClientId cid = 0;
static TfClientId tid = 0;
+static ITextStoreACPSink *ACPSink;
+
#define SINK_UNEXPECTED 0
#define SINK_EXPECTED 1
#define SINK_FIRED 2
+#define SINK_IGNORE 3
+#define SINK_OPTIONAL 4
+
+#define SINK_ACTION_MASK 0xff
+#define SINK_OPTION_MASK 0xff00
+#define SINK_EXPECTED_COUNT_MASK 0xff0000
+
+#define SINK_OPTION_TODO 0x0100
+
+#define FOCUS_IGNORE (ITfDocumentMgr*)0xffffffff
static BOOL test_ShouldActivate = FALSE;
static BOOL test_ShouldDeactivate = FALSE;
static DWORD tmSinkCookie;
static DWORD tmSinkRefCount;
+static DWORD documentStatus;
static ITfDocumentMgr *test_CurrentFocus = NULL;
static ITfDocumentMgr *test_PrevFocus = NULL;
static INT test_OnSetFocus = SINK_UNEXPECTED;
@@ -54,671 +67,81 @@ static INT test_OnInitDocumentMgr = SINK_UNEXPECTED;
static INT test_OnPushContext = SINK_UNEXPECTED;
static INT test_OnPopContext = SINK_UNEXPECTED;
static INT test_KEV_OnSetFocus = SINK_UNEXPECTED;
-
-HRESULT RegisterTextService(REFCLSID rclsid);
-HRESULT UnregisterTextService();
-HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut);
-HRESULT TextStoreACP_Constructor(IUnknown **ppOut);
-
-DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3);
-DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed);
-DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7);
-DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31);
-DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14);
-DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43);
-DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B);
-DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
-DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50);
-DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72);
+static INT test_ACP_AdviseSink = SINK_UNEXPECTED;
+static INT test_ACP_GetStatus = SINK_UNEXPECTED;
+static INT test_ACP_RequestLock = SINK_UNEXPECTED;
+static INT test_ACP_GetEndACP = SINK_UNEXPECTED;
+static INT test_ACP_GetSelection = SINK_UNEXPECTED;
+static INT test_DoEditSession = SINK_UNEXPECTED;
+static INT test_ACP_InsertTextAtSelection = SINK_UNEXPECTED;
+static INT test_ACP_SetSelection = SINK_UNEXPECTED;
+static INT test_OnEndEdit = SINK_UNEXPECTED;
-static HRESULT initialize(void)
+static inline int expected_count(int *sink)
{
- HRESULT hr;
- CoInitialize(NULL);
- hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL,
- CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp);
- if (SUCCEEDED(hr))
- hr = CoCreateInstance (&CLSID_TF_CategoryMgr, NULL,
- CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm);
- if (SUCCEEDED(hr))
- hr = CoCreateInstance (&CLSID_TF_ThreadMgr, NULL,
- CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm);
- return hr;
+ return (*sink & SINK_EXPECTED_COUNT_MASK)>>16;
}
-static void cleanup(void)
+static inline void _sink_fire_ok(INT *sink, const CHAR* name)
{
- if (g_ipp)
- ITfInputProcessorProfiles_Release(g_ipp);
- if (g_cm)
- ITfCategoryMgr_Release(g_cm);
- if (g_tm)
- ITfThreadMgr_Release(g_tm);
- CoUninitialize();
-}
+ int count;
+ int todo = *sink & SINK_OPTION_TODO;
+ int action = *sink & SINK_ACTION_MASK;
-static void test_Register(void)
-{
- HRESULT hr;
+ if (winetest_interactive)
+ winetest_trace("firing %s\n",name);
- static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0};
- static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0};
-
- hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid);
- ok(SUCCEEDED(hr),"Unable to get current language id\n");
- trace("Current Language %x\n",gLangid);
-
- hr = RegisterTextService(&CLSID_FakeService);
- ok(SUCCEEDED(hr),"Unable to register COM for TextService\n");
- hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService);
- ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr);
- hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid, &CLSID_FakeService, szDesc, sizeof(szDesc)/sizeof(WCHAR), szFile, sizeof(szFile)/sizeof(WCHAR), 1);
- ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr);
-}
-
-static void test_Unregister(void)
-{
- HRESULT hr;
- hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService);
- ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr);
- UnregisterTextService();
-}
-
-static void test_EnumInputProcessorInfo(void)
-{
- IEnumGUID *ppEnum;
- BOOL found = FALSE;
-
- if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum)))
+ switch (action)
{
- ULONG fetched;
- GUID g;
- while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK)
- {
- if(IsEqualGUID(&g,&CLSID_FakeService))
- found = TRUE;
- }
- }
- ok(found,"Did not find registered text service\n");
-}
-
-static void test_EnumLanguageProfiles(void)
-{
- BOOL found = FALSE;
- IEnumTfLanguageProfiles *ppEnum;
- if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum)))
- {
- TF_LANGUAGEPROFILE profile;
- while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK)
- {
- if (IsEqualGUID(&profile.clsid,&CLSID_FakeService))
+ case SINK_OPTIONAL:
+ case SINK_EXPECTED:
+ count = expected_count(sink);
+ if (count > 1)
{
- found = TRUE;
- ok(profile.langid == gLangid, "LangId Incorrect\n");
- ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n");
- ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n");
+ count --;
+ *sink = (*sink & ~SINK_EXPECTED_COUNT_MASK) + (count << 16);
+ return;
}
- }
+ break;
+ case SINK_IGNORE:
+ winetest_trace("Ignoring %s\n",name);
+ return;
+ default:
+ if (todo)
+ todo_wine winetest_ok(0, "Unexpected %s sink\n",name);
+ else
+ winetest_ok(0, "Unexpected %s sink\n",name);
}
- ok(found,"Registered text service not found\n");
+ *sink = SINK_FIRED;
}
-static void test_RegisterCategory(void)
+#define sink_fire_ok(a,b) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_fire_ok(a,b)
+
+static inline void _sink_check_ok(INT *sink, const CHAR* name)
{
- HRESULT hr;
- hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n");
- hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n");
-}
+ int action = *sink & SINK_ACTION_MASK;
+ int todo = *sink & SINK_OPTION_TODO;
-static void test_UnregisterCategory(void)
-{
- HRESULT hr;
- hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n");
- hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n");
-}
-
-static void test_FindClosestCategory(void)
-{
- GUID output;
- HRESULT hr;
- const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING};
-
- hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
- ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n");
-
- hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
- ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n");
-
- hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
- ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n");
-}
-
-static void test_Enable(void)
-{
- HRESULT hr;
- BOOL enabled = FALSE;
-
- hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE);
- ok(SUCCEEDED(hr),"Failed to enable text service\n");
- hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled);
- ok(SUCCEEDED(hr),"Failed to get enabled state\n");
- ok(enabled == TRUE,"enabled state incorrect\n");
-}
-
-static void test_Disable(void)
-{
- HRESULT hr;
-
- trace("Disabling\n");
- hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE);
- ok(SUCCEEDED(hr),"Failed to disable text service\n");
-}
-
-static void test_ThreadMgrAdviseSinks(void)
-{
- ITfSource *source = NULL;
- HRESULT hr;
- IUnknown *sink;
-
- hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source);
- ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n");
- if (!source)
- return;
-
- ThreadMgrEventSink_Constructor(&sink);
-
- tmSinkRefCount = 1;
- tmSinkCookie = 0;
- hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie);
- ok(SUCCEEDED(hr),"Failed to Advise Sink\n");
- ok(tmSinkCookie!=0,"Failed to get sink cookie\n");
-
- /* Advising the sink adds a ref, Relesing here lets the object be deleted
- when unadvised */
- tmSinkRefCount = 2;
- IUnknown_Release(sink);
- ITfSource_Release(source);
-}
-
-static void test_ThreadMgrUnadviseSinks(void)
-{
- ITfSource *source = NULL;
- HRESULT hr;
-
- hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source);
- ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n");
- if (!source)
- return;
-
- tmSinkRefCount = 1;
- hr = ITfSource_UnadviseSink(source, tmSinkCookie);
- ok(SUCCEEDED(hr),"Failed to unadvise Sink\n");
- ITfSource_Release(source);
-}
-
-/**********************************************************************
- * ITfKeyEventSink
- **********************************************************************/
-typedef struct tagKeyEventSink
-{
- const ITfKeyEventSinkVtbl *KeyEventSinkVtbl;
- LONG refCount;
-} KeyEventSink;
-
-static void KeyEventSink_Destructor(KeyEventSink *This)
-{
- HeapFree(GetProcessHeap(),0,This);
-}
-
-static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut)
-{
- KeyEventSink *This = (KeyEventSink *)iface;
- *ppvOut = NULL;
-
- if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink))
+ switch (action)
{
- *ppvOut = This;
+ case SINK_OPTIONAL:
+ if (winetest_interactive)
+ winetest_trace("optional sink %s not fired\n",name);
+ case SINK_FIRED:
+ break;
+ case SINK_IGNORE:
+ return;
+ default:
+ if (todo)
+ todo_wine winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink);
+ else
+ winetest_ok(0, "%s not fired as expected, in state %x\n",name,*sink);
}
-
- if (*ppvOut)
- {
- IUnknown_AddRef(iface);
- return S_OK;
- }
-
- return E_NOINTERFACE;
+ *sink = SINK_UNEXPECTED;
}
-static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface)
-{
- KeyEventSink *This = (KeyEventSink *)iface;
- return InterlockedIncrement(&This->refCount);
-}
-
-static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface)
-{
- KeyEventSink *This = (KeyEventSink *)iface;
- ULONG ret;
-
- ret = InterlockedDecrement(&This->refCount);
- if (ret == 0)
- KeyEventSink_Destructor(This);
- return ret;
-}
-
-static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface,
- BOOL fForeground)
-{
- ok(test_KEV_OnSetFocus == SINK_EXPECTED,"Unexpected KeyEventSink_OnSetFocus\n");
- test_KEV_OnSetFocus = SINK_FIRED;
- return S_OK;
-}
-
-static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface,
- ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
-{
- trace("\n");
- return S_OK;
-}
-
-static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface,
- ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
-{
- trace("\n");
- return S_OK;
-}
-
-static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface,
- ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
-{
- trace("\n");
- return S_OK;
-}
-
-static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface,
- ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
-{
- trace("\n");
- return S_OK;
-}
-
-static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface,
- ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
-{
- trace("\n");
- return S_OK;
-}
-
-static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl =
-{
- KeyEventSink_QueryInterface,
- KeyEventSink_AddRef,
- KeyEventSink_Release,
-
- KeyEventSink_OnSetFocus,
- KeyEventSink_OnTestKeyDown,
- KeyEventSink_OnTestKeyUp,
- KeyEventSink_OnKeyDown,
- KeyEventSink_OnKeyUp,
- KeyEventSink_OnPreservedKey
-};
-
-HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut)
-{
- KeyEventSink *This;
-
- This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(KeyEventSink));
- if (This == NULL)
- return E_OUTOFMEMORY;
-
- This->KeyEventSinkVtbl = &KeyEventSink_KeyEventSinkVtbl;
- This->refCount = 1;
-
- *ppOut = (ITfKeyEventSink*)This;
- return S_OK;
-}
-
-
-static void test_KeystrokeMgr(void)
-{
- ITfKeystrokeMgr *keymgr= NULL;
- HRESULT hr;
- TF_PRESERVEDKEY tfpk;
- BOOL preserved;
- ITfKeyEventSink *sink;
-
- KeyEventSink_Constructor(&sink);
-
- hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr);
- ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n");
-
- tfpk.uVKey = 'A';
- tfpk.uModifiers = TF_MOD_SHIFT;
-
- test_KEV_OnSetFocus = SINK_EXPECTED;
- hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE);
- todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n");
- todo_wine ok(test_KEV_OnSetFocus == SINK_FIRED, "KeyEventSink_OnSetFocus not fired as expected\n");
-
- hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0);
- ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n");
-
- hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
- ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n");
-
- hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
- ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n");
-
- preserved = FALSE;
- hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
- ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n");
- if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n");
-
- hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
- ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n");
-
- hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
- ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n");
- if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n");
-
- hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
- ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n");
-
- hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid);
- todo_wine ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n");
-
- ITfKeystrokeMgr_Release(keymgr);
- ITfKeyEventSink_Release(sink);
-}
-
-static void test_Activate(void)
-{
- HRESULT hr;
-
- hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService);
- ok(SUCCEEDED(hr),"Failed to Activate text service\n");
-}
-
-static inline int check_context_refcount(ITfContext *iface)
-{
- IUnknown_AddRef(iface);
- return IUnknown_Release(iface);
-}
-
-static void test_startSession(void)
-{
- HRESULT hr;
- DWORD cnt;
- DWORD editCookie;
- ITfDocumentMgr *dmtest;
- ITfContext *cxt,*cxt2,*cxt3,*cxtTest;
- ITextStoreACP *ts;
- TfClientId cid2 = 0;
-
- hr = ITfThreadMgr_Deactivate(g_tm);
- ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n");
-
- test_ShouldActivate = TRUE;
- hr = ITfThreadMgr_Activate(g_tm,&cid);
- ok(SUCCEEDED(hr),"Failed to Activate\n");
- ok(cid != tid,"TextService id mistakenly matches Client id\n");
-
- test_ShouldActivate = FALSE;
- hr = ITfThreadMgr_Activate(g_tm,&cid2);
- ok(SUCCEEDED(hr),"Failed to Activate\n");
- ok (cid == cid2, "Second activate client ID does not match\n");
-
- hr = ITfThreadMgr_Deactivate(g_tm);
- ok(SUCCEEDED(hr),"Failed to Deactivate\n");
-
- hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm);
- ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
-
- hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
- ok(SUCCEEDED(hr),"GetFocus Failed\n");
- ok(dmtest == NULL,"Initial focus not null\n");
-
- test_CurrentFocus = g_dm;
- test_PrevFocus = NULL;
- test_OnSetFocus = SINK_EXPECTED;
- hr = ITfThreadMgr_SetFocus(g_tm,g_dm);
- ok(SUCCEEDED(hr),"SetFocus Failed\n");
- ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n");
- test_OnSetFocus = SINK_UNEXPECTED;
-
- hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
- ok(SUCCEEDED(hr),"GetFocus Failed\n");
- ok(g_dm == dmtest,"Expected DocumentMgr not focused\n");
-
- cnt = ITfDocumentMgr_Release(g_dm);
- ok(cnt == 2,"DocumentMgr refcount not expected (2 vs %i)\n",cnt);
-
- hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
- ok(SUCCEEDED(hr),"GetFocus Failed\n");
- ok(g_dm == dmtest,"Expected DocumentMgr not focused\n");
-
- TextStoreACP_Constructor((IUnknown**)&ts);
-
- hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie);
- ok(SUCCEEDED(hr),"CreateContext Failed\n");
-
- hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie);
- ok(SUCCEEDED(hr),"CreateContext Failed\n");
-
- hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie);
- ok(SUCCEEDED(hr),"CreateContext Failed\n");
-
- cnt = check_context_refcount(cxt);
- test_OnPushContext = SINK_EXPECTED;
- test_OnInitDocumentMgr = SINK_EXPECTED;
- hr = ITfDocumentMgr_Push(g_dm, cxt);
- ok(SUCCEEDED(hr),"Push Failed\n");
- ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
- ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n");
- ok(test_OnInitDocumentMgr == SINK_FIRED, "OnInitDocumentMgr sink not fired\n");
-
- hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetTop Failed\n");
- ok(cxtTest == cxt, "Wrong context on top\n");
- ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
- cnt = ITfContext_Release(cxtTest);
-
- hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetBase Failed\n");
- ok(cxtTest == cxt, "Wrong context on Base\n");
- ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
- ITfContext_Release(cxtTest);
-
- check_context_refcount(cxt2);
- test_OnPushContext = SINK_EXPECTED;
- hr = ITfDocumentMgr_Push(g_dm, cxt2);
- ok(SUCCEEDED(hr),"Push Failed\n");
- ok(test_OnPushContext == SINK_FIRED, "OnPushContext sink not fired\n");
-
- cnt = check_context_refcount(cxt2);
- hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetTop Failed\n");
- ok(cxtTest == cxt2, "Wrong context on top\n");
- ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n");
- ITfContext_Release(cxtTest);
-
- cnt = check_context_refcount(cxt);
- hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetBase Failed\n");
- ok(cxtTest == cxt, "Wrong context on Base\n");
- ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
- ITfContext_Release(cxtTest);
-
- cnt = check_context_refcount(cxt3);
- hr = ITfDocumentMgr_Push(g_dm, cxt3);
- ok(!SUCCEEDED(hr),"Push Succeeded\n");
- ok(check_context_refcount(cxt3) == cnt, "Ref changed\n");
-
- cnt = check_context_refcount(cxt2);
- hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetTop Failed\n");
- ok(cxtTest == cxt2, "Wrong context on top\n");
- ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n");
- ITfContext_Release(cxtTest);
-
- cnt = check_context_refcount(cxt);
- hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetBase Failed\n");
- ok(cxtTest == cxt, "Wrong context on Base\n");
- ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
- ITfContext_Release(cxtTest);
-
- cnt = check_context_refcount(cxt2);
- test_OnPopContext = SINK_EXPECTED;
- hr = ITfDocumentMgr_Pop(g_dm, 0);
- ok(SUCCEEDED(hr),"Pop Failed\n");
- ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n");
- ok(test_OnPopContext == SINK_FIRED, "OnPopContext sink not fired\n");
-
- hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetTop Failed\n");
- ok(cxtTest == cxt, "Wrong context on top\n");
- ITfContext_Release(cxtTest);
-
- hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetBase Failed\n");
- ok(cxtTest == cxt, "Wrong context on base\n");
- ITfContext_Release(cxtTest);
-
- hr = ITfDocumentMgr_Pop(g_dm, 0);
- ok(!SUCCEEDED(hr),"Pop Succeeded\n");
-
- hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetTop Failed\n");
- ok(cxtTest == cxt, "Wrong context on top\n");
- ITfContext_Release(cxtTest);
-
- hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
- ok(SUCCEEDED(hr),"GetBase Failed\n");
- ok(cxtTest == cxt, "Wrong context on base\n");
- ITfContext_Release(cxtTest);
-
- ITfContext_Release(cxt);
- ITfContext_Release(cxt2);
- ITfContext_Release(cxt3);
-}
-
-static void test_endSession(void)
-{
- HRESULT hr;
- test_ShouldDeactivate = TRUE;
- test_CurrentFocus = NULL;
- test_PrevFocus = g_dm;
- test_OnSetFocus = SINK_EXPECTED;
- hr = ITfThreadMgr_Deactivate(g_tm);
- ok(SUCCEEDED(hr),"Failed to Deactivate\n");
- ok(test_OnSetFocus == SINK_FIRED, "OnSetFocus sink not called\n");
- test_OnSetFocus = SINK_UNEXPECTED;
-}
-
-static void test_TfGuidAtom(void)
-{
- GUID gtest,g1;
- HRESULT hr;
- TfGuidAtom atom1,atom2;
- BOOL equal;
-
- CoCreateGuid(>est);
-
- /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/
- /*
- hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,NULL);
- ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n");
- */
- hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom1);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n");
- hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom2);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n");
- ok(atom1 == atom2,"atoms do not match\n");
- hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL);
- ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n");
- hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n");
- ok(IsEqualGUID(&g1,>est),"guids do not match\n");
- hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,NULL);
- ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n");
- hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,&equal);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n");
- ok(equal == TRUE,"Equal value invalid\n");
-
- /* show that cid and tid TfClientIds are also TfGuidAtoms */
- hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n");
- ok(equal == TRUE,"Equal value invalid\n");
- hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1);
- ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n");
- ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n");
-}
-
-static void test_ClientId(void)
-{
- ITfClientId *pcid;
- TfClientId id1,id2;
- HRESULT hr;
- GUID g2;
-
- hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid);
- ok(SUCCEEDED(hr),"Unable to aquire ITfClientId interface\n");
-
- CoCreateGuid(&g2);
-
- hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1);
- ok(SUCCEEDED(hr),"GetClientId failed\n");
- hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2);
- ok(SUCCEEDED(hr),"GetClientId failed\n");
- ok(id1==id2,"Id's for GUID_NULL do not match\n");
- hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2);
- ok(SUCCEEDED(hr),"GetClientId failed\n");
- ok(id2!=id1,"Id matches GUID_NULL\n");
- ok(id2==tid,"Id for CLSID_FakeService not matching tid\n");
- ok(id2!=cid,"Id for CLSID_FakeService matching cid\n");
- hr = ITfClientId_GetClientId(pcid,&g2,&id2);
- ok(SUCCEEDED(hr),"GetClientId failed\n");
- ok(id2!=id1,"Id matches GUID_NULL\n");
- ok(id2!=tid,"Id for random guid matching tid\n");
- ok(id2!=cid,"Id for random guid matching cid\n");
- ITfClientId_Release(pcid);
-}
-
-START_TEST(inputprocessor)
-{
- if (SUCCEEDED(initialize()))
- {
- test_Register();
- test_RegisterCategory();
- test_EnumInputProcessorInfo();
- test_Enable();
- test_ThreadMgrAdviseSinks();
- test_Activate();
- test_startSession();
- test_TfGuidAtom();
- test_ClientId();
- test_KeystrokeMgr();
- test_endSession();
- test_EnumLanguageProfiles();
- test_FindClosestCategory();
- test_Disable();
- test_ThreadMgrUnadviseSinks();
- test_UnregisterCategory();
- test_Unregister();
- }
- else
- skip("Unable to create InputProcessor\n");
- cleanup();
-}
+#define sink_check_ok(a,b) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _sink_check_ok(a,b)
/**********************************************************************
* ITextStoreACP
@@ -727,6 +150,7 @@ typedef struct tagTextStoreACP
{
const ITextStoreACPVtbl *TextStoreACPVtbl;
LONG refCount;
+
} TextStoreACP;
static void TextStoreACP_Destructor(TextStoreACP *This)
@@ -773,7 +197,12 @@ static ULONG WINAPI TextStoreACP_Release(ITextStoreACP *iface)
static HRESULT WINAPI TextStoreACP_AdviseSink(ITextStoreACP *iface,
REFIID riid, IUnknown *punk, DWORD dwMask)
{
- trace("\n");
+ HRESULT hr;
+
+ sink_fire_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
+
+ hr = IUnknown_QueryInterface(punk, &IID_ITextStoreACPSink,(LPVOID*)(&ACPSink));
+ ok(SUCCEEDED(hr),"Unable to QueryInterface on sink\n");
return S_OK;
}
@@ -783,16 +212,19 @@ static HRESULT WINAPI TextStoreACP_UnadviseSink(ITextStoreACP *iface,
trace("\n");
return S_OK;
}
+
static HRESULT WINAPI TextStoreACP_RequestLock(ITextStoreACP *iface,
DWORD dwLockFlags, HRESULT *phrSession)
{
- trace("\n");
+ sink_fire_ok(&test_ACP_RequestLock,"TextStoreACP_RequestLock");
+ *phrSession = ITextStoreACPSink_OnLockGranted(ACPSink, dwLockFlags);
return S_OK;
}
static HRESULT WINAPI TextStoreACP_GetStatus(ITextStoreACP *iface,
TS_STATUS *pdcs)
{
- trace("\n");
+ sink_fire_ok(&test_ACP_GetStatus,"TextStoreACP_GetStatus");
+ pdcs->dwDynamicFlags = documentStatus;
return S_OK;
}
static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface,
@@ -805,13 +237,20 @@ static HRESULT WINAPI TextStoreACP_QueryInsert(ITextStoreACP *iface,
static HRESULT WINAPI TextStoreACP_GetSelection(ITextStoreACP *iface,
ULONG ulIndex, ULONG ulCount, TS_SELECTION_ACP *pSelection, ULONG *pcFetched)
{
- trace("\n");
+ sink_fire_ok(&test_ACP_GetSelection,"TextStoreACP_GetSelection");
+
+ pSelection->acpStart = 10;
+ pSelection->acpEnd = 20;
+ pSelection->style.fInterimChar = 0;
+ pSelection->style.ase = TS_AE_NONE;
+ *pcFetched = 1;
+
return S_OK;
}
static HRESULT WINAPI TextStoreACP_SetSelection(ITextStoreACP *iface,
ULONG ulCount, const TS_SELECTION_ACP *pSelection)
{
- trace("\n");
+ sink_fire_ok(&test_ACP_SetSelection,"TextStoreACP_SetSelection");
return S_OK;
}
static HRESULT WINAPI TextStoreACP_GetText(ITextStoreACP *iface,
@@ -858,7 +297,7 @@ static HRESULT WINAPI TextStoreACP_InsertTextAtSelection(ITextStoreACP *iface,
DWORD dwFlags, const WCHAR *pchText, ULONG cch, LONG *pacpStart,
LONG *pacpEnd, TS_TEXTCHANGE *pChange)
{
- trace("\n");
+ sink_fire_ok(&test_ACP_InsertTextAtSelection,"TextStoreACP_InsertTextAtSelection");
return S_OK;
}
static HRESULT WINAPI TextStoreACP_InsertEmbeddedAtSelection(ITextStoreACP *iface,
@@ -904,7 +343,7 @@ static HRESULT WINAPI TextStoreACP_RetrieveRequestedAttrs(ITextStoreACP *iface,
static HRESULT WINAPI TextStoreACP_GetEndACP(ITextStoreACP *iface,
LONG *pacp)
{
- trace("\n");
+ sink_fire_ok(&test_ACP_GetEndACP,"TextStoreACP_GetEndACP");
return S_OK;
}
static HRESULT WINAPI TextStoreACP_GetActiveView(ITextStoreACP *iface,
@@ -974,7 +413,7 @@ static const ITextStoreACPVtbl TextStoreACP_TextStoreACPVtbl =
TextStoreACP_GetWnd
};
-HRESULT TextStoreACP_Constructor(IUnknown **ppOut)
+static HRESULT TextStoreACP_Constructor(IUnknown **ppOut)
{
TextStoreACP *This;
@@ -1044,8 +483,7 @@ static ULONG WINAPI ThreadMgrEventSink_Release(ITfThreadMgrEventSink *iface)
static HRESULT WINAPI ThreadMgrEventSink_OnInitDocumentMgr(ITfThreadMgrEventSink *iface,
ITfDocumentMgr *pdim)
{
- ok(test_OnInitDocumentMgr == SINK_EXPECTED, "Unexpected OnInitDocumentMgr sink\n");
- test_OnInitDocumentMgr = SINK_FIRED;
+ sink_fire_ok(&test_OnInitDocumentMgr,"ThreadMgrEventSink_OnInitDocumentMgr");
return S_OK;
}
@@ -1059,26 +497,53 @@ ITfDocumentMgr *pdim)
static HRESULT WINAPI ThreadMgrEventSink_OnSetFocus(ITfThreadMgrEventSink *iface,
ITfDocumentMgr *pdimFocus, ITfDocumentMgr *pdimPrevFocus)
{
- ok(test_OnSetFocus == SINK_EXPECTED, "Unexpected OnSetFocus sink\n");
- ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n");
- ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n");
- test_OnSetFocus = SINK_FIRED;
+ sink_fire_ok(&test_OnSetFocus,"ThreadMgrEventSink_OnSetFocus");
+ if (test_CurrentFocus != FOCUS_IGNORE)
+ ok(pdimFocus == test_CurrentFocus,"Sink reports wrong focus\n");
+ if (test_PrevFocus != FOCUS_IGNORE)
+ ok(pdimPrevFocus == test_PrevFocus,"Sink reports wrong previous focus\n");
return S_OK;
}
static HRESULT WINAPI ThreadMgrEventSink_OnPushContext(ITfThreadMgrEventSink *iface,
ITfContext *pic)
{
- ok(test_OnPushContext == SINK_EXPECTED, "Unexpected OnPushContext sink\n");
- test_OnPushContext = SINK_FIRED;
+ HRESULT hr;
+ ITfDocumentMgr *docmgr;
+ ITfContext *test;
+
+ hr = ITfContext_GetDocumentMgr(pic,&docmgr);
+ ok(SUCCEEDED(hr),"GetDocumenMgr failed\n");
+ test = (ITfContext*)0xdeadbeef;
+ ITfDocumentMgr_Release(docmgr);
+ hr = ITfDocumentMgr_GetTop(docmgr,&test);
+ ok(SUCCEEDED(hr),"GetTop failed\n");
+ ok(test == pic, "Wrong context is on top\n");
+ if (test)
+ ITfContext_Release(test);
+
+ sink_fire_ok(&test_OnPushContext,"ThreadMgrEventSink_OnPushContext");
return S_OK;
}
static HRESULT WINAPI ThreadMgrEventSink_OnPopContext(ITfThreadMgrEventSink *iface,
ITfContext *pic)
{
- ok(test_OnPopContext == SINK_EXPECTED, "Unexpected OnPopContext sink\n");
- test_OnPopContext = SINK_FIRED;
+ HRESULT hr;
+ ITfDocumentMgr *docmgr;
+ ITfContext *test;
+
+ hr = ITfContext_GetDocumentMgr(pic,&docmgr);
+ ok(SUCCEEDED(hr),"GetDocumenMgr failed\n");
+ ITfDocumentMgr_Release(docmgr);
+ test = (ITfContext*)0xdeadbeef;
+ hr = ITfDocumentMgr_GetTop(docmgr,&test);
+ ok(SUCCEEDED(hr),"GetTop failed\n");
+ ok(test == pic, "Wrong context is on top\n");
+ if (test)
+ ITfContext_Release(test);
+
+ sink_fire_ok(&test_OnPopContext,"ThreadMgrEventSink_OnPopContext");
return S_OK;
}
@@ -1095,7 +560,7 @@ static const ITfThreadMgrEventSinkVtbl ThreadMgrEventSink_ThreadMgrEventSinkVtbl
ThreadMgrEventSink_OnPopContext
};
-HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut)
+static HRESULT ThreadMgrEventSink_Constructor(IUnknown **ppOut)
{
ThreadMgrEventSink *This;
@@ -1282,7 +747,7 @@ static const ITfTextInputProcessorVtbl TextService_TextInputProcessorVtbl=
TextService_Deactivate
};
-HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
+static HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
TextService *This;
if (pUnkOuter)
@@ -1299,13 +764,1339 @@ HRESULT TextService_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
return S_OK;
}
-HRESULT RegisterTextService(REFCLSID rclsid)
+static HRESULT RegisterTextService(REFCLSID rclsid)
{
ClassFactory_Constructor( TextService_Constructor ,(LPVOID*)&cf);
return CoRegisterClassObject(rclsid, (IUnknown*) cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, ®id);
}
-HRESULT UnregisterTextService()
+static HRESULT UnregisterTextService(void)
{
return CoRevokeClassObject(regid);
}
+
+/*
+ * The tests
+ */
+
+DEFINE_GUID(CLSID_FakeService, 0xEDE1A7AD,0x66DE,0x47E0,0xB6,0x20,0x3E,0x92,0xF8,0x24,0x6B,0xF3);
+DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed);
+DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7);
+DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745c63,0xb2f0,0x4784,0x8b,0x67,0x5e,0x12,0xc8,0x70,0x1a,0x31);
+DEFINE_GUID(GUID_TFCAT_TIP_SPEECH, 0xB5A73CD1,0x8355,0x426B,0xA1,0x61,0x25,0x98,0x08,0xF2,0x6B,0x14);
+DEFINE_GUID(GUID_TFCAT_TIP_HANDWRITING, 0x246ecb87,0xc2f2,0x4abe,0x90,0x5b,0xc8,0xb3,0x8a,0xdd,0x2c,0x43);
+DEFINE_GUID (GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, 0x046B8C80,0x1647,0x40F7,0x9B,0x21,0xB9,0x3B,0x81,0xAA,0xBC,0x1B);
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50);
+DEFINE_GUID(CLSID_PreservedKey, 0xA0ED8E55,0xCD3B,0x4274,0xB2,0x95,0xF6,0xC9,0xBA,0x2B,0x84,0x72);
+DEFINE_GUID(GUID_COMPARTMENT_KEYBOARD_DISABLED, 0x71a5b253,0x1951,0x466b,0x9f,0xbc,0x9c,0x88,0x08,0xfa,0x84,0xf2);
+DEFINE_GUID(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, 0x58273aad,0x01bb,0x4164,0x95,0xc6,0x75,0x5b,0xa0,0xb5,0x16,0x2d);
+DEFINE_GUID(GUID_COMPARTMENT_HANDWRITING_OPENCLOSE, 0xf9ae2c6b,0x1866,0x4361,0xaf,0x72,0x7a,0xa3,0x09,0x48,0x89,0x0e);
+DEFINE_GUID(GUID_COMPARTMENT_SPEECH_DISABLED, 0x56c5c607,0x0703,0x4e59,0x8e,0x52,0xcb,0xc8,0x4e,0x8b,0xbe,0x35);
+DEFINE_GUID(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0x544d6a63,0xe2e8,0x4752,0xbb,0xd1,0x00,0x09,0x60,0xbc,0xa0,0x83);
+DEFINE_GUID(GUID_COMPARTMENT_SPEECH_GLOBALSTATE, 0x2a54fe8e,0x0d08,0x460c,0xa7,0x5d,0x87,0x03,0x5f,0xf4,0x36,0xc5);
+DEFINE_GUID(GUID_COMPARTMENT_PERSISTMENUENABLED, 0x575f3783,0x70c8,0x47c8,0xae,0x5d,0x91,0xa0,0x1a,0x1f,0x75,0x92);
+DEFINE_GUID(GUID_COMPARTMENT_EMPTYCONTEXT, 0xd7487dbf,0x804e,0x41c5,0x89,0x4d,0xad,0x96,0xfd,0x4e,0xea,0x13);
+DEFINE_GUID(GUID_COMPARTMENT_TIPUISTATUS, 0x148ca3ec,0x0366,0x401c,0x8d,0x75,0xed,0x97,0x8d,0x85,0xfb,0xc9);
+
+static HRESULT initialize(void)
+{
+ HRESULT hr;
+ CoInitialize(NULL);
+ hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL,
+ CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp);
+ if (SUCCEEDED(hr))
+ hr = CoCreateInstance (&CLSID_TF_CategoryMgr, NULL,
+ CLSCTX_INPROC_SERVER, &IID_ITfCategoryMgr, (void**)&g_cm);
+ if (SUCCEEDED(hr))
+ hr = CoCreateInstance (&CLSID_TF_ThreadMgr, NULL,
+ CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (void**)&g_tm);
+ return hr;
+}
+
+static void cleanup(void)
+{
+ if (g_ipp)
+ ITfInputProcessorProfiles_Release(g_ipp);
+ if (g_cm)
+ ITfCategoryMgr_Release(g_cm);
+ if (g_tm)
+ ITfThreadMgr_Release(g_tm);
+ CoUninitialize();
+}
+
+static void test_Register(void)
+{
+ HRESULT hr;
+
+ static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0};
+ static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0};
+
+ hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid);
+ ok(SUCCEEDED(hr),"Unable to get current language id\n");
+ trace("Current Language %x\n",gLangid);
+
+ hr = RegisterTextService(&CLSID_FakeService);
+ ok(SUCCEEDED(hr),"Unable to register COM for TextService\n");
+ hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService);
+ ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr);
+ hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid, &CLSID_FakeService, szDesc, sizeof(szDesc)/sizeof(WCHAR), szFile, sizeof(szFile)/sizeof(WCHAR), 1);
+ ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr);
+}
+
+static void test_Unregister(void)
+{
+ HRESULT hr;
+ hr = ITfInputProcessorProfiles_Unregister(g_ipp, &CLSID_FakeService);
+ ok(SUCCEEDED(hr),"Unable to unregister text service(%x)\n",hr);
+ UnregisterTextService();
+}
+
+static void test_EnumInputProcessorInfo(void)
+{
+ IEnumGUID *ppEnum;
+ BOOL found = FALSE;
+
+ if (SUCCEEDED(ITfInputProcessorProfiles_EnumInputProcessorInfo(g_ipp, &ppEnum)))
+ {
+ ULONG fetched;
+ GUID g;
+ while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK)
+ {
+ if(IsEqualGUID(&g,&CLSID_FakeService))
+ found = TRUE;
+ }
+ }
+ ok(found,"Did not find registered text service\n");
+}
+
+static void test_EnumLanguageProfiles(void)
+{
+ BOOL found = FALSE;
+ IEnumTfLanguageProfiles *ppEnum;
+ if (SUCCEEDED(ITfInputProcessorProfiles_EnumLanguageProfiles(g_ipp,gLangid,&ppEnum)))
+ {
+ TF_LANGUAGEPROFILE profile;
+ while (IEnumTfLanguageProfiles_Next(ppEnum,1,&profile,NULL)==S_OK)
+ {
+ if (IsEqualGUID(&profile.clsid,&CLSID_FakeService))
+ {
+ found = TRUE;
+ ok(profile.langid == gLangid, "LangId Incorrect\n");
+ ok(IsEqualGUID(&profile.catid,&GUID_TFCAT_TIP_KEYBOARD), "CatId Incorrect\n");
+ ok(IsEqualGUID(&profile.guidProfile,&CLSID_FakeService), "guidProfile Incorrect\n");
+ }
+ }
+ }
+ ok(found,"Registered text service not found\n");
+}
+
+static void test_RegisterCategory(void)
+{
+ HRESULT hr;
+ hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n");
+ hr = ITfCategoryMgr_RegisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterCategory failed\n");
+}
+
+static void test_UnregisterCategory(void)
+{
+ HRESULT hr;
+ hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_TIP_KEYBOARD, &CLSID_FakeService);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n");
+ hr = ITfCategoryMgr_UnregisterCategory(g_cm, &CLSID_FakeService, &GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_FakeService);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_UnregisterCategory failed\n");
+}
+
+static void test_FindClosestCategory(void)
+{
+ GUID output;
+ HRESULT hr;
+ const GUID *list[3] = {&GUID_TFCAT_TIP_SPEECH, &GUID_TFCAT_TIP_KEYBOARD, &GUID_TFCAT_TIP_HANDWRITING};
+
+ hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, NULL, 0);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
+ ok(IsEqualGUID(&output,&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER),"Wrong GUID\n");
+
+ hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 1);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
+ ok(IsEqualGUID(&output,&GUID_NULL),"Wrong GUID\n");
+
+ hr = ITfCategoryMgr_FindClosestCategory(g_cm, &CLSID_FakeService, &output, list, 3);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_FindClosestCategory failed (%x)\n",hr);
+ ok(IsEqualGUID(&output,&GUID_TFCAT_TIP_KEYBOARD),"Wrong GUID\n");
+}
+
+static void test_Enable(void)
+{
+ HRESULT hr;
+ BOOL enabled = FALSE;
+
+ hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, TRUE);
+ ok(SUCCEEDED(hr),"Failed to enable text service\n");
+ hr = ITfInputProcessorProfiles_IsEnabledLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, &enabled);
+ ok(SUCCEEDED(hr),"Failed to get enabled state\n");
+ ok(enabled == TRUE,"enabled state incorrect\n");
+}
+
+static void test_Disable(void)
+{
+ HRESULT hr;
+
+ trace("Disabling\n");
+ hr = ITfInputProcessorProfiles_EnableLanguageProfile(g_ipp,&CLSID_FakeService, gLangid, &CLSID_FakeService, FALSE);
+ ok(SUCCEEDED(hr),"Failed to disable text service\n");
+}
+
+static void test_ThreadMgrAdviseSinks(void)
+{
+ ITfSource *source = NULL;
+ HRESULT hr;
+ IUnknown *sink;
+
+ hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source);
+ ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n");
+ if (!source)
+ return;
+
+ hr = ThreadMgrEventSink_Constructor(&sink);
+ ok(hr == S_OK, "got %08x\n", hr);
+ if(FAILED(hr)) return;
+
+ tmSinkRefCount = 1;
+ tmSinkCookie = 0;
+ hr = ITfSource_AdviseSink(source,&IID_ITfThreadMgrEventSink, sink, &tmSinkCookie);
+ ok(SUCCEEDED(hr),"Failed to Advise Sink\n");
+ ok(tmSinkCookie!=0,"Failed to get sink cookie\n");
+
+ /* Advising the sink adds a ref, Relesing here lets the object be deleted
+ when unadvised */
+ tmSinkRefCount = 2;
+ IUnknown_Release(sink);
+ ITfSource_Release(source);
+}
+
+static void test_ThreadMgrUnadviseSinks(void)
+{
+ ITfSource *source = NULL;
+ HRESULT hr;
+
+ hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfSource, (LPVOID*)&source);
+ ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for ThreadMgr\n");
+ if (!source)
+ return;
+
+ tmSinkRefCount = 1;
+ hr = ITfSource_UnadviseSink(source, tmSinkCookie);
+ ok(SUCCEEDED(hr),"Failed to unadvise Sink\n");
+ ITfSource_Release(source);
+}
+
+/**********************************************************************
+ * ITfKeyEventSink
+ **********************************************************************/
+typedef struct tagKeyEventSink
+{
+ const ITfKeyEventSinkVtbl *KeyEventSinkVtbl;
+ LONG refCount;
+} KeyEventSink;
+
+static void KeyEventSink_Destructor(KeyEventSink *This)
+{
+ HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI KeyEventSink_QueryInterface(ITfKeyEventSink *iface, REFIID iid, LPVOID *ppvOut)
+{
+ KeyEventSink *This = (KeyEventSink *)iface;
+ *ppvOut = NULL;
+
+ if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfKeyEventSink))
+ {
+ *ppvOut = This;
+ }
+
+ if (*ppvOut)
+ {
+ IUnknown_AddRef(iface);
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI KeyEventSink_AddRef(ITfKeyEventSink *iface)
+{
+ KeyEventSink *This = (KeyEventSink *)iface;
+ return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI KeyEventSink_Release(ITfKeyEventSink *iface)
+{
+ KeyEventSink *This = (KeyEventSink *)iface;
+ ULONG ret;
+
+ ret = InterlockedDecrement(&This->refCount);
+ if (ret == 0)
+ KeyEventSink_Destructor(This);
+ return ret;
+}
+
+static HRESULT WINAPI KeyEventSink_OnSetFocus(ITfKeyEventSink *iface,
+ BOOL fForeground)
+{
+ sink_fire_ok(&test_KEV_OnSetFocus,"KeyEventSink_OnSetFocus");
+ return S_OK;
+}
+
+static HRESULT WINAPI KeyEventSink_OnTestKeyDown(ITfKeyEventSink *iface,
+ ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
+{
+ trace("\n");
+ return S_OK;
+}
+
+static HRESULT WINAPI KeyEventSink_OnTestKeyUp(ITfKeyEventSink *iface,
+ ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
+{
+ trace("\n");
+ return S_OK;
+}
+
+static HRESULT WINAPI KeyEventSink_OnKeyDown(ITfKeyEventSink *iface,
+ ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
+{
+ trace("\n");
+ return S_OK;
+}
+
+static HRESULT WINAPI KeyEventSink_OnKeyUp(ITfKeyEventSink *iface,
+ ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
+{
+ trace("\n");
+ return S_OK;
+}
+
+static HRESULT WINAPI KeyEventSink_OnPreservedKey(ITfKeyEventSink *iface,
+ ITfContext *pic, REFGUID rguid, BOOL *pfEaten)
+{
+ trace("\n");
+ return S_OK;
+}
+
+static const ITfKeyEventSinkVtbl KeyEventSink_KeyEventSinkVtbl =
+{
+ KeyEventSink_QueryInterface,
+ KeyEventSink_AddRef,
+ KeyEventSink_Release,
+
+ KeyEventSink_OnSetFocus,
+ KeyEventSink_OnTestKeyDown,
+ KeyEventSink_OnTestKeyUp,
+ KeyEventSink_OnKeyDown,
+ KeyEventSink_OnKeyUp,
+ KeyEventSink_OnPreservedKey
+};
+
+static HRESULT KeyEventSink_Constructor(ITfKeyEventSink **ppOut)
+{
+ KeyEventSink *This;
+
+ This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(KeyEventSink));
+ if (This == NULL)
+ return E_OUTOFMEMORY;
+
+ This->KeyEventSinkVtbl = &KeyEventSink_KeyEventSinkVtbl;
+ This->refCount = 1;
+
+ *ppOut = (ITfKeyEventSink*)This;
+ return S_OK;
+}
+
+
+static void test_KeystrokeMgr(void)
+{
+ ITfKeystrokeMgr *keymgr= NULL;
+ HRESULT hr;
+ TF_PRESERVEDKEY tfpk;
+ BOOL preserved;
+ ITfKeyEventSink *sink = NULL;
+
+ KeyEventSink_Constructor(&sink);
+
+ hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfKeystrokeMgr, (LPVOID*)&keymgr);
+ ok(SUCCEEDED(hr),"Failed to get IID_ITfKeystrokeMgr for ThreadMgr\n");
+
+ tfpk.uVKey = 'A';
+ tfpk.uModifiers = TF_MOD_SHIFT;
+
+ test_KEV_OnSetFocus = SINK_EXPECTED;
+ hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE);
+ ok(SUCCEEDED(hr),"ITfKeystrokeMgr_AdviseKeyEventSink failed\n");
+ sink_check_ok(&test_KEV_OnSetFocus,"KeyEventSink_OnSetFocus");
+ hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,tid,sink,TRUE);
+ ok(hr == CONNECT_E_ADVISELIMIT,"Wrong return, expected CONNECT_E_ADVISELIMIT\n");
+ hr = ITfKeystrokeMgr_AdviseKeyEventSink(keymgr,cid,sink,TRUE);
+ ok(hr == E_INVALIDARG,"Wrong return, expected E_INVALIDARG\n");
+
+ hr =ITfKeystrokeMgr_PreserveKey(keymgr, 0, &CLSID_PreservedKey, &tfpk, NULL, 0);
+ ok(hr==E_INVALIDARG,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n");
+
+ hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
+ ok(SUCCEEDED(hr),"ITfKeystrokeMgr_PreserveKey failed\n");
+
+ hr =ITfKeystrokeMgr_PreserveKey(keymgr, tid, &CLSID_PreservedKey, &tfpk, NULL, 0);
+ ok(hr == TF_E_ALREADY_EXISTS,"ITfKeystrokeMgr_PreserveKey inproperly succeeded\n");
+
+ preserved = FALSE;
+ hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
+ ok(hr == S_OK, "ITfKeystrokeMgr_IsPreservedKey failed\n");
+ if (hr == S_OK) ok(preserved == TRUE,"misreporting preserved key\n");
+
+ hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
+ ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnpreserveKey failed\n");
+
+ hr = ITfKeystrokeMgr_IsPreservedKey(keymgr, &CLSID_PreservedKey, &tfpk, &preserved);
+ ok(hr == S_FALSE, "ITfKeystrokeMgr_IsPreservedKey failed\n");
+ if (hr == S_FALSE) ok(preserved == FALSE,"misreporting preserved key\n");
+
+ hr = ITfKeystrokeMgr_UnpreserveKey(keymgr, &CLSID_PreservedKey,&tfpk);
+ ok(hr==CONNECT_E_NOCONNECTION,"ITfKeystrokeMgr_UnpreserveKey inproperly succeeded\n");
+
+ hr = ITfKeystrokeMgr_UnadviseKeyEventSink(keymgr,tid);
+ ok(SUCCEEDED(hr),"ITfKeystrokeMgr_UnadviseKeyEventSink failed\n");
+
+ ITfKeystrokeMgr_Release(keymgr);
+ ITfKeyEventSink_Release(sink);
+}
+
+static void test_Activate(void)
+{
+ HRESULT hr;
+
+ hr = ITfInputProcessorProfiles_ActivateLanguageProfile(g_ipp,&CLSID_FakeService,gLangid,&CLSID_FakeService);
+ ok(SUCCEEDED(hr),"Failed to Activate text service\n");
+}
+
+
+static void test_EnumContexts(ITfDocumentMgr *dm, ITfContext *search)
+{
+ HRESULT hr;
+ IEnumTfContexts* pEnum;
+ BOOL found = FALSE;
+
+ hr = ITfDocumentMgr_EnumContexts(dm,&pEnum);
+ ok(SUCCEEDED(hr),"EnumContexts failed\n");
+ if (SUCCEEDED(hr))
+ {
+ ULONG fetched;
+ ITfContext *cxt;
+ while (IEnumTfContexts_Next(pEnum, 1, &cxt, &fetched) == S_OK)
+ {
+ if (!search)
+ found = TRUE;
+ else if (search == cxt)
+ found = TRUE;
+ ITfContext_Release(cxt);
+ }
+ IEnumTfContexts_Release(pEnum);
+ }
+ if (search)
+ ok(found,"Did not find proper ITfContext\n");
+ else
+ ok(!found,"Found an ITfContext we should should not have\n");
+}
+
+static void test_EnumDocumentMgr(ITfThreadMgr *tm, ITfDocumentMgr *search, ITfDocumentMgr *absent)
+{
+ HRESULT hr;
+ IEnumTfDocumentMgrs* pEnum;
+ BOOL found = FALSE;
+ BOOL notfound = TRUE;
+
+ hr = ITfThreadMgr_EnumDocumentMgrs(tm,&pEnum);
+ ok(SUCCEEDED(hr),"EnumDocumentMgrs failed\n");
+ if (SUCCEEDED(hr))
+ {
+ ULONG fetched;
+ ITfDocumentMgr *dm;
+ while (IEnumTfDocumentMgrs_Next(pEnum, 1, &dm, &fetched) == S_OK)
+ {
+ if (!search)
+ found = TRUE;
+ else if (search == dm)
+ found = TRUE;
+ if (absent && dm == absent)
+ notfound = FALSE;
+ ITfDocumentMgr_Release(dm);
+ }
+ IEnumTfDocumentMgrs_Release(pEnum);
+ }
+ if (search)
+ ok(found,"Did not find proper ITfDocumentMgr\n");
+ else
+ ok(!found,"Found an ITfDocumentMgr we should should not have\n");
+ if (absent)
+ ok(notfound,"Found an ITfDocumentMgr we believe should be absent\n");
+}
+
+static inline int check_context_refcount(ITfContext *iface)
+{
+ IUnknown_AddRef(iface);
+ return IUnknown_Release(iface);
+}
+
+
+/**********************************************************************
+ * ITfTextEditSink
+ **********************************************************************/
+typedef struct tagTextEditSink
+{
+ const ITfTextEditSinkVtbl *TextEditSinkVtbl;
+ LONG refCount;
+} TextEditSink;
+
+static void TextEditSink_Destructor(TextEditSink *This)
+{
+ HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI TextEditSink_QueryInterface(ITfTextEditSink *iface, REFIID iid, LPVOID *ppvOut)
+{
+ TextEditSink *This = (TextEditSink *)iface;
+ *ppvOut = NULL;
+
+ if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfTextEditSink))
+ {
+ *ppvOut = This;
+ }
+
+ if (*ppvOut)
+ {
+ IUnknown_AddRef(iface);
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TextEditSink_AddRef(ITfTextEditSink *iface)
+{
+ TextEditSink *This = (TextEditSink *)iface;
+ return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI TextEditSink_Release(ITfTextEditSink *iface)
+{
+ TextEditSink *This = (TextEditSink *)iface;
+ ULONG ret;
+
+ ret = InterlockedDecrement(&This->refCount);
+ if (ret == 0)
+ TextEditSink_Destructor(This);
+ return ret;
+}
+
+static HRESULT WINAPI TextEditSink_OnEndEdit(ITfTextEditSink *iface,
+ ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
+{
+ sink_fire_ok(&test_OnEndEdit,"TextEditSink_OnEndEdit");
+ return S_OK;
+}
+
+static const ITfTextEditSinkVtbl TextEditSink_TextEditSinkVtbl =
+{
+ TextEditSink_QueryInterface,
+ TextEditSink_AddRef,
+ TextEditSink_Release,
+
+ TextEditSink_OnEndEdit
+};
+
+static HRESULT TextEditSink_Constructor(ITfTextEditSink **ppOut)
+{
+ TextEditSink *This;
+
+ *ppOut = NULL;
+ This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TextEditSink));
+ if (This == NULL)
+ return E_OUTOFMEMORY;
+
+ This->TextEditSinkVtbl = &TextEditSink_TextEditSinkVtbl;
+ This->refCount = 1;
+
+ *ppOut = (ITfTextEditSink*)This;
+ return S_OK;
+}
+
+static void test_startSession(void)
+{
+ HRESULT hr;
+ DWORD cnt;
+ DWORD editCookie;
+ ITfDocumentMgr *dmtest;
+ ITfContext *cxt,*cxt2,*cxt3,*cxtTest;
+ ITextStoreACP *ts;
+ TfClientId cid2 = 0;
+
+ hr = ITfThreadMgr_Deactivate(g_tm);
+ ok(hr == E_UNEXPECTED,"Deactivate should have failed with E_UNEXPECTED\n");
+
+ test_ShouldActivate = TRUE;
+ hr = ITfThreadMgr_Activate(g_tm,&cid);
+ ok(SUCCEEDED(hr),"Failed to Activate\n");
+ ok(cid != tid,"TextService id mistakenly matches Client id\n");
+
+ test_ShouldActivate = FALSE;
+ hr = ITfThreadMgr_Activate(g_tm,&cid2);
+ ok(SUCCEEDED(hr),"Failed to Activate\n");
+ ok (cid == cid2, "Second activate client ID does not match\n");
+
+ hr = ITfThreadMgr_Deactivate(g_tm);
+ ok(SUCCEEDED(hr),"Failed to Deactivate\n");
+
+ test_EnumDocumentMgr(g_tm,NULL,NULL);
+
+ hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&g_dm);
+ ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
+
+ test_EnumDocumentMgr(g_tm,g_dm,NULL);
+
+ hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dmtest);
+ ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
+
+ test_EnumDocumentMgr(g_tm,dmtest,NULL);
+
+ ITfDocumentMgr_Release(dmtest);
+ test_EnumDocumentMgr(g_tm,g_dm,dmtest);
+
+ hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
+ ok(SUCCEEDED(hr),"GetFocus Failed\n");
+ ok(dmtest == NULL,"Initial focus not null\n");
+
+ test_CurrentFocus = g_dm;
+ test_PrevFocus = NULL;
+ test_OnSetFocus = SINK_EXPECTED;
+ hr = ITfThreadMgr_SetFocus(g_tm,g_dm);
+ ok(SUCCEEDED(hr),"SetFocus Failed\n");
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
+ ok(SUCCEEDED(hr),"GetFocus Failed\n");
+ ok(g_dm == dmtest,"Expected DocumentMgr not focused\n");
+
+ cnt = ITfDocumentMgr_Release(g_dm);
+ ok(cnt == 2,"DocumentMgr refcount not expected (2 vs %i)\n",cnt);
+
+ hr = ITfThreadMgr_GetFocus(g_tm,&dmtest);
+ ok(SUCCEEDED(hr),"GetFocus Failed\n");
+ ok(g_dm == dmtest,"Expected DocumentMgr not focused\n");
+ ITfDocumentMgr_Release(dmtest);
+
+ TextStoreACP_Constructor((IUnknown**)&ts);
+
+ hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, (IUnknown*)ts, &cxt, &editCookie);
+ ok(SUCCEEDED(hr),"CreateContext Failed\n");
+
+ hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt2, &editCookie);
+ ok(SUCCEEDED(hr),"CreateContext Failed\n");
+
+ hr = ITfDocumentMgr_CreateContext(g_dm, cid, 0, NULL, &cxt3, &editCookie);
+ ok(SUCCEEDED(hr),"CreateContext Failed\n");
+
+ test_EnumContexts(g_dm, NULL);
+
+ hr = ITfContext_GetDocumentMgr(cxt,&dmtest);
+ ok(hr == S_OK, "ITfContext_GetDocumentMgr failed with %x\n",hr);
+ ok(dmtest == g_dm, "Wrong documentmgr\n");
+ ITfDocumentMgr_Release(dmtest);
+
+ cnt = check_context_refcount(cxt);
+ test_OnPushContext = SINK_EXPECTED;
+ test_ACP_AdviseSink = SINK_EXPECTED;
+ test_OnInitDocumentMgr = SINK_EXPECTED;
+ hr = ITfDocumentMgr_Push(g_dm, cxt);
+ ok(SUCCEEDED(hr),"Push Failed\n");
+ ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
+ sink_check_ok(&test_OnPushContext,"OnPushContext");
+ sink_check_ok(&test_OnInitDocumentMgr,"OnInitDocumentMgr");
+ sink_check_ok(&test_ACP_AdviseSink,"TextStoreACP_AdviseSink");
+
+ test_EnumContexts(g_dm, cxt);
+
+ hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetTop Failed\n");
+ ok(cxtTest == cxt, "Wrong context on top\n");
+ ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
+ cnt = ITfContext_Release(cxtTest);
+
+ hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetBase Failed\n");
+ ok(cxtTest == cxt, "Wrong context on Base\n");
+ ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
+ ITfContext_Release(cxtTest);
+
+ check_context_refcount(cxt2);
+ test_OnPushContext = SINK_EXPECTED;
+ hr = ITfDocumentMgr_Push(g_dm, cxt2);
+ ok(SUCCEEDED(hr),"Push Failed\n");
+ sink_check_ok(&test_OnPushContext,"OnPushContext");
+
+ cnt = check_context_refcount(cxt2);
+ hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetTop Failed\n");
+ ok(cxtTest == cxt2, "Wrong context on top\n");
+ ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n");
+ ITfContext_Release(cxtTest);
+
+ cnt = check_context_refcount(cxt);
+ hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetBase Failed\n");
+ ok(cxtTest == cxt, "Wrong context on Base\n");
+ ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
+ ITfContext_Release(cxtTest);
+
+ cnt = check_context_refcount(cxt3);
+ hr = ITfDocumentMgr_Push(g_dm, cxt3);
+ ok(FAILED(hr),"Push Succeeded\n");
+ ok(check_context_refcount(cxt3) == cnt, "Ref changed\n");
+
+ cnt = check_context_refcount(cxt2);
+ hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetTop Failed\n");
+ ok(cxtTest == cxt2, "Wrong context on top\n");
+ ok(check_context_refcount(cxt2) > cnt, "Ref count did not increase\n");
+ ITfContext_Release(cxtTest);
+
+ cnt = check_context_refcount(cxt);
+ hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetBase Failed\n");
+ ok(cxtTest == cxt, "Wrong context on Base\n");
+ ok(check_context_refcount(cxt) > cnt, "Ref count did not increase\n");
+ ITfContext_Release(cxtTest);
+
+ cnt = check_context_refcount(cxt2);
+ test_OnPopContext = SINK_EXPECTED;
+ hr = ITfDocumentMgr_Pop(g_dm, 0);
+ ok(SUCCEEDED(hr),"Pop Failed\n");
+ ok(check_context_refcount(cxt2) < cnt, "Ref count did not decrease\n");
+ sink_check_ok(&test_OnPopContext,"OnPopContext");
+
+ dmtest = (void *)0xfeedface;
+ hr = ITfContext_GetDocumentMgr(cxt2,&dmtest);
+ ok(hr == S_FALSE, "ITfContext_GetDocumentMgr wrong rc %x\n",hr);
+ ok(dmtest == NULL,"returned documentmgr should be null\n");
+
+ hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetTop Failed\n");
+ ok(cxtTest == cxt, "Wrong context on top\n");
+ ITfContext_Release(cxtTest);
+
+ hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetBase Failed\n");
+ ok(cxtTest == cxt, "Wrong context on base\n");
+ ITfContext_Release(cxtTest);
+
+ hr = ITfDocumentMgr_Pop(g_dm, 0);
+ ok(FAILED(hr),"Pop Succeeded\n");
+
+ hr = ITfDocumentMgr_GetTop(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetTop Failed\n");
+ ok(cxtTest == cxt, "Wrong context on top\n");
+ ITfContext_Release(cxtTest);
+
+ hr = ITfDocumentMgr_GetBase(g_dm, &cxtTest);
+ ok(SUCCEEDED(hr),"GetBase Failed\n");
+ ok(cxtTest == cxt, "Wrong context on base\n");
+ ITfContext_Release(cxtTest);
+
+ ITfContext_Release(cxt);
+ ITfContext_Release(cxt2);
+ ITfContext_Release(cxt3);
+}
+
+static void test_endSession(void)
+{
+ HRESULT hr;
+ test_ShouldDeactivate = TRUE;
+ test_CurrentFocus = NULL;
+ test_PrevFocus = g_dm;
+ test_OnSetFocus = SINK_EXPECTED;
+ hr = ITfThreadMgr_Deactivate(g_tm);
+ ok(SUCCEEDED(hr),"Failed to Deactivate\n");
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+ test_OnSetFocus = SINK_UNEXPECTED;
+}
+
+static void test_TfGuidAtom(void)
+{
+ GUID gtest,g1;
+ HRESULT hr;
+ TfGuidAtom atom1,atom2;
+ BOOL equal;
+
+ CoCreateGuid(>est);
+
+ /* msdn reports this should return E_INVALIDARG. However my test show it crashing (winxp)*/
+ /*
+ hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,NULL);
+ ok(hr==E_INVALIDARG,"ITfCategoryMgr_RegisterGUID should have failed\n");
+ */
+ hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom1);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n");
+ hr = ITfCategoryMgr_RegisterGUID(g_cm,>est,&atom2);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_RegisterGUID failed\n");
+ ok(atom1 == atom2,"atoms do not match\n");
+ hr = ITfCategoryMgr_GetGUID(g_cm,atom2,NULL);
+ ok(hr==E_INVALIDARG,"ITfCategoryMgr_GetGUID should have failed\n");
+ hr = ITfCategoryMgr_GetGUID(g_cm,atom2,&g1);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n");
+ ok(IsEqualGUID(&g1,>est),"guids do not match\n");
+ hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,NULL);
+ ok(hr==E_INVALIDARG,"ITfCategoryMgr_IsEqualTfGuidAtom should have failed\n");
+ hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,atom1,>est,&equal);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n");
+ ok(equal == TRUE,"Equal value invalid\n");
+
+ /* show that cid and tid TfClientIds are also TfGuidAtoms */
+ hr = ITfCategoryMgr_IsEqualTfGuidAtom(g_cm,tid,&CLSID_FakeService,&equal);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_IsEqualTfGuidAtom failed\n");
+ ok(equal == TRUE,"Equal value invalid\n");
+ hr = ITfCategoryMgr_GetGUID(g_cm,cid,&g1);
+ ok(SUCCEEDED(hr),"ITfCategoryMgr_GetGUID failed\n");
+ ok(!IsEqualGUID(&g1,&GUID_NULL),"guid should not be NULL\n");
+}
+
+static void test_ClientId(void)
+{
+ ITfClientId *pcid;
+ TfClientId id1,id2;
+ HRESULT hr;
+ GUID g2;
+
+ hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfClientId, (LPVOID*)&pcid);
+ ok(SUCCEEDED(hr),"Unable to acquire ITfClientId interface\n");
+
+ CoCreateGuid(&g2);
+
+ hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id1);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ hr = ITfClientId_GetClientId(pcid,&GUID_NULL,&id2);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ ok(id1==id2,"Id's for GUID_NULL do not match\n");
+ hr = ITfClientId_GetClientId(pcid,&CLSID_FakeService,&id2);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ ok(id2!=id1,"Id matches GUID_NULL\n");
+ ok(id2==tid,"Id for CLSID_FakeService not matching tid\n");
+ ok(id2!=cid,"Id for CLSID_FakeService matching cid\n");
+ hr = ITfClientId_GetClientId(pcid,&g2,&id2);
+ ok(SUCCEEDED(hr),"GetClientId failed\n");
+ ok(id2!=id1,"Id matches GUID_NULL\n");
+ ok(id2!=tid,"Id for random guid matching tid\n");
+ ok(id2!=cid,"Id for random guid matching cid\n");
+ ITfClientId_Release(pcid);
+}
+
+/**********************************************************************
+ * ITfEditSession
+ **********************************************************************/
+typedef struct tagEditSession
+{
+ const ITfEditSessionVtbl *EditSessionVtbl;
+ LONG refCount;
+} EditSession;
+
+static void EditSession_Destructor(EditSession *This)
+{
+ HeapFree(GetProcessHeap(),0,This);
+}
+
+static HRESULT WINAPI EditSession_QueryInterface(ITfEditSession *iface, REFIID iid, LPVOID *ppvOut)
+{
+ EditSession *This = (EditSession *)iface;
+ *ppvOut = NULL;
+
+ if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_ITfEditSession))
+ {
+ *ppvOut = This;
+ }
+
+ if (*ppvOut)
+ {
+ IUnknown_AddRef(iface);
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI EditSession_AddRef(ITfEditSession *iface)
+{
+ EditSession *This = (EditSession *)iface;
+ return InterlockedIncrement(&This->refCount);
+}
+
+static ULONG WINAPI EditSession_Release(ITfEditSession *iface)
+{
+ EditSession *This = (EditSession *)iface;
+ ULONG ret;
+
+ ret = InterlockedDecrement(&This->refCount);
+ if (ret == 0)
+ EditSession_Destructor(This);
+ return ret;
+}
+
+static void test_InsertAtSelection(TfEditCookie ec, ITfContext *cxt)
+{
+ HRESULT hr;
+ ITfInsertAtSelection *iis;
+ ITfRange *range=NULL;
+ static const WCHAR txt[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
+
+ hr = ITfContext_QueryInterface(cxt, &IID_ITfInsertAtSelection , (LPVOID*)&iis);
+ ok(SUCCEEDED(hr),"Failed to get ITfInsertAtSelection interface\n");
+ test_ACP_InsertTextAtSelection = SINK_EXPECTED;
+ hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, txt, 11, &range);
+ ok(SUCCEEDED(hr),"ITfInsertAtSelection_InsertTextAtSelection failed %x\n",hr);
+ sink_check_ok(&test_ACP_InsertTextAtSelection,"InsertTextAtSelection");
+ ok(range != NULL,"No range returned\n");
+ ITfRange_Release(range);
+ ITfInsertAtSelection_Release(iis);
+}
+
+static HRESULT WINAPI EditSession_DoEditSession(ITfEditSession *iface,
+TfEditCookie ec)
+{
+ ITfContext *cxt;
+ ITfDocumentMgr *dm;
+ ITfRange *range;
+ TF_SELECTION selection;
+ ULONG fetched;
+ HRESULT hr;
+
+ sink_fire_ok(&test_DoEditSession,"EditSession_DoEditSession");
+ sink_check_ok(&test_ACP_RequestLock,"RequestLock");
+
+ ITfThreadMgr_GetFocus(g_tm, &dm);
+ ITfDocumentMgr_GetTop(dm,&cxt);
+
+ hr = ITfContext_GetStart(cxt,ec,NULL);
+ ok(hr == E_INVALIDARG,"Unexpected return code %x\n",hr);
+
+ range = (ITfRange*)0xdeaddead;
+ hr = ITfContext_GetStart(cxt,0xdeadcafe,&range);
+ ok(hr == TF_E_NOLOCK,"Unexpected return code %x\n",hr);
+ ok(range == NULL,"Range not set to NULL\n");
+
+ hr = ITfContext_GetStart(cxt,ec,&range);
+ ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr);
+ ok(range != NULL,"Range set to NULL\n");
+
+ ITfRange_Release(range);
+
+ hr = ITfContext_GetEnd(cxt,ec,NULL);
+ ok(hr == E_INVALIDARG,"Unexpected return code %x\n",hr);
+
+ range = (ITfRange*)0xdeaddead;
+ hr = ITfContext_GetEnd(cxt,0xdeadcafe,&range);
+ ok(hr == TF_E_NOLOCK,"Unexpected return code %x\n",hr);
+ ok(range == NULL,"Range not set to NULL\n");
+
+ test_ACP_GetEndACP = SINK_EXPECTED;
+ hr = ITfContext_GetEnd(cxt,ec,&range);
+ ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr);
+ ok(range != NULL,"Range set to NULL\n");
+ sink_check_ok(&test_ACP_GetEndACP,"GetEndACP");
+
+ ITfRange_Release(range);
+
+ selection.range = NULL;
+ test_ACP_GetSelection = SINK_EXPECTED;
+ hr = ITfContext_GetSelection(cxt, ec, TF_DEFAULT_SELECTION, 1, &selection, &fetched);
+ ok(SUCCEEDED(hr),"ITfContext_GetSelection failed\n");
+ ok(fetched == 1,"fetched incorrect\n");
+ ok(selection.range != NULL,"NULL range\n");
+ sink_check_ok(&test_ACP_GetSelection,"ACP_GetSepection");
+ ITfRange_Release(selection.range);
+
+ test_InsertAtSelection(ec, cxt);
+
+ test_ACP_GetEndACP = SINK_EXPECTED;
+ hr = ITfContext_GetEnd(cxt,ec,&range);
+ ok(SUCCEEDED(hr),"Unexpected return code %x\n",hr);
+ ok(range != NULL,"Range set to NULL\n");
+ sink_check_ok(&test_ACP_GetEndACP,"GetEndACP");
+
+ selection.range = range;
+ selection.style.ase = TF_AE_NONE;
+ selection.style.fInterimChar = FALSE;
+ test_ACP_SetSelection = SINK_EXPECTED;
+ hr = ITfContext_SetSelection(cxt, ec, 1, &selection);
+ sink_check_ok(&test_ACP_SetSelection,"SetSelection");
+ ITfRange_Release(range);
+
+ ITfContext_Release(cxt);
+ ITfDocumentMgr_Release(dm);
+ return 0xdeadcafe;
+}
+
+static const ITfEditSessionVtbl EditSession_EditSessionVtbl =
+{
+ EditSession_QueryInterface,
+ EditSession_AddRef,
+ EditSession_Release,
+
+ EditSession_DoEditSession
+};
+
+static HRESULT EditSession_Constructor(ITfEditSession **ppOut)
+{
+ EditSession *This;
+
+ *ppOut = NULL;
+ This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EditSession));
+ if (This == NULL)
+ return E_OUTOFMEMORY;
+
+ This->EditSessionVtbl = &EditSession_EditSessionVtbl;
+ This->refCount = 1;
+
+ *ppOut = (ITfEditSession*)This;
+ return S_OK;
+}
+
+static void test_TStoApplicationText(void)
+{
+ HRESULT hr, hrSession;
+ ITfEditSession *es;
+ ITfContext *cxt;
+ ITfDocumentMgr *dm;
+ ITfTextEditSink *sink;
+ ITfSource *source = NULL;
+ DWORD editSinkCookie = -1;
+
+ ITfThreadMgr_GetFocus(g_tm, &dm);
+ EditSession_Constructor(&es);
+ ITfDocumentMgr_GetTop(dm,&cxt);
+
+ TextEditSink_Constructor(&sink);
+ hr = ITfContext_QueryInterface(cxt,&IID_ITfSource,(LPVOID*)&source);
+ ok(SUCCEEDED(hr),"Failed to get IID_ITfSource for Context\n");
+ if (source)
+ {
+ hr = ITfSource_AdviseSink(source, &IID_ITfTextEditSink, (LPVOID)sink, &editSinkCookie);
+ ok(SUCCEEDED(hr),"Failed to advise Sink\n");
+ ok(editSinkCookie != -1,"Failed to get sink cookie\n");
+ }
+
+ hrSession = 0xfeedface;
+ /* Test no premissions flags */
+ hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC, &hrSession);
+ ok(hr == E_INVALIDARG,"RequestEditSession should have failed with %x not %x\n",E_INVALIDARG,hr);
+ ok(hrSession == E_FAIL,"hrSession should be %x not %x\n",E_FAIL,hrSession);
+
+ documentStatus = TS_SD_READONLY;
+ hrSession = 0xfeedface;
+ test_ACP_GetStatus = SINK_EXPECTED;
+ hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession);
+ ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n");
+ ok(hrSession == TS_E_READONLY,"Unexpected hrSession (%x)\n",hrSession);
+ sink_check_ok(&test_ACP_GetStatus,"GetStatus");
+
+ /* signal a change to allow readwrite sessions */
+ documentStatus = 0;
+ test_ACP_RequestLock = SINK_EXPECTED;
+ ITextStoreACPSink_OnStatusChange(ACPSink,documentStatus);
+ sink_check_ok(&test_ACP_RequestLock,"RequestLock");
+
+ test_ACP_GetStatus = SINK_EXPECTED;
+ test_ACP_RequestLock = SINK_EXPECTED;
+ test_DoEditSession = SINK_EXPECTED;
+ hrSession = 0xfeedface;
+ test_OnEndEdit = SINK_EXPECTED;
+ hr = ITfContext_RequestEditSession(cxt, tid, es, TF_ES_SYNC|TF_ES_READWRITE, &hrSession);
+ ok(SUCCEEDED(hr),"ITfContext_RequestEditSession failed\n");
+ sink_check_ok(&test_OnEndEdit,"OnEndEdit");
+ sink_check_ok(&test_DoEditSession,"DoEditSession");
+ sink_check_ok(&test_ACP_GetStatus,"GetStatus");
+ ok(hrSession == 0xdeadcafe,"Unexpected hrSession (%x)\n",hrSession);
+
+ if (source)
+ {
+ hr = ITfSource_UnadviseSink(source, editSinkCookie);
+ ok(SUCCEEDED(hr),"Failed to unadvise Sink\n");
+ ITfTextEditSink_Release(sink);
+ ITfSource_Release(source);
+ }
+
+ ITfContext_Release(cxt);
+ ITfDocumentMgr_Release(dm);
+ ITfEditSession_Release(es);
+}
+
+static void enum_compartments(ITfCompartmentMgr *cmpmgr, REFGUID present, REFGUID absent)
+{
+ BOOL found,found2;
+ IEnumGUID *ppEnum;
+ found = FALSE;
+ found2 = FALSE;
+ if (SUCCEEDED(ITfCompartmentMgr_EnumCompartments(cmpmgr, &ppEnum)))
+ {
+ ULONG fetched;
+ GUID g;
+ while (IEnumGUID_Next(ppEnum, 1, &g, &fetched) == S_OK)
+ {
+ WCHAR str[50];
+ CHAR strA[50];
+ StringFromGUID2(&g,str,sizeof(str)/sizeof(str[0]));
+ WideCharToMultiByte(CP_ACP,0,str,-1,strA,sizeof(strA),0,0);
+ trace("found %s\n",strA);
+ if (present && IsEqualGUID(present,&g))
+ found = TRUE;
+ if (absent && IsEqualGUID(absent, &g))
+ found2 = TRUE;
+ }
+ IEnumGUID_Release(ppEnum);
+ }
+ if (present)
+ ok(found,"Did not find compartment\n");
+ if (absent)
+ ok(!found2,"Found compartment that should be absent\n");
+}
+
+static void test_Compartments(void)
+{
+ ITfContext *cxt;
+ ITfDocumentMgr *dm;
+ ITfCompartmentMgr *cmpmgr;
+ ITfCompartment *cmp;
+ HRESULT hr;
+
+ ITfThreadMgr_GetFocus(g_tm, &dm);
+ ITfDocumentMgr_GetTop(dm,&cxt);
+
+ /* Global */
+ hr = ITfThreadMgr_GetGlobalCompartment(g_tm, &cmpmgr);
+ ok(SUCCEEDED(hr),"GetGlobalCompartment failed\n");
+ hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &GUID_COMPARTMENT_SPEECH_OPENCLOSE, &cmp);
+ ok(SUCCEEDED(hr),"GetCompartment failed\n");
+ ITfCompartment_Release(cmp);
+ enum_compartments(cmpmgr,&GUID_COMPARTMENT_SPEECH_OPENCLOSE,NULL);
+ ITfCompartmentMgr_Release(cmpmgr);
+
+ /* Thread */
+ hr = ITfThreadMgr_QueryInterface(g_tm, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr);
+ ok(SUCCEEDED(hr),"ThreadMgr QI for IID_ITfCompartmentMgr failed\n");
+ hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &CLSID_FakeService, &cmp);
+ ok(SUCCEEDED(hr),"GetCompartment failed\n");
+ enum_compartments(cmpmgr,&CLSID_FakeService,&GUID_COMPARTMENT_SPEECH_OPENCLOSE);
+ ITfCompartmentMgr_ClearCompartment(cmpmgr,tid,&CLSID_FakeService);
+ enum_compartments(cmpmgr,NULL,&CLSID_FakeService);
+ ITfCompartmentMgr_Release(cmpmgr);
+ ITfCompartment_Release(cmp);
+
+ /* DocumentMgr */
+ hr = ITfDocumentMgr_QueryInterface(dm, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr);
+ ok(SUCCEEDED(hr),"DocumentMgr QI for IID_ITfCompartmentMgr failed\n");
+
+ hr = ITfCompartmentMgr_GetCompartment(cmpmgr, &GUID_COMPARTMENT_PERSISTMENUENABLED, &cmp);
+ ok(SUCCEEDED(hr),"GetCompartment failed\n");
+ enum_compartments(cmpmgr,&GUID_COMPARTMENT_PERSISTMENUENABLED,&GUID_COMPARTMENT_SPEECH_OPENCLOSE);
+ ITfCompartmentMgr_Release(cmpmgr);
+
+ /* Context */
+ hr = ITfContext_QueryInterface(cxt, &IID_ITfCompartmentMgr, (LPVOID*)&cmpmgr);
+ ok(SUCCEEDED(hr),"Context QI for IID_ITfCompartmentMgr failed\n");
+ enum_compartments(cmpmgr,NULL,&GUID_COMPARTMENT_PERSISTMENUENABLED);
+ ITfCompartmentMgr_Release(cmpmgr);
+
+ ITfContext_Release(cxt);
+ ITfDocumentMgr_Release(dm);
+}
+
+static void processPendingMessages(void)
+{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+static void test_AssociateFocus(void)
+{
+ ITfDocumentMgr *dm1, *dm2, *olddm, *dmcheck, *dmorig;
+ HWND wnd1, wnd2, wnd3;
+ HRESULT hr;
+
+ ITfThreadMgr_GetFocus(g_tm, &dmorig);
+ test_CurrentFocus = NULL;
+ test_PrevFocus = dmorig;
+ test_OnSetFocus = SINK_EXPECTED;
+ hr = ITfThreadMgr_SetFocus(g_tm,NULL);
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+ ITfDocumentMgr_Release(dmorig);
+
+ hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm1);
+ ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
+
+ hr = ITfThreadMgr_CreateDocumentMgr(g_tm,&dm2);
+ ok(SUCCEEDED(hr),"CreateDocumentMgr failed\n");
+
+ wnd1 = CreateWindow("edit",NULL,WS_POPUP,0,0,200,60,NULL,NULL,NULL,NULL);
+ ok(wnd1!=NULL,"Unable to create window 1\n");
+ wnd2 = CreateWindow("edit",NULL,WS_POPUP,0,65,200,60,NULL,NULL,NULL,NULL);
+ ok(wnd2!=NULL,"Unable to create window 2\n");
+ wnd3 = CreateWindow("edit",NULL,WS_POPUP,0,130,200,60,NULL,NULL,NULL,NULL);
+ ok(wnd3!=NULL,"Unable to create window 3\n");
+
+ processPendingMessages();
+
+ test_OnInitDocumentMgr = SINK_OPTIONAL; /* Vista and greater */
+ test_OnPushContext = SINK_OPTIONAL; /* Vista and greater */
+
+ ShowWindow(wnd1,SW_SHOWNORMAL);
+ SetFocus(wnd1);
+ sink_check_ok(&test_OnInitDocumentMgr,"OnInitDocumentMgr");
+ sink_check_ok(&test_OnPushContext,"OnPushContext");
+
+ test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */
+ ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus);
+ test_CurrentFocus = FOCUS_IGNORE; /* This is a default system context */
+ processPendingMessages();
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ test_CurrentFocus = dm1;
+ test_PrevFocus = FOCUS_IGNORE;
+ test_OnSetFocus = SINK_EXPECTED;
+ hr = ITfThreadMgr_AssociateFocus(g_tm,wnd1,dm1,&olddm);
+ ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ processPendingMessages();
+
+ ITfThreadMgr_GetFocus(g_tm, &dmcheck);
+ ok(dmcheck == dm1, "Expected DocumentMgr not focused\n");
+ ITfDocumentMgr_Release(dmcheck);
+
+ hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,dm2,&olddm);
+ ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+ processPendingMessages();
+ ITfThreadMgr_GetFocus(g_tm, &dmcheck);
+ ok(dmcheck == dm1, "Expected DocumentMgr not focused\n");
+ ITfDocumentMgr_Release(dmcheck);
+
+ hr = ITfThreadMgr_AssociateFocus(g_tm,wnd3,dm2,&olddm);
+ ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+ processPendingMessages();
+ ITfThreadMgr_GetFocus(g_tm, &dmcheck);
+ ok(dmcheck == dm1, "Expected DocumentMgr not focused\n");
+ ITfDocumentMgr_Release(dmcheck);
+
+ test_CurrentFocus = dm2;
+ test_PrevFocus = dm1;
+ test_OnSetFocus = SINK_OPTIONAL; /* wine and Winxp */
+ ShowWindow(wnd2,SW_SHOWNORMAL);
+ SetFocus(wnd2);
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+ test_CurrentFocus = FOCUS_IGNORE; /* occasional wine race */
+ test_PrevFocus = FOCUS_IGNORE; /* occasional wine race */
+ test_OnSetFocus = SINK_IGNORE; /* occasional wine race */
+ processPendingMessages();
+
+ ShowWindow(wnd3,SW_SHOWNORMAL);
+ SetFocus(wnd3);
+ processPendingMessages();
+
+ test_CurrentFocus = dm1;
+ test_PrevFocus = dm2;
+ test_OnSetFocus = SINK_EXPECTED;
+ SetFocus(wnd1);
+ processPendingMessages();
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ hr = ITfThreadMgr_AssociateFocus(g_tm,wnd3,NULL,&olddm);
+ ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+ ok(olddm == dm2, "incorrect old DocumentMgr returned\n");
+ ITfDocumentMgr_Release(olddm);
+
+ test_CurrentFocus = dmorig;
+ test_PrevFocus = dm1;
+ test_OnSetFocus = SINK_EXPECTED;
+ test_ACP_GetStatus = SINK_EXPECTED;
+ ITfThreadMgr_SetFocus(g_tm,dmorig);
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ test_CurrentFocus = FOCUS_IGNORE; /* NULL on XP, system default on Vista */
+ test_PrevFocus = dmorig;
+ test_OnSetFocus = SINK_EXPECTED;
+ SetFocus(wnd3);
+ processPendingMessages();
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,NULL,&olddm);
+ ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+ ok(olddm == dm2, "incorrect old DocumentMgr returned\n");
+ ITfDocumentMgr_Release(olddm);
+ hr = ITfThreadMgr_AssociateFocus(g_tm,wnd1,NULL,&olddm);
+ ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+ ok(olddm == dm1, "incorrect old DocumentMgr returned\n");
+ ITfDocumentMgr_Release(olddm);
+
+ SetFocus(wnd2);
+ processPendingMessages();
+ SetFocus(wnd1);
+ processPendingMessages();
+
+ ITfDocumentMgr_Release(dm1);
+ ITfDocumentMgr_Release(dm2);
+
+ test_CurrentFocus = dmorig;
+ test_PrevFocus = FOCUS_IGNORE;
+ test_OnSetFocus = SINK_EXPECTED;
+ test_ACP_GetStatus = SINK_IGNORE;
+ ITfThreadMgr_SetFocus(g_tm,dmorig);
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+
+ DestroyWindow(wnd1);
+ DestroyWindow(wnd2);
+ test_OnPopContext = SINK_OPTIONAL; /* Vista and greater */
+ test_OnSetFocus = SINK_OPTIONAL; /* Vista and greater */
+ ITfThreadMgr_GetFocus(g_tm, &test_PrevFocus);
+ test_CurrentFocus = NULL;
+ DestroyWindow(wnd3);
+ sink_check_ok(&test_OnSetFocus,"OnSetFocus");
+ sink_check_ok(&test_OnPopContext,"OnPopContext");
+}
+
+START_TEST(inputprocessor)
+{
+ if (SUCCEEDED(initialize()))
+ {
+ test_Register();
+ test_RegisterCategory();
+ test_EnumLanguageProfiles();
+ test_EnumInputProcessorInfo();
+ test_Enable();
+ test_ThreadMgrAdviseSinks();
+ test_Activate();
+ test_startSession();
+ test_TfGuidAtom();
+ test_ClientId();
+ test_KeystrokeMgr();
+ test_TStoApplicationText();
+ test_Compartments();
+ test_AssociateFocus();
+ test_endSession();
+ test_FindClosestCategory();
+ test_Disable();
+ test_ThreadMgrUnadviseSinks();
+ test_UnregisterCategory();
+ test_Unregister();
+ }
+ else
+ skip("Unable to create InputProcessor\n");
+ cleanup();
+}
diff --git a/rostests/winetests/mshtml/dom.c b/rostests/winetests/mshtml/dom.c
index 25bf7641eb1..c6f54793ce5 100644
--- a/rostests/winetests/mshtml/dom.c
+++ b/rostests/winetests/mshtml/dom.c
@@ -3173,6 +3173,16 @@ static void test_navigator(IHTMLDocument2 *doc)
ok(!strcmp_wa(bstr, buf), "userAgent returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf);
SysFreeString(bstr);
+ if(!strncmp(buf, "Mozilla/", 8)) {
+ bstr = NULL;
+ hres = IOmNavigator_get_appVersion(navigator, &bstr);
+ ok(hres == S_OK, "get_appVersion failed: %08x\n", hres);
+ ok(!strcmp_wa(bstr, buf+8), "appVersion returned %s, expected \"%s\"\n", wine_dbgstr_w(bstr), buf+8);
+ SysFreeString(bstr);
+ }else {
+ skip("nonstandard user agent\n");
+ }
+
ref = IOmNavigator_Release(navigator);
ok(!ref, "navigator should be destroyed here\n");
}
@@ -3185,8 +3195,6 @@ static void test_screen(IHTMLWindow2 *window)
HDC hdc;
HRESULT hres;
- static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
-
screen = NULL;
hres = IHTMLWindow2_get_screen(window, &screen);
ok(hres == S_OK, "get_screen failed: %08x\n", hres);
@@ -3206,7 +3214,7 @@ static void test_screen(IHTMLWindow2 *window)
IDispatchEx_Release(dispex);
}
- hdc = CreateICW(displayW, NULL, NULL, NULL);
+ hdc = CreateICA("DISPLAY", NULL, NULL, NULL);
exl = GetDeviceCaps(hdc, HORZRES);
l = 0xdeadbeef;
diff --git a/rostests/winetests/mshtml/events.c b/rostests/winetests/mshtml/events.c
index 16f727fdec7..d62df7a3b0b 100644
--- a/rostests/winetests/mshtml/events.c
+++ b/rostests/winetests/mshtml/events.c
@@ -67,6 +67,8 @@ DEFINE_EXPECT(div_onclick_disp);
DEFINE_EXPECT(iframe_onreadystatechange_loading);
DEFINE_EXPECT(iframe_onreadystatechange_interactive);
DEFINE_EXPECT(iframe_onreadystatechange_complete);
+DEFINE_EXPECT(iframedoc_onreadystatechange);
+DEFINE_EXPECT(img_onload);
static HWND container_hwnd = NULL;
static IHTMLWindow2 *window;
@@ -92,7 +94,10 @@ static const char click_doc_str[] =
"