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
21 #include <wine/test.h>
23 //#include <windows.h>
27 #include <reactos/undocuser.h>
30 #include "resources.h"
32 static HWND parenthwnd
;
33 static HWND sheethwnd
;
35 static LONG active_page
= -1;
37 #define IDC_APPLY_BUTTON 12321
40 /* try to make sure pending X events have been processed before continuing */
41 static void flush_events(void)
45 int min_timeout
= 100;
46 DWORD time
= GetTickCount() + diff
;
50 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
51 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA( &msg
);
52 diff
= time
- GetTickCount();
57 static int CALLBACK
sheet_callback(HWND hwnd
, UINT msg
, LPARAM lparam
)
61 case PSCB_INITIALIZED
:
64 GetWindowTextA(hwnd
, caption
, sizeof(caption
));
65 ok(!strcmp(caption
,"test caption"), "caption: %s\n", caption
);
73 static INT_PTR CALLBACK
page_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wparam
,
80 HWND sheet
= GetParent(hwnd
);
82 GetWindowTextA(sheet
, caption
, sizeof(caption
));
83 ok(!strcmp(caption
,"test caption"), "caption: %s\n", caption
);
89 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
99 ok(!SendMessageA(sheethwnd
, PSM_INDEXTOHWND
, 400, 0),"Should always be 0\n");
107 static void test_title(void)
109 HPROPSHEETPAGE hpsp
[1];
111 PROPSHEETHEADERA psh
;
115 memset(&psp
, 0, sizeof(psp
));
116 psp
.dwSize
= sizeof(psp
);
118 psp
.hInstance
= GetModuleHandleA(NULL
);
119 U(psp
).pszTemplate
= "prop_page1";
120 U2(psp
).pszIcon
= NULL
;
121 psp
.pfnDlgProc
= page_dlg_proc
;
124 hpsp
[0] = CreatePropertySheetPageA(&psp
);
126 memset(&psh
, 0, sizeof(psh
));
127 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
128 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
129 psh
.pszCaption
= "test caption";
131 psh
.hwndParent
= GetDesktopWindow();
132 U3(psh
).phpage
= hpsp
;
133 psh
.pfnCallback
= sheet_callback
;
135 hdlg
= (HWND
)PropertySheetA(&psh
);
136 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle value %p\n", hdlg
);
138 style
= GetWindowLongA(hdlg
, GWL_STYLE
);
139 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|WS_SYSMENU
|
140 DS_CONTEXTHELP
|DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
141 "got unexpected style: %x\n", style
);
146 static void test_nopage(void)
148 HPROPSHEETPAGE hpsp
[1];
150 PROPSHEETHEADERA psh
;
154 memset(&psp
, 0, sizeof(psp
));
155 psp
.dwSize
= sizeof(psp
);
157 psp
.hInstance
= GetModuleHandleA(NULL
);
158 U(psp
).pszTemplate
= "prop_page1";
159 U2(psp
).pszIcon
= NULL
;
160 psp
.pfnDlgProc
= page_dlg_proc
;
163 hpsp
[0] = CreatePropertySheetPageA(&psp
);
165 memset(&psh
, 0, sizeof(psh
));
166 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
167 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
168 psh
.pszCaption
= "test caption";
170 psh
.hwndParent
= GetDesktopWindow();
171 U3(psh
).phpage
= hpsp
;
172 psh
.pfnCallback
= sheet_callback
;
174 hdlg
= (HWND
)PropertySheetA(&psh
);
175 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle value %p\n", hdlg
);
177 ShowWindow(hdlg
,SW_NORMAL
);
178 SendMessageA(hdlg
, PSM_REMOVEPAGE
, 0, 0);
179 hpage
= /* PropSheet_GetCurrentPageHwnd(hdlg); */
180 (HWND
)SendMessageA(hdlg
, PSM_GETCURRENTPAGEHWND
, 0, 0);
181 active_page
= /* PropSheet_HwndToIndex(hdlg, hpage)); */
182 (int)SendMessageA(hdlg
, PSM_HWNDTOINDEX
, (WPARAM
)hpage
, 0);
183 ok(hpage
== NULL
, "expected no current page, got %p, index=%d\n", hpage
, active_page
);
185 RedrawWindow(hdlg
,NULL
,NULL
,RDW_UPDATENOW
|RDW_ERASENOW
);
187 /* Check that the property sheet was fully redrawn */
188 ok(!PeekMessageA(&msg
, 0, WM_PAINT
, WM_PAINT
, PM_NOREMOVE
),
189 "expected no pending WM_PAINT messages\n");
193 static int CALLBACK
disableowner_callback(HWND hwnd
, UINT msg
, LPARAM lparam
)
197 case PSCB_INITIALIZED
:
199 ok(IsWindowEnabled(parenthwnd
) == 0, "parent window should be disabled\n");
207 static void register_parent_wnd_class(void)
212 cls
.lpfnWndProc
= DefWindowProcA
;
215 cls
.hInstance
= GetModuleHandleA(NULL
);
217 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
218 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
219 cls
.lpszMenuName
= NULL
;
220 cls
.lpszClassName
= "parent class";
221 RegisterClassA(&cls
);
224 static void test_disableowner(void)
226 HPROPSHEETPAGE hpsp
[1];
228 PROPSHEETHEADERA psh
;
231 register_parent_wnd_class();
232 parenthwnd
= CreateWindowA("parent class", "", WS_CAPTION
| WS_SYSMENU
| WS_VISIBLE
, 100, 100, 100, 100, GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), 0);
234 memset(&psp
, 0, sizeof(psp
));
235 psp
.dwSize
= sizeof(psp
);
237 psp
.hInstance
= GetModuleHandleA(NULL
);
238 U(psp
).pszTemplate
= "prop_page1";
239 U2(psp
).pszIcon
= NULL
;
240 psp
.pfnDlgProc
= NULL
;
243 hpsp
[0] = CreatePropertySheetPageA(&psp
);
245 memset(&psh
, 0, sizeof(psh
));
246 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
247 psh
.dwFlags
= PSH_USECALLBACK
;
248 psh
.pszCaption
= "test caption";
250 psh
.hwndParent
= parenthwnd
;
251 U3(psh
).phpage
= hpsp
;
252 psh
.pfnCallback
= disableowner_callback
;
254 p
= PropertySheetA(&psh
);
256 ok(p
== 0, "Expected 0, got %ld\n", p
);
257 ok(IsWindowEnabled(parenthwnd
) != 0, "parent window should be enabled\n");
258 DestroyWindow(parenthwnd
);
261 static INT_PTR CALLBACK
nav_page_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
266 LPNMHDR hdr
= (LPNMHDR
)lparam
;
269 active_page
= /* PropSheet_HwndToIndex(hdr->hwndFrom, hwnd); */
270 (int)SendMessageA(hdr
->hwndFrom
, PSM_HWNDTOINDEX
, (WPARAM
)hwnd
, 0);
273 /* prevent navigation away from the fourth page */
274 if(active_page
== 3){
275 SetWindowLongPtrA(hwnd
, DWLP_MSGRESULT
, TRUE
);
285 static WNDPROC old_nav_dialog_proc
;
287 static LRESULT CALLBACK
new_nav_dialog_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
292 ok( IsWindowEnabled( GetDlgItem(hwnd
, wp
) ), "button is not enabled\n" );
295 return CallWindowProcW( old_nav_dialog_proc
, hwnd
, msg
, wp
, lp
);
298 static LRESULT CALLBACK
hook_proc( int code
, WPARAM wp
, LPARAM lp
)
301 if (code
== HCBT_CREATEWND
)
303 CBT_CREATEWNDW
*c
= (CBT_CREATEWNDW
*)lp
;
305 /* The first dialog created will be the parent dialog */
306 if (!done
&& c
->lpcs
->lpszClass
== MAKEINTRESOURCEW(WC_DIALOG
))
308 old_nav_dialog_proc
= (WNDPROC
)SetWindowLongPtrW( (HWND
)wp
, GWLP_WNDPROC
, (LONG_PTR
)new_nav_dialog_proc
);
313 return CallNextHookEx( NULL
, code
, wp
, lp
);
316 static void test_wiznavigation(void)
318 HPROPSHEETPAGE hpsp
[4];
319 PROPSHEETPAGEA psp
[4];
320 PROPSHEETHEADERA psh
;
325 BOOL hwndtoindex_supported
= TRUE
;
326 const INT nextID
= 12324;
327 const INT backID
= 12323;
330 /* set up a hook proc in order to subclass the main dialog early on */
331 hook
= SetWindowsHookExW( WH_CBT
, hook_proc
, NULL
, GetCurrentThreadId() );
333 /* create the property sheet pages */
334 memset(psp
, 0, sizeof(PROPSHEETPAGEA
) * 4);
336 psp
[0].dwSize
= sizeof(PROPSHEETPAGEA
);
337 psp
[0].hInstance
= GetModuleHandleA(NULL
);
338 U(psp
[0]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_INTRO
);
339 psp
[0].pfnDlgProc
= nav_page_proc
;
340 hpsp
[0] = CreatePropertySheetPageA(&psp
[0]);
342 psp
[1].dwSize
= sizeof(PROPSHEETPAGEA
);
343 psp
[1].hInstance
= GetModuleHandleA(NULL
);
344 U(psp
[1]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_EDIT
);
345 psp
[1].pfnDlgProc
= nav_page_proc
;
346 hpsp
[1] = CreatePropertySheetPageA(&psp
[1]);
348 psp
[2].dwSize
= sizeof(PROPSHEETPAGEA
);
349 psp
[2].hInstance
= GetModuleHandleA(NULL
);
350 U(psp
[2]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_RADIO
);
351 psp
[2].pfnDlgProc
= nav_page_proc
;
352 hpsp
[2] = CreatePropertySheetPageA(&psp
[2]);
354 psp
[3].dwSize
= sizeof(PROPSHEETPAGEA
);
355 psp
[3].hInstance
= GetModuleHandleA(NULL
);
356 U(psp
[3]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_EXIT
);
357 psp
[3].pfnDlgProc
= nav_page_proc
;
358 hpsp
[3] = CreatePropertySheetPageA(&psp
[3]);
360 /* set up the property sheet dialog */
361 memset(&psh
, 0, sizeof(psh
));
362 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
363 psh
.dwFlags
= PSH_MODELESS
| PSH_WIZARD
;
364 psh
.pszCaption
= "A Wizard";
366 psh
.hwndParent
= GetDesktopWindow();
367 U3(psh
).phpage
= hpsp
;
368 hdlg
= (HWND
)PropertySheetA(&psh
);
369 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
371 ok(active_page
== 0, "Active page should be 0. Is: %d\n", active_page
);
373 style
= GetWindowLongA(hdlg
, GWL_STYLE
) & ~(DS_CONTEXTHELP
|WS_SYSMENU
);
374 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|
375 DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
376 "got unexpected style: %x\n", style
);
378 control
= GetFocus();
379 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
380 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
382 /* simulate pressing the Next button */
383 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
384 if (!active_page
) hwndtoindex_supported
= FALSE
;
385 if (hwndtoindex_supported
)
386 ok(active_page
== 1, "Active page should be 1 after pressing Next. Is: %d\n", active_page
);
388 control
= GetFocus();
389 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
390 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
);
392 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
393 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
395 /* set the focus to the second edit box on this page */
396 SetFocus(GetNextDlgTabItem(hdlg
, control
, FALSE
));
398 /* press next again */
399 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
400 if (hwndtoindex_supported
)
401 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
403 control
= GetFocus();
404 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
405 ok(controlID
== IDC_PS_RADIO1
, "Focus should have been set to item on third page. Expected: %d, Found %ld\n", IDC_PS_RADIO1
, controlID
);
408 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
409 if (hwndtoindex_supported
)
410 ok(active_page
== 1, "Active page should be 1 after pressing Back. Is: %d\n", active_page
);
412 control
= GetFocus();
413 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
414 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
);
416 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
417 ok(defidres
== MAKELRESULT(backID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", backID
, LOWORD(defidres
));
419 /* press next twice */
420 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
421 if (hwndtoindex_supported
)
422 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
423 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
424 if (hwndtoindex_supported
)
425 ok(active_page
== 3, "Active page should be 3 after pressing Next. Is: %d\n", active_page
);
429 control
= GetFocus();
430 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
431 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
433 /* try to navigate away, but shouldn't be able to */
434 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
435 ok(active_page
== 3, "Active page should still be 3 after pressing Back. Is: %d\n", active_page
);
437 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
438 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
441 UnhookWindowsHookEx( hook
);
444 static void test_buttons(void)
446 HPROPSHEETPAGE hpsp
[1];
448 PROPSHEETHEADERA psh
;
454 memset(&psp
, 0, sizeof(psp
));
455 psp
.dwSize
= sizeof(psp
);
457 psp
.hInstance
= GetModuleHandleA(NULL
);
458 U(psp
).pszTemplate
= "prop_page1";
459 U2(psp
).pszIcon
= NULL
;
460 psp
.pfnDlgProc
= page_dlg_proc
;
463 hpsp
[0] = CreatePropertySheetPageA(&psp
);
465 memset(&psh
, 0, sizeof(psh
));
466 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
467 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
468 psh
.pszCaption
= "test caption";
470 psh
.hwndParent
= GetDesktopWindow();
471 U3(psh
).phpage
= hpsp
;
472 psh
.pfnCallback
= sheet_callback
;
474 hdlg
= (HWND
)PropertySheetA(&psh
);
475 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got null handle\n");
478 button
= GetDlgItem(hdlg
, IDOK
);
479 GetWindowRect(button
, &rc
);
480 prevRight
= rc
.right
;
484 button
= GetDlgItem(hdlg
, IDCANCEL
);
485 GetWindowRect(button
, &rc
);
486 ok(rc
.top
== top
, "Cancel button should have same top as OK button\n");
487 ok(rc
.left
> prevRight
, "Cancel button should be to the right of OK button\n");
488 prevRight
= rc
.right
;
490 button
= GetDlgItem(hdlg
, IDC_APPLY_BUTTON
);
491 GetWindowRect(button
, &rc
);
492 ok(rc
.top
== top
, "Apply button should have same top as OK button\n");
493 ok(rc
.left
> prevRight
, "Apply button should be to the right of Cancel button\n");
494 prevRight
= rc
.right
;
496 button
= GetDlgItem(hdlg
, IDHELP
);
497 GetWindowRect(button
, &rc
);
498 ok(rc
.top
== top
, "Help button should have same top as OK button\n");
499 ok(rc
.left
> prevRight
, "Help button should be to the right of Apply button\n");
504 static BOOL add_button_has_been_pressed
;
506 static INT_PTR CALLBACK
507 page_with_custom_default_button_dlg_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
512 switch(LOWORD(wparam
))
514 case IDC_PS_PUSHBUTTON1
:
515 switch(HIWORD(wparam
))
518 add_button_has_been_pressed
= TRUE
;
528 static void test_custom_default_button(void)
531 PROPSHEETPAGEA psp
[1];
532 PROPSHEETHEADERA psh
;
536 psp
[0].dwSize
= sizeof (PROPSHEETPAGEA
);
537 psp
[0].dwFlags
= PSP_USETITLE
;
538 psp
[0].hInstance
= GetModuleHandleA(NULL
);
539 U(psp
[0]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON
);
540 U2(psp
[0]).pszIcon
= NULL
;
541 psp
[0].pfnDlgProc
= page_with_custom_default_button_dlg_proc
;
542 psp
[0].pszTitle
= "Page1";
545 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
546 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
;
547 psh
.hwndParent
= GetDesktopWindow();
548 psh
.hInstance
= GetModuleHandleA(NULL
);
549 U(psh
).pszIcon
= NULL
;
550 psh
.pszCaption
= "PropertySheet1";
553 U2(psh
).nStartPage
= 0;
555 /* The goal of the test is to make sure that the Add button is pressed
556 * when the ENTER key is pressed and a different control, a combobox,
557 * has the keyboard focus. */
558 add_button_has_been_pressed
= FALSE
;
560 /* Create the modeless property sheet. */
561 hdlg
= (HWND
)PropertySheetA(&psh
);
562 ok(hdlg
!= INVALID_HANDLE_VALUE
, "Cannot create the property sheet\n");
564 /* Set the Add button as the default button. */
565 SendMessageA(hdlg
, DM_SETDEFID
, (WPARAM
)IDC_PS_PUSHBUTTON1
, 0);
567 /* Make sure the default button is the Add button. */
568 result
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
569 ok(DC_HASDEFID
== HIWORD(result
), "The property sheet does not have a default button\n");
570 ok(IDC_PS_PUSHBUTTON1
== LOWORD(result
), "The default button is not the Add button\n");
572 /* At this point, the combobox should have keyboard focus, so we press ENTER.
573 * Pull the lever, Kronk! */
574 page
= (HWND
)SendMessageW(hdlg
, PSM_GETCURRENTPAGEHWND
, 0, 0);
575 PostMessageW(GetDlgItem(page
, IDC_PS_COMBO1
), WM_KEYDOWN
, VK_RETURN
, 0);
577 /* Process all the messages in the queue for this thread. */
578 while (PeekMessageA(&msg
, NULL
, 0, 0, PM_REMOVE
))
580 /* (!PropSheet_IsDialogMessage(hdlg, &msg)) */
581 if (!((BOOL
)SendMessageA(hdlg
, PSM_ISDIALOGMESSAGE
, 0, (LPARAM
)&msg
)))
583 TranslateMessage(&msg
);
584 DispatchMessageA(&msg
);
588 ok(add_button_has_been_pressed
, "The Add button has not been pressed!\n");
593 #define RECEIVER_SHEET_CALLBACK 0
594 #define RECEIVER_SHEET_WINPROC 1
595 #define RECEIVER_PAGE 2
597 #define NUM_MSG_SEQUENCES 1
598 #define PROPSHEET_SEQ_INDEX 0
600 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
601 static WNDPROC oldWndProc
;
603 static const struct message property_sheet_seq
[] = {
604 { PSCB_PRECREATE
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
605 { PSCB_INITIALIZED
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
606 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
607 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
608 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
609 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
610 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
611 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
612 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
613 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
614 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
615 { WM_NCCALCSIZE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC },
616 { DM_REPOSITION, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
617 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
618 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
619 { WM_ACTIVATEAPP
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
620 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
621 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
622 { WM_GETICON, 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_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
626 { WM_ACTIVATE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
627 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
628 { WM_IME_NOTIFY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
629 { WM_SETFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
630 { WM_KILLFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
631 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
632 { WM_PARENTNOTIFY
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
633 { WM_INITDIALOG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
634 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_PAGE
},
635 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_PAGE },*/
636 { WM_CHILDACTIVATE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
637 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_PAGE
},
638 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
639 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
640 { WM_NOTIFY
, sent
|id
, 0, 0, RECEIVER_PAGE
},
641 { WM_STYLECHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
642 { WM_STYLECHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
643 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
644 { WM_GETICON, 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_SETTEXT
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
648 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_PAGE
},
649 /*{ 0x00000401, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
650 { 0x00000400, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
651 { WM_CHANGEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
652 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
653 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
654 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
655 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
656 /*{ WM_NCPAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
657 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
658 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
659 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
660 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
661 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
662 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
663 /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
664 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
665 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
666 { WM_PAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
667 { WM_PAINT, sent|id, 0, 0, RECEIVER_PAGE },
668 { WM_NCPAINT, sent|id, 0, 0, RECEIVER_PAGE },
669 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_PAGE },*/
670 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
671 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_PAGE
},
672 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
673 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
674 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
675 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
676 /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
677 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
678 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
679 { WM_COMMAND
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
680 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
681 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
682 { WM_WINDOWPOSCHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
683 { WM_WINDOWPOSCHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
684 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
685 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
686 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
687 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
688 /*{ WM_ACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
689 { WM_ACTIVATE, sent|id, 0, 0, RECEIVER_PAGE },
690 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
691 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_PAGE },
692 { WM_DESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
693 { WM_DESTROY, sent|id, 0, 0, RECEIVER_PAGE },*/
694 /*{ WM_NCDESTROY, sent|id, 0, 0, RECEIVER_PAGE },
695 { WM_NCDESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
699 static void save_message(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
, INT receiver
)
703 if (message
< WM_USER
&&
704 message
!= WM_GETICON
&&
705 message
!= WM_GETTEXT
&&
706 message
!= WM_IME_SETCONTEXT
&&
707 message
!= WM_IME_NOTIFY
&&
708 message
!= WM_PAINT
&&
709 message
!= WM_ERASEBKGND
&&
710 message
!= WM_SETCURSOR
&&
711 (message
< WM_NCCREATE
|| message
> WM_NCMBUTTONDBLCLK
) &&
712 (message
< WM_MOUSEFIRST
|| message
> WM_MOUSEHWHEEL
) &&
715 msg
.message
= message
;
716 msg
.flags
= sent
|wparam
|lparam
|id
;
720 add_message(sequences
, PROPSHEET_SEQ_INDEX
, &msg
);
724 static LRESULT CALLBACK
sheet_callback_messages_proc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
726 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_SHEET_WINPROC
);
728 return CallWindowProcA(oldWndProc
, hwnd
, msg
, wParam
, lParam
);
731 static int CALLBACK
sheet_callback_messages(HWND hwnd
, UINT msg
, LPARAM lParam
)
733 save_message(hwnd
, msg
, 0, lParam
, RECEIVER_SHEET_CALLBACK
);
737 case PSCB_INITIALIZED
:
738 oldWndProc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_WNDPROC
);
739 SetWindowLongPtrA(hwnd
, GWLP_WNDPROC
, (LONG_PTR
)&sheet_callback_messages_proc
);
746 static INT_PTR CALLBACK
page_dlg_proc_messages(HWND hwnd
, UINT msg
, WPARAM wParam
,
749 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_PAGE
);
754 static void test_messages(void)
756 HPROPSHEETPAGE hpsp
[1];
758 PROPSHEETHEADERA psh
;
761 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
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 hpsp
[0] = CreatePropertySheetPageA(&psp
);
774 memset(&psh
, 0, sizeof(psh
));
775 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
776 psh
.dwFlags
= PSH_NOAPPLYNOW
| PSH_WIZARD
| PSH_USECALLBACK
777 | PSH_MODELESS
| PSH_USEICONID
;
778 psh
.pszCaption
= "test caption";
780 psh
.hwndParent
= GetDesktopWindow();
781 U3(psh
).phpage
= hpsp
;
782 psh
.pfnCallback
= sheet_callback_messages
;
784 hdlg
= (HWND
)PropertySheetA(&psh
);
785 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
787 ShowWindow(hdlg
,SW_NORMAL
);
789 ok_sequence(sequences
, PROPSHEET_SEQ_INDEX
, property_sheet_seq
, "property sheet with custom window proc", TRUE
);
794 static void test_PSM_ADDPAGE(void)
796 HPROPSHEETPAGE hpsp
[5];
798 PROPSHEETHEADERA psh
;
803 memset(&psp
, 0, sizeof(psp
));
804 psp
.dwSize
= sizeof(psp
);
806 psp
.hInstance
= GetModuleHandleA(NULL
);
807 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
808 U2(psp
).pszIcon
= NULL
;
809 psp
.pfnDlgProc
= page_dlg_proc_messages
;
812 /* two page with the same data */
813 hpsp
[0] = CreatePropertySheetPageA(&psp
);
814 hpsp
[1] = CreatePropertySheetPageA(&psp
);
815 hpsp
[2] = CreatePropertySheetPageA(&psp
);
817 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_ERROR
);
818 hpsp
[3] = CreatePropertySheetPageA(&psp
);
820 psp
.dwFlags
= PSP_PREMATURE
;
821 hpsp
[4] = CreatePropertySheetPageA(&psp
);
823 memset(&psh
, 0, sizeof(psh
));
824 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
825 psh
.dwFlags
= PSH_MODELESS
;
826 psh
.pszCaption
= "test caption";
828 psh
.hwndParent
= GetDesktopWindow();
829 U3(psh
).phpage
= hpsp
;
831 hdlg
= (HWND
)PropertySheetA(&psh
);
832 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
834 /* add pages one by one */
835 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[1]);
836 ok(ret
== TRUE
, "got %d\n", ret
);
838 /* try with null and invalid value */
839 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, 0);
840 ok(ret
== FALSE
, "got %d\n", ret
);
844 /* crashes on native */
845 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)INVALID_HANDLE_VALUE
);
847 /* check item count */
848 tab
= (HWND
)SendMessageA(hdlg
, PSM_GETTABCONTROL
, 0, 0);
850 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
851 ok(r
== 2, "got %d\n", r
);
853 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[2]);
854 ok(ret
== TRUE
, "got %d\n", ret
);
856 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
857 ok(r
== 3, "got %d\n", r
);
859 /* add property sheet page that can't be created */
860 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[3]);
861 ok(ret
== TRUE
, "got %d\n", ret
);
863 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
864 ok(r
== 4, "got %d\n", r
);
866 /* select page that can't be created */
867 ret
= SendMessageA(hdlg
, PSM_SETCURSEL
, 3, 1);
868 ok(ret
== TRUE
, "got %d\n", ret
);
870 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
871 ok(r
== 3, "got %d\n", r
);
873 /* test PSP_PREMATURE flag with incorrect property sheet page */
874 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[4]);
875 ok(ret
== FALSE
, "got %d\n", ret
);
877 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
878 ok(r
== 3, "got %d\n", r
);
880 DestroyPropertySheetPage(hpsp
[4]);
884 START_TEST(propsheet
)
889 test_wiznavigation();
891 test_custom_default_button();