Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 68 participants
- 1149 messages
[PATCH 2/3] wsdapi: Implement generation of ProbeMatches message.
by Owen Rudge
Signed-off-by: Owen Rudge <orudge(a)codeweavers.com>
---
dlls/wsdapi/soap.c | 169
+++++++++++++++++++++++++++++++++++++++++-
dlls/wsdapi/tests/discovery.c | 2 +-
2 files changed, 169 insertions(+), 2 deletions(-)
June 25, 2018
[PATCH 1/3] wsdapi: Implement matching of names in MatchProbeEx.
by Owen Rudge
Signed-off-by: Owen Rudge <orudge(a)codeweavers.com>
---
dlls/wsdapi/discovery.c | 58
++++++++++++++++++++++++++++++++++++++++---
dlls/wsdapi/soap.c | 9 +++++++
dlls/wsdapi/wsdapi_internal.h | 6 +++++
3 files changed, 69 insertions(+), 4 deletions(-)
June 25, 2018
wine-3.0.2-rc3 Available
by Michael Stefaniuc
Hello guys,
I have pushed wine-3.0.2-rc3 (with tag) to
https://github.com/mstefani/wine-stable/tree/stable
http://static-winehq.193b.starter-ca-central-1.openshiftapps.com/stable/
Changes since rc2:
- Added "ddraw: Fix D3DEXECUTEDATA.dwSize handling." as that is a
dependency for "ddraw: Don't read past the end of the executebuffer."
bye
michael
June 25, 2018
Re: [PATCH v2] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
On 25/06/18 15:09, Alexandre Julliard wrote:
> Zebediah Figura <z.figura12(a)gmail.com> writes:
>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
>> dlls/hnetcfg/tests/policy.c | 5 ++++-
>> 2 files changed, 16 insertions(+), 6 deletions(-)
>
> It doesn't work here:
>
> ../../../tools/runtest -q -P wine -T ../../.. -M hnetcfg.dll -p hnetcfg_test.exe.so policy && touch policy.ok
> 0009:err:seh:raise_exception Unhandled exception code c0000005 flags 0 addr 0x7bc4ed69
> Makefile:183: recipe for target 'policy.ok' failed
>
Sorry I'm so sloppy today. Updated version sent.
June 25, 2018
[PATCH v3] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/hnetcfg/apps.c | 17 ++++++++++++-----
dlls/hnetcfg/tests/policy.c | 5 ++++-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
index 34ef108..69eabd6 100644
--- a/dlls/hnetcfg/apps.c
+++ b/dlls/hnetcfg/apps.c
@@ -268,7 +268,7 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
{
fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
UNIVERSAL_NAME_INFOW *info;
- WCHAR *netpath;
+ WCHAR *path;
DWORD res;
DWORD sz;
@@ -281,22 +281,29 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, NULL, &sz);
if (res == WN_MORE_DATA)
{
- if (!(netpath = heap_alloc(sz)))
+ if (!(path = heap_alloc(sz)))
return E_OUTOFMEMORY;
- info = (UNIVERSAL_NAME_INFOW *)&netpath;
+ info = (UNIVERSAL_NAME_INFOW *)&path;
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (res == NO_ERROR)
{
SysFreeString(This->filename);
This->filename = SysAllocString(info->lpUniversalName);
}
- heap_free(netpath);
+ heap_free(path);
return HRESULT_FROM_WIN32(res);
}
+ sz = GetFullPathNameW(image, 0, NULL, NULL);
+ if (!(path = heap_alloc(++sz * sizeof(WCHAR))))
+ return E_OUTOFMEMORY;
+
+ GetFullPathNameW(image, sz, path, NULL);
+
SysFreeString( This->filename );
- This->filename = SysAllocString(image);
+ This->filename = SysAllocString(path);
+ heap_free(path);
return This->filename ? S_OK : E_OUTOFMEMORY;
}
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f2d1372..954af5c 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -107,6 +107,7 @@ static void test_NetFwAuthorizedApplication(void)
INetFwAuthorizedApplication *app;
static WCHAR empty[] = {0};
UNIVERSAL_NAME_INFOW *info;
+ WCHAR fullpath[MAX_PATH];
WCHAR netpath[MAX_PATH];
WCHAR image[MAX_PATH];
HRESULT hr;
@@ -138,13 +139,15 @@ static void test_NetFwAuthorizedApplication(void)
ok(hr == S_OK, "got: %08x\n", hr);
SysFreeString(bstr);
+ GetFullPathNameW(image, ARRAY_SIZE(fullpath), fullpath, NULL);
+
info = (UNIVERSAL_NAME_INFOW *)&netpath;
sz = sizeof(netpath);
hr = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (hr != NO_ERROR)
{
info->lpUniversalName = netpath + sizeof(*info)/sizeof(WCHAR);
- lstrcpyW(info->lpUniversalName, image);
+ lstrcpyW(info->lpUniversalName, fullpath);
}
hr = INetFwAuthorizedApplication_get_ProcessImageFileName(app, &bstr);
--
2.7.4
June 25, 2018
Re: [PATCH v2] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Alexandre Julliard
Zebediah Figura <z.figura12(a)gmail.com> writes:
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
> dlls/hnetcfg/tests/policy.c | 5 ++++-
> 2 files changed, 16 insertions(+), 6 deletions(-)
It doesn't work here:
../../../tools/runtest -q -P wine -T ../../.. -M hnetcfg.dll -p hnetcfg_test.exe.so policy && touch policy.ok
0009:err:seh:raise_exception Unhandled exception code c0000005 flags 0 addr 0x7bc4ed69
Makefile:183: recipe for target 'policy.ok' failed
--
Alexandre Julliard
julliard(a)winehq.org
June 25, 2018
[PATCH v2 4/4] winemac.drv: Implement waking up the display when activity occurs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/winemac.drv/macdrv_main.c | 12 ++++++++++++
dlls/winemac.drv/winemac.drv.spec | 3 +++
2 files changed, 15 insertions(+)
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index 491ab06..ea0beec 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -451,3 +451,15 @@ BOOL CDECL macdrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_p
}
return FALSE;
}
+
+/***********************************************************************
+ * wine_notify_activity (MACDRV.@)
+ *
+ * Notify the display server that activity has occurred, e.g. to wake up
+ * the display and reset any power management related timeouts.
+ */
+void CDECL macdrv_notify_activity(void)
+{
+ static IOPMAssertionID assertion;
+ IOPMAssertionDeclareUserActivity(CFSTR("Wine user input"), kIOPMUserActiveLocal, &assertion);
+}
diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec
index 6fa723a..9658fad 100644
--- a/dlls/winemac.drv/winemac.drv.spec
+++ b/dlls/winemac.drv/winemac.drv.spec
@@ -45,6 +45,9 @@
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) macdrv_WindowPosChanged
@ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) macdrv_WindowPosChanging
+# Desktop
+@ cdecl wine_notify_activity() macdrv_notify_activity
+
# System tray
@ cdecl wine_notify_icon(long ptr)
--
2.7.4
June 25, 2018
[PATCH v2 3/4] winex11.drv: Implement waking up the display when activity occurs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/winex11.drv/winex11.drv.spec | 1 +
dlls/winex11.drv/x11drv_main.c | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 614f0b9..c833edb 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -57,6 +57,7 @@
# Desktop
@ cdecl wine_create_desktop(long long) X11DRV_create_desktop
+@ cdecl wine_notify_activity() X11DRV_notify_activity
# System tray
@ cdecl wine_notify_icon(long ptr)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 4654556..0dbd4f6 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -739,3 +739,15 @@ BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_p
}
return FALSE; /* let user32 handle it */
}
+
+/***********************************************************************
+ * wine_notify_activity (X11DRV.@)
+ *
+ * Notify the display server that activity has occurred, e.g. to wake up
+ * the display and reset any power management related timeouts.
+ */
+void CDECL X11DRV_notify_activity(void)
+{
+ XResetScreenSaver( gdi_display );
+ XFlush( gdi_display );
+}
--
2.7.4
June 25, 2018
[PATCH v2 2/4] dinput: Notify the desktop window when device input is received.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/dinput/device.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 7b83a39..daa6406 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -39,6 +39,8 @@
#include "device_private.h"
#include "dinput_private.h"
+#define WM_WINE_NOTIFY_ACTIVITY WM_USER
+
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
static inline IDirectInputDeviceImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
@@ -935,6 +937,8 @@ void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD tim
/* Event is being set regardless of the queue state */
if (This->hEvent) SetEvent(This->hEvent);
+ SendMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0);
+
if (!This->queue_len || This->overflow || ofs < 0) return;
next_pos = (This->queue_head + 1) % This->queue_len;
--
2.7.4
June 25, 2018
[PATCH v2 1/4] explorer: Add a private message to notify the graphics driver when activity occurs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
programs/explorer/desktop.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index a2d9e1a..f5a01c2 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -46,6 +46,10 @@ static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0};
static const WCHAR default_driver[] = {'x','1','1',0};
#endif
+static void (CDECL *wine_notify_activity)(void);
+
+#define WM_WINE_NOTIFY_ACTIVITY WM_USER
+
static BOOL using_root;
struct launcher
@@ -661,6 +665,11 @@ static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPAR
}
return 0;
+ case WM_WINE_NOTIFY_ACTIVITY:
+ if (wine_notify_activity)
+ wine_notify_activity();
+ return 0;
+
default:
return DefWindowProcW( hwnd, message, wp, lp );
}
@@ -1005,6 +1014,8 @@ void manage_desktop( WCHAR *arg )
{
pShellDDEInit( TRUE );
}
+
+ wine_notify_activity = (void *)GetProcAddress( graphics_driver, "wine_notify_activity" );
}
}
--
2.7.4
June 25, 2018
[PATCH] gdi32/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/gdi32/tests/bitmap.c | 10 ++++-----
dlls/gdi32/tests/brush.c | 2 +-
dlls/gdi32/tests/dc.c | 6 +++---
dlls/gdi32/tests/dib.c | 38 ++++++++++++++++-----------------
dlls/gdi32/tests/font.c | 52 ++++++++++++++++++++++-----------------------
dlls/gdi32/tests/gdiobj.c | 2 +-
dlls/gdi32/tests/icm.c | 2 +-
dlls/gdi32/tests/metafile.c | 7 +++---
dlls/gdi32/tests/path.c | 14 ++++++------
dlls/gdi32/tests/pen.c | 2 +-
10 files changed, 67 insertions(+), 68 deletions(-)
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index a4002c83b5..4748691791 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -84,7 +84,7 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
SetLastError(0xdeadbeef);
test_size[0] = bm.bmWidthBytes * bm.bmHeight;
/* NULL output buffer with different count values */
- for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_size); i++)
{
ret = GetBitmapBits(hbm, test_size[i], NULL);
ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
@@ -94,7 +94,7 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
/* Correct output buffer with different count values */
- for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_size); i++)
{
int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight;
memset(buf, 0xAA, sizeof(buf));
@@ -1745,7 +1745,7 @@ static void test_mono_bitmap(void)
SelectObject( hdc, hbmp );
- for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
+ for (col = 0; col < ARRAY_SIZE(colors); col++)
{
SetTextColor( hdc, colors[col][0] );
SetBkColor( hdc, colors[col][1] );
@@ -2690,7 +2690,7 @@ static void test_select_object(void)
DeleteObject(hbm);
- for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
+ for(i = 0; i < ARRAY_SIZE(depths); i++) {
/* test a color bitmap to dc bpp matching */
planes = GetDeviceCaps(hdc, PLANES);
bpp = GetDeviceCaps(hdc, BITSPIXEL);
@@ -5710,7 +5710,7 @@ static void test_D3DKMTCreateDCFromMemory( void )
status = pD3DKMTCreateDCFromMemory( NULL );
ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status);
- for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
+ for (i = 0; i < ARRAY_SIZE(test_data); ++i)
{
memset( data, 0xaa, sizeof(data) );
diff --git a/dlls/gdi32/tests/brush.c b/dlls/gdi32/tests/brush.c
index 1a10429c05..a3ebb91e1e 100644
--- a/dlls/gdi32/tests/brush.c
+++ b/dlls/gdi32/tests/brush.c
@@ -48,7 +48,7 @@ static void test_solidbrush(void)
size_t i;
INT ret;
- for(i=0; i<sizeof(stock)/sizeof(stock[0]); i++) {
+ for(i = 0; i < ARRAY_SIZE(stock); i++) {
solidBrush = CreateSolidBrush(stock[i].color);
if(stock[i].stockobj != -1) {
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c
index 3c1fa603a6..5ad3b31483 100644
--- a/dlls/gdi32/tests/dc.c
+++ b/dlls/gdi32/tests/dc.c
@@ -361,7 +361,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
if (GetObjectType( hdc ) == OBJ_METADC)
{
- for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(caps); i++)
ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
"wrong caps on %s for %u: %u\n", descr, caps[i],
GetDeviceCaps( hdc, caps[i] ) );
@@ -384,7 +384,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
}
else
{
- for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(caps); i++)
{
INT precision = 0;
INT hdc_caps = GetDeviceCaps( hdc, caps[i] );
@@ -506,7 +506,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
old = SelectObject( hdc, dib );
- for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(caps); i++)
ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
"mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index e3f188749d..d16cb0df5c 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -1559,7 +1559,7 @@ static const POINT polypoly_lines[] =
static const DWORD polypoly_counts[] =
{
- sizeof(polypoly_lines)/sizeof(polypoly_lines[0])
+ ARRAY_SIZE(polypoly_lines)
};
static const RECT patblt_clips[] =
@@ -1816,7 +1816,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
}
compare_hash(hdc, bmi, bits, "diagonal solid lines");
- for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(bias_check); i++)
{
MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
@@ -1851,21 +1851,21 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
DeleteObject(hrgn2);
- for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(hline_clips); i++)
{
MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped solid hlines");
- for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(vline_clips); i++)
{
MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped solid vlines");
- for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(line_clips); i++)
{
MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
@@ -1873,7 +1873,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
compare_hash(hdc, bmi, bits, "clipped solid diagonal lines");
/* clipped PatBlt */
- for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(patblt_clips); i++)
{
PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
patblt_clips[i].right - patblt_clips[i].left,
@@ -1887,35 +1887,35 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
SetBkMode(hdc, TRANSPARENT);
SetBkColor(hdc, RGB(0, 0xff, 0));
- for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(hline_clips); i++)
{
MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped dashed hlines");
- for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(hline_clips); i++)
{
MoveToEx(hdc, hline_clips[i].right - 1, hline_clips[i].bottom, NULL);
LineTo(hdc, hline_clips[i].left - 1, hline_clips[i].top);
}
compare_hash(hdc, bmi, bits, "clipped dashed hlines r -> l");
- for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(vline_clips); i++)
{
MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped dashed vlines");
- for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(vline_clips); i++)
{
MoveToEx(hdc, vline_clips[i].right, vline_clips[i].bottom - 1, NULL);
LineTo(hdc, vline_clips[i].left, vline_clips[i].top - 1);
}
compare_hash(hdc, bmi, bits, "clipped dashed vlines b -> t");
- for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(line_clips); i++)
{
MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
@@ -1924,7 +1924,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
SetBkMode(hdc, OPAQUE);
- for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(line_clips); i++)
{
MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
@@ -2163,13 +2163,13 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
SelectObject(hdc, solid_pen);
SelectObject(hdc, solid_brush);
- for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(rectangles); i++)
{
Rectangle(hdc, rectangles[i].left, rectangles[i].top, rectangles[i].right, rectangles[i].bottom);
}
SelectObject(hdc, dashed_pen);
- for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(rectangles); i++)
{
Rectangle(hdc, rectangles[i].left, rectangles[i].top + 150, rectangles[i].right, rectangles[i].bottom + 150);
}
@@ -2775,7 +2775,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
wide_pen = CreatePen( PS_SOLID, 7, RGB( 0xff, 0, 0 ) );
SelectObject( hdc, wide_pen );
- for (i = 0; i < sizeof( wide_lines ) / sizeof( wide_lines[0] ); i++)
+ for (i = 0; i < ARRAY_SIZE(wide_lines); i++)
{
MoveToEx( hdc, wide_lines[i].left, wide_lines[i].top, NULL );
LineTo( hdc, wide_lines[i].right, wide_lines[i].bottom );
@@ -2794,7 +2794,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
9, &log_brush, 0, NULL );
SelectObject( hdc, wide_pen );
SetBrushOrgEx( hdc, 3, 3, NULL );
- Polyline( hdc, poly_lines, sizeof(poly_lines) / sizeof(poly_lines[0]) );
+ Polyline( hdc, poly_lines, ARRAY_SIZE( poly_lines ));
compare_hash_broken_todo( hdc, bmi, bits, "wide pen - flat caps, mitred", is_ddb, is_ddb );
SetBrushOrgEx( hdc, 0, 0, NULL );
@@ -2805,7 +2805,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
16, &log_brush, 0, NULL );
SelectObject( hdc, wide_pen );
- Polyline( hdc, poly_lines, sizeof(poly_lines) / sizeof(poly_lines[0]) );
+ Polyline( hdc, poly_lines, ARRAY_SIZE( poly_lines ));
compare_hash_broken_todo( hdc, bmi, bits, "wide pen - square caps, bevelled", is_ddb, is_ddb );
SelectObject( hdc, orig_pen );
@@ -2815,7 +2815,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
9, &log_brush, 0, NULL );
SelectObject( hdc, wide_pen );
- PolyPolyline( hdc, polypoly_lines, polypoly_counts, sizeof(polypoly_counts)/sizeof(polypoly_counts[0]) );
+ PolyPolyline( hdc, polypoly_lines, polypoly_counts, ARRAY_SIZE( polypoly_counts ));
compare_hash_broken_todo( hdc, bmi, bits, "wide pen - empty segments", is_ddb, is_ddb );
SelectObject( hdc, orig_pen );
@@ -2833,7 +2833,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
12, &log_brush, 0, NULL );
ok( wide_pen != 0, "failed to create pen\n" );
SelectObject( hdc, wide_pen );
- Polyline( hdc, poly_lines, sizeof(poly_lines) / sizeof(poly_lines[0]) );
+ Polyline( hdc, poly_lines, ARRAY_SIZE( poly_lines ));
for (i = 1; i < 20; i++)
{
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 6243a6d339..8f5454b918 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -937,7 +937,7 @@ static void test_bitmap_font_metrics(void)
screen_log_pixels = GetDeviceCaps(hdc, LOGPIXELSY);
diff = 32768;
font_res = 0;
- for (i = 0; i < sizeof(font_log_pixels)/sizeof(font_log_pixels[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(font_log_pixels); i++)
{
int new_diff = abs(font_log_pixels[i] - screen_log_pixels);
if (new_diff < diff)
@@ -948,7 +948,7 @@ static void test_bitmap_font_metrics(void)
}
trace("best font resolution is %d\n", font_res);
- for (i = 0; i < sizeof(fd)/sizeof(fd[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(fd); i++)
{
int bit, height;
@@ -1190,7 +1190,7 @@ static void test_GetCharABCWidths(void)
UINT cs;
UINT a;
UINT w;
- BOOL r[sizeof range / sizeof range[0]];
+ BOOL r[ARRAY_SIZE(range)];
} c[] =
{
{ANSI_CHARSET, 0x30, 0x30,
@@ -1253,7 +1253,7 @@ static void test_GetCharABCWidths(void)
hfont = SelectObject(hdc, hfont);
DeleteObject(hfont);
- for (i = 0; i < sizeof c / sizeof c[0]; ++i)
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
{
ABC a[2], w[2];
ABC full[256];
@@ -1285,7 +1285,7 @@ static void test_GetCharABCWidths(void)
ok(memcmp(&a[0], &full[code], sizeof(ABC)) == 0,
"GetCharABCWidthsA info should match. codepage = %u\n", c[i].cs);
- for (j = 0; j < sizeof range / sizeof range[0]; ++j)
+ for (j = 0; j < ARRAY_SIZE(range); ++j)
{
memset(full, 0xdd, sizeof full);
ret = pGetCharABCWidthsA(hdc, range[j].first, range[j].last, full);
@@ -1774,7 +1774,7 @@ static void test_GetKerningPairs(void)
return;
}
- for (i = 0; i < sizeof(kd)/sizeof(kd[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(kd); i++)
{
OUTLINETEXTMETRICW otm;
UINT uiRet;
@@ -2095,7 +2095,7 @@ static void test_height_selection_vdmx( HDC hdc )
return;
}
- for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(data); i++)
{
res = get_res_data( "wine_vdmx.ttf", &size );
@@ -2356,7 +2356,7 @@ static void testJustification(HDC hdc, PCSTR str, RECT *clientArea)
{
SetTextJustification(hdc, areaWidth - size.cx, breakCount);
GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
- if (size.cx != areaWidth && nErrors < sizeof(error)/sizeof(error[0]) - 1)
+ if (size.cx != areaWidth && nErrors < ARRAY_SIZE(error) - 1)
{
error[nErrors].start = pFirstChar;
error[nErrors].len = pLastChar - pFirstChar;
@@ -2613,7 +2613,7 @@ static void test_font_charset(void)
return;
}
- for (i = 0; i < sizeof(cd)/sizeof(cd[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cd); i++)
{
if (cd[i].charset == SYMBOL_CHARSET)
{
@@ -2687,7 +2687,7 @@ static void test_GdiGetCodePage(void)
acp = GetACP();
- for (i = 0; i < sizeof(matching_data) / sizeof(struct _matching_data); i++)
+ for (i = 0; i < ARRAY_SIZE(matching_data); i++)
{
/* only test data matched current locale codepage */
if (matching_data[i].current_codepage != acp)
@@ -3700,7 +3700,7 @@ static int match_name_table_language( const sfnt_name *name, LANGID lang )
break;
case TT_PLATFORM_MACINTOSH:
if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
- if (GET_BE_WORD(name->language_id) >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
+ if (GET_BE_WORD(name->language_id) >= ARRAY_SIZE(mac_langid_table)) return 0;
name_lang = mac_langid_table[GET_BE_WORD(name->language_id)];
break;
case TT_PLATFORM_APPLE_UNICODE:
@@ -3710,7 +3710,7 @@ static int match_name_table_language( const sfnt_name *name, LANGID lang )
case TT_APPLE_ID_DEFAULT:
case TT_APPLE_ID_ISO_10646:
case TT_APPLE_ID_UNICODE_2_0:
- if (GET_BE_WORD(name->language_id) >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
+ if (GET_BE_WORD(name->language_id) >= ARRAY_SIZE(mac_langid_table)) return 0;
name_lang = mac_langid_table[GET_BE_WORD(name->language_id)];
break;
default:
@@ -4105,7 +4105,7 @@ static void test_nonexistent_font(void)
hdc = CreateCompatibleDC(0);
- for (i = 0; i < sizeof(shell_subst)/sizeof(shell_subst[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(shell_subst); i++)
{
ret = is_font_installed(shell_subst[i].name);
ok(ret || broken(!ret) /* win2000 */, "%s should be enumerated\n", shell_subst[i].name);
@@ -4201,7 +4201,7 @@ todo_wine /* Wine uses Arial for all substitutions */
ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
DeleteObject(SelectObject(hdc, hfont));
- for (i = 0; i < sizeof(font_subst)/sizeof(font_subst[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(font_subst); i++)
{
ret = is_font_installed(font_subst[i].name);
todo_wine
@@ -4487,8 +4487,8 @@ static void test_GetTextFace(void)
dc = GetDC(NULL);
g = SelectObject(dc, f);
- n = GetTextFaceW(dc, sizeof bufW / sizeof bufW[0], bufW);
- ok(n == sizeof faceW / sizeof faceW[0], "GetTextFaceW returned %d\n", n);
+ n = GetTextFaceW(dc, ARRAY_SIZE(bufW), bufW);
+ ok(n == ARRAY_SIZE(faceW), "GetTextFaceW returned %d\n", n);
ok(lstrcmpW(faceW, bufW) == 0, "GetTextFaceW\n");
/* Play with the count arg. */
@@ -4508,7 +4508,7 @@ static void test_GetTextFace(void)
ok(bufW[0] == faceW[0] && bufW[1] == '\0', "GetTextFaceW didn't copy\n");
n = GetTextFaceW(dc, 0, NULL);
- ok(n == sizeof faceW / sizeof faceW[0], "GetTextFaceW returned %d\n", n);
+ ok(n == ARRAY_SIZE(faceW), "GetTextFaceW returned %d\n", n);
DeleteObject(SelectObject(dc, g));
ReleaseDC(NULL, dc);
@@ -4719,7 +4719,7 @@ static void test_GetGlyphOutline(void)
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
ok(ret == GDI_ERROR, "GetGlyphOutlineW should return an error when the buffer size is too small.\n");
- for (i = 0; i < sizeof(fmt) / sizeof(fmt[0]); ++i)
+ for (i = 0; i < ARRAY_SIZE(fmt); ++i)
{
DWORD dummy;
@@ -4785,7 +4785,7 @@ static void test_GetGlyphOutline(void)
SelectObject(hdc, old_hfont);
DeleteObject(hfont);
- for (i = 0; i < sizeof c / sizeof c[0]; ++i)
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
{
static const MAT2 rotate_mat = {{0, 0}, {0, -1}, {0, 1}, {0, 0}};
TEXTMETRICA tm;
@@ -4955,7 +4955,7 @@ static void test_CreateFontIndirect(void)
lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE;
- for (i = 0; i < sizeof(TestName)/sizeof(TestName[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(TestName); i++)
{
lstrcpyA(lf.lfFaceName, TestName[i]);
hfont = CreateFontIndirectA(&lf);
@@ -5409,7 +5409,7 @@ static void test_fullname(void)
lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE;
- for (i = 0; i < sizeof(TestName) / sizeof(TestName[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(TestName); i++)
{
if (!is_font_installed_fullname("Lucida Sans", TestName[i]))
{
@@ -6058,7 +6058,7 @@ static void test_vertical_font(void)
ok(hgi != vgi, "same glyph h:%u v:%u\n", hgi, vgi);
- for (i = 0; i < sizeof(face_list)/sizeof(face_list[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(face_list); i++) {
const char* face = face_list[i];
if (!is_truetype_font_installed(face)) {
skip("%s is not installed\n", face);
@@ -6092,7 +6092,7 @@ static void test_east_asian_font_selection(void)
hdc = GetDC(NULL);
- for (i = 0; i < sizeof(charset)/sizeof(charset[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(charset); i++)
{
LOGFONTA lf;
HFONT hfont;
@@ -6214,7 +6214,7 @@ static void test_stock_fonts(void)
};
int i, j;
- for (i = 0; i < sizeof(font)/sizeof(font[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(font); i++)
{
HFONT hfont;
LOGFONTA lf;
@@ -6314,7 +6314,7 @@ static void test_max_height(void)
DeleteObject(SelectObject(hdc, hfont_old));
/* test an invalid value */
- for (i = 0; i < sizeof(invalid_height)/sizeof(invalid_height[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(invalid_height); i++) {
lf.lfHeight = invalid_height[i];
hfont = CreateFontIndirectA(&lf);
hfont_old = SelectObject(hdc, hfont);
@@ -6638,7 +6638,7 @@ static void test_bitmap_font_glyph_index(void)
bmi.bmiHeader.biHeight = 32;
bmi.bmiHeader.biCompression = BI_RGB;
- for (i = 0; i < sizeof(bitmap_font_list)/sizeof(bitmap_font_list[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(bitmap_font_list); i++) {
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = bitmap_font_list[i].charset;
strcpy(lf.lfFaceName, bitmap_font_list[i].face);
diff --git a/dlls/gdi32/tests/gdiobj.c b/dlls/gdi32/tests/gdiobj.c
index 65374ea85d..8f3d01c27d 100644
--- a/dlls/gdi32/tests/gdiobj.c
+++ b/dlls/gdi32/tests/gdiobj.c
@@ -345,7 +345,7 @@ static void test_handles_on_win64(void)
if (sizeof(void*) != 8)
return;
- for (i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cases); i++)
{
hrgn = CreateRectRgn(10, 10, 20, 20);
hrgn_test = (HRGN)(ULONG_PTR)((ULONG_PTR)hrgn | ((ULONGLONG)cases[i].high << 32) | cases[i].low);
diff --git a/dlls/gdi32/tests/icm.c b/dlls/gdi32/tests/icm.c
index 620809018a..340ebeef55 100644
--- a/dlls/gdi32/tests/icm.c
+++ b/dlls/gdi32/tests/icm.c
@@ -278,7 +278,7 @@ static void test_SetICMProfileW( HDC dc )
return;
}
- len = sizeof(profile)/sizeof(profile[0]);
+ len = ARRAY_SIZE(profile);
ret = GetICMProfileW( dc, &len, profile );
ok(ret, "GetICMProfileW failed %u\n", GetLastError());
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 780b65f1b6..230d1e6d84 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -183,7 +183,7 @@ static void test_ExtTextOut(void)
static const RECT rc = { 0, 0, 100, 100 };
BOOL ret;
- assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
+ assert(ARRAY_SIZE(dx) >= lstrlenA(text));
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
@@ -3895,8 +3895,7 @@ static void test_emf_GradientFill(void)
* written to the EMF, but is not considered in the bounds
* calculation.
*/
- ret = GdiGradientFill( mf, v, sizeof(v) / sizeof(v[0]), tri, sizeof(tri) / sizeof(tri[0]),
- GRADIENT_FILL_TRIANGLE );
+ ret = GdiGradientFill( mf, v, ARRAY_SIZE(v), tri, ARRAY_SIZE(tri), GRADIENT_FILL_TRIANGLE );
ok( ret, "GradientFill\n" );
hemf = CloseEnhMetaFile( mf );
@@ -4117,7 +4116,7 @@ static void test_emf_WorldTransform(void)
{ "manual modify", TRUE, FALSE }
};
- for(i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
+ for(i = 0; i < ARRAY_SIZE(test_data); ++i)
{
hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
diff --git a/dlls/gdi32/tests/path.c b/dlls/gdi32/tests/path.c
index 48ef4f016a..80145fc6b2 100644
--- a/dlls/gdi32/tests/path.c
+++ b/dlls/gdi32/tests/path.c
@@ -495,7 +495,7 @@ static void test_arcto(void)
CloseFigure(hdc);
EndPath(hdc);
- ok_path(hdc, "arcto_path", arcto_path, sizeof(arcto_path)/sizeof(path_test_t));
+ ok_path(hdc, "arcto_path", arcto_path, ARRAY_SIZE(arcto_path));
done:
ReleaseDC(0, hdc);
}
@@ -540,7 +540,7 @@ static void test_anglearc(void)
CloseFigure(hdc);
EndPath(hdc);
- ok_path(hdc, "anglearc_path", anglearc_path, sizeof(anglearc_path)/sizeof(path_test_t));
+ ok_path(hdc, "anglearc_path", anglearc_path, ARRAY_SIZE(anglearc_path));
done:
ReleaseDC(0, hdc);
}
@@ -681,7 +681,7 @@ static void test_polydraw(void)
ok( pos.x == 80 && pos.y == 80, "wrong pos %d,%d\n", pos.x, pos.y );
EndPath(hdc);
- ok_path(hdc, "polydraw_path", polydraw_path, sizeof(polydraw_path)/sizeof(path_test_t));
+ ok_path(hdc, "polydraw_path", polydraw_path, ARRAY_SIZE(polydraw_path));
GetCurrentPositionEx( hdc, &pos );
ok( pos.x == 80 && pos.y == 80, "wrong pos %d,%d\n", pos.x, pos.y );
done:
@@ -966,7 +966,7 @@ static void test_rectangle(void)
SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
EndPath( hdc );
SetMapMode( hdc, MM_TEXT );
- ok_path( hdc, "rectangle_path", rectangle_path, sizeof(rectangle_path)/sizeof(path_test_t) );
+ ok_path( hdc, "rectangle_path", rectangle_path, ARRAY_SIZE(rectangle_path) );
ReleaseDC( 0, hdc );
}
@@ -1327,7 +1327,7 @@ static void test_roundrect(void)
SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
EndPath( hdc );
SetMapMode( hdc, MM_TEXT );
- ok_path( hdc, "roundrect_path", roundrect_path, sizeof(roundrect_path)/sizeof(path_test_t) );
+ ok_path( hdc, "roundrect_path", roundrect_path, ARRAY_SIZE(roundrect_path) );
ReleaseDC( 0, hdc );
}
@@ -1707,7 +1707,7 @@ static void test_ellipse(void)
SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
EndPath( hdc );
SetMapMode( hdc, MM_TEXT );
- ok_path( hdc, "ellipse_path", ellipse_path, sizeof(ellipse_path)/sizeof(path_test_t) );
+ ok_path( hdc, "ellipse_path", ellipse_path, ARRAY_SIZE(ellipse_path) );
}
static const path_test_t all_funcs_path[] =
@@ -1890,7 +1890,7 @@ static void test_all_functions(void)
LineTo( hdc, 150, 150 );
/* FIXME: ExtTextOut */
EndPath( hdc );
- ok_path( hdc, "all_funcs_path", all_funcs_path, sizeof(all_funcs_path)/sizeof(path_test_t) );
+ ok_path( hdc, "all_funcs_path", all_funcs_path, ARRAY_SIZE(all_funcs_path) );
ReleaseDC( 0, hdc );
}
diff --git a/dlls/gdi32/tests/pen.c b/dlls/gdi32/tests/pen.c
index 43f00d8f50..badc585f57 100644
--- a/dlls/gdi32/tests/pen.c
+++ b/dlls/gdi32/tests/pen.c
@@ -72,7 +72,7 @@ static void test_logpen(void)
EXTLOGPEN *ext_pen = (EXTLOGPEN *)elp_buffer;
DWORD *ext_style = ext_pen->elpStyleEntry;
- for (i = 0; i < sizeof(pen)/sizeof(pen[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(pen); i++)
{
trace("%d: testing style %u\n", i, pen[i].style);
--
2.14.4
June 25, 2018
Re: [PATCH] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
On 25/06/18 08:20, Nikolay Sivov wrote:
> On 06/25/2018 06:46 AM, Zebediah Figura wrote:
>
>> Should hopefully fix test failures on Windows.
>>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
>> dlls/hnetcfg/tests/policy.c | 5 ++++-
>> 2 files changed, 16 insertions(+), 6 deletions(-)
>>
>> diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
>> index 34ef108..fe47721 100644
>> --- a/dlls/hnetcfg/apps.c
>> +++ b/dlls/hnetcfg/apps.c
>> @@ -268,7 +268,7 @@ static HRESULT WINAPI
>> fw_app_put_ProcessImageFileName(
>> {
>> fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
>> UNIVERSAL_NAME_INFOW *info;
>> - WCHAR *netpath;
>> + WCHAR *path;
>> DWORD res;
>> DWORD sz;
>> @@ -281,22 +281,29 @@ static HRESULT WINAPI
>> fw_app_put_ProcessImageFileName(
>> res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL,
>> NULL, &sz);
>> if (res == WN_MORE_DATA)
>> {
>> - if (!(netpath = heap_alloc(sz)))
>> + if (!(path = heap_alloc(sz)))
>> return E_OUTOFMEMORY;
>> - info = (UNIVERSAL_NAME_INFOW *)&netpath;
>> + info = (UNIVERSAL_NAME_INFOW *)&path;
>> res = WNetGetUniversalNameW(image,
>> UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
>> if (res == NO_ERROR)
>> {
>> SysFreeString(This->filename);
>> This->filename = SysAllocString(info->lpUniversalName);
>> }
>> - heap_free(netpath);
>> + heap_free(path);
>> return HRESULT_FROM_WIN32(res);
>> }
>> + sz = GetFullPathNameW(image, 0, NULL, NULL);
>> + if (!(path = heap_alloc(++sz)))
>> + return E_OUTOFMEMORY;
>> +
>> + GetFullPathNameW(image, sz, path, NULL);
>
> ...
>
>>
>> + GetFullPathNameW(image, sizeof(fullpath), fullpath, NULL);
> ...
>
> This one takes character length I think, not byte length.
>
>
Thanks for the catch; resent.
June 25, 2018
[PATCH v2] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/hnetcfg/apps.c | 17 ++++++++++++-----
dlls/hnetcfg/tests/policy.c | 5 ++++-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
index 34ef108..fe47721 100644
--- a/dlls/hnetcfg/apps.c
+++ b/dlls/hnetcfg/apps.c
@@ -268,7 +268,7 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
{
fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
UNIVERSAL_NAME_INFOW *info;
- WCHAR *netpath;
+ WCHAR *path;
DWORD res;
DWORD sz;
@@ -281,22 +281,29 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, NULL, &sz);
if (res == WN_MORE_DATA)
{
- if (!(netpath = heap_alloc(sz)))
+ if (!(path = heap_alloc(sz)))
return E_OUTOFMEMORY;
- info = (UNIVERSAL_NAME_INFOW *)&netpath;
+ info = (UNIVERSAL_NAME_INFOW *)&path;
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (res == NO_ERROR)
{
SysFreeString(This->filename);
This->filename = SysAllocString(info->lpUniversalName);
}
- heap_free(netpath);
+ heap_free(path);
return HRESULT_FROM_WIN32(res);
}
+ sz = GetFullPathNameW(image, 0, NULL, NULL);
+ if (!(path = heap_alloc(++sz)))
+ return E_OUTOFMEMORY;
+
+ GetFullPathNameW(image, sz, path, NULL);
+
SysFreeString( This->filename );
- This->filename = SysAllocString(image);
+ This->filename = SysAllocString(path);
+ heap_free(path);
return This->filename ? S_OK : E_OUTOFMEMORY;
}
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f2d1372..954af5c 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -107,6 +107,7 @@ static void test_NetFwAuthorizedApplication(void)
INetFwAuthorizedApplication *app;
static WCHAR empty[] = {0};
UNIVERSAL_NAME_INFOW *info;
+ WCHAR fullpath[MAX_PATH];
WCHAR netpath[MAX_PATH];
WCHAR image[MAX_PATH];
HRESULT hr;
@@ -138,13 +139,15 @@ static void test_NetFwAuthorizedApplication(void)
ok(hr == S_OK, "got: %08x\n", hr);
SysFreeString(bstr);
+ GetFullPathNameW(image, ARRAY_SIZE(fullpath), fullpath, NULL);
+
info = (UNIVERSAL_NAME_INFOW *)&netpath;
sz = sizeof(netpath);
hr = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (hr != NO_ERROR)
{
info->lpUniversalName = netpath + sizeof(*info)/sizeof(WCHAR);
- lstrcpyW(info->lpUniversalName, image);
+ lstrcpyW(info->lpUniversalName, fullpath);
}
hr = INetFwAuthorizedApplication_get_ProcessImageFileName(app, &bstr);
--
2.7.4
June 25, 2018
[PATCH] hnetcfg: GetModuleFileNameW gets characters, not bytes (Coverity)
by Marcus Meissner
CID 1437516
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
dlls/hnetcfg/tests/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f2d1372ba6..b28535d448 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -117,7 +117,7 @@ static void test_NetFwAuthorizedApplication(void)
&IID_INetFwAuthorizedApplication, (void**)&app);
ok(hr == S_OK, "got: %08x\n", hr);
- hr = GetModuleFileNameW(NULL, image, sizeof(image));
+ hr = GetModuleFileNameW(NULL, image, ARRAY_SIZE(image));
ok(hr, "GetModuleFileName failed: %u\n", GetLastError());
hr = INetFwAuthorizedApplication_get_ProcessImageFileName(app, NULL);
--
2.17.1
June 25, 2018
[PATCH v3] comctl32/imagelist: fix ImageList_Read
by Denis Malikov
Fix for versions x600 and x620 and pointer calculation for mixing image and mask bits.
Tested on *.reg files extracted from:
- XP/2003 key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify;
- Vista/7 key HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify
Signed-off-by: Denis Malikov <mdn40000(a)mail.ru>
---
dlls/comctl32/imagelist.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index a08d60752e..be901462a0 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -2267,7 +2267,9 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
return NULL;
if (ilHead.usMagic != (('L' << 8) | 'I'))
return NULL;
- if (ilHead.usVersion != 0x101) /* probably version? */
+ if (ilHead.usVersion != 0x101 &&
+ ilHead.usVersion != 0x600 && /* XP/2003 version */
+ ilHead.usVersion != 0x620) /* Vista/7 version */
return NULL;
TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
@@ -2296,23 +2298,25 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
{
DWORD *ptr = image_bits;
BYTE *mask_ptr = mask_bits;
- int stride = himl->cy * image_info->bmiHeader.biWidth;
+ int stride = himl->cy * (ilHead.usVersion != 0x101 ? himl->cx : image_info->bmiHeader.biWidth);
+ int image_step = ilHead.usVersion != 0x101 ? 1 : TILE_COUNT;
+ int mask_step = ilHead.usVersion != 0x101 ? 4 : 8;
if (image_info->bmiHeader.biHeight > 0) /* bottom-up */
{
ptr += image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride;
- mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / 8;
+ mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / mask_step;
stride = -stride;
image_info->bmiHeader.biHeight = himl->cy;
}
else image_info->bmiHeader.biHeight = -himl->cy;
- for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT)
+ for (i = 0; i < ilHead.cCurImage; i += image_step)
{
- add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ),
+ add_dib_bits( himl, i, min( ilHead.cCurImage - i, image_step ),
himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr );
ptr += stride;
- mask_ptr += stride / 8;
+ mask_ptr += stride / mask_step;
}
}
else
--
2.16.2.windows.1
June 25, 2018
Re: [PATCH] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Nikolay Sivov
On 06/25/2018 06:46 AM, Zebediah Figura wrote:
> Should hopefully fix test failures on Windows.
>
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
> dlls/hnetcfg/tests/policy.c | 5 ++++-
> 2 files changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
> index 34ef108..fe47721 100644
> --- a/dlls/hnetcfg/apps.c
> +++ b/dlls/hnetcfg/apps.c
> @@ -268,7 +268,7 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
> {
> fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
> UNIVERSAL_NAME_INFOW *info;
> - WCHAR *netpath;
> + WCHAR *path;
> DWORD res;
> DWORD sz;
>
> @@ -281,22 +281,29 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
> res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, NULL, &sz);
> if (res == WN_MORE_DATA)
> {
> - if (!(netpath = heap_alloc(sz)))
> + if (!(path = heap_alloc(sz)))
> return E_OUTOFMEMORY;
>
> - info = (UNIVERSAL_NAME_INFOW *)&netpath;
> + info = (UNIVERSAL_NAME_INFOW *)&path;
> res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
> if (res == NO_ERROR)
> {
> SysFreeString(This->filename);
> This->filename = SysAllocString(info->lpUniversalName);
> }
> - heap_free(netpath);
> + heap_free(path);
> return HRESULT_FROM_WIN32(res);
> }
>
> + sz = GetFullPathNameW(image, 0, NULL, NULL);
> + if (!(path = heap_alloc(++sz)))
> + return E_OUTOFMEMORY;
> +
> + GetFullPathNameW(image, sz, path, NULL);
...
>
>
> + GetFullPathNameW(image, sizeof(fullpath), fullpath, NULL);
...
This one takes character length I think, not byte length.
June 25, 2018
[PATCH] fonts: Add clock images to Wingdings font. (v2)
by Dmitry Timoshkov
v2: I've created the glyphs on my own.
wingding.ttf should be rebuilt in maintainer mode after applying this patch.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
fonts/wingding.sfd | 760 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 758 insertions(+), 2 deletions(-)
diff --git a/fonts/wingding.sfd b/fonts/wingding.sfd
index c46152b077..d5b7ec871b 100644
--- a/fonts/wingding.sfd
+++ b/fonts/wingding.sfd
@@ -50,9 +50,9 @@ NameList: Adobe Glyph List
DisplaySize: -48
AntiAlias: 1
FitToEm: 1
-WinInfo: 0 29 12
+WinInfo: 0 38 13
TeXData: 1 0 0 708670 354335 236222 1342177 -2147484 236222 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
-BeginChars: 256 38
+BeginChars: 256 50
StartChar: f020
Encoding: 0 61472 0
@@ -788,5 +788,761 @@ LayerCount: 2
Fore
Refer: 34 63724 N 0 1 -1 0 1653 -173 2
EndChar
+
+StartChar: oneoclock
+Encoding: 183 8721 38
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1045.63 1112.56 m 1,0,-1
+ 1117 1081.1 l 1,1,-1
+ 888.373 614.638 l 1,2,-1
+ 817 646.1 l 1,3,-1
+ 1045.63 1112.56 l 1,0,-1
+1045.63 1112.56 m 1,4,-1
+ 1117 1081.1 l 1,5,-1
+ 888.373 614.638 l 1,6,-1
+ 817 646.1 l 1,7,-1
+ 1045.63 1112.56 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: twooclock
+Encoding: 184 8719 39
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1259.61 981.841 m 1,0,-1
+ 1308.09 920.734 l 1,1,-1
+ 888.373 614.638 l 1,2,-1
+ 839.896 675.744 l 1,3,-1
+ 1259.61 981.841 l 1,0,-1
+1259.61 981.841 m 1,4,-1
+ 1308.09 920.734 l 1,5,-1
+ 888.373 614.638 l 1,6,-1
+ 839.896 675.744 l 1,7,-1
+ 1259.61 981.841 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: threeoclock
+Encoding: 185 960 40
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1417 769.1 m 1,0,-1
+ 1492 769.1 l 1,1,-1
+ 1492 682.1 l 1,2,-1
+ 1417 682.1 l 1,3,-1
+ 1417 769.1 l 1,0,-1
+1354 760.1 m 1,4,-1
+ 1357.3 682.17 l 1,5,-1
+ 837.828 681.208 l 1,6,-1
+ 834.522 759.138 l 1,7,-1
+ 1354 760.1 l 1,4,-1
+1354 760.1 m 1,8,-1
+ 1357.3 682.17 l 1,9,-1
+ 837.828 681.208 l 1,10,-1
+ 834.522 759.138 l 1,11,-1
+ 1354 760.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+871 1297.1 m 1,16,-1
+ 949 1297.1 l 1,17,-1
+ 949 595.1 l 1,18,-1
+ 871 595.1 l 1,19,-1
+ 871 1297.1 l 1,16,-1
+868 238.1 m 1,20,-1
+ 943 238.1 l 1,21,-1
+ 943 151.1 l 1,22,-1
+ 868 151.1 l 1,23,-1
+ 868 238.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: fouroclock
+Encoding: 186 8747 41
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1400.73 513.884 m 1,0,-1
+ 1377.42 439.448 l 1,1,-1
+ 888.373 614.638 l 1,2,-1
+ 911.681 689.074 l 1,3,-1
+ 1400.73 513.884 l 1,0,-1
+1400.73 513.884 m 1,4,-1
+ 1377.42 439.448 l 1,5,-1
+ 888.373 614.638 l 1,6,-1
+ 911.681 689.074 l 1,7,-1
+ 1400.73 513.884 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: fiveoclock
+Encoding: 187 170 42
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1169.2 333.396 m 1,0,-1
+ 1105 289.1 l 1,1,-1
+ 827.557 728.283 l 1,2,-1
+ 891.758 772.579 l 1,3,-1
+ 1169.2 333.396 l 1,0,-1
+1169.2 333.396 m 1,4,-1
+ 1105 289.1 l 1,5,-1
+ 827.557 728.283 l 1,6,-1
+ 891.758 772.579 l 1,7,-1
+ 1169.2 333.396 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: sixoclock
+Encoding: 188 186 43
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+872.619 844.557 m 1,0,-1
+ 950.58 847.024 l 1,1,-1
+ 945.961 327.567 l 1,2,-1
+ 868 325.1 l 1,3,-1
+ 872.619 844.557 l 1,0,-1
+872.619 844.557 m 1,4,-1
+ 950.58 847.024 l 1,5,-1
+ 945.961 327.567 l 1,6,-1
+ 868 325.1 l 1,7,-1
+ 872.619 844.557 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: sevenoclock
+Encoding: 189 937 44
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+682 289.1 m 1,0,-1
+ 616.783 331.886 l 1,1,-1
+ 919.107 754.327 l 1,2,-1
+ 984.324 711.541 l 1,3,-1
+ 682 289.1 l 1,0,-1
+682 289.1 m 1,4,-1
+ 616.783 331.886 l 1,5,-1
+ 919.107 754.327 l 1,6,-1
+ 984.324 711.541 l 1,7,-1
+ 682 289.1 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: eightoclock
+Encoding: 190 230 45
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+544.217 438.639 m 1,0,-1
+ 501.419 503.848 l 1,1,-1
+ 946.903 771.055 l 1,2,-1
+ 989.703 705.847 l 1,3,-1
+ 544.217 438.639 l 1,0,-1
+544.217 438.639 m 1,4,-1
+ 501.419 503.848 l 1,5,-1
+ 946.903 771.055 l 1,6,-1
+ 989.703 705.847 l 1,7,-1
+ 544.217 438.639 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: nineoclock
+Encoding: 191 248 46
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+517 679.1 m 1,0,-1
+ 513.82 757.034 l 1,1,-1
+ 1033.3 757.157 l 1,2,-1
+ 1036.48 679.223 l 1,3,-1
+ 517 679.1 l 1,0,-1
+517 679.1 m 1,4,-1
+ 513.82 757.034 l 1,5,-1
+ 1033.3 757.157 l 1,6,-1
+ 1036.48 679.223 l 1,7,-1
+ 517 679.1 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: tenoclock
+Encoding: 192 191 47
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+555.232 898.87 m 1,0,-1
+ 598 964.1 l 1,1,-1
+ 1020.53 661.897 l 1,2,-1
+ 977.762 596.668 l 1,3,-1
+ 555.232 898.87 l 1,0,-1
+555.232 898.87 m 1,4,-1
+ 598 964.1 l 1,5,-1
+ 1020.53 661.897 l 1,6,-1
+ 977.762 596.668 l 1,7,-1
+ 555.232 898.87 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: elevenoclock
+Encoding: 193 161 48
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+693.722 1059.02 m 1,0,-1
+ 758.041 1103.14 l 1,1,-1
+ 1034.32 663.226 l 1,2,-1
+ 970 619.1 l 1,3,-1
+ 693.722 1059.02 l 1,0,-1
+693.722 1059.02 m 1,4,-1
+ 758.041 1103.14 l 1,5,-1
+ 1034.32 663.226 l 1,6,-1
+ 970 619.1 l 1,7,-1
+ 693.722 1059.02 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: twelveoclock
+Encoding: 194 172 49
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+872.906 1111.69 m 1,0,-1
+ 950.853 1114.57 l 1,1,-1
+ 949 595.1 l 1,2,-1
+ 871.054 592.217 l 1,3,-1
+ 872.906 1111.69 l 1,0,-1
+872.906 1111.69 m 1,4,-1
+ 950.853 1114.57 l 1,5,-1
+ 949 595.1 l 1,6,-1
+ 871.054 592.217 l 1,7,-1
+ 872.906 1111.69 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
EndChars
EndSplineFont
--
2.16.3
June 25, 2018
[PATCH] crypt32: Correctly return how the issuer of a self signed certificate was matched.
by Nikolay Sivov
Original patch by Michael Müller.
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/chain.c | 53 +++++++++++++++-------------------
dlls/crypt32/crypt32_private.h | 2 +-
2 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 6e8076c66c..d7015d797d 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -265,10 +265,10 @@ typedef struct _CertificateChain
LONG ref;
} CertificateChain;
-BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
+DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
{
+ DWORD size, status = 0;
PCERT_EXTENSION ext;
- DWORD size;
BOOL ret;
if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
@@ -296,10 +296,9 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
&info->AuthorityCertIssuer.rgAltEntry[i];
if (directoryName)
{
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
- && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber,
- &cert->pCertInfo->SerialNumber);
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
+ && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
}
else
{
@@ -317,16 +316,12 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
if (buf)
{
- CertGetCertificateContextProperty(cert,
- CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
- ret = !memcmp(buf, info->KeyId.pbData, size);
+ CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
+ if (!memcmp(buf, info->KeyId.pbData, size))
+ status = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
CryptMemFree(buf);
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
}
LocalFree(info);
}
@@ -344,10 +339,9 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
{
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &info->CertIssuer, &cert->pCertInfo->Issuer) &&
- CertCompareIntegerBlob(&info->CertSerialNumber,
- &cert->pCertInfo->SerialNumber);
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &info->CertIssuer, &cert->pCertInfo->Issuer)
+ && CertCompareIntegerBlob(&info->CertSerialNumber, &cert->pCertInfo->SerialNumber))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
}
else if (info->KeyId.cbData)
{
@@ -361,24 +355,23 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
- ret = !memcmp(buf, info->KeyId.pbData, size);
+ if (!memcmp(buf, info->KeyId.pbData, size))
+ status = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
CryptMemFree(buf);
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
LocalFree(info);
}
}
else
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
- return ret;
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
+
+ if (status)
+ status |= CERT_TRUST_IS_SELF_SIGNED;
+
+ return status;
}
static void CRYPT_FreeChainElement(PCERT_CHAIN_ELEMENT element)
@@ -1890,6 +1883,7 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
int i;
BOOL pathLengthConstraintViolated = FALSE;
CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 };
+ DWORD status;
TRACE_(chain)("checking chain with %d elements for time %s\n",
chain->cElement, filetime_to_str(time));
@@ -1977,10 +1971,9 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
}
CRYPT_CheckChainNameConstraints(chain);
CRYPT_CheckChainPolicies(chain);
- if (CRYPT_IsCertificateSelfSigned(rootElement->pCertContext))
+ if ((status = CRYPT_IsCertificateSelfSigned(rootElement->pCertContext)))
{
- rootElement->TrustStatus.dwInfoStatus |=
- CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER;
+ rootElement->TrustStatus.dwInfoStatus |= status;
CRYPT_CheckRootCert(engine->hRoot, rootElement);
}
CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index dbf6dca411..95ee67c6cb 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -343,7 +343,7 @@ void CRYPT_ImportSystemRootCertsToReg(void) DECLSPEC_HIDDEN;
BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD flags, const WINE_CONTEXT_INTERFACE *contextInterface,
HCERTSTORE memStore) DECLSPEC_HIDDEN;
-BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert) DECLSPEC_HIDDEN;
+DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert) DECLSPEC_HIDDEN;
/* Allocates and initializes a certificate chain engine, but without creating
* the root store. Instead, it uses root, and assumes the caller has done any
--
2.18.0
June 25, 2018
Wine staging 3.11 release
by Alistair Leslie-Hughes
Binary packages for various distributions will be available from:
https://www.winehq.org/download
Summary of the past few weeks
* Rebased to current wine 3.11 (900 patches are applied to wine vanilla)
* Reviewed and upstreamed patches.
Added
* [34989] msi: Implement deferral for standard and custom actions
Where can you help
* Run Steam/Battle.net/UPlay.
* Try you favorite game: Upward lonely robot
* Test your favorite applications.
* Steal staging patches and get them accepted upstream.
As always, if you find a bug, please report it via
https://bugs.winehq.org
Best Regards
Alistair.
June 25, 2018
[PATCH] wininet: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/wininet/ftp.c | 2 +-
dlls/wininet/http.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c
index e12e494160..9e4da08fdf 100644
--- a/dlls/wininet/ftp.c
+++ b/dlls/wininet/ftp.c
@@ -3290,7 +3290,7 @@ static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile)
{
nBytesToSend = nBytesRead - nBytesSent;
- if (nBytesToSend <= 0)
+ if (nBytesToSend == 0)
{
/* Read data from file. */
nBytesSent = 0;
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index b91dbdf175..3e14049b4e 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -6264,7 +6264,7 @@ static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHd
*/
static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index)
{
- if( request->nCustHeaders <= 0 )
+ if( request->nCustHeaders == 0 )
return FALSE;
if( index >= request->nCustHeaders )
return FALSE;
--
2.17.1
June 25, 2018
[PATCH] msi: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/msi/format.c | 2 +-
dlls/msi/string.c | 2 +-
dlls/msi/table.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/msi/format.c b/dlls/msi/format.c
index 9356c9e30d..2534b8f6a3 100644
--- a/dlls/msi/format.c
+++ b/dlls/msi/format.c
@@ -242,7 +242,7 @@ static WCHAR *deformat_file( FORMAT *format, FORMSTR *str, BOOL shortname, int *
if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret );
goto done;
}
- if ((len = GetShortPathNameW(file->TargetPath, NULL, 0)) <= 0)
+ if ((len = GetShortPathNameW(file->TargetPath, NULL, 0)) == 0)
{
if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret );
goto done;
diff --git a/dlls/msi/string.c b/dlls/msi/string.c
index f094a53c9e..b0e61e5d76 100644
--- a/dlls/msi/string.c
+++ b/dlls/msi/string.c
@@ -246,7 +246,7 @@ static UINT string2id( const string_table *st, const char *buffer, UINT *id )
}
sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 );
- if( sz <= 0 )
+ if( sz == 0 )
return r;
str = msi_alloc( sz*sizeof(WCHAR) );
if( !str )
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index 45a181445a..41e313736f 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1279,7 +1279,7 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT
UINT r;
int ival;
- if ( (iField <= 0) ||
+ if ( (iField == 0) ||
(iField > tv->num_cols) ||
MSI_RecordIsNull( rec, iField ) )
return ERROR_FUNCTION_FAILED;
--
2.17.1
June 25, 2018
[PATCH] comctl32: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/comctl32/rebar.c | 2 +-
dlls/comctl32/tab.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index 20ce49b3f9..2d00dfd7ca 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -2090,7 +2090,7 @@ REBAR_HandleUDDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
INT iHitBand, iRowBegin, iNextRowBegin;
REBAR_BAND *hitBand, *rowBeginBand;
- if(infoPtr->uNumBands <= 0)
+ if(infoPtr->uNumBands == 0)
ERR("There are no bands in this rebar\n");
/* Up/down dragging can only occur when there is more than one
diff --git a/dlls/comctl32/tab.c b/dlls/comctl32/tab.c
index f8a54935ca..2e17e142f6 100644
--- a/dlls/comctl32/tab.c
+++ b/dlls/comctl32/tab.c
@@ -365,7 +365,7 @@ static BOOL TAB_InternalGetItemRect(
RECT tmpItemRect,clientRect;
/* Perform a sanity check and a trivial visibility check. */
- if ( (infoPtr->uNumItem <= 0) ||
+ if ( (infoPtr->uNumItem == 0) ||
(itemIndex >= infoPtr->uNumItem) ||
(!(((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL))) &&
(itemIndex < infoPtr->leftmostVisible)))
--
2.17.1
June 25, 2018
[PATCH] advapi32: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/advapi32/crypt.c | 2 +-
dlls/advapi32/crypt_lmhash.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c
index 01d5880423..6ac63e7f08 100644
--- a/dlls/advapi32/crypt.c
+++ b/dlls/advapi32/crypt.c
@@ -661,7 +661,7 @@ BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, ULONG_PTR dwFlags)
}
pProv->refcount--;
- if (pProv->refcount <= 0)
+ if (pProv->refcount == 0)
{
ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
pProv->dwMagic = 0;
diff --git a/dlls/advapi32/crypt_lmhash.c b/dlls/advapi32/crypt_lmhash.c
index 345c89ddb7..de4fce2511 100644
--- a/dlls/advapi32/crypt_lmhash.c
+++ b/dlls/advapi32/crypt_lmhash.c
@@ -196,7 +196,7 @@ NTSTATUS WINAPI SystemFunction004(const struct ustring *in,
unsigned char deskey[7];
unsigned int crypt_len, ofs;
- if (key->Length<=0)
+ if (key->Length==0)
return STATUS_INVALID_PARAMETER_2;
crypt_len = ((in->Length+7)&~7);
@@ -255,7 +255,7 @@ NTSTATUS WINAPI SystemFunction005(const struct ustring *in,
unsigned char deskey[7];
unsigned int ofs, crypt_len;
- if (key->Length<=0)
+ if (key->Length==0)
return STATUS_INVALID_PARAMETER_2;
if (key->Length<sizeof deskey)
--
2.17.1
June 25, 2018
Re: [PATCH 2/3] comctl32/taskdialog: Add support for radio buttons.
by Zhiyi Zhang
On Mon 6 25 13:22, Nikolay Sivov wrote:
>
>
> On 06/17/2018 11:17 AM, Zhiyi Zhang wrote:
>> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
>> ---
>> dlls/comctl32/taskdialog.c | 130 ++++++++++++++++++++++-
>> dlls/comctl32/tests/taskdialog.c | 172 +++++++++++++++++++++++++++----
>> 2 files changed, 281 insertions(+), 21 deletions(-)
>>
>> diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
>> index 33fb578910..c3c5fa0420 100644
>> --- a/dlls/comctl32/taskdialog.c
>> +++ b/dlls/comctl32/taskdialog.c
>> @@ -58,6 +58,8 @@ struct taskdialog_info
>> HWND main_instruction;
>> HWND content;
>> HWND progress_bar;
>> + HWND *radio_buttons;
>> + INT radio_button_count;
>> HWND *buttons;
>> INT button_count;
>> HWND default_button;
>> @@ -69,6 +71,7 @@ struct taskdialog_info
>> LONG h_spacing;
>> LONG v_spacing;
>> } m;
>> + INT selected_radio_id;
>> };
>> struct button_layout_info
>> @@ -185,6 +188,18 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info,
>> if (hwnd) EnableWindow(hwnd, enable);
>> }
>> +static void taskdialog_enable_radio_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable)
>> +{
>> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
>> + if (hwnd) EnableWindow(hwnd, enable);
>> +}
>> +
>> +static void taskdialog_click_radio_button(const struct taskdialog_info *dialog_info, INT id)
>> +{
>> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
>> + if (hwnd) SendMessageW(hwnd, BM_CLICK, 0, 0);
>> +}
>> +
>> static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
>> {
>> const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> @@ -193,8 +208,18 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif
>> : S_OK;
>> }
>> -static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
>> +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, unsigned long command_id)
>
> Why the type change?
>
In taskdialog_check_default_radio_buttons(), id via GetWindowLongW(default_button, GWLP_ID) is passed to
taskdialog_on_button_click(). And id is originally int in pRadioButtons. So WORD is not enough. Tested on
Windows, 0x1FFFF is allowed as a valid id. And on second thought, an INT should be enough.
>> {
>> + HWND radio_button;
>> +
>> + radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id);
>> + if (radio_button)
>> + {
>> + dialog_info->selected_radio_id = command_id;
>> + taskdialog_notify(dialog_info, TDN_RADIO_BUTTON_CLICKED, command_id, 0);
>> + return;
>> + }
>> +
>> if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
>> EndDialog(dialog_info->hwnd, command_id);
>> }
>> @@ -260,6 +285,40 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
>> ReleaseDC(hwnd, hdc);
>> }
>> +static void taskdialog_get_checkbox_height(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size)
>
> Do we call that "checkbox" anywhere in wine? It doesn't feel right.
>
>> +{
>> + DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK;
>> + HFONT hfont, old_hfont;
>> + HDC hdc;
>> + RECT rect = {0};
>> + WCHAR text[1024];
>
> I think it's better to make this dynamic.
>
>> + INT text_length;
>> + LONG text_offset, checkbox_width, checkbox_height;
>> +
>> + hdc = GetDC(hwnd);
>> + hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
>> + old_hfont = SelectObject(hdc, hfont);
>> +
>> + checkbox_width = 12 * GetDeviceCaps(hdc, LOGPIXELSX) / 96 + 1;
>> + checkbox_height = 12 * GetDeviceCaps(hdc, LOGPIXELSY) / 96 + 1;
>> + GetCharWidthW(hdc, '0', '0', &text_offset);
>> + text_offset /= 2;
>> +
>> + if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT)
>> + style |= DT_RIGHT | DT_RTLREADING;
>> + else
>> + style |= DT_LEFT;
>> +
>> + rect.right = max_width - checkbox_width - text_offset;
>> + text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text));
>> + size->cy = DrawTextW(hdc, text, text_length, &rect, style);
>> + size->cx = min(max_width - checkbox_width - text_offset, rect.right - rect.left);
>> + size->cx += checkbox_width + text_offset;
>> + size->cy = max(size->cy, checkbox_height);
>> + if (old_hfont) SelectObject(hdc, old_hfont);
>> + ReleaseDC(hwnd, hdc);
>> +}
>> +
>> static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon)
>> {
>> if (icon == TD_WARNING_ICON)
>> @@ -300,6 +359,28 @@ static void taskdialog_set_icon(struct taskdialog_info *dialog_info, INT element
>> }
>> }
>> +static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialog_info)
>> +{
>> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> + HWND default_button;
>> + INT id;
>> +
>> + if (!dialog_info->radio_button_count) return;
>> +
>> + default_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count,
>> + taskconfig->nDefaultRadioButton);
>> +
>> + if (!default_button && !(taskconfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON))
>> + default_button = dialog_info->radio_buttons[0];
>> +
>> + if (default_button)
>> + {
>> + SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0);
>> + id = GetWindowLongW(default_button, GWLP_ID);
>> + taskdialog_on_button_click(dialog_info, id);
>> + }
>> +}
>> +
>> static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info)
>> {
>> if (!dialog_info->taskconfig->u.hMainIcon) return;
>> @@ -363,6 +444,30 @@ static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info)
>> CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
>> }
>> +static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info)
>> +{
>> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> + static const DWORD style = BS_AUTORADIOBUTTON | BS_MULTILINE | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
>> + WCHAR *textW;
>> + INT i;
>> +
>> + if (!taskconfig->cRadioButtons || !taskconfig->pRadioButtons) return;
>> +
>> + dialog_info->radio_buttons = Alloc(taskconfig->cRadioButtons * sizeof(*dialog_info->radio_buttons));
>> + if (!dialog_info->radio_buttons) return;
>> +
>> + dialog_info->radio_button_count = taskconfig->cRadioButtons;
>> + for (i = 0; i < dialog_info->radio_button_count; i++)
>> + {
>> + textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pRadioButtons[i].pszButtonText);
>> + dialog_info->radio_buttons[i] =
>> + CreateWindowW(WC_BUTTONW, textW, i == 0 ? style | WS_GROUP : style, 0, 0, 0, 0, dialog_info->hwnd,
>> + (HMENU)taskconfig->pRadioButtons[i].nButtonID, 0, NULL);
>> + SendMessageW(dialog_info->radio_buttons[i], WM_SETFONT, (WPARAM)dialog_info->font, 0);
>> + Free(textW);
>> + }
>> +}
>> +
>> static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text,
>> BOOL custom_button)
>> {
>> @@ -487,6 +592,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
>> dialog_height = y + size.cy;
>> }
>> + /* Radio buttons */
>> + for (i = 0; i < dialog_info->radio_button_count; i++)
>> + {
>> + x = main_icon_right + h_spacing;
>> + y = dialog_height;
>> + taskdialog_get_checkbox_height(dialog_info, dialog_info->radio_buttons[i], dialog_width - x - h_spacing, &size);
>> + size.cx = dialog_width - x - h_spacing;
>> + SetWindowPos(dialog_info->radio_buttons[i], 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 */
>> @@ -621,6 +737,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
>> taskdialog_add_main_instruction(dialog_info);
>> taskdialog_add_content(dialog_info);
>> taskdialog_add_progress_bar(dialog_info);
>> + taskdialog_add_radio_buttons(dialog_info);
>> taskdialog_add_buttons(dialog_info);
>> /* Set default button */
>> @@ -638,6 +755,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info)
>> if (dialog_info->font) DeleteObject(dialog_info->font);
>> if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font);
>> if (dialog_info->buttons) Free(dialog_info->buttons);
>> + if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons);
>> }
>> static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
>> @@ -689,6 +807,12 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
>> case TDM_SET_PROGRESS_BAR_MARQUEE:
>> SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
>> break;
>> + case TDM_CLICK_RADIO_BUTTON:
>> + taskdialog_click_radio_button(dialog_info, wParam);
>> + break;
>> + case TDM_ENABLE_RADIO_BUTTON:
>> + taskdialog_enable_radio_button(dialog_info, wParam, lParam);
>> + break;
>> case WM_INITDIALOG:
>> dialog_info = (struct taskdialog_info *)lParam;
>> @@ -697,6 +821,8 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
>> SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);
>> taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
>> taskdialog_notify(dialog_info, TDN_CREATED, 0, 0);
>> + /* Default radio button click notification sent after TDN_CREATED */
>> + taskdialog_check_default_radio_buttons(dialog_info);
>> return FALSE;
>> case WM_COMMAND:
>> if (HIWORD(wParam) == BN_CLICKED)
>> @@ -762,7 +888,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
>> Free(template);
>> if (button) *button = ret;
>> - if (radio_button) *radio_button = taskconfig->nDefaultButton;
>> + if (radio_button) *radio_button = dialog_info.selected_radio_id;
>> if (verification_flag_checked) *verification_flag_checked = TRUE;
>> return S_OK;
>> diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
>> index e91a878876..2cda04081f 100644
>> --- a/dlls/comctl32/tests/taskdialog.c
>> +++ b/dlls/comctl32/tests/taskdialog.c
>> @@ -35,9 +35,11 @@
>> #define TASKDIALOG_SEQ_INDEX 0
>> #define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
>> +#define TEST_NUM_RADIO_BUTTONS 3
>> #define ID_START 20 /* Lower IDs might be used by the system */
>> #define ID_START_BUTTON (ID_START + 0)
>> +#define ID_START_RADIO_BUTTON (ID_START + 20)
>> static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
>> static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
>> @@ -141,6 +143,78 @@ static const struct message_info msg_got_tdn_help[] =
>> { 0 }
>> };
>> +/* Three radio buttons */
>> +static const struct message_info msg_return_default_radio_button_1[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_default_radio_button_2[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_default_radio_button_3[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_select_first_radio_button[] =
>> +{
>> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_first_radio_button[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] =
>> +{
>> + { TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
>> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
>> + { TDM_CLICK_BUTTON, IDOK, 0 },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_default_radio_button_clicking_disabled[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_no_default_radio_button_flag[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_no_default_radio_button_id_and_flag[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
>> {
>> msg->message = WM_TD_CALLBACK;
>> @@ -151,11 +225,13 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
>> msg->stage = 0;
>> }
>> -#define run_test(info, expect_button, seq, context) \
>> - run_test_(info, expect_button, seq, context, ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
>> +#define run_test(info, expect_button, expect_radio_button, seq, context) \
>> + run_test_(info, expect_button, expect_radio_button, seq, context, \
>> + ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
>> -static 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)
>> +static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button,
>> + const struct message_info *test_messages, const char *context, int test_messages_len,
>> + const char *file, int line)
>> {
>> struct message *msg, *msg_start;
>> int ret_button = 0;
>> @@ -182,6 +258,8 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me
>> 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_button,
>> + "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
>> heap_free(msg_start);
>> }
>> @@ -239,16 +317,17 @@ static void test_callback(void)
>> info.pfCallback = taskdialog_callback_proc;
>> info.lpCallbackData = test_ref_data;
>> - run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
>> + run_test(&info, IDOK, 0, msg_return_press_ok, "Press VK_RETURN.");
>> }
>> static void test_buttons(void)
>> {
>> TASKDIALOGCONFIG info = {0};
>> - TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
>> + TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_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 */
>> + /* Each button has two digits as title, plus null-terminator */
>> + WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
>> int i;
>> info.cbSize = sizeof(TASKDIALOGCONFIG);
>> @@ -266,48 +345,103 @@ static void test_buttons(void)
>> }
>> custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
>> + /* Init radio buttons */
>> + for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
>> + {
>> + WCHAR *text = &radio_button_titles[i * 3];
>> + wsprintfW(text, button_format, i);
>> +
>> + radio_buttons[i].pszButtonText = text;
>> + radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
>> + }
>> + radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
>> +
>> /* 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");
>> + run_test(&info, IDOK, 0, 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");
>> + run_test(&info, IDYES, 0, 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");
>> + run_test(&info, IDNO, 0, 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");
>> + run_test(&info, IDRETRY, 0, 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");
>> + run_test(&info, IDCANCEL, 0, 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");
>> + run_test(&info, ID_START_BUTTON, 0, 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");
>> + run_test(&info, -1, 0, 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");
>> + run_test(&info, ID_START_BUTTON, 0, 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");
>> + run_test(&info, ID_START_BUTTON, 0, 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");
>> + run_test(&info, IDRETRY, 0, 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");
>> + run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
>> +
>> + /* Test radio buttons */
>> + info.nDefaultButton = 0;
>> + info.cButtons = 0;
>> + info.pButtons = 0;
>> + info.dwCommonButtons = TDCBF_OK_BUTTON;
>> + info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
>> + info.pRadioButtons = radio_buttons;
>> +
>> + /* Test default first radio button */
>> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_1, "default radio button: default first radio button");
>> +
>> + /* Test default radio button */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
>> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_2, "default radio button: default radio button");
>> +
>> + /* Test default radio button with -2 */
>> + info.nDefaultRadioButton = -2;
>> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_3, "default radio button: default radio button with id -2");
>> +
>> + /* Test default radio button after clicking the first, messages still work even radio button is disabled */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
>> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_first_radio_button, "default radio button: radio button after clicking");
>> +
>> + /* Test radio button after disabling and clicking the first */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
>> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_clicking_disabled, "default radio button: disable radio button before clicking");
>> +
>> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
>> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
>> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_no_default_radio_button_flag, "default radio button: no default radio flag");
>> +
>> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
>> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
>> + info.nDefaultRadioButton = 0;
>> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
>> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default radio id and flag");
>> +
>> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
>> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
>> + info.nDefaultRadioButton = 0xff;
>> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
>> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default flag, invalid id");
>> }
>> static void test_help(void)
>> @@ -319,7 +453,7 @@ static void test_help(void)
>> info.lpCallbackData = test_ref_data;
>> info.dwCommonButtons = TDCBF_OK_BUTTON;
>> - run_test(&info, IDOK, msg_got_tdn_help, "send f1");
>> + run_test(&info, IDOK, 0, msg_got_tdn_help, "send f1");
>> }
>> struct timer_notification_data
>
>
>
June 25, 2018
Re: [PATCH 2/3] comctl32/taskdialog: Add support for radio buttons.
by Nikolay Sivov
On 06/17/2018 11:17 AM, Zhiyi Zhang wrote:
> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
> ---
> dlls/comctl32/taskdialog.c | 130 ++++++++++++++++++++++-
> dlls/comctl32/tests/taskdialog.c | 172 +++++++++++++++++++++++++++----
> 2 files changed, 281 insertions(+), 21 deletions(-)
>
> diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
> index 33fb578910..c3c5fa0420 100644
> --- a/dlls/comctl32/taskdialog.c
> +++ b/dlls/comctl32/taskdialog.c
> @@ -58,6 +58,8 @@ struct taskdialog_info
> HWND main_instruction;
> HWND content;
> HWND progress_bar;
> + HWND *radio_buttons;
> + INT radio_button_count;
> HWND *buttons;
> INT button_count;
> HWND default_button;
> @@ -69,6 +71,7 @@ struct taskdialog_info
> LONG h_spacing;
> LONG v_spacing;
> } m;
> + INT selected_radio_id;
> };
>
> struct button_layout_info
> @@ -185,6 +188,18 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info,
> if (hwnd) EnableWindow(hwnd, enable);
> }
>
> +static void taskdialog_enable_radio_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable)
> +{
> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
> + if (hwnd) EnableWindow(hwnd, enable);
> +}
> +
> +static void taskdialog_click_radio_button(const struct taskdialog_info *dialog_info, INT id)
> +{
> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
> + if (hwnd) SendMessageW(hwnd, BM_CLICK, 0, 0);
> +}
> +
> static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
> {
> const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
> @@ -193,8 +208,18 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif
> : S_OK;
> }
>
> -static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
> +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, unsigned long command_id)
Why the type change?
> {
> + HWND radio_button;
> +
> + radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id);
> + if (radio_button)
> + {
> + dialog_info->selected_radio_id = command_id;
> + taskdialog_notify(dialog_info, TDN_RADIO_BUTTON_CLICKED, command_id, 0);
> + return;
> + }
> +
> if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
> EndDialog(dialog_info->hwnd, command_id);
> }
> @@ -260,6 +285,40 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
> ReleaseDC(hwnd, hdc);
> }
>
> +static void taskdialog_get_checkbox_height(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size)
Do we call that "checkbox" anywhere in wine? It doesn't feel right.
> +{
> + DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK;
> + HFONT hfont, old_hfont;
> + HDC hdc;
> + RECT rect = {0};
> + WCHAR text[1024];
I think it's better to make this dynamic.
> + INT text_length;
> + LONG text_offset, checkbox_width, checkbox_height;
> +
> + hdc = GetDC(hwnd);
> + hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
> + old_hfont = SelectObject(hdc, hfont);
> +
> + checkbox_width = 12 * GetDeviceCaps(hdc, LOGPIXELSX) / 96 + 1;
> + checkbox_height = 12 * GetDeviceCaps(hdc, LOGPIXELSY) / 96 + 1;
> + GetCharWidthW(hdc, '0', '0', &text_offset);
> + text_offset /= 2;
> +
> + if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT)
> + style |= DT_RIGHT | DT_RTLREADING;
> + else
> + style |= DT_LEFT;
> +
> + rect.right = max_width - checkbox_width - text_offset;
> + text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text));
> + size->cy = DrawTextW(hdc, text, text_length, &rect, style);
> + size->cx = min(max_width - checkbox_width - text_offset, rect.right - rect.left);
> + size->cx += checkbox_width + text_offset;
> + size->cy = max(size->cy, checkbox_height);
> + if (old_hfont) SelectObject(hdc, old_hfont);
> + ReleaseDC(hwnd, hdc);
> +}
> +
> static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon)
> {
> if (icon == TD_WARNING_ICON)
> @@ -300,6 +359,28 @@ static void taskdialog_set_icon(struct taskdialog_info *dialog_info, INT element
> }
> }
>
> +static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialog_info)
> +{
> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
> + HWND default_button;
> + INT id;
> +
> + if (!dialog_info->radio_button_count) return;
> +
> + default_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count,
> + taskconfig->nDefaultRadioButton);
> +
> + if (!default_button && !(taskconfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON))
> + default_button = dialog_info->radio_buttons[0];
> +
> + if (default_button)
> + {
> + SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0);
> + id = GetWindowLongW(default_button, GWLP_ID);
> + taskdialog_on_button_click(dialog_info, id);
> + }
> +}
> +
> static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info)
> {
> if (!dialog_info->taskconfig->u.hMainIcon) return;
> @@ -363,6 +444,30 @@ static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info)
> CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
> }
>
> +static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info)
> +{
> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
> + static const DWORD style = BS_AUTORADIOBUTTON | BS_MULTILINE | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
> + WCHAR *textW;
> + INT i;
> +
> + if (!taskconfig->cRadioButtons || !taskconfig->pRadioButtons) return;
> +
> + dialog_info->radio_buttons = Alloc(taskconfig->cRadioButtons * sizeof(*dialog_info->radio_buttons));
> + if (!dialog_info->radio_buttons) return;
> +
> + dialog_info->radio_button_count = taskconfig->cRadioButtons;
> + for (i = 0; i < dialog_info->radio_button_count; i++)
> + {
> + textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pRadioButtons[i].pszButtonText);
> + dialog_info->radio_buttons[i] =
> + CreateWindowW(WC_BUTTONW, textW, i == 0 ? style | WS_GROUP : style, 0, 0, 0, 0, dialog_info->hwnd,
> + (HMENU)taskconfig->pRadioButtons[i].nButtonID, 0, NULL);
> + SendMessageW(dialog_info->radio_buttons[i], WM_SETFONT, (WPARAM)dialog_info->font, 0);
> + Free(textW);
> + }
> +}
> +
> static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text,
> BOOL custom_button)
> {
> @@ -487,6 +592,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
> dialog_height = y + size.cy;
> }
>
> + /* Radio buttons */
> + for (i = 0; i < dialog_info->radio_button_count; i++)
> + {
> + x = main_icon_right + h_spacing;
> + y = dialog_height;
> + taskdialog_get_checkbox_height(dialog_info, dialog_info->radio_buttons[i], dialog_width - x - h_spacing, &size);
> + size.cx = dialog_width - x - h_spacing;
> + SetWindowPos(dialog_info->radio_buttons[i], 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 */
> @@ -621,6 +737,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
> taskdialog_add_main_instruction(dialog_info);
> taskdialog_add_content(dialog_info);
> taskdialog_add_progress_bar(dialog_info);
> + taskdialog_add_radio_buttons(dialog_info);
> taskdialog_add_buttons(dialog_info);
>
> /* Set default button */
> @@ -638,6 +755,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info)
> if (dialog_info->font) DeleteObject(dialog_info->font);
> if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font);
> if (dialog_info->buttons) Free(dialog_info->buttons);
> + if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons);
> }
>
> static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
> @@ -689,6 +807,12 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
> case TDM_SET_PROGRESS_BAR_MARQUEE:
> SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
> break;
> + case TDM_CLICK_RADIO_BUTTON:
> + taskdialog_click_radio_button(dialog_info, wParam);
> + break;
> + case TDM_ENABLE_RADIO_BUTTON:
> + taskdialog_enable_radio_button(dialog_info, wParam, lParam);
> + break;
> case WM_INITDIALOG:
> dialog_info = (struct taskdialog_info *)lParam;
>
> @@ -697,6 +821,8 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
> SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);
> taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
> taskdialog_notify(dialog_info, TDN_CREATED, 0, 0);
> + /* Default radio button click notification sent after TDN_CREATED */
> + taskdialog_check_default_radio_buttons(dialog_info);
> return FALSE;
> case WM_COMMAND:
> if (HIWORD(wParam) == BN_CLICKED)
> @@ -762,7 +888,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
> Free(template);
>
> if (button) *button = ret;
> - if (radio_button) *radio_button = taskconfig->nDefaultButton;
> + if (radio_button) *radio_button = dialog_info.selected_radio_id;
> if (verification_flag_checked) *verification_flag_checked = TRUE;
>
> return S_OK;
> diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
> index e91a878876..2cda04081f 100644
> --- a/dlls/comctl32/tests/taskdialog.c
> +++ b/dlls/comctl32/tests/taskdialog.c
> @@ -35,9 +35,11 @@
> #define TASKDIALOG_SEQ_INDEX 0
>
> #define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
> +#define TEST_NUM_RADIO_BUTTONS 3
>
> #define ID_START 20 /* Lower IDs might be used by the system */
> #define ID_START_BUTTON (ID_START + 0)
> +#define ID_START_RADIO_BUTTON (ID_START + 20)
>
> static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
> static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
> @@ -141,6 +143,78 @@ static const struct message_info msg_got_tdn_help[] =
> { 0 }
> };
>
> +/* Three radio buttons */
> +static const struct message_info msg_return_default_radio_button_1[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_default_radio_button_2[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_default_radio_button_3[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_select_first_radio_button[] =
> +{
> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_first_radio_button[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] =
> +{
> + { TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
> + { TDM_CLICK_BUTTON, IDOK, 0 },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_default_radio_button_clicking_disabled[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_no_default_radio_button_flag[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_no_default_radio_button_id_and_flag[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
> {
> msg->message = WM_TD_CALLBACK;
> @@ -151,11 +225,13 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
> msg->stage = 0;
> }
>
> -#define run_test(info, expect_button, seq, context) \
> - run_test_(info, expect_button, seq, context, ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
> +#define run_test(info, expect_button, expect_radio_button, seq, context) \
> + run_test_(info, expect_button, expect_radio_button, seq, context, \
> + ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
>
> -static 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)
> +static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button,
> + const struct message_info *test_messages, const char *context, int test_messages_len,
> + const char *file, int line)
> {
> struct message *msg, *msg_start;
> int ret_button = 0;
> @@ -182,6 +258,8 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me
> 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_button,
> + "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
>
> heap_free(msg_start);
> }
> @@ -239,16 +317,17 @@ static void test_callback(void)
> info.pfCallback = taskdialog_callback_proc;
> info.lpCallbackData = test_ref_data;
>
> - run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
> + run_test(&info, IDOK, 0, msg_return_press_ok, "Press VK_RETURN.");
> }
>
> static void test_buttons(void)
> {
> TASKDIALOGCONFIG info = {0};
>
> - TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
> + TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_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 */
> + /* Each button has two digits as title, plus null-terminator */
> + WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
> int i;
>
> info.cbSize = sizeof(TASKDIALOGCONFIG);
> @@ -266,48 +345,103 @@ static void test_buttons(void)
> }
> custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
>
> + /* Init radio buttons */
> + for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
> + {
> + WCHAR *text = &radio_button_titles[i * 3];
> + wsprintfW(text, button_format, i);
> +
> + radio_buttons[i].pszButtonText = text;
> + radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
> + }
> + radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
> +
> /* 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");
> + run_test(&info, IDOK, 0, 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");
> + run_test(&info, IDYES, 0, 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");
> + run_test(&info, IDNO, 0, 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");
> + run_test(&info, IDRETRY, 0, 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");
> + run_test(&info, IDCANCEL, 0, 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");
> + run_test(&info, ID_START_BUTTON, 0, 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");
> + run_test(&info, -1, 0, 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");
> + run_test(&info, ID_START_BUTTON, 0, 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");
> + run_test(&info, ID_START_BUTTON, 0, 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");
> + run_test(&info, IDRETRY, 0, 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");
> + run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
> +
> + /* Test radio buttons */
> + info.nDefaultButton = 0;
> + info.cButtons = 0;
> + info.pButtons = 0;
> + info.dwCommonButtons = TDCBF_OK_BUTTON;
> + info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
> + info.pRadioButtons = radio_buttons;
> +
> + /* Test default first radio button */
> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_1, "default radio button: default first radio button");
> +
> + /* Test default radio button */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_2, "default radio button: default radio button");
> +
> + /* Test default radio button with -2 */
> + info.nDefaultRadioButton = -2;
> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_3, "default radio button: default radio button with id -2");
> +
> + /* Test default radio button after clicking the first, messages still work even radio button is disabled */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_first_radio_button, "default radio button: radio button after clicking");
> +
> + /* Test radio button after disabling and clicking the first */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_clicking_disabled, "default radio button: disable radio button before clicking");
> +
> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_no_default_radio_button_flag, "default radio button: no default radio flag");
> +
> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
> + info.nDefaultRadioButton = 0;
> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default radio id and flag");
> +
> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
> + info.nDefaultRadioButton = 0xff;
> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default flag, invalid id");
> }
>
> static void test_help(void)
> @@ -319,7 +453,7 @@ static void test_help(void)
> info.lpCallbackData = test_ref_data;
> info.dwCommonButtons = TDCBF_OK_BUTTON;
>
> - run_test(&info, IDOK, msg_got_tdn_help, "send f1");
> + run_test(&info, IDOK, 0, msg_got_tdn_help, "send f1");
> }
>
> struct timer_notification_data
June 25, 2018