ReactOS  0.4.10-dev-358-g66981e1
syslink.c
Go to the documentation of this file.
1 /* Unit tests for the syslink control.
2  *
3  * Copyright 2011 Francois Gouget for CodeWeavers
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 <windows.h>
21 #include <commctrl.h>
22 
23 #include "wine/test.h"
24 #include "v6util.h"
25 #include "msg.h"
26 
27 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
28 #define NUM_MSG_SEQUENCE 2
29 #define PARENT_SEQ_INDEX 0
30 #define SYSLINK_SEQ_INDEX 1
31 
33 
35 
36 static const struct message empty_wnd_seq[] = {
37  {0}
38 };
39 
40 static const struct message parent_create_syslink_wnd_seq[] = {
41  { WM_GETFONT, sent|optional}, /* Only on XP */
42  { WM_QUERYUISTATE, sent|optional},
44  { WM_NOTIFY, sent|wparam, 0},
46  {0}
47 };
48 
49 static const struct message visible_syslink_wnd_seq[] = {
50  { WM_STYLECHANGING, sent|wparam, GWL_STYLE},
51  { WM_STYLECHANGED, sent|wparam, GWL_STYLE},
52  { WM_PAINT, sent},
53  {0}
54 };
55 
56 static const struct message parent_visible_syslink_wnd_seq[] = {
58  { WM_NOTIFY, sent|wparam, 0},
59  {0}
60 };
61 
62 /* Try to make sure pending X events have been processed before continuing */
63 static void flush_events(void)
64 {
65  MSG msg;
66  int diff = 200;
67  int min_timeout = 100;
68  DWORD time = GetTickCount() + diff;
69 
70  while (diff > 0)
71  {
72  if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
73  while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
74  diff = time - GetTickCount();
75  }
76 }
77 
79 {
80  static LONG defwndproc_counter = 0;
81  LRESULT ret;
82  struct message msg;
83 
84  /* log system messages, except for painting */
85  if (message < WM_USER &&
86  message != WM_PAINT &&
87  message != WM_ERASEBKGND &&
88  message != WM_NCPAINT &&
89  message != WM_NCHITTEST &&
90  message != WM_GETTEXT &&
91  message != WM_GETICON &&
92  message != WM_DEVICECHANGE)
93  {
94  msg.message = message;
95  msg.flags = sent|wparam|lparam;
96  if (defwndproc_counter) msg.flags |= defwinproc;
97  msg.wParam = wParam;
98  msg.lParam = lParam;
99  add_message(sequences, PARENT_SEQ_INDEX, &msg);
100  }
101 
102  defwndproc_counter++;
103  ret = DefWindowProcW(hwnd, message, wParam, lParam);
104  defwndproc_counter--;
105 
106  return ret;
107 }
108 
109 static const WCHAR parentClassW[] = {'S','y','s','l','i','n','k',' ','t','e','s','t',' ','p','a','r','e','n','t',' ','c','l','a','s','s',0};
110 
112 {
113  WNDCLASSW cls;
114 
115  cls.style = 0;
117  cls.cbClsExtra = 0;
118  cls.cbWndExtra = 0;
120  cls.hIcon = 0;
123  cls.lpszMenuName = NULL;
125  return RegisterClassW(&cls);
126 }
127 
129 {
130  static const WCHAR titleW[] = {'S','y','s','l','i','n','k',' ','t','e','s','t',' ','p','a','r','e','n','t',' ','w','i','n','d','o','w',0};
132  return NULL;
133 
134  return CreateWindowExW(0, parentClassW, titleW,
137  0, 0, 200, 100, GetDesktopWindow(),
139 }
140 
142 
144 {
145  static LONG defwndproc_counter = 0;
146  struct message msg = { 0 };
147  LRESULT ret;
148 
149  msg.message = message;
150  msg.flags = sent|wparam|lparam;
151  if (defwndproc_counter) msg.flags |= defwinproc;
152  msg.wParam = wParam;
153  msg.lParam = lParam;
154  add_message(sequences, SYSLINK_SEQ_INDEX, &msg);
155 
156  defwndproc_counter++;
157  ret = CallWindowProcW(syslink_oldproc, hwnd, message, wParam, lParam);
158  defwndproc_counter--;
159 
160  return ret;
161 }
162 
164 {
165  HWND hWndSysLink;
166  static const WCHAR linkW[] = {'H','e','a','d',' ','<','a',' ','h','r','e','f','=','"','l','i','n','k','1','"','>','N','a','m','e','1','<','/','a','>',' ','M','i','d','d','l','e',' ','<','a',' ','h','r','e','f','=','"','l','i','n','k','2','"','>','N','a','m','e','2','<','/','a','>',' ','T','a','i','l',0};
167 
168  /* Only Unicode will do here */
169  hWndSysLink = CreateWindowExW(0, WC_LINK, linkW,
170  style, 0, 0, 150, 50,
171  parent, NULL, GetModuleHandleW(NULL), NULL);
172  if (!hWndSysLink) return NULL;
173 
174  if (GetWindowLongPtrW(hWndSysLink, GWLP_USERDATA))
175  /* On Windows XP SysLink takes GWLP_USERDATA for itself! */
176  trace("SysLink makes use of GWLP_USERDATA\n");
177 
179 
180  return hWndSysLink;
181 }
182 
183 static void test_create_syslink(void)
184 {
185  HWND hWndSysLink;
186  LONG oldstyle;
187 
188  /* Create an invisible SysLink control */
189  flush_sequences(sequences, NUM_MSG_SEQUENCE);
190  hWndSysLink = create_syslink(WS_CHILD | WS_TABSTOP, hWndParent);
191  ok(hWndSysLink != NULL, "Expected non NULL value (le %u)\n", GetLastError());
192  flush_events();
193  ok_sequence(sequences, SYSLINK_SEQ_INDEX, empty_wnd_seq, "create SysLink", FALSE);
194  ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_syslink_wnd_seq, "create SysLink (parent)", TRUE);
195 
196  /* Make the SysLink control visible */
197  flush_sequences(sequences, NUM_MSG_SEQUENCE);
198  oldstyle = GetWindowLongA(hWndSysLink, GWL_STYLE);
199  SetWindowLongA(hWndSysLink, GWL_STYLE, oldstyle | WS_VISIBLE);
200  RedrawWindow(hWndSysLink, NULL, NULL, RDW_INVALIDATE);
201  flush_events();
202  ok_sequence(sequences, SYSLINK_SEQ_INDEX, visible_syslink_wnd_seq, "visible SysLink", TRUE);
203  ok_sequence(sequences, PARENT_SEQ_INDEX, parent_visible_syslink_wnd_seq, "visible SysLink (parent)", TRUE);
204 
205  DestroyWindow(hWndSysLink);
206 }
207 
208 static void test_LM_GETIDEALHEIGHT(void)
209 {
210  HWND hwnd;
211  LONG ret;
212 
214  ok(hwnd != NULL, "Failed to create SysLink window.\n");
215 
216  ret = SendMessageA(hwnd, LM_GETIDEALHEIGHT, 0, 0);
217  ok(ret > 0, "Unexpected ideal height, %d.\n", ret);
218 
219  DestroyWindow(hwnd);
220 }
221 
222 static void test_LM_GETIDEALSIZE(void)
223 {
224  HWND hwnd;
225  LONG ret;
226  SIZE sz;
227 
229  ok(hwnd != NULL, "Failed to create SysLink window.\n");
230 
231  memset(&sz, 0, sizeof(sz));
232  ret = SendMessageA(hwnd, LM_GETIDEALSIZE, 0, (LPARAM)&sz);
233  ok(ret > 0, "Unexpected return value, %d.\n", ret);
234  if (sz.cy == 0)
235  win_skip("LM_GETIDEALSIZE is not supported.\n");
236  else
237  {
238  ok(sz.cx > 5, "Unexpected ideal width, %d.\n", sz.cx);
239  ok(sz.cy == ret, "Unexpected ideal height, %d.\n", sz.cy);
240  }
241 
242  DestroyWindow(hwnd);
243 }
244 
245 START_TEST(syslink)
246 {
247  ULONG_PTR ctx_cookie;
249  POINT orig_pos;
250  HANDLE hCtx;
251 
252  if (!load_v6_module(&ctx_cookie, &hCtx))
253  return;
254 
255  /* LoadLibrary is needed. This file has no reference to functions in comctl32 */
256  hComctl32 = LoadLibraryA("comctl32.dll");
257  ok(hComctl32 != NULL, "Failed to load comctl32.dll.\n");
258 
259  /* Move the cursor off the parent window */
260  GetCursorPos(&orig_pos);
261  SetCursorPos(400, 400);
262 
264 
265  /* Create parent window */
267  ok(hWndParent != NULL, "Failed to create parent Window!\n");
268  flush_events();
269 
273 
275  unload_v6_module(ctx_cookie, hCtx);
276  SetCursorPos(orig_pos.x, orig_pos.y);
277 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define GWLP_WNDPROC
Definition: winuser.h:843
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define trace(...)
Definition: kmt_test.h:217
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
UINT message
Definition: msg.h:50
UINT style
Definition: startmenu.cpp:1386
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
#define TRUE
Definition: types.h:120
#define WC_LINK
Definition: commctrl.h:4697
long y
Definition: polytest.cpp:48
UINT style
Definition: winuser.h:3124
LPCWSTR lpszMenuName
Definition: winuser.h:3132
long x
Definition: polytest.cpp:48
__wchar_t WCHAR
Definition: xmlstorage.h:180
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_CTLCOLORSTATIC
Definition: winuser.h:1743
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define WM_GETTEXT
Definition: winuser.h:1595
Definition: msg.h:39
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
HANDLE HWND
Definition: compat.h:13
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1056
int cbClsExtra
Definition: winuser.h:3126
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:63
#define WHITE_BRUSH
Definition: wingdi.h:900
#define WM_NCHITTEST
Definition: winuser.h:1663
r parent
Definition: btrfs.c:2624
#define WS_CHILD
Definition: pedump.c:617
#define GetWindowLongPtrW
Definition: winuser.h:4693
__u16 time
Definition: mkdosfs.c:366
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
BOOL WINAPI DestroyWindow(_In_ HWND)
DWORD DWORD
Definition: winlogon.h:83
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT_PTR WPARAM
Definition: windef.h:207
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define WM_NCPAINT
Definition: winuser.h:1664
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define FALSE
Definition: types.h:117
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
Definition: v6util.h:71
#define WM_PARENTNOTIFY
Definition: winuser.h:1774
long LONG
Definition: pedump.c:60
LONG_PTR LPARAM
Definition: windef.h:208
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
WNDPROC lpfnWndProc
Definition: winuser.h:3125
static HMODULE hComctl32
Definition: misc.c:38
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:391
smooth NULL
Definition: ftsmooth.c:416
#define WM_GETFONT
Definition: winuser.h:1628
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:635
LPCWSTR lpszClassName
Definition: winuser.h:3133
#define WS_MAXIMIZEBOX
Definition: pedump.c:632
Definition: msg.h:41
#define ok(value,...)
Definition: CComObject.cpp:34
#define WS_CAPTION
Definition: pedump.c:624
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2854
unsigned int BOOL
Definition: ntddk_ex.h:94
int cbWndExtra
Definition: winuser.h:3127
#define LM_GETIDEALHEIGHT
Definition: commctrl.h:4731
UINT WPARAM wParam
Definition: precomp.h:45
#define GWLP_USERDATA
Definition: winuser.h:851
#define ok_sequence(seq, index, exp, contx, todo)
Definition: msg.h:387
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:2627
static const WCHAR titleW[]
Definition: htmlelem.c:1067
HICON hIcon
Definition: winuser.h:3129
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define WM_PAINT
Definition: winuser.h:1597
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
int ret
Definition: msg.h:34
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define WS_TABSTOP
Definition: pedump.c:634
UINT WPARAM LPARAM lparam
Definition: msvc.h:92
#define WINAPI
Definition: msvc.h:20
#define WM_USER
Definition: winuser.h:1851
HCURSOR hCursor
Definition: winuser.h:3130
#define GWL_STYLE
Definition: winuser.h:841
DWORD *typedef HANDLE
Definition: winlogon.h:60
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define add_message(msg)
Definition: msg.c:2142
HBRUSH hbrBackground
Definition: winuser.h:3131
#define QS_ALLINPUT
Definition: winuser.h:869
#define LM_GETIDEALSIZE
Definition: commctrl.h:4732
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:97
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
UINT WPARAM LPARAM lParam
Definition: precomp.h:45
unsigned int UINT
Definition: ndis.h:50
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
#define WM_DEVICECHANGE
Definition: winuser.h:1782
HANDLE HMODULE
Definition: typedefs.h:75
HINSTANCE hInstance
Definition: winuser.h:3128
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define WM_CREATE
Definition: winuser.h:1585
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:844
#define SetWindowLongPtrW
Definition: winuser.h:5210
#define PM_REMOVE
Definition: winuser.h:1177
#define WM_ERASEBKGND
Definition: winuser.h:1602
LONG_PTR LRESULT
Definition: windef.h:209
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_SYSMENU
Definition: pedump.c:629
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
static const WCHAR linkW[]
Definition: string.c:50
msg_flags_t flags
Definition: msg.h:51
#define WM_NOTIFY
Definition: richedit.h:61
#define RDW_INVALIDATE
Definition: winuser.h:1195
UINT WPARAM wparam
Definition: msvc.h:92