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
)
60 HMODULE module
= GetModuleHandleA("comctl32.dll");
61 DWORD size
, buffer_size
;
64 hrsrc
= FindResourceA(module
, MAKEINTRESOURCEA(1006 /* IDD_PROPSHEET */),
66 size
= SizeofResource(module
, hrsrc
);
67 ok(size
!= 0, "Failed to get size of propsheet dialog resource\n");
68 buffer_size
= HeapSize(GetProcessHeap(), 0, (void *)lparam
);
69 ok(buffer_size
== 2 * size
, "Unexpected template buffer size %u, resource size %u\n",
73 case PSCB_INITIALIZED
:
76 GetWindowTextA(hwnd
, caption
, sizeof(caption
));
77 ok(!strcmp(caption
,"test caption"), "caption: %s\n", caption
);
85 static INT_PTR CALLBACK
page_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wparam
,
92 HWND sheet
= GetParent(hwnd
);
94 GetWindowTextA(sheet
, caption
, sizeof(caption
));
95 ok(!strcmp(caption
,"test caption"), "caption: %s\n", caption
);
101 NMHDR
*nmhdr
= (NMHDR
*)lparam
;
111 ok(!SendMessageA(sheethwnd
, PSM_INDEXTOHWND
, 400, 0),"Should always be 0\n");
119 static void test_title(void)
121 HPROPSHEETPAGE hpsp
[1];
123 PROPSHEETHEADERA psh
;
127 memset(&psp
, 0, sizeof(psp
));
128 psp
.dwSize
= sizeof(psp
);
130 psp
.hInstance
= GetModuleHandleA(NULL
);
131 U(psp
).pszTemplate
= "prop_page1";
132 U2(psp
).pszIcon
= NULL
;
133 psp
.pfnDlgProc
= page_dlg_proc
;
136 hpsp
[0] = CreatePropertySheetPageA(&psp
);
138 memset(&psh
, 0, sizeof(psh
));
139 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
140 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
141 psh
.pszCaption
= "test caption";
143 psh
.hwndParent
= GetDesktopWindow();
144 U3(psh
).phpage
= hpsp
;
145 psh
.pfnCallback
= sheet_callback
;
147 hdlg
= (HWND
)PropertySheetA(&psh
);
148 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle value %p\n", hdlg
);
150 style
= GetWindowLongA(hdlg
, GWL_STYLE
);
151 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|WS_SYSMENU
|
152 DS_CONTEXTHELP
|DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
153 "got unexpected style: %x\n", style
);
158 static void test_nopage(void)
160 HPROPSHEETPAGE hpsp
[1];
162 PROPSHEETHEADERA psh
;
166 memset(&psp
, 0, sizeof(psp
));
167 psp
.dwSize
= sizeof(psp
);
169 psp
.hInstance
= GetModuleHandleA(NULL
);
170 U(psp
).pszTemplate
= "prop_page1";
171 U2(psp
).pszIcon
= NULL
;
172 psp
.pfnDlgProc
= page_dlg_proc
;
175 hpsp
[0] = CreatePropertySheetPageA(&psp
);
177 memset(&psh
, 0, sizeof(psh
));
178 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
179 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
180 psh
.pszCaption
= "test caption";
182 psh
.hwndParent
= GetDesktopWindow();
183 U3(psh
).phpage
= hpsp
;
184 psh
.pfnCallback
= sheet_callback
;
186 hdlg
= (HWND
)PropertySheetA(&psh
);
187 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle value %p\n", hdlg
);
189 ShowWindow(hdlg
,SW_NORMAL
);
190 SendMessageA(hdlg
, PSM_REMOVEPAGE
, 0, 0);
191 hpage
= /* PropSheet_GetCurrentPageHwnd(hdlg); */
192 (HWND
)SendMessageA(hdlg
, PSM_GETCURRENTPAGEHWND
, 0, 0);
193 active_page
= /* PropSheet_HwndToIndex(hdlg, hpage)); */
194 (int)SendMessageA(hdlg
, PSM_HWNDTOINDEX
, (WPARAM
)hpage
, 0);
195 ok(hpage
== NULL
, "expected no current page, got %p, index=%d\n", hpage
, active_page
);
197 RedrawWindow(hdlg
,NULL
,NULL
,RDW_UPDATENOW
|RDW_ERASENOW
);
199 /* Check that the property sheet was fully redrawn */
200 ok(!PeekMessageA(&msg
, 0, WM_PAINT
, WM_PAINT
, PM_NOREMOVE
),
201 "expected no pending WM_PAINT messages\n");
205 static int CALLBACK
disableowner_callback(HWND hwnd
, UINT msg
, LPARAM lparam
)
209 case PSCB_INITIALIZED
:
211 ok(IsWindowEnabled(parenthwnd
) == 0, "parent window should be disabled\n");
219 static void register_parent_wnd_class(void)
224 cls
.lpfnWndProc
= DefWindowProcA
;
227 cls
.hInstance
= GetModuleHandleA(NULL
);
229 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
230 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
231 cls
.lpszMenuName
= NULL
;
232 cls
.lpszClassName
= "parent class";
233 RegisterClassA(&cls
);
236 static void test_disableowner(void)
238 HPROPSHEETPAGE hpsp
[1];
240 PROPSHEETHEADERA psh
;
243 register_parent_wnd_class();
244 parenthwnd
= CreateWindowA("parent class", "", WS_CAPTION
| WS_SYSMENU
| WS_VISIBLE
, 100, 100, 100, 100, GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), 0);
246 memset(&psp
, 0, sizeof(psp
));
247 psp
.dwSize
= sizeof(psp
);
249 psp
.hInstance
= GetModuleHandleA(NULL
);
250 U(psp
).pszTemplate
= "prop_page1";
251 U2(psp
).pszIcon
= NULL
;
252 psp
.pfnDlgProc
= NULL
;
255 hpsp
[0] = CreatePropertySheetPageA(&psp
);
257 memset(&psh
, 0, sizeof(psh
));
258 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
259 psh
.dwFlags
= PSH_USECALLBACK
;
260 psh
.pszCaption
= "test caption";
262 psh
.hwndParent
= parenthwnd
;
263 U3(psh
).phpage
= hpsp
;
264 psh
.pfnCallback
= disableowner_callback
;
266 p
= PropertySheetA(&psh
);
268 ok(p
== 0, "Expected 0, got %ld\n", p
);
269 ok(IsWindowEnabled(parenthwnd
) != 0, "parent window should be enabled\n");
270 DestroyWindow(parenthwnd
);
273 static INT_PTR CALLBACK
nav_page_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
278 LPNMHDR hdr
= (LPNMHDR
)lparam
;
281 active_page
= /* PropSheet_HwndToIndex(hdr->hwndFrom, hwnd); */
282 (int)SendMessageA(hdr
->hwndFrom
, PSM_HWNDTOINDEX
, (WPARAM
)hwnd
, 0);
285 /* prevent navigation away from the fourth page */
286 if(active_page
== 3){
287 SetWindowLongPtrA(hwnd
, DWLP_MSGRESULT
, TRUE
);
297 static WNDPROC old_nav_dialog_proc
;
299 static LRESULT CALLBACK
new_nav_dialog_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
304 ok( IsWindowEnabled( GetDlgItem(hwnd
, wp
) ), "button is not enabled\n" );
307 return CallWindowProcW( old_nav_dialog_proc
, hwnd
, msg
, wp
, lp
);
310 static LRESULT CALLBACK
hook_proc( int code
, WPARAM wp
, LPARAM lp
)
313 if (code
== HCBT_CREATEWND
)
315 CBT_CREATEWNDW
*c
= (CBT_CREATEWNDW
*)lp
;
317 /* The first dialog created will be the parent dialog */
318 if (!done
&& c
->lpcs
->lpszClass
== (LPWSTR
)WC_DIALOG
)
320 old_nav_dialog_proc
= (WNDPROC
)SetWindowLongPtrW( (HWND
)wp
, GWLP_WNDPROC
, (LONG_PTR
)new_nav_dialog_proc
);
325 return CallNextHookEx( NULL
, code
, wp
, lp
);
328 static void test_wiznavigation(void)
330 HPROPSHEETPAGE hpsp
[4];
331 PROPSHEETPAGEA psp
[4];
332 PROPSHEETHEADERA psh
;
337 BOOL hwndtoindex_supported
= TRUE
;
338 const INT nextID
= 12324;
339 const INT backID
= 12323;
342 /* set up a hook proc in order to subclass the main dialog early on */
343 hook
= SetWindowsHookExW( WH_CBT
, hook_proc
, NULL
, GetCurrentThreadId() );
345 /* create the property sheet pages */
346 memset(psp
, 0, sizeof(PROPSHEETPAGEA
) * 4);
348 psp
[0].dwSize
= sizeof(PROPSHEETPAGEA
);
349 psp
[0].hInstance
= GetModuleHandleA(NULL
);
350 U(psp
[0]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_INTRO
);
351 psp
[0].pfnDlgProc
= nav_page_proc
;
352 hpsp
[0] = CreatePropertySheetPageA(&psp
[0]);
354 psp
[1].dwSize
= sizeof(PROPSHEETPAGEA
);
355 psp
[1].hInstance
= GetModuleHandleA(NULL
);
356 U(psp
[1]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_EDIT
);
357 psp
[1].pfnDlgProc
= nav_page_proc
;
358 hpsp
[1] = CreatePropertySheetPageA(&psp
[1]);
360 psp
[2].dwSize
= sizeof(PROPSHEETPAGEA
);
361 psp
[2].hInstance
= GetModuleHandleA(NULL
);
362 U(psp
[2]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_RADIO
);
363 psp
[2].pfnDlgProc
= nav_page_proc
;
364 hpsp
[2] = CreatePropertySheetPageA(&psp
[2]);
366 psp
[3].dwSize
= sizeof(PROPSHEETPAGEA
);
367 psp
[3].hInstance
= GetModuleHandleA(NULL
);
368 U(psp
[3]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_EXIT
);
369 psp
[3].pfnDlgProc
= nav_page_proc
;
370 hpsp
[3] = CreatePropertySheetPageA(&psp
[3]);
372 /* set up the property sheet dialog */
373 memset(&psh
, 0, sizeof(psh
));
374 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
375 psh
.dwFlags
= PSH_MODELESS
| PSH_WIZARD
;
376 psh
.pszCaption
= "A Wizard";
378 psh
.hwndParent
= GetDesktopWindow();
379 U3(psh
).phpage
= hpsp
;
380 hdlg
= (HWND
)PropertySheetA(&psh
);
381 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
383 ok(active_page
== 0, "Active page should be 0. Is: %d\n", active_page
);
385 style
= GetWindowLongA(hdlg
, GWL_STYLE
) & ~(DS_CONTEXTHELP
|WS_SYSMENU
);
386 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|
387 DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
388 "got unexpected style: %x\n", style
);
390 control
= GetFocus();
391 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
392 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
394 /* simulate pressing the Next button */
395 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
396 if (!active_page
) hwndtoindex_supported
= FALSE
;
397 if (hwndtoindex_supported
)
398 ok(active_page
== 1, "Active page should be 1 after pressing Next. Is: %d\n", active_page
);
400 control
= GetFocus();
401 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
402 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
);
404 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
405 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
407 /* set the focus to the second edit box on this page */
408 SetFocus(GetNextDlgTabItem(hdlg
, control
, FALSE
));
410 /* press next again */
411 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
412 if (hwndtoindex_supported
)
413 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
415 control
= GetFocus();
416 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
417 ok(controlID
== IDC_PS_RADIO1
, "Focus should have been set to item on third page. Expected: %d, Found %ld\n", IDC_PS_RADIO1
, controlID
);
420 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
421 if (hwndtoindex_supported
)
422 ok(active_page
== 1, "Active page should be 1 after pressing Back. Is: %d\n", active_page
);
424 control
= GetFocus();
425 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
426 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
);
428 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
429 ok(defidres
== MAKELRESULT(backID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", backID
, LOWORD(defidres
));
431 /* press next twice */
432 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
433 if (hwndtoindex_supported
)
434 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
435 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
436 if (hwndtoindex_supported
)
437 ok(active_page
== 3, "Active page should be 3 after pressing Next. Is: %d\n", active_page
);
441 control
= GetFocus();
442 controlID
= GetWindowLongPtrA(control
, GWLP_ID
);
443 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
445 /* try to navigate away, but shouldn't be able to */
446 SendMessageA(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
447 ok(active_page
== 3, "Active page should still be 3 after pressing Back. Is: %d\n", active_page
);
449 defidres
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
450 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
453 UnhookWindowsHookEx( hook
);
456 static void test_buttons(void)
458 HPROPSHEETPAGE hpsp
[1];
460 PROPSHEETHEADERA psh
;
466 memset(&psp
, 0, sizeof(psp
));
467 psp
.dwSize
= sizeof(psp
);
469 psp
.hInstance
= GetModuleHandleA(NULL
);
470 U(psp
).pszTemplate
= "prop_page1";
471 U2(psp
).pszIcon
= NULL
;
472 psp
.pfnDlgProc
= page_dlg_proc
;
475 hpsp
[0] = CreatePropertySheetPageA(&psp
);
477 memset(&psh
, 0, sizeof(psh
));
478 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
479 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
480 psh
.pszCaption
= "test caption";
482 psh
.hwndParent
= GetDesktopWindow();
483 U3(psh
).phpage
= hpsp
;
484 psh
.pfnCallback
= sheet_callback
;
486 hdlg
= (HWND
)PropertySheetA(&psh
);
487 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got null handle\n");
490 button
= GetDlgItem(hdlg
, IDOK
);
491 GetWindowRect(button
, &rc
);
492 prevRight
= rc
.right
;
496 button
= GetDlgItem(hdlg
, IDCANCEL
);
497 GetWindowRect(button
, &rc
);
498 ok(rc
.top
== top
, "Cancel button should have same top as OK button\n");
499 ok(rc
.left
> prevRight
, "Cancel button should be to the right of OK button\n");
500 prevRight
= rc
.right
;
502 button
= GetDlgItem(hdlg
, IDC_APPLY_BUTTON
);
503 GetWindowRect(button
, &rc
);
504 ok(rc
.top
== top
, "Apply button should have same top as OK button\n");
505 ok(rc
.left
> prevRight
, "Apply button should be to the right of Cancel button\n");
506 prevRight
= rc
.right
;
508 button
= GetDlgItem(hdlg
, IDHELP
);
509 GetWindowRect(button
, &rc
);
510 ok(rc
.top
== top
, "Help button should have same top as OK button\n");
511 ok(rc
.left
> prevRight
, "Help button should be to the right of Apply button\n");
516 static BOOL add_button_has_been_pressed
;
518 static INT_PTR CALLBACK
519 page_with_custom_default_button_dlg_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
524 switch(LOWORD(wparam
))
526 case IDC_PS_PUSHBUTTON1
:
527 switch(HIWORD(wparam
))
530 add_button_has_been_pressed
= TRUE
;
540 static void test_custom_default_button(void)
543 PROPSHEETPAGEA psp
[1];
544 PROPSHEETHEADERA psh
;
548 psp
[0].dwSize
= sizeof (PROPSHEETPAGEA
);
549 psp
[0].dwFlags
= PSP_USETITLE
;
550 psp
[0].hInstance
= GetModuleHandleA(NULL
);
551 U(psp
[0]).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON
);
552 U2(psp
[0]).pszIcon
= NULL
;
553 psp
[0].pfnDlgProc
= page_with_custom_default_button_dlg_proc
;
554 psp
[0].pszTitle
= "Page1";
557 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
558 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
;
559 psh
.hwndParent
= GetDesktopWindow();
560 psh
.hInstance
= GetModuleHandleA(NULL
);
561 U(psh
).pszIcon
= NULL
;
562 psh
.pszCaption
= "PropertySheet1";
565 U2(psh
).nStartPage
= 0;
567 /* The goal of the test is to make sure that the Add button is pressed
568 * when the ENTER key is pressed and a different control, a combobox,
569 * has the keyboard focus. */
570 add_button_has_been_pressed
= FALSE
;
572 /* Create the modeless property sheet. */
573 hdlg
= (HWND
)PropertySheetA(&psh
);
574 ok(hdlg
!= INVALID_HANDLE_VALUE
, "Cannot create the property sheet\n");
576 /* Set the Add button as the default button. */
577 SendMessageA(hdlg
, DM_SETDEFID
, (WPARAM
)IDC_PS_PUSHBUTTON1
, 0);
579 /* Make sure the default button is the Add button. */
580 result
= SendMessageA(hdlg
, DM_GETDEFID
, 0, 0);
581 ok(DC_HASDEFID
== HIWORD(result
), "The property sheet does not have a default button\n");
582 ok(IDC_PS_PUSHBUTTON1
== LOWORD(result
), "The default button is not the Add button\n");
584 /* At this point, the combobox should have keyboard focus, so we press ENTER.
585 * Pull the lever, Kronk! */
586 page
= (HWND
)SendMessageW(hdlg
, PSM_GETCURRENTPAGEHWND
, 0, 0);
587 PostMessageW(GetDlgItem(page
, IDC_PS_COMBO1
), WM_KEYDOWN
, VK_RETURN
, 0);
589 /* Process all the messages in the queue for this thread. */
590 while (PeekMessageA(&msg
, NULL
, 0, 0, PM_REMOVE
))
592 /* (!PropSheet_IsDialogMessage(hdlg, &msg)) */
593 if (!((BOOL
)SendMessageA(hdlg
, PSM_ISDIALOGMESSAGE
, 0, (LPARAM
)&msg
)))
595 TranslateMessage(&msg
);
596 DispatchMessageA(&msg
);
600 ok(add_button_has_been_pressed
, "The Add button has not been pressed!\n");
605 #define RECEIVER_SHEET_CALLBACK 0
606 #define RECEIVER_SHEET_WINPROC 1
607 #define RECEIVER_PAGE 2
609 #define NUM_MSG_SEQUENCES 1
610 #define PROPSHEET_SEQ_INDEX 0
612 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
613 static WNDPROC oldWndProc
;
615 static const struct message property_sheet_seq
[] = {
616 { PSCB_PRECREATE
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
617 { PSCB_INITIALIZED
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
618 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
619 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
620 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
621 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
622 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
623 /*{ WM_GETTEXT, 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_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
627 { WM_NCCALCSIZE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC },
628 { DM_REPOSITION, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
629 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
630 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
631 { WM_ACTIVATEAPP
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
632 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
633 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
634 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
635 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
636 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
637 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
638 { WM_ACTIVATE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
639 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
640 { WM_IME_NOTIFY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
641 { WM_SETFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
642 { WM_KILLFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
643 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
644 { WM_PARENTNOTIFY
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
645 { WM_INITDIALOG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
646 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_PAGE
},
647 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_PAGE },*/
648 { WM_CHILDACTIVATE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
649 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_PAGE
},
650 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
651 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
652 { WM_NOTIFY
, sent
|id
, 0, 0, RECEIVER_PAGE
},
653 { WM_STYLECHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
654 { WM_STYLECHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
655 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
656 { WM_GETICON, 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_SETTEXT
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
660 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_PAGE
},
661 /*{ 0x00000401, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
662 { 0x00000400, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
663 { WM_CHANGEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
664 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
665 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
666 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
667 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
668 /*{ WM_NCPAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
669 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
670 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
671 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
672 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
673 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
674 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
675 /*{ WM_GETICON, 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_PAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
679 { WM_PAINT, sent|id, 0, 0, RECEIVER_PAGE },
680 { WM_NCPAINT, sent|id, 0, 0, RECEIVER_PAGE },
681 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_PAGE },*/
682 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
683 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_PAGE
},
684 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
685 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
686 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
687 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
688 /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
689 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
690 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
691 { WM_COMMAND
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
692 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
693 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
694 { WM_WINDOWPOSCHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
695 { WM_WINDOWPOSCHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
696 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
697 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
698 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
699 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
700 /*{ WM_ACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
701 { WM_ACTIVATE, sent|id, 0, 0, RECEIVER_PAGE },
702 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
703 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_PAGE },
704 { WM_DESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
705 { WM_DESTROY, sent|id, 0, 0, RECEIVER_PAGE },*/
706 /*{ WM_NCDESTROY, sent|id, 0, 0, RECEIVER_PAGE },
707 { WM_NCDESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
711 static void save_message(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
, INT receiver
)
715 if (message
< WM_USER
&&
716 message
!= WM_GETICON
&&
717 message
!= WM_GETTEXT
&&
718 message
!= WM_IME_SETCONTEXT
&&
719 message
!= WM_IME_NOTIFY
&&
720 message
!= WM_PAINT
&&
721 message
!= WM_ERASEBKGND
&&
722 message
!= WM_SETCURSOR
&&
723 (message
< WM_NCCREATE
|| message
> WM_NCMBUTTONDBLCLK
) &&
724 (message
< WM_MOUSEFIRST
|| message
> WM_MOUSEHWHEEL
) &&
727 msg
.message
= message
;
728 msg
.flags
= sent
|wparam
|lparam
|id
;
732 add_message(sequences
, PROPSHEET_SEQ_INDEX
, &msg
);
736 static LRESULT CALLBACK
sheet_callback_messages_proc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
738 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_SHEET_WINPROC
);
740 return CallWindowProcA(oldWndProc
, hwnd
, msg
, wParam
, lParam
);
743 static int CALLBACK
sheet_callback_messages(HWND hwnd
, UINT msg
, LPARAM lParam
)
745 save_message(hwnd
, msg
, 0, lParam
, RECEIVER_SHEET_CALLBACK
);
749 case PSCB_INITIALIZED
:
750 oldWndProc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_WNDPROC
);
751 SetWindowLongPtrA(hwnd
, GWLP_WNDPROC
, (LONG_PTR
)&sheet_callback_messages_proc
);
758 static INT_PTR CALLBACK
page_dlg_proc_messages(HWND hwnd
, UINT msg
, WPARAM wParam
,
761 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_PAGE
);
766 static void test_messages(void)
768 HPROPSHEETPAGE hpsp
[1];
770 PROPSHEETHEADERA psh
;
773 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
775 memset(&psp
, 0, sizeof(psp
));
776 psp
.dwSize
= sizeof(psp
);
778 psp
.hInstance
= GetModuleHandleA(NULL
);
779 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
780 U2(psp
).pszIcon
= NULL
;
781 psp
.pfnDlgProc
= page_dlg_proc_messages
;
784 hpsp
[0] = CreatePropertySheetPageA(&psp
);
786 memset(&psh
, 0, sizeof(psh
));
787 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
788 psh
.dwFlags
= PSH_NOAPPLYNOW
| PSH_WIZARD
| PSH_USECALLBACK
789 | PSH_MODELESS
| PSH_USEICONID
;
790 psh
.pszCaption
= "test caption";
792 psh
.hwndParent
= GetDesktopWindow();
793 U3(psh
).phpage
= hpsp
;
794 psh
.pfnCallback
= sheet_callback_messages
;
796 hdlg
= (HWND
)PropertySheetA(&psh
);
797 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
799 ShowWindow(hdlg
,SW_NORMAL
);
801 ok_sequence(sequences
, PROPSHEET_SEQ_INDEX
, property_sheet_seq
, "property sheet with custom window proc", TRUE
);
806 static void test_PSM_ADDPAGE(void)
808 HPROPSHEETPAGE hpsp
[5];
810 PROPSHEETHEADERA psh
;
815 memset(&psp
, 0, sizeof(psp
));
816 psp
.dwSize
= sizeof(psp
);
818 psp
.hInstance
= GetModuleHandleA(NULL
);
819 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
820 U2(psp
).pszIcon
= NULL
;
821 psp
.pfnDlgProc
= page_dlg_proc_messages
;
824 /* multiple pages with the same data */
825 hpsp
[0] = CreatePropertySheetPageA(&psp
);
826 hpsp
[1] = CreatePropertySheetPageA(&psp
);
827 hpsp
[2] = CreatePropertySheetPageA(&psp
);
829 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_ERROR
);
830 hpsp
[3] = CreatePropertySheetPageA(&psp
);
832 psp
.dwFlags
= PSP_PREMATURE
;
833 hpsp
[4] = CreatePropertySheetPageA(&psp
);
835 memset(&psh
, 0, sizeof(psh
));
836 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
837 psh
.dwFlags
= PSH_MODELESS
;
838 psh
.pszCaption
= "test caption";
840 psh
.hwndParent
= GetDesktopWindow();
841 U3(psh
).phpage
= hpsp
;
843 hdlg
= (HWND
)PropertySheetA(&psh
);
844 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
846 /* add pages one by one */
847 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[1]);
848 ok(ret
== TRUE
, "got %d\n", ret
);
850 /* try with null and invalid value */
851 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, 0);
852 ok(ret
== FALSE
, "got %d\n", ret
);
856 /* crashes on native */
857 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)INVALID_HANDLE_VALUE
);
859 /* check item count */
860 tab
= (HWND
)SendMessageA(hdlg
, PSM_GETTABCONTROL
, 0, 0);
862 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
863 ok(r
== 2, "got %d\n", r
);
865 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[2]);
866 ok(ret
== TRUE
, "got %d\n", ret
);
868 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
869 ok(r
== 3, "got %d\n", r
);
871 /* add property sheet page that can't be created */
872 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[3]);
873 ok(ret
== TRUE
, "got %d\n", ret
);
875 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
876 ok(r
== 4, "got %d\n", r
);
878 /* select page that can't be created */
879 ret
= SendMessageA(hdlg
, PSM_SETCURSEL
, 3, 1);
880 ok(ret
== TRUE
, "got %d\n", ret
);
882 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
883 ok(r
== 3, "got %d\n", r
);
885 /* test PSP_PREMATURE flag with incorrect property sheet page */
886 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[4]);
887 ok(ret
== FALSE
, "got %d\n", ret
);
889 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
890 ok(r
== 3, "got %d\n", r
);
892 DestroyPropertySheetPage(hpsp
[4]);
896 static void test_PSM_INSERTPAGE(void)
898 HPROPSHEETPAGE hpsp
[5];
900 PROPSHEETHEADERA psh
;
905 memset(&psp
, 0, sizeof(psp
));
906 psp
.dwSize
= sizeof(psp
);
908 psp
.hInstance
= GetModuleHandleA(NULL
);
909 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
910 U2(psp
).pszIcon
= NULL
;
911 psp
.pfnDlgProc
= page_dlg_proc_messages
;
914 /* multiple pages with the same data */
915 hpsp
[0] = CreatePropertySheetPageA(&psp
);
916 hpsp
[1] = CreatePropertySheetPageA(&psp
);
917 hpsp
[2] = CreatePropertySheetPageA(&psp
);
919 U(psp
).pszTemplate
= (LPCSTR
)MAKEINTRESOURCE(IDD_PROP_PAGE_ERROR
);
920 hpsp
[3] = CreatePropertySheetPageA(&psp
);
922 psp
.dwFlags
= PSP_PREMATURE
;
923 hpsp
[4] = CreatePropertySheetPageA(&psp
);
925 memset(&psh
, 0, sizeof(psh
));
926 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
927 psh
.dwFlags
= PSH_MODELESS
;
928 psh
.pszCaption
= "test caption";
930 psh
.hwndParent
= GetDesktopWindow();
931 U3(psh
).phpage
= hpsp
;
933 hdlg
= (HWND
)PropertySheetA(&psh
);
934 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
936 /* add pages one by one */
937 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, 5, (LPARAM
)hpsp
[1]);
938 ok(ret
== TRUE
, "got %d\n", ret
);
940 /* try with invalid values */
941 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, 0, 0);
942 ok(ret
== FALSE
, "got %d\n", ret
);
946 /* crashes on native */
947 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, 0, (LPARAM
)INVALID_HANDLE_VALUE
);
950 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, (WPARAM
)INVALID_HANDLE_VALUE
, (LPARAM
)hpsp
[2]);
951 ok(ret
== FALSE
, "got %d\n", ret
);
953 /* check item count */
954 tab
= (HWND
)SendMessageA(hdlg
, PSM_GETTABCONTROL
, 0, 0);
956 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
957 ok(r
== 2, "got %d\n", r
);
959 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, (WPARAM
)hpsp
[1], (LPARAM
)hpsp
[2]);
960 ok(ret
== TRUE
, "got %d\n", ret
);
962 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
963 ok(r
== 3, "got %d\n", r
);
965 /* add property sheet page that can't be created */
966 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, 1, (LPARAM
)hpsp
[3]);
967 ok(ret
== TRUE
, "got %d\n", ret
);
969 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
970 ok(r
== 4, "got %d\n", r
);
972 /* select page that can't be created */
973 ret
= SendMessageA(hdlg
, PSM_SETCURSEL
, 1, 0);
974 ok(ret
== TRUE
, "got %d\n", ret
);
976 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
977 ok(r
== 3, "got %d\n", r
);
979 /* test PSP_PREMATURE flag with incorrect property sheet page */
980 ret
= SendMessageA(hdlg
, PSM_INSERTPAGE
, 0, (LPARAM
)hpsp
[4]);
981 ok(ret
== FALSE
, "got %d\n", ret
);
983 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
984 ok(r
== 3, "got %d\n", r
);
986 DestroyPropertySheetPage(hpsp
[4]);
990 struct custom_proppage
994 PROPSHEETPAGEA pageA
;
995 PROPSHEETPAGEW pageW
;
997 unsigned int addref_called
;
998 unsigned int release_called
;
1001 static UINT CALLBACK
proppage_callback_a(HWND hwnd
, UINT msg
, PROPSHEETPAGEA
*psp
)
1003 struct custom_proppage
*cpage
= (struct custom_proppage
*)psp
->lParam
;
1004 PROPSHEETPAGEA
*psp_orig
= &cpage
->u
.pageA
;
1006 ok(hwnd
== NULL
, "Expected NULL hwnd, got %p\n", hwnd
);
1008 ok(psp
->lParam
&& psp
->lParam
!= (LPARAM
)psp
, "Expected newly allocated page description, got %lx, %p\n",
1010 ok(psp_orig
->pszTitle
== psp
->pszTitle
, "Expected same page title pointer\n");
1011 ok(!lstrcmpA(psp_orig
->pszTitle
, psp
->pszTitle
), "Expected same page title string\n");
1016 ok(psp
->dwSize
> PROPSHEETPAGEA_V1_SIZE
, "Expected ADDREF for V2+ only, got size %u\n", psp
->dwSize
);
1017 cpage
->addref_called
++;
1020 ok(psp
->dwSize
>= PROPSHEETPAGEA_V1_SIZE
, "Unexpected RELEASE, got size %u\n", psp
->dwSize
);
1021 cpage
->release_called
++;
1024 ok(0, "Unexpected message %u\n", msg
);
1030 static UINT CALLBACK
proppage_callback_w(HWND hwnd
, UINT msg
, PROPSHEETPAGEW
*psp
)
1032 struct custom_proppage
*cpage
= (struct custom_proppage
*)psp
->lParam
;
1033 PROPSHEETPAGEW
*psp_orig
= &cpage
->u
.pageW
;
1035 ok(hwnd
== NULL
, "Expected NULL hwnd, got %p\n", hwnd
);
1036 ok(psp
->lParam
&& psp
->lParam
!= (LPARAM
)psp
, "Expected newly allocated page description, got %lx, %p\n",
1038 ok(psp_orig
->pszTitle
== psp
->pszTitle
, "Expected same page title pointer\n");
1039 ok(!lstrcmpW(psp_orig
->pszTitle
, psp
->pszTitle
), "Expected same page title string\n");
1044 ok(psp
->dwSize
> PROPSHEETPAGEW_V1_SIZE
, "Expected ADDREF for V2+ only, got size %u\n", psp
->dwSize
);
1045 cpage
->addref_called
++;
1048 ok(psp
->dwSize
>= PROPSHEETPAGEW_V1_SIZE
, "Unexpected RELEASE, got size %u\n", psp
->dwSize
);
1049 cpage
->release_called
++;
1052 ok(0, "Unexpected message %u\n", msg
);
1058 static void test_CreatePropertySheetPage(void)
1060 static const WCHAR titleW
[] = {'T','i','t','l','e',0};
1061 struct custom_proppage page
;
1062 HPROPSHEETPAGE hpsp
;
1065 memset(&page
.u
.pageA
, 0, sizeof(page
.u
.pageA
));
1066 page
.u
.pageA
.dwFlags
= PSP_USECALLBACK
;
1067 page
.u
.pageA
.pfnDlgProc
= page_dlg_proc_messages
;
1068 page
.u
.pageA
.pfnCallback
= proppage_callback_a
;
1069 page
.u
.pageA
.lParam
= (LPARAM
)&page
;
1070 page
.u
.pageA
.pszTitle
= "Title";
1072 /* Only minimal size validation is performed */
1073 for (page
.u
.pageA
.dwSize
= PROPSHEETPAGEA_V1_SIZE
- 1; page
.u
.pageA
.dwSize
<= PROPSHEETPAGEA_V4_SIZE
+ 1; page
.u
.pageA
.dwSize
++)
1075 page
.addref_called
= 0;
1076 hpsp
= CreatePropertySheetPageA(&page
.u
.pageA
);
1078 if (page
.u
.pageA
.dwSize
< PROPSHEETPAGEA_V1_SIZE
)
1079 ok(hpsp
== NULL
, "Expected failure, size %u\n", page
.u
.pageA
.dwSize
);
1082 ok(hpsp
!= NULL
, "Failed to create a page, size %u\n", page
.u
.pageA
.dwSize
);
1083 todo_wine_if(page
.u
.pageA
.dwSize
> PROPSHEETPAGEA_V1_SIZE
)
1084 ok(page
.addref_called
== (page
.u
.pageA
.dwSize
> PROPSHEETPAGEA_V1_SIZE
) ? 1 : 0, "Expected ADDREF callback message\n");
1089 page
.release_called
= 0;
1090 ret
= DestroyPropertySheetPage(hpsp
);
1091 ok(ret
, "Failed to destroy a page\n");
1093 ok(page
.release_called
== 1, "Expected RELEASE callback message\n");
1097 memset(&page
.u
.pageW
, 0, sizeof(page
.u
.pageW
));
1098 page
.u
.pageW
.dwFlags
= PSP_USECALLBACK
;
1099 page
.u
.pageW
.pfnDlgProc
= page_dlg_proc_messages
;
1100 page
.u
.pageW
.pfnCallback
= proppage_callback_w
;
1101 page
.u
.pageW
.lParam
= (LPARAM
)&page
;
1102 page
.u
.pageW
.pszTitle
= titleW
;
1104 for (page
.u
.pageW
.dwSize
= PROPSHEETPAGEW_V1_SIZE
- 1; page
.u
.pageW
.dwSize
<= PROPSHEETPAGEW_V4_SIZE
+ 1; page
.u
.pageW
.dwSize
++)
1106 page
.addref_called
= 0;
1107 hpsp
= CreatePropertySheetPageW(&page
.u
.pageW
);
1109 if (page
.u
.pageW
.dwSize
< PROPSHEETPAGEW_V1_SIZE
)
1110 ok(hpsp
== NULL
, "Expected failure, size %u\n", page
.u
.pageW
.dwSize
);
1113 ok(hpsp
!= NULL
, "Failed to create a page, size %u\n", page
.u
.pageW
.dwSize
);
1114 todo_wine_if(page
.u
.pageW
.dwSize
> PROPSHEETPAGEW_V1_SIZE
)
1115 ok(page
.addref_called
== (page
.u
.pageW
.dwSize
> PROPSHEETPAGEW_V1_SIZE
) ? 1 : 0, "Expected ADDREF callback message\n");
1120 page
.release_called
= 0;
1121 ret
= DestroyPropertySheetPage(hpsp
);
1122 ok(ret
, "Failed to destroy a page\n");
1124 ok(page
.release_called
== 1, "Expected RELEASE callback message\n");
1129 START_TEST(propsheet
)
1133 test_disableowner();
1134 test_wiznavigation();
1136 test_custom_default_button();
1139 test_PSM_INSERTPAGE();
1140 test_CreatePropertySheetPage();