[PATCH 5/5] comctl32/taskdialog: Add support for progress bar.

Zhiyi Zhang zzhang at codeweavers.com
Thu Jun 14 09:52:52 CDT 2018



On Thu 6 14 21:03, Nikolay Sivov wrote:
> On 06/14/2018 11:02 AM, Zhiyi Zhang wrote:
> 
>> Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
>> ---
>>   dlls/comctl32/taskdialog.c       | 45 ++++++++++++++++++++++
>>   dlls/comctl32/tests/taskdialog.c | 65 ++++++++++++++++++++++++++++++++
>>   2 files changed, 110 insertions(+)
>>
>> diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
>> index 91c8af019b..3c198df6d1 100644
>> --- a/dlls/comctl32/taskdialog.c
>> +++ b/dlls/comctl32/taskdialog.c
>> @@ -57,6 +57,7 @@ struct taskdialog_info
>>       HWND main_icon;
>>       HWND main_instruction;
>>       HWND content;
>> +    HWND progress_bar;
>>       HWND *buttons;
>>       INT button_count;
>>       HWND default_button;
>> @@ -351,6 +352,17 @@ static void taskdialog_add_content(struct taskdialog_info *dialog_info)
>>                                                      taskdialog_hyperlink_enabled(dialog_info));
>>   }
>>   +static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info)
>> +{
>> +    const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> +    DWORD style = PBS_SMOOTH | PBS_SMOOTHREVERSE | WS_CHILD | WS_VISIBLE;
>> +
>> +    if (!(taskconfig->dwFlags & (TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR))) return;
>> +    if (taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR) style |= PBS_MARQUEE;
>> +    dialog_info->progress_bar =
>> +        CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
>> +}
>> +
>>   static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT id, const WCHAR *text,
>>                                     BOOL custom_button)
>>   {
>> @@ -464,6 +476,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
>>       /* Content */
>>       taskdialog_label_layout(dialog_info, dialog_info->content, main_icon_right, dialog_width, &dialog_height, syslink);
>>   +    /* Progress bar */
>> +    if (dialog_info->progress_bar)
>> +    {
>> +        x = main_icon_right + h_spacing;
>> +        y = dialog_height + v_spacing;
>> +        size.cx = dialog_width - x - h_spacing;
>> +        size.cy = GetSystemMetrics(SM_CYVSCROLL);
>> +        SetWindowPos(dialog_info->progress_bar, 0, x, y, size.cx, size.cy, SWP_NOZORDER);
>> +        dialog_height = y + size.cy;
>> +    }
>> +
>>       dialog_height = max(dialog_height, main_icon_bottom);
>>         /* Common and custom buttons */
>> @@ -598,6 +621,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
>>       taskdialog_add_main_icon(dialog_info);
>>       taskdialog_add_main_instruction(dialog_info);
>>       taskdialog_add_content(dialog_info);
>> +    taskdialog_add_progress_bar(dialog_info);
>>       taskdialog_add_buttons(dialog_info);
>>         /* Set default button */
>> @@ -621,6 +645,7 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
>>   {
>>       static const WCHAR taskdialog_info_propnameW[] = {'T','a','s','k','D','i','a','l','o','g','I','n','f','o',0};
>>       struct taskdialog_info *dialog_info;
>> +    LRESULT result;
>>         TRACE("hwnd=%p msg=0x%04x wparam=%lx lparam=%lx\n", hwnd, msg, wParam, lParam);
>>   @@ -635,6 +660,26 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
>>           case TDM_ENABLE_BUTTON:
>>               taskdialog_enable_button(dialog_info, wParam, lParam);
>>               break;
>> +        case TDM_SET_MARQUEE_PROGRESS_BAR:
>> +            SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, 0);
>> +            break;
> 
> This appears to be wrong, it shouldn't just start/stop animation, but switch from marquee to regular mode and back, in our case flipping styles.
> 
Thanks. In the end, turns out I still got it confused with TDM_SET_PROGRESS_BAR_MARQUEE, even though I noticed the easy confusion from the start :(

I sent a v2.

>>
>> +        case TDM_SET_PROGRESS_BAR_POS:
>> +            result = 0;
>> +            if (!(dialog_info->taskconfig->dwFlags & TDF_SHOW_MARQUEE_PROGRESS_BAR))
>> +                result = SendMessageW(dialog_info->progress_bar, PBM_SETPOS, wParam, 0);
>> +            SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, result);
>> +            break;
> 
> Did you verify that Progress control handles this correctly, maybe flags check is not necessary?
> 
>> +        case TDM_SET_PROGRESS_BAR_MARQUEE:
>> +            SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
>> +            break;
>>           case WM_INITDIALOG:
>>               dialog_info = (struct taskdialog_info *)lParam;
>>   diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
>> index cca700cd18..10cd3da794 100644
>> --- a/dlls/comctl32/tests/taskdialog.c
>> +++ b/dlls/comctl32/tests/taskdialog.c
>> @@ -373,6 +373,70 @@ static void test_timer(void)
>>       pTaskDialogIndirect(&info, NULL, NULL, NULL);
>>   }
>>   +static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam,
>> +                                                              LPARAM lParam, LONG_PTR ref_data)
>> +{
>> +    unsigned long ret;
>> +    DWORD *flags = (DWORD *)ref_data;
> You can pass flags by value.
> 
> 

Sure.





More information about the wine-devel mailing list