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 (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &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
= GetWindowLong(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 SendMessage(hdlg
, PSM_REMOVEPAGE
, 0, 0);
176 hpage
= PropSheet_GetCurrentPageHwnd(hdlg
);
177 ok(hpage
== NULL
, "expected no current page, got %p, index=%d\n", hpage
, PropSheet_HwndToIndex(hdlg
, hpage
));
179 RedrawWindow(hdlg
,NULL
,NULL
,RDW_UPDATENOW
|RDW_ERASENOW
);
181 /* Check that the property sheet was fully redrawn */
182 ok(!PeekMessage(&msg
, 0, WM_PAINT
, WM_PAINT
, PM_NOREMOVE
),
183 "expected no pending WM_PAINT messages\n");
187 static int CALLBACK
disableowner_callback(HWND hwnd
, UINT msg
, LPARAM lparam
)
191 case PSCB_INITIALIZED
:
193 ok(IsWindowEnabled(parenthwnd
) == 0, "parent window should be disabled\n");
201 static void register_parent_wnd_class(void)
206 cls
.lpfnWndProc
= DefWindowProcA
;
209 cls
.hInstance
= GetModuleHandleA(NULL
);
211 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
212 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
213 cls
.lpszMenuName
= NULL
;
214 cls
.lpszClassName
= "parent class";
215 RegisterClassA(&cls
);
218 static void test_disableowner(void)
220 HPROPSHEETPAGE hpsp
[1];
222 PROPSHEETHEADERA psh
;
225 register_parent_wnd_class();
226 parenthwnd
= CreateWindowA("parent class", "", WS_CAPTION
| WS_SYSMENU
| WS_VISIBLE
, 100, 100, 100, 100, GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), 0);
228 memset(&psp
, 0, sizeof(psp
));
229 psp
.dwSize
= sizeof(psp
);
231 psp
.hInstance
= GetModuleHandleA(NULL
);
232 U(psp
).pszTemplate
= "prop_page1";
233 U2(psp
).pszIcon
= NULL
;
234 psp
.pfnDlgProc
= NULL
;
237 hpsp
[0] = CreatePropertySheetPageA(&psp
);
239 memset(&psh
, 0, sizeof(psh
));
240 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
241 psh
.dwFlags
= PSH_USECALLBACK
;
242 psh
.pszCaption
= "test caption";
244 psh
.hwndParent
= parenthwnd
;
245 U3(psh
).phpage
= hpsp
;
246 psh
.pfnCallback
= disableowner_callback
;
248 p
= PropertySheetA(&psh
);
250 ok(p
== 0, "Expected 0, got %ld\n", p
);
251 ok(IsWindowEnabled(parenthwnd
) != 0, "parent window should be enabled\n");
252 DestroyWindow(parenthwnd
);
255 static INT_PTR CALLBACK
nav_page_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
260 LPNMHDR hdr
= (LPNMHDR
)lparam
;
263 active_page
= PropSheet_HwndToIndex(hdr
->hwndFrom
, hwnd
);
266 /* prevent navigation away from the fourth page */
267 if(active_page
== 3){
268 SetWindowLongPtr(hwnd
, DWLP_MSGRESULT
, TRUE
);
278 static void test_wiznavigation(void)
280 HPROPSHEETPAGE hpsp
[4];
281 PROPSHEETPAGEA psp
[4];
282 PROPSHEETHEADERA psh
;
287 BOOL hwndtoindex_supported
= TRUE
;
288 const INT nextID
= 12324;
289 const INT backID
= 12323;
291 /* create the property sheet pages */
292 memset(psp
, 0, sizeof(PROPSHEETPAGEA
) * 4);
294 psp
[0].dwSize
= sizeof(PROPSHEETPAGEA
);
295 psp
[0].hInstance
= GetModuleHandleA(NULL
);
296 U(psp
[0]).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_INTRO
);
297 psp
[0].pfnDlgProc
= nav_page_proc
;
298 hpsp
[0] = CreatePropertySheetPageA(&psp
[0]);
300 psp
[1].dwSize
= sizeof(PROPSHEETPAGEA
);
301 psp
[1].hInstance
= GetModuleHandleA(NULL
);
302 U(psp
[1]).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_EDIT
);
303 psp
[1].pfnDlgProc
= nav_page_proc
;
304 hpsp
[1] = CreatePropertySheetPageA(&psp
[1]);
306 psp
[2].dwSize
= sizeof(PROPSHEETPAGEA
);
307 psp
[2].hInstance
= GetModuleHandleA(NULL
);
308 U(psp
[2]).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_RADIO
);
309 psp
[2].pfnDlgProc
= nav_page_proc
;
310 hpsp
[2] = CreatePropertySheetPageA(&psp
[2]);
312 psp
[3].dwSize
= sizeof(PROPSHEETPAGEA
);
313 psp
[3].hInstance
= GetModuleHandleA(NULL
);
314 U(psp
[3]).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_EXIT
);
315 psp
[3].pfnDlgProc
= nav_page_proc
;
316 hpsp
[3] = CreatePropertySheetPageA(&psp
[3]);
318 /* set up the property sheet dialog */
319 memset(&psh
, 0, sizeof(psh
));
320 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
321 psh
.dwFlags
= PSH_MODELESS
| PSH_WIZARD
;
322 psh
.pszCaption
= "A Wizard";
324 psh
.hwndParent
= GetDesktopWindow();
325 U3(psh
).phpage
= hpsp
;
326 hdlg
= (HWND
)PropertySheetA(&psh
);
327 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
329 ok(active_page
== 0, "Active page should be 0. Is: %d\n", active_page
);
331 style
= GetWindowLong(hdlg
, GWL_STYLE
) & ~(DS_CONTEXTHELP
|WS_SYSMENU
);
332 ok(style
== (WS_POPUP
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CAPTION
|
333 DS_MODALFRAME
|DS_SETFONT
|DS_3DLOOK
),
334 "got unexpected style: %x\n", style
);
336 control
= GetFocus();
337 controlID
= GetWindowLongPtr(control
, GWLP_ID
);
338 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
340 /* simulate pressing the Next button */
341 SendMessage(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
342 if (!active_page
) hwndtoindex_supported
= FALSE
;
343 if (hwndtoindex_supported
)
344 ok(active_page
== 1, "Active page should be 1 after pressing Next. Is: %d\n", active_page
);
346 control
= GetFocus();
347 controlID
= GetWindowLongPtr(control
, GWLP_ID
);
348 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
);
350 defidres
= SendMessage(hdlg
, DM_GETDEFID
, 0, 0);
351 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
353 /* set the focus to the second edit box on this page */
354 SetFocus(GetNextDlgTabItem(hdlg
, control
, FALSE
));
356 /* press next again */
357 SendMessage(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
358 if (hwndtoindex_supported
)
359 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
361 control
= GetFocus();
362 controlID
= GetWindowLongPtr(control
, GWLP_ID
);
363 ok(controlID
== IDC_PS_RADIO1
, "Focus should have been set to item on third page. Expected: %d, Found %ld\n", IDC_PS_RADIO1
, controlID
);
366 SendMessage(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
367 if (hwndtoindex_supported
)
368 ok(active_page
== 1, "Active page should be 1 after pressing Back. Is: %d\n", active_page
);
370 control
= GetFocus();
371 controlID
= GetWindowLongPtr(control
, GWLP_ID
);
372 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
);
374 defidres
= SendMessage(hdlg
, DM_GETDEFID
, 0, 0);
375 ok(defidres
== MAKELRESULT(backID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", backID
, LOWORD(defidres
));
377 /* press next twice */
378 SendMessage(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
379 if (hwndtoindex_supported
)
380 ok(active_page
== 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page
);
381 SendMessage(hdlg
, PSM_PRESSBUTTON
, PSBTN_NEXT
, 0);
382 if (hwndtoindex_supported
)
383 ok(active_page
== 3, "Active page should be 3 after pressing Next. Is: %d\n", active_page
);
387 control
= GetFocus();
388 controlID
= GetWindowLongPtr(control
, GWLP_ID
);
389 ok(controlID
== nextID
, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID
, controlID
);
391 /* try to navigate away, but shouldn't be able to */
392 SendMessage(hdlg
, PSM_PRESSBUTTON
, PSBTN_BACK
, 0);
393 ok(active_page
== 3, "Active page should still be 3 after pressing Back. Is: %d\n", active_page
);
395 defidres
= SendMessage(hdlg
, DM_GETDEFID
, 0, 0);
396 ok(defidres
== MAKELRESULT(nextID
, DC_HASDEFID
), "Expected default button ID to be %d, is %d\n", nextID
, LOWORD(defidres
));
401 static void test_buttons(void)
403 HPROPSHEETPAGE hpsp
[1];
405 PROPSHEETHEADERA psh
;
411 memset(&psp
, 0, sizeof(psp
));
412 psp
.dwSize
= sizeof(psp
);
414 psp
.hInstance
= GetModuleHandleA(NULL
);
415 U(psp
).pszTemplate
= "prop_page1";
416 U2(psp
).pszIcon
= NULL
;
417 psp
.pfnDlgProc
= page_dlg_proc
;
420 hpsp
[0] = CreatePropertySheetPageA(&psp
);
422 memset(&psh
, 0, sizeof(psh
));
423 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
424 psh
.dwFlags
= PSH_MODELESS
| PSH_USECALLBACK
;
425 psh
.pszCaption
= "test caption";
427 psh
.hwndParent
= GetDesktopWindow();
428 U3(psh
).phpage
= hpsp
;
429 psh
.pfnCallback
= sheet_callback
;
431 hdlg
= (HWND
)PropertySheetA(&psh
);
432 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got null handle\n");
435 button
= GetDlgItem(hdlg
, IDOK
);
436 GetWindowRect(button
, &rc
);
437 prevRight
= rc
.right
;
441 button
= GetDlgItem(hdlg
, IDCANCEL
);
442 GetWindowRect(button
, &rc
);
443 ok(rc
.top
== top
, "Cancel button should have same top as OK button\n");
444 ok(rc
.left
> prevRight
, "Cancel button should be to the right of OK button\n");
445 prevRight
= rc
.right
;
447 button
= GetDlgItem(hdlg
, IDC_APPLY_BUTTON
);
448 GetWindowRect(button
, &rc
);
449 ok(rc
.top
== top
, "Apply button should have same top as OK button\n");
450 ok(rc
.left
> prevRight
, "Apply button should be to the right of Cancel button\n");
451 prevRight
= rc
.right
;
453 button
= GetDlgItem(hdlg
, IDHELP
);
454 GetWindowRect(button
, &rc
);
455 ok(rc
.top
== top
, "Help button should have same top as OK button\n");
456 ok(rc
.left
> prevRight
, "Help button should be to the right of Apply button\n");
461 static BOOL add_button_has_been_pressed
;
463 static INT_PTR CALLBACK
464 page_with_custom_default_button_dlg_proc(HWND hdlg
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
469 switch(LOWORD(wparam
))
471 case IDC_PS_PUSHBUTTON1
:
472 switch(HIWORD(wparam
))
475 add_button_has_been_pressed
= TRUE
;
485 static void test_custom_default_button(void)
488 PROPSHEETPAGEA psp
[1];
489 PROPSHEETHEADERA psh
;
493 psp
[0].dwSize
= sizeof (PROPSHEETPAGEA
);
494 psp
[0].dwFlags
= PSP_USETITLE
;
495 psp
[0].hInstance
= GetModuleHandleA(NULL
);
496 U(psp
[0]).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON
);
497 U2(psp
[0]).pszIcon
= NULL
;
498 psp
[0].pfnDlgProc
= page_with_custom_default_button_dlg_proc
;
499 psp
[0].pszTitle
= "Page1";
502 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
503 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_MODELESS
;
504 psh
.hwndParent
= GetDesktopWindow();
505 psh
.hInstance
= GetModuleHandleA(NULL
);
506 U(psh
).pszIcon
= NULL
;
507 psh
.pszCaption
= "PropertySheet1";
510 U2(psh
).nStartPage
= 0;
512 /* The goal of the test is to make sure that the Add button is pressed
513 * when the ENTER key is pressed and a different control, a combobox,
514 * has the keyboard focus. */
515 add_button_has_been_pressed
= FALSE
;
517 /* Create the modeless property sheet. */
518 hdlg
= (HWND
)PropertySheetA(&psh
);
519 ok(hdlg
!= INVALID_HANDLE_VALUE
, "Cannot create the property sheet\n");
521 /* Set the Add button as the default button. */
522 SendMessage(hdlg
, DM_SETDEFID
, (WPARAM
)IDC_PS_PUSHBUTTON1
, 0);
524 /* Make sure the default button is the Add button. */
525 result
= SendMessage(hdlg
, DM_GETDEFID
, 0, 0);
526 ok(DC_HASDEFID
== HIWORD(result
), "The property sheet does not have a default button\n");
527 ok(IDC_PS_PUSHBUTTON1
== LOWORD(result
), "The default button is not the Add button\n");
529 /* At this point, the combobox should have keyboard focus, so we press ENTER.
530 * Pull the lever, Kronk! */
531 keybd_event(VK_RETURN
, 0, 0, 0);
533 /* Process all the messages in the queue for this thread. */
534 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
536 if (!PropSheet_IsDialogMessage(hdlg
, &msg
))
538 TranslateMessage(&msg
);
539 DispatchMessage(&msg
);
543 ok(add_button_has_been_pressed
, "The Add button has not been pressed!\n");
548 #define RECEIVER_SHEET_CALLBACK 0
549 #define RECEIVER_SHEET_WINPROC 1
550 #define RECEIVER_PAGE 2
552 #define NUM_MSG_SEQUENCES 1
553 #define PROPSHEET_SEQ_INDEX 0
555 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
556 static WNDPROC oldWndProc
;
558 static const struct message property_sheet_seq
[] = {
559 { PSCB_PRECREATE
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
560 { PSCB_INITIALIZED
, sent
|id
, 0, 0, RECEIVER_SHEET_CALLBACK
},
561 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
562 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
563 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
564 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
565 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
566 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
567 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
568 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
569 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
570 { WM_NCCALCSIZE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC },
571 { DM_REPOSITION, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
572 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
573 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
574 { WM_ACTIVATEAPP
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
575 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
576 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
577 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
578 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
579 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
580 { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
581 { WM_ACTIVATE
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
582 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
583 { WM_IME_NOTIFY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
584 { WM_SETFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
585 { WM_KILLFOCUS
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
586 /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
587 { WM_PARENTNOTIFY
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
588 { WM_INITDIALOG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
589 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_PAGE
},
590 /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_PAGE },*/
591 { WM_CHILDACTIVATE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
592 { WM_WINDOWPOSCHANGED
, sent
|id
, 0, 0, RECEIVER_PAGE
},
593 { WM_MOVE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
594 { WM_SIZE
, sent
|id
, 0, 0, RECEIVER_PAGE
},
595 { WM_NOTIFY
, sent
|id
, 0, 0, RECEIVER_PAGE
},
596 { WM_STYLECHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
597 { WM_STYLECHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
598 /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
599 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
600 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
601 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
602 { WM_SETTEXT
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
603 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_PAGE
},
604 /*{ 0x00000401, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
605 { 0x00000400, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
606 { WM_CHANGEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
607 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
608 { WM_UPDATEUISTATE
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
609 { WM_SHOWWINDOW
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
610 { WM_WINDOWPOSCHANGING
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
611 /*{ WM_NCPAINT, 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_ERASEBKGND, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
616 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
617 { WM_WINDOWPOSCHANGED
, 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_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
621 { WM_PAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
622 { WM_PAINT, sent|id, 0, 0, RECEIVER_PAGE },
623 { WM_NCPAINT, sent|id, 0, 0, RECEIVER_PAGE },
624 { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_PAGE },*/
625 { WM_CTLCOLORDLG
, sent
|id
, 0, 0, RECEIVER_PAGE
},
626 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_PAGE
},
627 { WM_CTLCOLORSTATIC
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
628 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
629 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
630 { WM_CTLCOLORBTN
, sent
|id
, 0, 0, RECEIVER_SHEET_WINPROC
},
631 /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
632 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
633 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
634 { WM_COMMAND
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
635 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
636 { WM_NOTIFY
, sent
|id
|optional
, 0, 0, RECEIVER_PAGE
},
637 { WM_WINDOWPOSCHANGING
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
638 { WM_WINDOWPOSCHANGED
, sent
|id
|optional
, 0, 0, RECEIVER_SHEET_WINPROC
},
639 /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
640 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
641 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
642 { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
643 /*{ WM_ACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
644 { WM_ACTIVATE, sent|id, 0, 0, RECEIVER_PAGE },
645 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
646 { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_PAGE },
647 { WM_DESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },
648 { WM_DESTROY, sent|id, 0, 0, RECEIVER_PAGE },*/
649 /*{ WM_NCDESTROY, sent|id, 0, 0, RECEIVER_PAGE },
650 { WM_NCDESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/
654 static void save_message(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
, INT receiver
)
658 if (message
< WM_USER
&&
659 message
!= WM_GETICON
&&
660 message
!= WM_GETTEXT
&&
661 message
!= WM_IME_SETCONTEXT
&&
662 message
!= WM_IME_NOTIFY
&&
663 message
!= WM_PAINT
&&
664 message
!= WM_ERASEBKGND
&&
665 message
!= WM_SETCURSOR
&&
666 (message
< WM_NCCREATE
|| message
> WM_NCMBUTTONDBLCLK
) &&
667 (message
< WM_MOUSEFIRST
|| message
> WM_MOUSEHWHEEL
) &&
670 msg
.message
= message
;
671 msg
.flags
= sent
|wparam
|lparam
|id
;
675 add_message(sequences
, PROPSHEET_SEQ_INDEX
, &msg
);
679 static LRESULT CALLBACK
sheet_callback_messages_proc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
681 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_SHEET_WINPROC
);
683 return CallWindowProc (oldWndProc
, hwnd
, msg
, wParam
, lParam
);
686 static int CALLBACK
sheet_callback_messages(HWND hwnd
, UINT msg
, LPARAM lParam
)
688 save_message(hwnd
, msg
, 0, lParam
, RECEIVER_SHEET_CALLBACK
);
692 case PSCB_INITIALIZED
:
693 oldWndProc
= (WNDPROC
)GetWindowLongPtr (hwnd
, GWLP_WNDPROC
);
694 SetWindowLongPtr (hwnd
, GWLP_WNDPROC
, (LONG_PTR
)&sheet_callback_messages_proc
);
701 static INT_PTR CALLBACK
page_dlg_proc_messages(HWND hwnd
, UINT msg
, WPARAM wParam
,
704 save_message(hwnd
, msg
, wParam
, lParam
, RECEIVER_PAGE
);
709 static void test_messages(void)
711 HPROPSHEETPAGE hpsp
[1];
713 PROPSHEETHEADERA psh
;
716 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
718 memset(&psp
, 0, sizeof(psp
));
719 psp
.dwSize
= sizeof(psp
);
721 psp
.hInstance
= GetModuleHandleA(NULL
);
722 U(psp
).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
723 U2(psp
).pszIcon
= NULL
;
724 psp
.pfnDlgProc
= page_dlg_proc_messages
;
727 hpsp
[0] = CreatePropertySheetPageA(&psp
);
729 memset(&psh
, 0, sizeof(psh
));
730 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
731 psh
.dwFlags
= PSH_NOAPPLYNOW
| PSH_WIZARD
| PSH_USECALLBACK
732 | PSH_MODELESS
| PSH_USEICONID
;
733 psh
.pszCaption
= "test caption";
735 psh
.hwndParent
= GetDesktopWindow();
736 U3(psh
).phpage
= hpsp
;
737 psh
.pfnCallback
= sheet_callback_messages
;
739 hdlg
= (HWND
)PropertySheetA(&psh
);
740 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
742 ShowWindow(hdlg
,SW_NORMAL
);
744 ok_sequence(sequences
, PROPSHEET_SEQ_INDEX
, property_sheet_seq
, "property sheet with custom window proc", TRUE
);
749 static void test_PSM_ADDPAGE(void)
751 HPROPSHEETPAGE hpsp
[5];
753 PROPSHEETHEADERA psh
;
758 memset(&psp
, 0, sizeof(psp
));
759 psp
.dwSize
= sizeof(psp
);
761 psp
.hInstance
= GetModuleHandleA(NULL
);
762 U(psp
).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST
);
763 U2(psp
).pszIcon
= NULL
;
764 psp
.pfnDlgProc
= page_dlg_proc_messages
;
767 /* two page with the same data */
768 hpsp
[0] = CreatePropertySheetPageA(&psp
);
769 hpsp
[1] = CreatePropertySheetPageA(&psp
);
770 hpsp
[2] = CreatePropertySheetPageA(&psp
);
772 U(psp
).pszTemplate
= MAKEINTRESOURCE(IDD_PROP_PAGE_ERROR
);
773 hpsp
[3] = CreatePropertySheetPageA(&psp
);
775 psp
.dwFlags
= PSP_PREMATURE
;
776 hpsp
[4] = CreatePropertySheetPageA(&psp
);
778 memset(&psh
, 0, sizeof(psh
));
779 psh
.dwSize
= PROPSHEETHEADERA_V1_SIZE
;
780 psh
.dwFlags
= PSH_MODELESS
;
781 psh
.pszCaption
= "test caption";
783 psh
.hwndParent
= GetDesktopWindow();
784 U3(psh
).phpage
= hpsp
;
786 hdlg
= (HWND
)PropertySheetA(&psh
);
787 ok(hdlg
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", hdlg
);
789 /* add pages one by one */
790 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[1]);
791 ok(ret
== TRUE
, "got %d\n", ret
);
793 /* try with null and invalid value */
794 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, 0);
795 ok(ret
== FALSE
, "got %d\n", ret
);
799 /* crashes on native */
800 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)INVALID_HANDLE_VALUE
);
802 /* check item count */
803 tab
= (HWND
)SendMessageA(hdlg
, PSM_GETTABCONTROL
, 0, 0);
805 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
806 ok(r
== 2, "got %d\n", r
);
808 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[2]);
809 ok(ret
== TRUE
, "got %d\n", ret
);
811 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
812 ok(r
== 3, "got %d\n", r
);
814 /* add property sheet page that can't be created */
815 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[3]);
816 ok(ret
== TRUE
, "got %d\n", ret
);
818 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
819 ok(r
== 4, "got %d\n", r
);
821 /* select page that can't be created */
822 ret
= SendMessageA(hdlg
, PSM_SETCURSEL
, 3, 1);
823 ok(ret
== TRUE
, "got %d\n", ret
);
825 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
826 ok(r
== 3, "got %d\n", r
);
828 /* test PSP_PREMATURE flag with incorrect property sheet page */
829 ret
= SendMessageA(hdlg
, PSM_ADDPAGE
, 0, (LPARAM
)hpsp
[4]);
830 ok(ret
== FALSE
, "got %d\n", ret
);
832 r
= SendMessageA(tab
, TCM_GETITEMCOUNT
, 0, 0);
833 ok(r
== 3, "got %d\n", r
);
838 START_TEST(propsheet
)
843 test_wiznavigation();
845 test_custom_default_button();