1 /* Unit test suite for static controls. 2 * 3 * Copyright 2007 Google (Mikolaj Zalewski) 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include <stdarg.h> 21 #include <stdio.h> 22 23 #define STRICT 24 #define WIN32_LEAN_AND_MEAN 25 #include <windows.h> 26 27 #include "wine/test.h" 28 29 #define TODO_COUNT 1 30 31 #define CTRL_ID 1995 32 33 static HWND hMainWnd; 34 35 #define expect_eq(expr, value, type, fmt) { type val = expr; ok(val == (value), #expr " expected " fmt " got " fmt "\n", (value), val); } 36 37 static int g_nReceivedColorStatic = 0; 38 39 /* try to make sure pending X events have been processed before continuing */ 40 static void flush_events(void) 41 { 42 MSG msg; 43 int diff = 200; 44 int min_timeout = 100; 45 DWORD time = GetTickCount() + diff; 46 47 while (diff > 0) 48 { 49 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break; 50 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg ); 51 diff = time - GetTickCount(); 52 } 53 } 54 55 static HWND build_static(DWORD style) 56 { 57 return CreateWindowA("static", "Test", WS_VISIBLE|WS_CHILD|style, 5, 5, 100, 100, hMainWnd, (HMENU)CTRL_ID, NULL, 0); 58 } 59 60 static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 61 { 62 switch (msg) 63 { 64 case WM_CTLCOLORSTATIC: 65 { 66 HDC hdc = (HDC)wparam; 67 HRGN hrgn = CreateRectRgn(0, 0, 1, 1); 68 ok(GetClipRgn(hdc, hrgn) == 1, "Static controls during a WM_CTLCOLORSTATIC must have a clipping region\n"); 69 DeleteObject(hrgn); 70 g_nReceivedColorStatic++; 71 return (LRESULT) GetStockObject(BLACK_BRUSH); 72 } 73 break; 74 } 75 76 return DefWindowProcA(hwnd, msg, wparam, lparam); 77 } 78 79 static void test_updates(int style, int flags) 80 { 81 RECT r1 = {20, 20, 30, 30}; 82 HWND hStatic = build_static(style); 83 int exp; 84 85 flush_events(); 86 trace("Testing style 0x%x\n", style); 87 g_nReceivedColorStatic = 0; 88 /* during each update parent WndProc will test the WM_CTLCOLORSTATIC message */ 89 InvalidateRect(hMainWnd, NULL, FALSE); 90 UpdateWindow(hMainWnd); 91 InvalidateRect(hMainWnd, &r1, FALSE); 92 UpdateWindow(hMainWnd); 93 InvalidateRect(hStatic, &r1, FALSE); 94 UpdateWindow(hStatic); 95 InvalidateRect(hStatic, NULL, FALSE); 96 UpdateWindow(hStatic); 97 98 if( (style & SS_TYPEMASK) == SS_BITMAP) { 99 HDC hdc = GetDC( hStatic); 100 COLORREF colour = GetPixel( hdc, 10, 10); 101 ok ( colour != 0, "pixel should NOT be painted black!\n"); 102 ReleaseDC(hStatic, hdc); 103 } 104 if (style != SS_ETCHEDHORZ && style != SS_ETCHEDVERT) 105 exp = 4; 106 else 107 exp = 1; /* SS_ETCHED* seems to send WM_CTLCOLORSTATIC only sometimes */ 108 109 if (flags & TODO_COUNT) 110 todo_wine { expect_eq(g_nReceivedColorStatic, exp, int, "%d"); } 111 else if ((style & SS_TYPEMASK) == SS_ICON || (style & SS_TYPEMASK) == SS_BITMAP) 112 ok( g_nReceivedColorStatic == exp, "expected %u got %u\n", exp, g_nReceivedColorStatic ); 113 else 114 expect_eq(g_nReceivedColorStatic, exp, int, "%d"); 115 DestroyWindow(hStatic); 116 } 117 118 static void test_set_text(void) 119 { 120 HWND hStatic = build_static(SS_SIMPLE); 121 char buffA[10]; 122 123 GetWindowTextA(hStatic, buffA, sizeof(buffA)); 124 ok(!strcmp(buffA, "Test"), "got wrong text %s\n", buffA); 125 126 SetWindowTextA(hStatic, NULL); 127 GetWindowTextA(hStatic, buffA, sizeof(buffA)); 128 ok(buffA[0] == 0, "got wrong text %s\n", buffA); 129 130 DestroyWindow(hStatic); 131 } 132 133 START_TEST(static) 134 { 135 static const char szClassName[] = "testclass"; 136 WNDCLASSEXA wndclass; 137 138 wndclass.cbSize = sizeof(wndclass); 139 wndclass.style = CS_HREDRAW | CS_VREDRAW; 140 wndclass.lpfnWndProc = WndProc; 141 wndclass.cbClsExtra = 0; 142 wndclass.cbWndExtra = 0; 143 wndclass.hInstance = GetModuleHandleA(NULL); 144 wndclass.hIcon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION); 145 wndclass.hIconSm = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION); 146 wndclass.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); 147 wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); 148 wndclass.lpszClassName = szClassName; 149 wndclass.lpszMenuName = NULL; 150 RegisterClassExA(&wndclass); 151 152 hMainWnd = CreateWindowA(szClassName, "Test", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, GetModuleHandleA(NULL), NULL); 153 ShowWindow(hMainWnd, SW_SHOW); 154 155 test_updates(0, 0); 156 test_updates(SS_SIMPLE, 0); 157 test_updates(SS_ICON, 0); 158 test_updates(SS_BITMAP, 0); 159 test_updates(SS_BITMAP | SS_CENTERIMAGE, 0); 160 test_updates(SS_BLACKRECT, TODO_COUNT); 161 test_updates(SS_WHITERECT, TODO_COUNT); 162 test_updates(SS_ETCHEDHORZ, TODO_COUNT); 163 test_updates(SS_ETCHEDVERT, TODO_COUNT); 164 test_set_text(); 165 166 DestroyWindow(hMainWnd); 167 } 168