From 0a4f4b9ced1424dd670301837c6a233d8ac94043 Mon Sep 17 00:00:00 2001 From: Austin Lund Date: Thu, 3 Jul 2008 15:53:32 +1000 Subject: [PATCH] richedit: Added a test for TxDraw in txtsrv.c. This test will output the capital letters in an undecorated window exactly the size of the text. The window will kill itself within 2 seconds if WINETEST_INTERACTIVE is set otherwise it will kill itself immediately. --- dlls/riched20/tests/txtsrv.c | 211 +++++++++++++++++++++++++++++++++++++++++- 1 files changed, 209 insertions(+), 2 deletions(-) diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c index 1d062fe..73ea2a7 100644 --- a/dlls/riched20/tests/txtsrv.c +++ b/dlls/riched20/tests/txtsrv.c @@ -124,6 +124,33 @@ __ASM_GLOBAL_FUNC(fnTextSrv_TxGetNaturalSize, STDCALL_TO_THISCALL); psizelExtent, pwidth, pheight) #endif +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxDraw(LPVOID function, + ITextServices *iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcDraw, + HDC hdcTargetDev, + LPCRECTL lprcBounds, + LPCRECTL lprcWBounds, + LPRECT lprcUpdate, + BOOL (CALLBACK * pfnContinue)(DWORD), + DWORD dwContinue, + LONG lViewId); +__ASM_GLOBAL_FUNC(fnTextSrv_TxDraw, STDCALL_TO_THISCALL) +#else +#define fnTextSrv_TxDraw(function, iface, dwDrawAspect, lindex, \ + pvAspect, ptd, hdcDraw, hdcTargetDev, \ + lprcBounds, lprcWBounds, lprcUpdate, \ + pfnContinue, dwContinue, lViewId) \ + function(iface, dwDrawAspect, lindex, pvAspect, \ + ptd, hdcDraw, hdcTargetDev, lprcBounds, \ + lprcWBounds, lprcUpdate, pfnContinue, \ + dwContinue, lViewId) +#endif + /************************************************************************/ /* ITextHost implementation for conformance testing. */ @@ -356,6 +383,12 @@ COLORREF WINAPI ITextHostImpl_TxGetSysColor(ITextHost *iface, int nIndex) { ITextHostTestImpl *This = (ITextHostTestImpl *)iface; trace("(%p) Call to TxGetSysColor (nIndex %d)\n", This, nIndex); + switch(nIndex) { + case COLOR_WINDOW: + return RGB(255,255,255); + case COLOR_WINDOWTEXT: + return RGB(0,0,0); + } return E_NOTIMPL; } @@ -434,7 +467,6 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, trace("(%p) Call to TxNotify (iNotify %d, pv %p)\n", This, iNotify, pv); return E_NOTIMPL; } - HIMC WINAPI ITextHostImpl_TxImmGetContext(ITextHost *iface) { ITextHostTestImpl *This = (ITextHostTestImpl *)iface; trace("(%p) Call to TxImmGetContext\n", This); @@ -446,12 +478,16 @@ void WINAPI ITextHostImpl_TxImmReleaseContext(ITextHost *iface, HIMC himc) { trace("(%p) Call to TxImmReleaseContext\n", This); } +/* This function must set the variable pointed to by *lSelBarWidth. + Otherwise an uninitalized value will be used to calculate + positions. */ HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface, LONG *lSelBarWidth) { ITextHostTestImpl *This = (ITextHostTestImpl *)iface; trace("(%p) Call to TxGetSelectionBarWidth (lSelBarWidth %p)\n", This, lSelBarWidth); - return E_NOTIMPL; + *lSelBarWidth = 0; + return S_OK; } /* Each function must now be converted into a thiscall style function. @@ -916,6 +952,170 @@ void TEST_TxGetNaturalSize_MEASURE() { ReleaseDC(NULL,hdcDraw); } +/* Test TxDraw and actually draw on a hdcDraw within the rectangle + * given in client. */ +void TEST_TxDraw(HDC hdcDraw, LPRECTL client) { + DWORD dwAspect = (DWORD) ((DVASPECT) DVASPECT_CONTENT); + HDC hicTargetDev = NULL; /* Means "default" device */ + DVTARGETDEVICE *ptd = NULL; + void * pvAspect = NULL; + HRESULT result; + + todo_wine { + trace("Performing TxDraw test (client %d %d %d %d)\n", + client->top, client->left, client->bottom, client->right); + result = fnTextSrv_TxDraw(txtserv->lpVtbl->TxDraw,txtserv, + dwAspect, 0, pvAspect, ptd, + hdcDraw, hicTargetDev, + client, NULL, NULL, + NULL, 0, 0/*TXTVIEW_INACTIVE*/); + ok(result == S_OK, "TxDraw failed (%08x)\n", result); + } + +} + +/* With this WndProc function the window kills itself after 2 seconds. + * If not in the winetest_interactive mode it will destroy itself + * after the first WM_PAINT call. + * + * It is absolutely necessary to call the window as if it was going to + * be painted for all cases. This option just allows for an automated + * test to run quickly but for an interested user it pauses so the + * output can be viewed. + */ +LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT Paint; + RECT client; + HDC hdc; + switch(msg) + { + case WM_CREATE: + if (winetest_interactive) + if (!SetTimer(hwnd,0xdeadbeef,2000,NULL)) { + trace("WM_CREATE: Cannot set timer\n"); + return 0; + } + break; + case WM_CLOSE: + DestroyWindow(hwnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + case WM_PAINT: + hdc = BeginPaint(hwnd,&Paint); + if (hdc == NULL) break; + GetClientRect(hwnd,&client); + TEST_TxDraw(hdc,(LPRECTL)&client); + EndPaint(hwnd,&Paint); + if (!winetest_interactive) + DestroyWindow(hwnd); + break; + case WM_TIMER: + DestroyWindow(hwnd); + break; + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return 0; +} + +/* This window class uses the suicide window lpfnWndProc. + */ +#define SUICIDE_CLASS "suicideWindowClass" + +BOOL init_window_class() +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = 0; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = NULL; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = SUICIDE_CLASS; + wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + + if(!RegisterClassEx(&wc)) { + trace("Register failed %d\n", GetLastError()); + return FALSE; + } + return TRUE; +} + +HWND create_suicide_window() +{ + HWND hwndRet; + hwndRet = CreateWindowEx( + 0, + SUICIDE_CLASS, + "Test Window", + WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, + NULL, NULL, NULL, NULL); + if(hwndRet == NULL) + { + trace("Window Creation Failed %d\n", GetLastError()); + return NULL; + } + return hwndRet; +} + +/* This is similar to above except the creates a window that will fit + * the current text set in the ITextServices object. */ +HWND create_exact_suicide_window() +{ + HWND hwndRet; + LONG pwidth = 0; + LONG pheight = 0; + HDC tmphdc = GetDC(NULL); + HRESULT result; + result = TEST_TxGetNaturalSize_RAW(tmphdc, TXTNS_FITTOCONTENT, + &pwidth, &pheight); + if (result != S_OK) + return NULL; + ReleaseDC(NULL,tmphdc); + hwndRet = CreateWindowEx( + 0, + SUICIDE_CLASS, + "Test Window", + WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, pwidth, pheight, + NULL, NULL, NULL, NULL); + if(hwndRet == NULL) + { + trace("Window Creation Failed %d\n", GetLastError()); + return NULL; + } + return hwndRet; +} + +/* Calls TxDraw on the current ITextServices object within a window + * the exact size of the text to be rendered. */ +void TEST_TxDraw_EXACT() +{ + MSG Msg; + HWND hwnd; + hwnd = create_exact_suicide_window(); + if (hwnd == NULL) + return; + + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + + while(GetMessage(&Msg, NULL, 0, 0) > 0) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + DestroyWindow(hwnd); +} START_TEST( txtsrv ) { @@ -926,7 +1126,14 @@ START_TEST( txtsrv ) if (!init_texthost()) return; + /* Add the window class SUICIDE_CLASS. */ + if (!init_window_class()) + return; + TEST_TxSetGetText((LPCTSTR)newtextw); TEST_TxGetNaturalSize_MEASURE(); + + TEST_TxSetText((LPCTSTR)newtextw); + TEST_TxDraw_EXACT(); } -- 1.5.4.3