1 /* Unit test suite for property sheet control.
3 * Copyright 2006 Huw Davies
4 * Copyright 2009 Jan de Mooij
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "resources.h"
27 #include "wine/test.h"
29 static HWND parenthwnd
;
30 static HWND sheethwnd
;
32 static LONG active_page
= -1;
34 #define IDC_APPLY_BUTTON 12321
37 /* try to make sure pending X events have been processed before continuing */
38 static void flush_events(void)
42 int min_timeout
= 100;
43 DWORD time
= GetTickCount() + diff
;
47 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
48 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA( &msg
);
49 diff
= time
- GetTickCount();
54 static int CALLBACK
sheet_callback(HWND hwnd
, UINT msg
, LPARAM lparam
)
58 case PSCB_INITIALIZED
:
61 GetWindowTextA(hwnd
, caption
, sizeof(caption
));
62 ok(!strcmp(caption
,"test caption"), "caption: %s\n", caption
);
70 static INT_PTR CALLBACK
page_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wparam
,
77 HWND sheet
= GetParent(hwnd
);
79 GetWindowTextA(sheet
, caption
, sizeof(caption
));
80 ok(!strcmp(caption
,"test caption"), "caption: %s\n", caption
);
86 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
96 ok(!SendMessageA(sheethwnd
, PSM_INDEXTOHWND
, 400, 0),"Should always be 0\n");
104 static void test_title(void)
106 HPROPSHEETPAGE hpsp
[1];
108 PROPSHEETHEADERA psh
;
112 memset(&psp
, 0, sizeof(psp
));
113 psp
.dwSize
= sizeof(psp
);
115 psp
.hInstance
= GetModuleHandleA(NULL
);
116 U(psp
).pszTemplate
= "prop_page1";
117 U2(psp
).pszIcon
= NULL
;
118 psp
.pfnDlgProc
= page_dlg_proc
;
121 hpsp
[0] = CreatePropertySheetPageA(&psp
);
123 memset(&psh
, 0, sizeof(psh
));
124 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
125 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
126 psh
.pszCaption
= "test caption";
128 psh
.hwndParent
= GetDesktopWindow();
129 U3(psh
).phpage
= hpsp
;
130 psh
.pfnCallback
= sheet_callback
;
132 hdlg
= (HWND
)PropertySheetA(&psh
);
133 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle value %p\n", hdlg
);
135 style
= GetWindowLongA(hdlg
, GWL_STYLE
);
136 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|WS_SYSMENU
|
137 DS_CONTEXTHELP
|DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
138 "got unexpected style: %x\n", style
);
143 static void test_nopage(void)
145 HPROPSHEETPAGE hpsp
[1];
147 PROPSHEETHEADERA psh
;
151 memset(&psp
, 0, sizeof(psp
));
152 psp
.dwSize
= sizeof(psp
);
154 psp
.hInstance
= GetModuleHandleA(NULL
);
155 U(psp
).pszTemplate
= "prop_page1";
156 U2(psp
).pszIcon
= NULL
;
157 psp
.pfnDlgProc
= page_dlg_proc
;
160 hpsp
[0] = CreatePropertySheetPageA(&psp
);
162 memset(&psh
, 0, sizeof(psh
));
163 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
164 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
165 psh
.pszCaption
= "test caption";
167 psh
.hwndParent
= GetDesktopWindow();
168 U3(psh
).phpage
= hpsp
;
169 psh
.pfnCallback
= sheet_callback
;
171 hdlg
= (HWND
)PropertySheetA(&psh
);
172 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle value %p\n", hdlg
);
174 ShowWindow(hdlg
,SW_NORMAL
);
175 SendMessageA(hdlg
, PSM_REMOVEPAGE
, 0, 0);
176 hpage
= /* PropSheet_GetCurrentPageHwnd(hdlg); */
177 (HWND
)SendMessageA(hdlg
, PSM_GETCURRENTPAGEHWND
, 0, 0);
178 active_page
= /* PropSheet_HwndToIndex(hdlg, hpage)); */
179 (int)SendMessageA(hdlg
, PSM_HWNDTOINDEX
, (WPARAM
)hpage
, 0);
180 ok(hpage
== NULL
, "expected no current page, got %p, index=%d\n", hpage
, active_page
);
182 RedrawWindow(hdlg
,NULL
,NULL
,RDW_UPDATENOW
|RDW_ERASENOW
);
184 /* Check that the property sheet was fully redrawn */
185 ok(!PeekMessageA(&msg
, 0, WM_PAINT
, WM_PAINT
, PM_NOREMOVE
),
186 "expected no pending WM_PAINT messages\n");
190 static int CALLBACK
disableowner_callback(HWND hwnd
, UINT msg
, LPARAM lparam
)
194 case PSCB_INITIALIZED
:
196 ok(IsWindowEnabled(parenthwnd
) == 0, "parent window should be disabled\n");
204 static void register_parent_wnd_class(void)
209 cls
.lpfnWndProc
= DefWindowProcA
;
212 cls
.hInstance
= GetModuleHandleA(NULL
);
214 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
215 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
216 cls
.lpszMenuName
= NULL
;
217 cls
.lpszClassName
= "parent class";
218 RegisterClassA(&cls
);
221 static void test_disableowner(void)
223 HPROPSHEETPAGE hpsp
[1];
225 PROPSHEETHEADERA psh
;
228 register_parent_wnd_class();
229 parenthwnd
= CreateWindowA("parent class", "", WS_CAPTION
| WS_SYSMENU
| WS_VISIBLE
, 100, 100, 100, 100, GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), 0);
231 memset(&psp
, 0, sizeof(psp
));
232 psp
.dwSize
= sizeof(psp
);
234 psp
.hInstance
= GetModuleHandleA(NULL
);
235 U(psp
).pszTemplate
= "prop_page1";
236 U2(psp
).pszIcon
= NULL
;
237 psp
.pfnDlgProc
= NULL
;
240 hpsp
[0] = CreatePropertySheetPageA(&psp
);
242 memset(&psh
, 0, sizeof(psh
));
243 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
244 psh
.dwFlags
= PSH_USECALLBACK
;
245 psh
.pszCaption
= "test caption";
247 psh
.hwndParent
= parenthwnd
;
248 U3(psh
).phpage
= hpsp
;
249 psh
.pfnCallback
= disableowner_callback
;
251 p
= PropertySheetA(&psh
);
253 ok(p
== 0, "Expected 0, got %ld\n", p
);
254 ok(IsWindowEnabled(parenthwnd
) != 0, "parent window should be enabled\n");
255 DestroyWindow(parenthwnd
);
258 static INT_PTR CALLBACK
nav_page_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
263 LPNMHDR hdr
= (LPNMHDR
)lparam
;
266 active_page
= /* PropSheet_HwndToIndex(hdr->hwndFrom, hwnd); */
267 (int)SendMessageA(hdr
->hwndFrom
, PSM_HWNDTOINDEX
, (WPARAM
)hwnd
, 0);
270 /* prevent navigation away from the fourth page */
271 if(active_page
== 3){
272 SetWindowLongPtrA(hwnd
, DWLP_MSGRESULT
, TRUE
);
282 static void test_wiznavigation(void)
284 HPROPSHEETPAGE hpsp
[4];
285 PROPSHEETPAGEA psp
[4];
286 PROPSHEETHEADERA psh
;
291 BOOL hwndtoindex_supported
= TRUE
;
292 const INT nextID
= 12324;
293 const INT backID
= 12323;
295 /* create the property sheet pages */
296 memset(psp
, 0, sizeof(PROPSHEETPAGEA
) * 4);
298 psp
[0].dwSize
= sizeof(PROPSHEETPAGEA
);
299 psp
[0].hInstance
= GetModuleHandleA(NULL
);
300 U(psp
[0]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_INTRO
);
301 psp
[0].pfnDlgProc
= nav_page_proc
;
302 hpsp
[0] = CreatePropertySheetPageA(&psp
[0]);
304 psp
[1].dwSize
= sizeof(PROPSHEETPAGEA
);
305 psp
[1].hInstance
= GetModuleHandleA(NULL
);
306 U(psp
[1]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_EDIT
);
307 psp
[1].pfnDlgProc
= nav_page_proc
;
308 hpsp
[1] = CreatePropertySheetPageA(&psp
[1]);
310 psp
[2].dwSize
= sizeof(PROPSHEETPAGEA
);
311 psp
[2].hInstance
= GetModuleHandleA(NULL
);
312 U(psp
[2]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_RADIO
);
313 psp
[2].pfnDlgProc
= nav_page_proc
;
314 hpsp
[2] = CreatePropertySheetPageA(&psp
[2]);
316 psp
[3].dwSize
= sizeof(PROPSHEETPAGEA
);
317 psp
[3].hInstance
= GetModuleHandleA(NULL
);
318 U(psp
[3]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_EXIT
);
319 psp
[3].pfnDlgProc
= nav_page_proc
;
320 hpsp
[3] = CreatePropertySheetPageA(&psp
[3]);
322 /* set up the property sheet dialog */
323 memset(&psh
, 0, sizeof(psh
));
324 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
325 psh
.dwFlags
= PSH_MODELESS
| PSH_WIZARD
;
326 psh
.pszCaption
= "A Wizard";
328 psh
.hwndParent
= GetDesktopWindow();
329 U3(psh
).phpage
= hpsp
;
330 hdlg
= (HWND
)PropertySheetA(&psh
);
331 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
333 ok(active_page
== 0, "Active page should be 0. Is: %d\n", active_page
);
335 style
= GetWindowLongA(hdlg
, GWL_STYLE
) & ~(DS_CONTEXTHELP
|WS_SYSMENU
);
336 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|
337 DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
338 "got unexpected style: %x\n", style
);
340 control
= GetFocus();
341 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
342 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
344 /* simulate pressing the Next button */
345 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
346 if (!active_page
) hwndtoindex_supported
= FALSE
;
347 if (hwndtoindex_supported
)
348 ok(active_page
== 1, "Active page should be 1 after pressing Next. Is: %d\n", active_page
);
350 control
= GetFocus();
351 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
352 ok(controlID
== IDC_PS_EDIT1
, "Focus should be set to the first item on the second page. Expected: %d, Found: %ld\n", IDC_PS_EDIT1
, controlID
);
354 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
355 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
357 /* set the focus to the second edit box on this page */
358 SetFocus(GetNextDlgTabItem(hdlg
, control
, FALSE
));
360 /* press next again */
361 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
362 if (hwndtoindex_supported
)
363 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
365 control
= GetFocus();
366 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
367 ok(controlID
== IDC_PS_RADIO1
, "Focus should have been set to item on third page. Expected: %d, Found %ld\n", IDC_PS_RADIO1
, controlID
);
370 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
371 if (hwndtoindex_supported
)
372 ok(active_page
== 1, "Active page should be 1 after pressing Back. Is: %d\n", active_page
);
374 control
= GetFocus();
375 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
376 ok(controlID
== IDC_PS_EDIT1
, "Focus should have been set to the first item on second page. Expected: %d, Found %ld\n", IDC_PS_EDIT1
, controlID
);
378 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
379 ok(defidres
== MAKELRESULT(backID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", backID
, LOWORD(defidres
));
381 /* press next twice */
382 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
383 if (hwndtoindex_supported
)
384 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
385 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
386 if (hwndtoindex_supported
)
387 ok(active_page
== 3, "Active page should be 3 after pressing Next. Is: %d\n", active_page
);
391 control
= GetFocus();
392 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
393 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
395 /* try to navigate away, but shouldn't be able to */
396 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
397 ok(active_page
== 3, "Active page should still be 3 after pressing Back. Is: %d\n", active_page
);
399 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
400 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
405 static void test_buttons(void)
407 HPROPSHEETPAGE hpsp
[1];
409 PROPSHEETHEADERA psh
;
415 memset(&psp
, 0, sizeof(psp
));
416 psp
.dwSize
= sizeof(psp
);
418 psp
.hInstance
= GetModuleHandleA(NULL
);
419 U(psp
).pszTemplate
= "prop_page1";
420 U2(psp
).pszIcon
= NULL
;
421 psp
.pfnDlgProc
= page_dlg_proc
;
424 hpsp
[0] = CreatePropertySheetPageA(&psp
);
426 memset(&psh
, 0, sizeof(psh
));
427 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
428 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
429 psh
.pszCaption
= "test caption";
431 psh
.hwndParent
= GetDesktopWindow();
432 U3(psh
).phpage
= hpsp
;
433 psh
.pfnCallback
= sheet_callback
;
435 hdlg
= (HWND
)PropertySheetA(&psh
);
436 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got null handle\n");
439 button
= GetDlgItem(hdlg
, IDOK
);
440 GetWindowRect(button
, &rc
);
441 prevRight
= rc
.right
;
445 button
= GetDlgItem(hdlg
, IDCANCEL
);
446 GetWindowRect(button
, &rc
);
447 ok(rc
.top
== top
, "Cancel button should have same top as OK button\n");
448 ok(rc
.left
> prevRight
, "Cancel button should be to the right of OK button\n");
449 prevRight
= rc
.right
;
451 button
= GetDlgItem(hdlg
, IDC_APPLY_BUTTON
);
452 GetWindowRect(button
, &rc
);
453 ok(rc
.top
== top
, "Apply button should have same top as OK button\n");
454 ok(rc
.left
> prevRight
, "Apply button should be to the right of Cancel button\n");
455 prevRight
= rc
.right
;
457 button
= GetDlgItem(hdlg
, IDHELP
);
458 GetWindowRect(button
, &rc
);
459 ok(rc
.top
== top
, "Help button should have same top as OK button\n");
460 ok(rc
.left
> prevRight
, "Help button should be to the right of Apply button\n");
465 static BOOL add_button_has_been_pressed
;
467 static INT_PTR CALLBACK
468 page_with_custom_default_button_dlg_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
473 switch(LOWORD(wparam
))
475 case IDC_PS_PUSHBUTTON1
:
476 switch(HIWORD(wparam
))
479 add_button_has_been_pressed
= TRUE
;
489 static void test_custom_default_button(void)
492 PROPSHEETPAGEA psp
[1];
493 PROPSHEETHEADERA psh
;
497 psp
[0].dwSize
= sizeof (PROPSHEETPAGEA
);
498 psp
[0].dwFlags
= PSP_USETITLE
;
499 psp
[0].hInstance
= GetModuleHandleA(NULL
);
500 U(psp
[0]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON
);
501 U2(psp
[0]).pszIcon
= NULL
;
502 psp
[0].pfnDlgProc
= page_with_custom_default_button_dlg_proc
;
503 psp
[0].pszTitle
= "Page1";
506 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
507 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
;
508 psh
.hwndParent
= GetDesktopWindow();
509 psh
.hInstance
= GetModuleHandleA(NULL
);
510 U(psh
).pszIcon
= NULL
;
511 psh
.pszCaption
= "PropertySheet1";
514 U2(psh
).nStartPage
= 0;
516 /* The goal of the test is to make sure that the Add button is pressed
517 * when the ENTER key is pressed and a different control, a combobox,
518 * has the keyboard focus. */
519 add_button_has_been_pressed
= FALSE
;
521 /* Create the modeless property sheet. */
522 hdlg
= (HWND
)PropertySheetA(&psh
);
523 ok(hdlg
!= INVALID_HANDLE_VALUE
, "Cannot create the property sheet\n");
525 /* Set the Add button as the default button. */
526 SendMessageA(hdlg
, DM_SETDEFID
, (WPARAM
)IDC_PS_PUSHBUTTON1
, 0);
528 /* Make sure the default button is the Add button. */
529 result
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
530 ok(DC_HASDEFID
== HIWORD(result
), "The property sheet does not have a default button\n");
531 ok(IDC_PS_PUSHBUTTON1
== LOWORD(result
), "The default button is not the Add button\n");
533 /* At this point, the combobox should have keyboard focus, so we press ENTER.
534 * Pull the lever, Kronk! */
535 keybd_event(VK_RETURN
, 0, 0, 0);
537 /* Process all the messages in the queue for this thread. */
538 while (PeekMessageA(&msg
, NULL
, 0, 0, PM_REMOVE
))
540 /* (!PropSheet_IsDialogMessage(hdlg, &msg)) */
541 if (!((BOOL
)SendMessageA(hdlg
, PSM_ISDIALOGMESSAGE
, 0, (LPARAM
)&msg
)))
543 TranslateMessage(&msg
);
544 DispatchMessageA(&msg
);
548 ok(add_button_has_been_pressed
, "The Add button has not been pressed!\n");
553 #define RECEIVER_SHEET_CALLBACK 0
554 #define RECEIVER_SHEET_WINPROC 1
555 #define RECEIVER_PAGE 2
557 #define NUM_MSG_SEQUENCES 1
558 #define PROPSHEET_SEQ_INDEX 0
560 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
561 static WNDPROC oldWndProc
;
563 static const struct message property_sheet_seq
[] = {
564 { PSCB_PRECREATE
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
565 { PSCB_INITIALIZED
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
566 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
567 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
568 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
569 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
570 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
571 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
572 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
573 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
574 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
575 { WM_NCCALCSIZE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC },
576 { DM_REPOSITION, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
577 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
578 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
579 { WM_ACTIVATEAPP
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
580 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
581 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
582 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
583 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
584 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
585 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
586 { WM_ACTIVATE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
587 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
588 { WM_IME_NOTIFY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
589 { WM_SETFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
590 { WM_KILLFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
591 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
592 { WM_PARENTNOTIFY
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
593 { WM_INITDIALOG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
594 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_PAGE
},
595 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_PAGE },*/
596 { WM_CHILDACTIVATE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
597 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_PAGE
},
598 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
599 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
600 { WM_NOTIFY
, sent
|id
, 0, 0, RECEIVER_PAGE
},
601 { WM_STYLECHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
602 { WM_STYLECHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
603 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
604 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
605 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
606 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
607 { WM_SETTEXT
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
608 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_PAGE
},
609 /*{ 0x00000401, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
610 { 0x00000400, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
611 { WM_CHANGEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
612 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
613 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
614 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
615 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
616 /*{ WM_NCPAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
617 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
618 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
619 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
620 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
621 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
622 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
623 /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
624 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
625 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
626 { WM_PAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
627 { WM_PAINT, sent|id, 0, 0, RECEIVER_PAGE },
628 { WM_NCPAINT, sent|id, 0, 0, RECEIVER_PAGE },
629 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_PAGE },*/
630 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
631 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_PAGE
},
632 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
633 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
634 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
635 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
636 /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
637 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
638 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
639 { WM_COMMAND
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
640 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
641 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
642 { WM_WINDOWPOSCHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
643 { WM_WINDOWPOSCHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
644 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
645 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
646 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
647 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
648 /*{ WM_ACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
649 { WM_ACTIVATE, sent|id, 0, 0, RECEIVER_PAGE },
650 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
651 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_PAGE },
652 { WM_DESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
653 { WM_DESTROY, sent|id, 0, 0, RECEIVER_PAGE },*/
654 /*{ WM_NCDESTROY, sent|id, 0, 0, RECEIVER_PAGE },
655 { WM_NCDESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
659 static void save_message(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
, INT receiver
)
663 if (message
< WM_USER
&&
664 message
!= WM_GETICON
&&
665 message
!= WM_GETTEXT
&&
666 message
!= WM_IME_SETCONTEXT
&&
667 message
!= WM_IME_NOTIFY
&&
668 message
!= WM_PAINT
&&
669 message
!= WM_ERASEBKGND
&&
670 message
!= WM_SETCURSOR
&&
671 (message
< WM_NCCREATE
|| message
> WM_NCMBUTTONDBLCLK
) &&
672 (message
< WM_MOUSEFIRST
|| message
> WM_MOUSEHWHEEL
) &&
675 msg
.message
= message
;
676 msg
.flags
= sent
|wparam
|lparam
|id
;
680 add_message(sequences
, PROPSHEET_SEQ_INDEX
, &msg
);
684 static LRESULT CALLBACK
sheet_callback_messages_proc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
686 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_SHEET_WINPROC
);
688 return CallWindowProcA(oldWndProc
, hwnd
, msg
, wParam
, lParam
);
691 static int CALLBACK
sheet_callback_messages(HWND hwnd
, UINT msg
, LPARAM lParam
)
693 save_message(hwnd
, msg
, 0, lParam
, RECEIVER_SHEET_CALLBACK
);
697 case PSCB_INITIALIZED
:
698 oldWndProc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_WNDPROC
);
699 SetWindowLongPtrA(hwnd
, GWLP_WNDPROC
, (LONG_PTR
)&sheet_callback_messages_proc
);
706 static INT_PTR CALLBACK
page_dlg_proc_messages(HWND hwnd
, UINT msg
, WPARAM wParam
,
709 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_PAGE
);
714 static void test_messages(void)
716 HPROPSHEETPAGE hpsp
[1];
718 PROPSHEETHEADERA psh
;
721 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
723 memset(&psp
, 0, sizeof(psp
));
724 psp
.dwSize
= sizeof(psp
);
726 psp
.hInstance
= GetModuleHandleA(NULL
);
727 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
728 U2(psp
).pszIcon
= NULL
;
729 psp
.pfnDlgProc
= page_dlg_proc_messages
;
732 hpsp
[0] = CreatePropertySheetPageA(&psp
);
734 memset(&psh
, 0, sizeof(psh
));
735 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
736 psh
.dwFlags
= PSH_NOAPPLYNOW
| PSH_WIZARD
| PSH_USECALLBACK
737 | PSH_MODELESS
| PSH_USEICONID
;
738 psh
.pszCaption
= "test caption";
740 psh
.hwndParent
= GetDesktopWindow();
741 U3(psh
).phpage
= hpsp
;
742 psh
.pfnCallback
= sheet_callback_messages
;
744 hdlg
= (HWND
)PropertySheetA(&psh
);
745 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
747 ShowWindow(hdlg
,SW_NORMAL
);
749 ok_sequence(sequences
, PROPSHEET_SEQ_INDEX
, property_sheet_seq
, "property sheet with custom window proc", TRUE
);
754 static void test_PSM_ADDPAGE(void)
756 HPROPSHEETPAGE hpsp
[5];
758 PROPSHEETHEADERA psh
;
763 memset(&psp
, 0, sizeof(psp
));
764 psp
.dwSize
= sizeof(psp
);
766 psp
.hInstance
= GetModuleHandleA(NULL
);
767 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
768 U2(psp
).pszIcon
= NULL
;
769 psp
.pfnDlgProc
= page_dlg_proc_messages
;
772 /* two page with the same data */
773 hpsp
[0] = CreatePropertySheetPageA(&psp
);
774 hpsp
[1] = CreatePropertySheetPageA(&psp
);
775 hpsp
[2] = CreatePropertySheetPageA(&psp
);
777 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_ERROR
);
778 hpsp
[3] = CreatePropertySheetPageA(&psp
);
780 psp
.dwFlags
= PSP_PREMATURE
;
781 hpsp
[4] = CreatePropertySheetPageA(&psp
);
783 memset(&psh
, 0, sizeof(psh
));
784 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
785 psh
.dwFlags
= PSH_MODELESS
;
786 psh
.pszCaption
= "test caption";
788 psh
.hwndParent
= GetDesktopWindow();
789 U3(psh
).phpage
= hpsp
;
791 hdlg
= (HWND
)PropertySheetA(&psh
);
792 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
794 /* add pages one by one */
795 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[1]);
796 ok(ret
== TRUE
, "got %d\n", ret
);
798 /* try with null and invalid value */
799 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, 0);
800 ok(ret
== FALSE
, "got %d\n", ret
);
804 /* crashes on native */
805 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)INVALID_HANDLE_VALUE
);
807 /* check item count */
808 tab
= (HWND
)SendMessageA(hdlg
, PSM_GETTABCONTROL
, 0, 0);
810 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
811 ok(r
== 2, "got %d\n", r
);
813 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[2]);
814 ok(ret
== TRUE
, "got %d\n", ret
);
816 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
817 ok(r
== 3, "got %d\n", r
);
819 /* add property sheet page that can't be created */
820 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[3]);
821 ok(ret
== TRUE
, "got %d\n", ret
);
823 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
824 ok(r
== 4, "got %d\n", r
);
826 /* select page that can't be created */
827 ret
= SendMessageA(hdlg
, PSM_SETCURSEL
, 3, 1);
828 ok(ret
== TRUE
, "got %d\n", ret
);
830 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
831 ok(r
== 3, "got %d\n", r
);
833 /* test PSP_PREMATURE flag with incorrect property sheet page */
834 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[4]);
835 ok(ret
== FALSE
, "got %d\n", ret
);
837 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
838 ok(r
== 3, "got %d\n", r
);
843 START_TEST(propsheet
)
848 test_wiznavigation();
850 test_custom_default_button();