ReactOS  r76032
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 <wine/test.h>
21 
22 //#include <windows.h>
23 #include <wingdi.h>
24 #include <winuser.h>
25 #include <commctrl.h>
26 
27 #include "v6util.h"
28 #include "msg.h"
29 
30 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
31 #define NUM_MSG_SEQUENCE 2
32 #define PARENT_SEQ_INDEX 0
33 #define SYSLINK_SEQ_INDEX 1
34 
36 
38 
39 static const struct message empty_wnd_seq[] = {
40  {0}
41 };
42 
43 static const struct message parent_create_syslink_wnd_seq[] = {
44  { WM_GETFONT, sent|optional}, /* Only on XP */
45  { WM_QUERYUISTATE, sent|optional},
47  { WM_NOTIFY, sent|wparam, 0},
49  {0}
50 };
51 
52 static const struct message visible_syslink_wnd_seq[] = {
53  { WM_STYLECHANGING, sent|wparam, GWL_STYLE},
54  { WM_STYLECHANGED, sent|wparam, GWL_STYLE},
55  { WM_PAINT, sent},
56  {0}
57 };
58 
59 static const struct message parent_visible_syslink_wnd_seq[] = {
61  { WM_NOTIFY, sent|wparam, 0},
62  {0}
63 };
64 
65 /* Try to make sure pending X events have been processed before continuing */
66 static void flush_events(void)
67 {
68  MSG msg;
69  int diff = 200;
70  int min_timeout = 100;
71  DWORD time = GetTickCount() + diff;
72 
73  while (diff > 0)
74  {
75  if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
76  while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
77  diff = time - GetTickCount();
78  }
79 }
80 
82 {
83  static LONG defwndproc_counter = 0;
84  LRESULT ret;
85  struct message msg;
86 
87  /* log system messages, except for painting */
88  if (message < WM_USER &&
89  message != WM_PAINT &&
90  message != WM_ERASEBKGND &&
91  message != WM_NCPAINT &&
92  message != WM_NCHITTEST &&
93  message != WM_GETTEXT &&
94  message != WM_GETICON &&
95  message != WM_DEVICECHANGE)
96  {
97  msg.message = message;
98  msg.flags = sent|wparam|lparam;
99  if (defwndproc_counter) msg.flags |= defwinproc;
100  msg.wParam = wParam;
101  msg.lParam = lParam;
102  add_message(sequences, PARENT_SEQ_INDEX, &msg);
103  }
104 
105  defwndproc_counter++;
106  ret = DefWindowProcW(hwnd, message, wParam, lParam);
107  defwndproc_counter--;
108 
109  return ret;
110 }
111 
112 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};
113 
115 {
116  WNDCLASSW cls;
117 
118  cls.style = 0;
120  cls.cbClsExtra = 0;
121  cls.cbWndExtra = 0;
123  cls.hIcon = 0;
126  cls.lpszMenuName = NULL;
128  return RegisterClassW(&cls);
129 }
130 
132 {
133  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};
135  return NULL;
136 
137  return CreateWindowExW(0, parentClassW, titleW,
140  0, 0, 200, 100, GetDesktopWindow(),
142 }
143 
145 
147 {
148  static LONG defwndproc_counter = 0;
149  struct message msg = { 0 };
150  LRESULT ret;
151 
152  msg.message = message;
153  msg.flags = sent|wparam|lparam;
154  if (defwndproc_counter) msg.flags |= defwinproc;
155  msg.wParam = wParam;
156  msg.lParam = lParam;
157  add_message(sequences, SYSLINK_SEQ_INDEX, &msg);
158 
159  defwndproc_counter++;
160  ret = CallWindowProcW(syslink_oldproc, hwnd, message, wParam, lParam);
161  defwndproc_counter--;
162 
163  return ret;
164 }
165 
167 {
168  HWND hWndSysLink;
169  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};
170 
171  /* Only Unicode will do here */
172  hWndSysLink = CreateWindowExW(0, WC_LINK, linkW,
173  style, 0, 0, 150, 50,
174  parent, NULL, GetModuleHandleW(NULL), NULL);
175  if (!hWndSysLink) return NULL;
176 
177  if (GetWindowLongPtrW(hWndSysLink, GWLP_USERDATA))
178  /* On Windows XP SysLink takes GWLP_USERDATA for itself! */
179  trace("SysLink makes use of GWLP_USERDATA\n");
180 
182 
183  return hWndSysLink;
184 }
185 
186 
187 START_TEST(syslink)
188 {
189  ULONG_PTR ctx_cookie;
190  HANDLE hCtx;
192  BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
193  INITCOMMONCONTROLSEX iccex;
194  BOOL rc;
195  HWND hWndSysLink;
196  LONG oldstyle;
197  POINT orig_pos;
198 
199  if (!load_v6_module(&ctx_cookie, &hCtx))
200  return;
201 
202  /* LoadLibrary is needed. This file has no reference to functions in comctl32 */
203  hComctl32 = LoadLibraryA("comctl32.dll");
204  pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
205  if (!pInitCommonControlsEx)
206  {
207  win_skip("InitCommonControlsEx() is missing. Skipping the tests\n");
208  return;
209  }
210  iccex.dwSize = sizeof(iccex);
211  iccex.dwICC = ICC_LINK_CLASS;
212  rc = pInitCommonControlsEx(&iccex);
213  ok(rc, "InitCommonControlsEx failed (le %u)\n", GetLastError());
214  if (!rc)
215  {
216  skip("Could not register ICC_LINK_CLASS\n");
217  return;
218  }
219 
220  /* Move the cursor off the parent window */
221  GetCursorPos(&orig_pos);
222  SetCursorPos(400, 400);
223 
225 
226  /* Create parent window */
228  ok(hWndParent != NULL, "Failed to create parent Window!\n");
229  if (!hWndParent)
230  {
231  skip("Parent window not present\n");
232  return;
233  }
234  flush_events();
235 
236  /* Create an invisible SysLink control */
237  flush_sequences(sequences, NUM_MSG_SEQUENCE);
238  hWndSysLink = create_syslink(WS_CHILD | WS_TABSTOP, hWndParent);
239  ok(hWndSysLink != NULL, "Expected non NULL value (le %u)\n", GetLastError());
240  if (!hWndSysLink)
241  {
242  skip("SysLink control not present?\n");
243  return;
244  }
245  flush_events();
246  ok_sequence(sequences, SYSLINK_SEQ_INDEX, empty_wnd_seq, "create SysLink", FALSE);
247  ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_syslink_wnd_seq, "create SysLink (parent)", TRUE);
248 
249  /* Make the SysLink control visible */
250  flush_sequences(sequences, NUM_MSG_SEQUENCE);
251  oldstyle = GetWindowLongA(hWndSysLink, GWL_STYLE);
252  SetWindowLongA(hWndSysLink, GWL_STYLE, oldstyle | WS_VISIBLE);
253  RedrawWindow(hWndSysLink, NULL, NULL, RDW_INVALIDATE);
254  flush_events();
255  ok_sequence(sequences, SYSLINK_SEQ_INDEX, visible_syslink_wnd_seq, "visible SysLink", TRUE);
256  ok_sequence(sequences, PARENT_SEQ_INDEX, parent_visible_syslink_wnd_seq, "visible SysLink (parent)", TRUE);
257 
258  DestroyWindow(hWndSysLink);
260  unload_v6_module(ctx_cookie, hCtx);
261  SetCursorPos(orig_pos.x, orig_pos.y);
262 }
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:172
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
UINT message
Definition: msg.h:47
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:4692
long y
Definition: polytest.cpp:48
UINT style
Definition: winuser.h:3119
LPCWSTR lpszMenuName
Definition: winuser.h:3127
long x
Definition: polytest.cpp:48
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WM_CTLCOLORSTATIC
Definition: winuser.h:1738
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define WM_GETTEXT
Definition: winuser.h:1590
Definition: msg.h:36
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:3121
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:1658
r parent
Definition: btrfs.c:2598
#define WS_CHILD
Definition: pedump.c:617
#define GetWindowLongPtrW
Definition: winuser.h:4677
__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:2637
BOOL WINAPI DestroyWindow(_In_ HWND)
DWORD DWORD
Definition: winlogon.h:75
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT_PTR WPARAM
Definition: windef.h:230
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define WM_NCPAINT
Definition: winuser.h:1659
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:84
#define WM_PARENTNOTIFY
Definition: winuser.h:1769
long LONG
Definition: pedump.c:60
LONG_PTR LPARAM
Definition: windef.h:231
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
WNDPROC lpfnWndProc
Definition: winuser.h:3120
static HMODULE hComctl32
Definition: misc.c:40
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:390
smooth NULL
Definition: ftsmooth.c:557
#define WM_GETFONT
Definition: winuser.h:1623
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:623
LPCWSTR lpszClassName
Definition: winuser.h:3128
#define WS_MAXIMIZEBOX
Definition: pedump.c:632
Definition: msg.h:38
LPARAM lParam
Definition: msg.h:50
#define WS_CAPTION
Definition: pedump.c:624
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2849
unsigned int BOOL
Definition: ntddk_ex.h:94
int cbWndExtra
Definition: winuser.h:3122
UINT WPARAM wParam
Definition: precomp.h:53
#define GWLP_USERDATA
Definition: winuser.h:851
#define ok_sequence(seq, index, exp, contx, todo)
Definition: msg.h:386
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:2629
static const WCHAR titleW[]
Definition: htmlelem.c:1067
HICON hIcon
Definition: winuser.h:3124
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2076
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define WM_PAINT
Definition: winuser.h:1592
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:31
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
WPARAM wParam
Definition: msg.h:49
#define WINAPI
Definition: msvc.h:20
#define WM_USER
Definition: winuser.h:1846
HCURSOR hCursor
Definition: winuser.h:3125
#define GWL_STYLE
Definition: winuser.h:841
DWORD *typedef HANDLE
Definition: winlogon.h:52
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define add_message(msg)
Definition: msg.c:2139
HBRUSH hbrBackground
Definition: winuser.h:3126
#define QS_ALLINPUT
Definition: winuser.h:864
#define skip(...)
Definition: CString.cpp:57
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:53
unsigned int UINT
Definition: ndis.h:50
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
#define WM_DEVICECHANGE
Definition: winuser.h:1777
HANDLE HMODULE
Definition: typedefs.h:75
HINSTANCE hInstance
Definition: winuser.h:3123
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define WM_CREATE
Definition: winuser.h:1580
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:844
#define GetProcAddress(x, y)
Definition: compat.h:410
#define ok(value,...)
Definition: CImage.cpp:33
#define SetWindowLongPtrW
Definition: winuser.h:5194
#define PM_REMOVE
Definition: winuser.h:1172
#define WM_ERASEBKGND
Definition: winuser.h:1597
LONG_PTR LRESULT
Definition: windef.h:232
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_SYSMENU
Definition: pedump.c:629
#define win_skip
Definition: test.h:141
#define BOOL
Definition: msvc.h:23
static const WCHAR linkW[]
Definition: string.c:42
msg_flags_t flags
Definition: msg.h:48
#define ICC_LINK_CLASS
Definition: commctrl.h:74
#define WM_NOTIFY
Definition: richedit.h:61
#define RDW_INVALIDATE
Definition: winuser.h:1190
UINT WPARAM wparam
Definition: msvc.h:92