Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
32c42cc1
Commit
32c42cc1
authored
Nov 06, 2017
by
Fabian Maurer
Committed by
Alexandre Julliard
Nov 06, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
comctl32/taskdialog: Added support for nDefaultButton.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
afbd598a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
153 additions
and
22 deletions
+153
-22
taskdialog.c
dlls/comctl32/taskdialog.c
+25
-15
taskdialog.c
dlls/comctl32/tests/taskdialog.c
+128
-7
No files found.
dlls/comctl32/taskdialog.c
View file @
32c42cc1
...
...
@@ -59,6 +59,15 @@ struct taskdialog_control
unsigned
int
template_size
;
};
struct
taskdialog_button_desc
{
int
id
;
const
WCHAR
*
text
;
unsigned
int
width
;
unsigned
int
line
;
HINSTANCE
hinst
;
};
struct
taskdialog_template_desc
{
const
TASKDIALOGCONFIG
*
taskconfig
;
...
...
@@ -69,15 +78,7 @@ struct taskdialog_template_desc
LONG
x_baseunit
;
LONG
y_baseunit
;
HFONT
font
;
};
struct
taskdialog_button_desc
{
int
id
;
const
WCHAR
*
text
;
unsigned
int
width
;
unsigned
int
line
;
HINSTANCE
hinst
;
struct
taskdialog_button_desc
*
default_button
;
};
struct
taskdialog_info
...
...
@@ -151,7 +152,7 @@ static void taskdialog_get_text_extent(const struct taskdialog_template_desc *de
}
static
unsigned
int
taskdialog_add_control
(
struct
taskdialog_template_desc
*
desc
,
WORD
id
,
const
WCHAR
*
class
,
HINSTANCE
hInstance
,
const
WCHAR
*
text
,
short
x
,
short
y
,
short
cx
,
short
cy
)
HINSTANCE
hInstance
,
const
WCHAR
*
text
,
DWORD
style
,
short
x
,
short
y
,
short
cx
,
short
cy
)
{
struct
taskdialog_control
*
control
=
Alloc
(
sizeof
(
*
control
));
unsigned
int
size
,
class_size
,
text_size
;
...
...
@@ -178,7 +179,7 @@ static unsigned int taskdialog_add_control(struct taskdialog_template_desc *desc
control
->
template
=
template
=
Alloc
(
size
);
control
->
template_size
=
size
;
template
->
style
=
WS_VISIBLE
;
template
->
style
=
WS_VISIBLE
|
style
;
template
->
dwExtendedStyle
=
0
;
template
->
x
=
x
;
template
->
y
=
y
;
...
...
@@ -206,7 +207,7 @@ static unsigned int taskdialog_add_static_label(struct taskdialog_template_desc
taskdialog_get_text_extent
(
desc
,
str
,
TRUE
,
&
sz
);
desc
->
dialog_height
+=
DIALOG_SPACING
;
size
=
taskdialog_add_control
(
desc
,
id
,
WC_STATICW
,
desc
->
taskconfig
->
hInstance
,
str
,
DIALOG_SPACING
,
size
=
taskdialog_add_control
(
desc
,
id
,
WC_STATICW
,
desc
->
taskconfig
->
hInstance
,
str
,
0
,
DIALOG_SPACING
,
desc
->
dialog_height
,
sz
.
cx
,
sz
.
cy
);
desc
->
dialog_height
+=
sz
.
cy
+
DIALOG_SPACING
;
return
size
;
...
...
@@ -234,6 +235,9 @@ static void taskdialog_init_button(struct taskdialog_button_desc *button, struct
button
->
width
=
max
(
DIALOG_BUTTON_WIDTH
,
sz
.
cx
+
DIALOG_SPACING
*
2
);
button
->
line
=
0
;
button
->
hinst
=
custom_button
?
desc
->
taskconfig
->
hInstance
:
COMCTL32_hModule
;
if
(
id
==
desc
->
taskconfig
->
nDefaultButton
)
desc
->
default_button
=
button
;
}
static
void
taskdialog_init_common_buttons
(
struct
taskdialog_template_desc
*
desc
,
struct
taskdialog_button_desc
*
buttons
,
...
...
@@ -290,6 +294,9 @@ static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc
if
(
count
==
0
)
taskdialog_init_button
(
&
buttons
[
count
++
],
desc
,
IDOK
,
MAKEINTRESOURCEW
(
IDS_BUTTON_OK
),
FALSE
);
if
(
!
desc
->
default_button
)
desc
->
default_button
=
&
buttons
[
0
];
/* For easy handling just allocate as many lines as buttons, the worst case. */
line_widths
=
Alloc
(
count
*
sizeof
(
*
line_widths
));
...
...
@@ -344,14 +351,16 @@ static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc
location_x
=
alignment
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
DWORD
style
=
&
buttons
[
i
]
==
desc
->
default_button
?
BS_DEFPUSHBUTTON
:
BS_PUSHBUTTON
;
if
(
i
>
0
&&
buttons
[
i
].
line
!=
buttons
[
i
-
1
].
line
)
/* New line */
{
location_x
=
alignment
;
desc
->
dialog_height
+=
DIALOG_BUTTON_HEIGHT
+
DIALOG_SPACING
;
}
size
+=
taskdialog_add_control
(
desc
,
buttons
[
i
].
id
,
WC_BUTTONW
,
buttons
[
i
].
hinst
,
buttons
[
i
].
text
,
location_x
,
desc
->
dialog_height
,
buttons
[
i
].
width
,
DIALOG_BUTTON_HEIGHT
);
size
+=
taskdialog_add_control
(
desc
,
buttons
[
i
].
id
,
WC_BUTTONW
,
buttons
[
i
].
hinst
,
buttons
[
i
].
text
,
style
,
location_x
,
desc
->
dialog_height
,
buttons
[
i
].
width
,
DIALOG_BUTTON_HEIGHT
);
location_x
+=
buttons
[
i
].
width
+
DIALOG_SPACING
;
}
...
...
@@ -464,6 +473,7 @@ static DLGTEMPLATE *create_taskdialog_template(const TASKDIALOGCONFIG *taskconfi
desc
.
dialog_height
=
0
;
desc
.
dialog_width
=
max
(
taskconfig
->
cxWidth
,
DIALOG_MIN_WIDTH
);
desc
.
dialog_width
=
min
(
desc
.
dialog_width
,
screen_width
);
desc
.
default_button
=
NULL
;
size
+=
taskdialog_add_main_instruction
(
&
desc
);
size
+=
taskdialog_add_content
(
&
desc
);
...
...
@@ -578,7 +588,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
dialog_info
.
callback_data
=
taskconfig
->
lpCallbackData
;
template
=
create_taskdialog_template
(
taskconfig
);
ret
=
DialogBoxIndirectParamW
(
taskconfig
->
hInstance
,
template
,
taskconfig
->
hwndParent
,
ret
=
(
short
)
DialogBoxIndirectParamW
(
taskconfig
->
hInstance
,
template
,
taskconfig
->
hwndParent
,
taskdialog_proc
,
(
LPARAM
)
&
dialog_info
);
Free
(
template
);
...
...
dlls/comctl32/tests/taskdialog.c
View file @
32c42cc1
...
...
@@ -33,6 +33,11 @@
#define NUM_MSG_SEQUENCES 1
#define TASKDIALOG_SEQ_INDEX 0
#define TEST_NUM_BUTTONS 10
/* Number of custom buttons to test with */
#define ID_START 20
/* Lower IDs might be used by the system */
#define ID_START_BUTTON (ID_START + 0)
static
HRESULT
(
WINAPI
*
pTaskDialogIndirect
)(
const
TASKDIALOGCONFIG
*
,
int
*
,
int
*
,
BOOL
*
);
static
HRESULT
(
WINAPI
*
pTaskDialog
)(
HWND
,
HINSTANCE
,
const
WCHAR
*
,
const
WCHAR
*
,
const
WCHAR
*
,
TASKDIALOG_COMMON_BUTTON_FLAGS
,
const
WCHAR
*
,
int
*
);
...
...
@@ -66,6 +71,55 @@ static const struct message_info msg_return_press_ok[] =
{
0
}
};
static
const
struct
message_info
msg_return_press_yes
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
IDYES
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
const
struct
message_info
msg_return_press_no
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
IDNO
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
const
struct
message_info
msg_return_press_cancel
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
IDCANCEL
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
const
struct
message_info
msg_return_press_retry
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
IDRETRY
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
const
struct
message_info
msg_return_press_custom1
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
ID_START_BUTTON
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
const
struct
message_info
msg_return_press_custom4
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
ID_START_BUTTON
+
3
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
const
struct
message_info
msg_return_press_custom10
[]
=
{
{
TDN_CREATED
,
0
,
0
,
S_OK
,
msg_send_return
},
{
TDN_BUTTON_CLICKED
,
-
1
,
0
,
S_OK
,
NULL
},
{
0
}
};
static
void
init_test_message
(
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
,
struct
message
*
msg
)
{
msg
->
message
=
WM_TD_CALLBACK
;
...
...
@@ -76,11 +130,11 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
msg
->
stage
=
0
;
}
#define run_test(info, expect_button,
expect_radio,
seq, context) \
run_test_(info, expect_button,
expect_radio,
seq, context, \
#define run_test(info, expect_button, seq, context) \
run_test_(info, expect_button, seq, context, \
sizeof(seq)/sizeof(seq[0]) - 1, __FILE__, __LINE__)
void
run_test_
(
TASKDIALOGCONFIG
*
info
,
int
expect_button
,
int
expect_radio
,
const
struct
message_info
*
test_messages
,
void
run_test_
(
TASKDIALOGCONFIG
*
info
,
int
expect_button
,
const
struct
message_info
*
test_messages
,
const
char
*
context
,
int
test_messages_len
,
const
char
*
file
,
int
line
)
{
struct
message
*
msg
,
*
msg_start
;
...
...
@@ -108,8 +162,6 @@ void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio, cons
ok_sequence_
(
sequences
,
TASKDIALOG_SEQ_INDEX
,
msg_start
,
context
,
FALSE
,
file
,
line
);
ok_
(
file
,
line
)(
ret_button
==
expect_button
,
"Wrong button. Expected %d, got %d
\n
"
,
expect_button
,
ret_button
);
ok_
(
file
,
line
)(
ret_radio
==
expect_radio
,
"Wrong radio button. Expected %d, got %d
\n
"
,
expect_radio
,
ret_radio
);
HeapFree
(
GetProcessHeap
(),
0
,
msg_start
);
}
...
...
@@ -125,7 +177,7 @@ static HRESULT CALLBACK taskdialog_callback_proc(HWND hwnd, UINT notification,
ok
(
test_ref_data
==
ref_data
,
"Unexpected ref data %lu.
\n
"
,
ref_data
);
init_test_message
(
notification
,
wParam
,
lParam
,
&
msg
);
init_test_message
(
notification
,
(
short
)
wParam
,
lParam
,
&
msg
);
add_message
(
sequences
,
TASKDIALOG_SEQ_INDEX
,
&
msg
);
if
(
notification
==
TDN_DIALOG_CONSTRUCTED
||
notification
==
TDN_DESTROYED
)
/* Skip implicit messages */
...
...
@@ -167,7 +219,75 @@ static void test_callback(void)
info
.
pfCallback
=
taskdialog_callback_proc
;
info
.
lpCallbackData
=
test_ref_data
;
run_test
(
&
info
,
IDOK
,
0
,
msg_return_press_ok
,
"Press VK_RETURN."
);
run_test
(
&
info
,
IDOK
,
msg_return_press_ok
,
"Press VK_RETURN."
);
}
static
void
test_buttons
(
void
)
{
TASKDIALOGCONFIG
info
=
{
0
};
TASKDIALOG_BUTTON
custom_buttons
[
TEST_NUM_BUTTONS
];
const
WCHAR
button_format
[]
=
{
'%'
,
'0'
,
'2'
,
'd'
,
0
};
WCHAR
button_titles
[
TEST_NUM_BUTTONS
*
3
];
/* Each button has two digits as title, plus null-terminator */
int
i
;
info
.
cbSize
=
sizeof
(
TASKDIALOGCONFIG
);
info
.
pfCallback
=
taskdialog_callback_proc
;
info
.
lpCallbackData
=
test_ref_data
;
/* Init custom buttons */
for
(
i
=
0
;
i
<
TEST_NUM_BUTTONS
;
i
++
)
{
WCHAR
*
text
=
&
button_titles
[
i
*
3
];
wsprintfW
(
text
,
button_format
,
i
);
custom_buttons
[
i
].
pszButtonText
=
text
;
custom_buttons
[
i
].
nButtonID
=
ID_START_BUTTON
+
i
;
}
custom_buttons
[
TEST_NUM_BUTTONS
-
1
].
nButtonID
=
-
1
;
/* Test nDefaultButton */
/* Test common buttons with invalid default ID */
info
.
nDefaultButton
=
0
;
/* Should default to first created button */
info
.
dwCommonButtons
=
TDCBF_OK_BUTTON
|
TDCBF_YES_BUTTON
|
TDCBF_NO_BUTTON
|
TDCBF_CANCEL_BUTTON
|
TDCBF_RETRY_BUTTON
|
TDCBF_CLOSE_BUTTON
;
run_test
(
&
info
,
IDOK
,
msg_return_press_ok
,
"default button: unset default"
);
info
.
dwCommonButtons
=
TDCBF_YES_BUTTON
|
TDCBF_NO_BUTTON
|
TDCBF_CANCEL_BUTTON
|
TDCBF_RETRY_BUTTON
|
TDCBF_CLOSE_BUTTON
;
run_test
(
&
info
,
IDYES
,
msg_return_press_yes
,
"default button: unset default"
);
info
.
dwCommonButtons
=
TDCBF_NO_BUTTON
|
TDCBF_CANCEL_BUTTON
|
TDCBF_RETRY_BUTTON
|
TDCBF_CLOSE_BUTTON
;
run_test
(
&
info
,
IDNO
,
msg_return_press_no
,
"default button: unset default"
);
info
.
dwCommonButtons
=
TDCBF_CANCEL_BUTTON
|
TDCBF_RETRY_BUTTON
|
TDCBF_CLOSE_BUTTON
;
run_test
(
&
info
,
IDRETRY
,
msg_return_press_retry
,
"default button: unset default"
);
info
.
dwCommonButtons
=
TDCBF_CANCEL_BUTTON
|
TDCBF_CLOSE_BUTTON
;
run_test
(
&
info
,
IDCANCEL
,
msg_return_press_cancel
,
"default button: unset default"
);
/* Test with all common and custom buttons and invalid default ID */
info
.
nDefaultButton
=
0xff
;
/* Random ID, should also default to first created button */
info
.
cButtons
=
TEST_NUM_BUTTONS
;
info
.
pButtons
=
custom_buttons
;
run_test
(
&
info
,
ID_START_BUTTON
,
msg_return_press_custom1
,
"default button: invalid default, with common buttons - 1"
);
info
.
nDefaultButton
=
-
1
;
/* Should work despite button ID -1 */
run_test
(
&
info
,
-
1
,
msg_return_press_custom10
,
"default button: invalid default, with common buttons - 2"
);
info
.
nDefaultButton
=
-
2
;
/* Should also default to first created button */
run_test
(
&
info
,
ID_START_BUTTON
,
msg_return_press_custom1
,
"default button: invalid default, with common buttons - 3"
);
/* Test with only custom buttons and invalid default ID */
info
.
dwCommonButtons
=
0
;
run_test
(
&
info
,
ID_START_BUTTON
,
msg_return_press_custom1
,
"default button: invalid default, no common buttons"
);
/* Test with common and custom buttons and valid default ID */
info
.
dwCommonButtons
=
TDCBF_OK_BUTTON
|
TDCBF_YES_BUTTON
|
TDCBF_NO_BUTTON
|
TDCBF_CANCEL_BUTTON
|
TDCBF_RETRY_BUTTON
|
TDCBF_CLOSE_BUTTON
;
info
.
nDefaultButton
=
IDRETRY
;
run_test
(
&
info
,
IDRETRY
,
msg_return_press_retry
,
"default button: valid default - 1"
);
/* Test with common and custom buttons and valid default ID */
info
.
nDefaultButton
=
ID_START_BUTTON
+
3
;
run_test
(
&
info
,
ID_START_BUTTON
+
3
,
msg_return_press_custom4
,
"default button: valid default - 2"
);
}
START_TEST
(
taskdialog
)
...
...
@@ -205,6 +325,7 @@ START_TEST(taskdialog)
test_invalid_parameters
();
test_callback
();
test_buttons
();
unload_v6_module
(
ctx_cookie
,
hCtx
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment