Wine-devel
Threads by month
- ----- 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
July 2021
- 86 participants
- 642 discussions
From: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
This supersedes patch 209630.
dlls/d2d1/d2d1_private.h | 5 +++-
dlls/d2d1/device.c | 3 +-
dlls/d2d1/effect.c | 65 +++++++++++++++++++++++++++++++++++++++-
dlls/d2d1/tests/d2d1.c | 5 +---
4 files changed, 71 insertions(+), 7 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index f25a7809b17..ce99e7c3432 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -568,10 +568,13 @@ void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *factory, IDXGIDev
struct d2d_effect
{
ID2D1Effect ID2D1Effect_iface;
+ ID2D1Image ID2D1Image_iface;
LONG refcount;
+
+ ID2D1Factory *factory;
};
-void d2d_effect_init(struct d2d_effect *effect) DECLSPEC_HIDDEN;
+void d2d_effect_init(struct d2d_effect *effect, ID2D1Factory *factory) DECLSPEC_HIDDEN;
static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
{
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c
index 44840f0010f..0647bc57fc3 100644
--- a/dlls/d2d1/device.c
+++ b/dlls/d2d1/device.c
@@ -1885,6 +1885,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(
static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext *iface,
REFCLSID effect_id, ID2D1Effect **effect)
{
+ struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
struct d2d_effect *object;
FIXME("iface %p, effect_id %s, effect %p stub!\n", iface, debugstr_guid(effect_id), effect);
@@ -1892,7 +1893,7 @@ static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceCont
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
- d2d_effect_init(object);
+ d2d_effect_init(object, context->factory);
TRACE("Created effect %p.\n", object);
*effect = &object->ID2D1Effect_iface;
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c
index fb1e66a3d9b..7487c4c4539 100644
--- a/dlls/d2d1/effect.c
+++ b/dlls/d2d1/effect.c
@@ -27,6 +27,7 @@ static inline struct d2d_effect *impl_from_ID2D1Effect(ID2D1Effect *iface)
static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, REFIID iid, void **out)
{
+ struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1Effect)
@@ -38,6 +39,14 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_QueryInterface(ID2D1Effect *iface, R
return S_OK;
}
+ if (IsEqualGUID(iid, &IID_ID2D1Image)
+ || IsEqualGUID(iid, &IID_ID2D1Resource))
+ {
+ ID2D1Image_AddRef(&effect->ID2D1Image_iface);
+ *out = &effect->ID2D1Image_iface;
+ return S_OK;
+ }
+
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
*out = NULL;
@@ -62,7 +71,10 @@ static ULONG STDMETHODCALLTYPE d2d_effect_Release(ID2D1Effect *iface)
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount)
+ {
+ ID2D1Factory_Release(effect->factory);
heap_free(effect);
+ }
return refcount;
}
@@ -204,8 +216,59 @@ static const ID2D1EffectVtbl d2d_effect_vtbl =
d2d_effect_GetOutput,
};
-void d2d_effect_init(struct d2d_effect *effect)
+static inline struct d2d_effect *impl_from_ID2D1Image(ID2D1Image *iface)
+{
+ return CONTAINING_RECORD(iface, struct d2d_effect, ID2D1Image_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_image_QueryInterface(ID2D1Image *iface, REFIID iid, void **out)
+{
+ struct d2d_effect *effect = impl_from_ID2D1Image(iface);
+
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ return d2d_effect_QueryInterface(&effect->ID2D1Effect_iface, iid, out);
+}
+
+static ULONG STDMETHODCALLTYPE d2d_effect_image_AddRef(ID2D1Image *iface)
+{
+ struct d2d_effect *effect = impl_from_ID2D1Image(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return d2d_effect_AddRef(&effect->ID2D1Effect_iface);
+}
+
+static ULONG STDMETHODCALLTYPE d2d_effect_image_Release(ID2D1Image *iface)
+{
+ struct d2d_effect *effect = impl_from_ID2D1Image(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return d2d_effect_Release(&effect->ID2D1Effect_iface);
+}
+
+static void STDMETHODCALLTYPE d2d_effect_image_GetFactory(ID2D1Image *iface, ID2D1Factory **factory)
+{
+ struct d2d_effect *effect = impl_from_ID2D1Image(iface);
+
+ TRACE("iface %p, factory %p.\n", iface, factory);
+
+ ID2D1Factory_AddRef(*factory = effect->factory);
+}
+
+static const ID2D1ImageVtbl d2d_effect_image_vtbl =
+{
+ d2d_effect_image_QueryInterface,
+ d2d_effect_image_AddRef,
+ d2d_effect_image_Release,
+ d2d_effect_image_GetFactory,
+};
+
+void d2d_effect_init(struct d2d_effect *effect, ID2D1Factory *factory)
{
effect->ID2D1Effect_iface.lpVtbl = &d2d_effect_vtbl;
+ effect->ID2D1Image_iface.lpVtbl = &d2d_effect_image_vtbl;
effect->refcount = 1;
+ ID2D1Factory_AddRef(effect->factory = factory);
}
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 41203f85019..5ac4aed7c4c 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -9703,16 +9703,13 @@ static void test_effect(BOOL d3d11)
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a);
- todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- if (hr != S_OK)
- goto done;
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
ID2D1Effect_GetOutput(effect, &image_b);
todo_wine ok(image_b == image_a, "Got unexpected image_b %p, expected %p.\n", image_b, image_a);
if (image_b)
ID2D1Image_Release(image_b);
ID2D1Image_Release(image_a);
-done:
ID2D1Effect_Release(effect);
ID2D1DeviceContext_Release(context);
ID2D1Factory1_Release(factory);
--
2.20.1
1
0
From: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
This supersedes patch 209628.
dlls/d2d1/tests/d2d1.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index e60128b38f2..41203f85019 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -9678,6 +9678,47 @@ static void test_mt_factory(BOOL d3d11)
ID2D1Factory_Release(factory);
}
+static void test_effect(BOOL d3d11)
+{
+ ID2D1Image *image_a, *image_b = NULL;
+ struct d2d1_test_context ctx;
+ ID2D1DeviceContext *context;
+ ID2D1Factory1 *factory;
+ ID2D1Effect *effect;
+ HRESULT hr;
+
+ if (!init_test_context(&ctx, d3d11))
+ return;
+
+ if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
+ {
+ win_skip("ID2D1Factory1 is not supported.\n");
+ release_test_context(&ctx);
+ return;
+ }
+
+ hr = ID2D1RenderTarget_QueryInterface(ctx.rt, &IID_ID2D1DeviceContext, (void **)&context);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D12DAffineTransform, &effect);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a);
+ todo_wine ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ if (hr != S_OK)
+ goto done;
+ ID2D1Effect_GetOutput(effect, &image_b);
+ todo_wine ok(image_b == image_a, "Got unexpected image_b %p, expected %p.\n", image_b, image_a);
+ if (image_b)
+ ID2D1Image_Release(image_b);
+ ID2D1Image_Release(image_a);
+
+done:
+ ID2D1Effect_Release(effect);
+ ID2D1DeviceContext_Release(context);
+ ID2D1Factory1_Release(factory);
+ release_test_context(&ctx);
+}
+
START_TEST(d2d1)
{
HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll");
@@ -9739,6 +9780,7 @@ START_TEST(d2d1)
queue_d3d10_test(test_colour_space);
queue_test(test_geometry_group);
queue_test(test_mt_factory);
+ queue_test(test_effect);
run_queued_tests();
}
--
2.20.1
1
0
20 Jul '21
From: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
This supersedes patch 209631.
include/Makefile.in | 1 +
include/d2d1_1.idl | 1 +
include/d2d1effects.idl | 46 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+)
create mode 100755 include/d2d1effects.idl
diff --git a/include/Makefile.in b/include/Makefile.in
index 61a74a210c9..46cb0f53a5e 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -99,6 +99,7 @@ SOURCES = \
d2d1.idl \
d2d1_1.idl \
d2d1_2.idl \
+ d2d1effects.idl \
d2dbasetypes.h \
d2derr.h \
d3d.h \
diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl
index 257a970968f..fdec8ae5f9c 100644
--- a/include/d2d1_1.idl
+++ b/include/d2d1_1.idl
@@ -17,6 +17,7 @@
*/
import "d2d1.idl";
+import "d2d1effects.idl";
interface ID2D1DeviceContext;
interface ID2D1PathGeometry1;
diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl
new file mode 100755
index 00000000000..ee1dbe94728
--- /dev/null
+++ b/include/d2d1effects.idl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 Ziqing Hui for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+cpp_quote("DEFINE_GUID(CLSID_D2D12DAffineTransform, 0x6aa97485,0x6354,0x4cfc,0x90,0x8c,0xe4,0xa7,0x4f,0x62,0xc9,0x6c);")
+
+typedef enum D2D1_BORDER_MODE
+{
+ D2D1_BORDER_MODE_SOFT = 0x0,
+ D2D1_BORDER_MODE_HARD = 0x1,
+ D2D1_BORDER_MODE_FORCE_DWORD = 0xffffffff
+} D2D1_BORDER_MODE;
+
+typedef enum D2D1_2DAFFINETRANSFORM_PROP
+{
+ D2D1_2DAFFINETRANSFORM_PROP_INTERPOLATION_MODE = 0x0,
+ D2D1_2DAFFINETRANSFORM_PROP_BORDER_MODE = 0x1,
+ D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX = 0x2,
+ D2D1_2DAFFINETRANSFORM_PROP_SHARPNESS = 0x3,
+ D2D1_2DAFFINETRANSFORM_PROP_FORCE_DWORD = 0xffffffff
+} D2D1_2DAFFINETRANSFORM_PROP;
+
+typedef enum D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE
+{
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_NEAREST_NEIGHBOR = 0x0,
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_LINEAR = 0x1,
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_CUBIC = 0x2,
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR = 0x3,
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_ANISOTROPIC = 0x4,
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC = 0x5,
+ D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE_FORCE_DWORD = 0xffffffff
+} D2D1_2DAFFINETRANSFORM_INTERPOLATION_MODE;
--
2.20.1
1
0
[PATCH v3 5/5] uxtheme: Support scroll bar state tracking in non-client areas.
by Zhiyi Zhang 20 Jul '21
by Zhiyi Zhang 20 Jul '21
20 Jul '21
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
v3: Supersede 209912. Fix a style inconsistency.
dlls/user32/controls.h | 3 +++
dlls/user32/defwnd.c | 11 +++++++++++
dlls/user32/nonclient.c | 33 +++++++++++++++++++++++++++++++++
dlls/user32/scroll.c | 37 ++++++++++++++++++++++++++++++++++---
4 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index bf32097f95c..2b3d405ae69 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -171,6 +171,8 @@ extern LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) DE
extern LRESULT NC_HandleNCCalcSize( HWND hwnd, WPARAM wParam, RECT *winRect ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
+extern LRESULT NC_HandleNCMouseMove( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
+extern LRESULT NC_HandleNCMouseLeave( HWND hwnd ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
@@ -184,6 +186,7 @@ extern void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BO
extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test,
const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows,
BOOL interior ) DECLSPEC_HIDDEN;
+extern void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) DECLSPEC_HIDDEN;
extern void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) DECLSPEC_HIDDEN;
/* combo box */
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index a3d92e84aef..5eb056ebd9e 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -245,6 +245,17 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
case WM_NCPAINT:
return NC_HandleNCPaint( hwnd, (HRGN)wParam );
+ case WM_NCMOUSEMOVE:
+ {
+ POINT pt;
+ pt.x = (short)LOWORD(lParam);
+ pt.y = (short)HIWORD(lParam);
+ return NC_HandleNCMouseMove( hwnd, pt );
+ }
+
+ case WM_NCMOUSELEAVE:
+ return NC_HandleNCMouseLeave( hwnd );
+
case WM_NCHITTEST:
{
POINT pt;
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c
index 50ecb0c4e2e..02e6ad92320 100644
--- a/dlls/user32/nonclient.c
+++ b/dlls/user32/nonclient.c
@@ -635,6 +635,39 @@ LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt )
return HTNOWHERE;
}
+LRESULT NC_HandleNCMouseMove(HWND hwnd, POINT pt)
+{
+ LONG hittest;
+ RECT rect;
+
+ TRACE("hwnd=%p pt=%s\n", hwnd, wine_dbgstr_point(&pt));
+
+ hittest = NC_HandleNCHitTest(hwnd, pt);
+ if (hittest != HTHSCROLL && hittest != HTVSCROLL)
+ return 0;
+
+ WIN_GetRectangles(hwnd, COORDS_CLIENT, &rect, NULL);
+ ScreenToClient(hwnd, &pt);
+ pt.x -= rect.left;
+ pt.y -= rect.top;
+ SCROLL_HandleScrollEvent(hwnd, hittest == HTHSCROLL ? SB_HORZ : SB_VERT, WM_NCMOUSEMOVE, pt);
+ return 0;
+}
+
+LRESULT NC_HandleNCMouseLeave(HWND hwnd)
+{
+ LONG style = GetWindowLongW(hwnd, GWL_STYLE);
+ POINT pt = {0, 0};
+
+ TRACE("hwnd=%p\n", hwnd);
+
+ if (style & WS_HSCROLL)
+ SCROLL_HandleScrollEvent(hwnd, SB_HORZ, WM_NCMOUSELEAVE, pt);
+ if (style & WS_VSCROLL)
+ SCROLL_HandleScrollEvent(hwnd, SB_VERT, WM_NCMOUSELEAVE, pt);
+
+ return 0;
+}
/******************************************************************************
*
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c
index c4c06476b9c..088e41eee43 100644
--- a/dlls/user32/scroll.c
+++ b/dlls/user32/scroll.c
@@ -751,7 +751,7 @@ static void SCROLL_HandleKbdEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
* 'pt' is the location of the mouse event in client (for SB_CTL) or
* windows coordinates.
*/
-static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
+void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt )
{
/* Previous mouse position for timer events */
static POINT prevPt;
@@ -773,7 +773,8 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
SCROLLBAR_INFO *infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, FALSE );
if (!infoPtr) return;
if ((g_tracking_info.hit_test == SCROLL_NOWHERE)
- && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE))
+ && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE
+ && msg != WM_NCMOUSEMOVE && msg != WM_NCMOUSELEAVE))
return;
if (nBar == SB_CTL && (GetWindowLongW( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX)))
@@ -841,6 +842,32 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
break;
+ case WM_NCMOUSEMOVE:
+ hittest = SCROLL_HitTest( hwnd, nBar, pt, vertical == g_tracking_info.vertical && GetCapture() == hwnd );
+ prevPt = pt;
+
+ if (nBar == SB_CTL)
+ break;
+
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_QUERY;
+ TrackMouseEvent( &tme );
+ if (((tme.dwFlags & (TME_NONCLIENT | TME_LEAVE)) != (TME_NONCLIENT | TME_LEAVE)) || tme.hwndTrack != hwnd)
+ {
+ tme.dwFlags = TME_NONCLIENT | TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ TrackMouseEvent( &tme );
+ }
+
+ break;
+
+ case WM_NCMOUSELEAVE:
+ if (nBar == SB_CTL)
+ return;
+
+ hittest = SCROLL_NOWHERE;
+ break;
+
case WM_MOUSELEAVE:
if (nBar != SB_CTL)
return;
@@ -870,7 +897,7 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
switch (g_tracking_info.hit_test)
{
case SCROLL_NOWHERE: /* No tracking in progress */
- if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE)
+ if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE || msg == WM_NCMOUSEMOVE || msg == WM_NCMOUSELEAVE)
SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE );
break;
@@ -1049,6 +1076,8 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
if (msg.message == WM_LBUTTONUP ||
msg.message == WM_MOUSEMOVE ||
msg.message == WM_MOUSELEAVE ||
+ msg.message == WM_NCMOUSEMOVE ||
+ msg.message == WM_NCMOUSELEAVE ||
(msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER))
{
pt.x = (short)LOWORD(msg.lParam) - rect.left;
@@ -1383,6 +1412,8 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA
}
break;
case WM_LBUTTONUP:
+ case WM_NCMOUSEMOVE:
+ case WM_NCMOUSELEAVE:
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
case WM_SYSTIMER:
--
2.30.2
1
0
[PATCH v2 5/5] uxtheme: Support scroll bar state tracking in non-client areas.
by Zhiyi Zhang 20 Jul '21
by Zhiyi Zhang 20 Jul '21
20 Jul '21
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/controls.h | 3 +++
dlls/user32/defwnd.c | 11 +++++++++++
dlls/user32/nonclient.c | 33 +++++++++++++++++++++++++++++++++
dlls/user32/scroll.c | 37 ++++++++++++++++++++++++++++++++++---
4 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index bf32097f95c..c25cb1721d5 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -171,6 +171,8 @@ extern LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) DE
extern LRESULT NC_HandleNCCalcSize( HWND hwnd, WPARAM wParam, RECT *winRect ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
+extern LRESULT NC_HandleNCMouseMove( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN;
+extern LRESULT NC_HandleNCMouseLeave( HWND hwnd ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN;
extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
@@ -184,6 +186,7 @@ extern void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BO
extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test,
const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows,
BOOL interior ) DECLSPEC_HIDDEN;
+void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt) DECLSPEC_HIDDEN;
extern void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) DECLSPEC_HIDDEN;
/* combo box */
diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c
index a3d92e84aef..5eb056ebd9e 100644
--- a/dlls/user32/defwnd.c
+++ b/dlls/user32/defwnd.c
@@ -245,6 +245,17 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa
case WM_NCPAINT:
return NC_HandleNCPaint( hwnd, (HRGN)wParam );
+ case WM_NCMOUSEMOVE:
+ {
+ POINT pt;
+ pt.x = (short)LOWORD(lParam);
+ pt.y = (short)HIWORD(lParam);
+ return NC_HandleNCMouseMove( hwnd, pt );
+ }
+
+ case WM_NCMOUSELEAVE:
+ return NC_HandleNCMouseLeave( hwnd );
+
case WM_NCHITTEST:
{
POINT pt;
diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c
index 50ecb0c4e2e..02e6ad92320 100644
--- a/dlls/user32/nonclient.c
+++ b/dlls/user32/nonclient.c
@@ -635,6 +635,39 @@ LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt )
return HTNOWHERE;
}
+LRESULT NC_HandleNCMouseMove(HWND hwnd, POINT pt)
+{
+ LONG hittest;
+ RECT rect;
+
+ TRACE("hwnd=%p pt=%s\n", hwnd, wine_dbgstr_point(&pt));
+
+ hittest = NC_HandleNCHitTest(hwnd, pt);
+ if (hittest != HTHSCROLL && hittest != HTVSCROLL)
+ return 0;
+
+ WIN_GetRectangles(hwnd, COORDS_CLIENT, &rect, NULL);
+ ScreenToClient(hwnd, &pt);
+ pt.x -= rect.left;
+ pt.y -= rect.top;
+ SCROLL_HandleScrollEvent(hwnd, hittest == HTHSCROLL ? SB_HORZ : SB_VERT, WM_NCMOUSEMOVE, pt);
+ return 0;
+}
+
+LRESULT NC_HandleNCMouseLeave(HWND hwnd)
+{
+ LONG style = GetWindowLongW(hwnd, GWL_STYLE);
+ POINT pt = {0, 0};
+
+ TRACE("hwnd=%p\n", hwnd);
+
+ if (style & WS_HSCROLL)
+ SCROLL_HandleScrollEvent(hwnd, SB_HORZ, WM_NCMOUSELEAVE, pt);
+ if (style & WS_VSCROLL)
+ SCROLL_HandleScrollEvent(hwnd, SB_VERT, WM_NCMOUSELEAVE, pt);
+
+ return 0;
+}
/******************************************************************************
*
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c
index c4c06476b9c..929d70cf08c 100644
--- a/dlls/user32/scroll.c
+++ b/dlls/user32/scroll.c
@@ -751,7 +751,7 @@ static void SCROLL_HandleKbdEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
* 'pt' is the location of the mouse event in client (for SB_CTL) or
* windows coordinates.
*/
-static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
+void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
{
/* Previous mouse position for timer events */
static POINT prevPt;
@@ -773,7 +773,8 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
SCROLLBAR_INFO *infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, FALSE );
if (!infoPtr) return;
if ((g_tracking_info.hit_test == SCROLL_NOWHERE)
- && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE))
+ && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE
+ && msg != WM_NCMOUSEMOVE && msg != WM_NCMOUSELEAVE))
return;
if (nBar == SB_CTL && (GetWindowLongW( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX)))
@@ -841,6 +842,32 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
break;
+ case WM_NCMOUSEMOVE:
+ hittest = SCROLL_HitTest( hwnd, nBar, pt, vertical == g_tracking_info.vertical && GetCapture() == hwnd );
+ prevPt = pt;
+
+ if (nBar == SB_CTL)
+ break;
+
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_QUERY;
+ TrackMouseEvent( &tme );
+ if (((tme.dwFlags & (TME_NONCLIENT | TME_LEAVE)) != (TME_NONCLIENT | TME_LEAVE)) || tme.hwndTrack != hwnd)
+ {
+ tme.dwFlags = TME_NONCLIENT | TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ TrackMouseEvent( &tme );
+ }
+
+ break;
+
+ case WM_NCMOUSELEAVE:
+ if (nBar == SB_CTL)
+ return;
+
+ hittest = SCROLL_NOWHERE;
+ break;
+
case WM_MOUSELEAVE:
if (nBar != SB_CTL)
return;
@@ -870,7 +897,7 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
switch (g_tracking_info.hit_test)
{
case SCROLL_NOWHERE: /* No tracking in progress */
- if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE)
+ if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE || msg == WM_NCMOUSEMOVE || msg == WM_NCMOUSELEAVE)
SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE );
break;
@@ -1049,6 +1076,8 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
if (msg.message == WM_LBUTTONUP ||
msg.message == WM_MOUSEMOVE ||
msg.message == WM_MOUSELEAVE ||
+ msg.message == WM_NCMOUSEMOVE ||
+ msg.message == WM_NCMOUSELEAVE ||
(msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER))
{
pt.x = (short)LOWORD(msg.lParam) - rect.left;
@@ -1383,6 +1412,8 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA
}
break;
case WM_LBUTTONUP:
+ case WM_NCMOUSEMOVE:
+ case WM_NCMOUSELEAVE:
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
case WM_SYSTIMER:
--
2.30.2
1
0
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index e8534cbd5f5..31164406cab 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -3614,6 +3614,9 @@ class VkRegistry(object):
_type = None
if not t.find("type") is None:
_type = t.find("type").text
+ tail = t.find("type").tail
+ if tail is not None:
+ _type += tail.strip()
basetype = VkBaseType(name, _type)
base_types.append(basetype)
type_info["data"] = basetype
--
2.32.0
1
2
20 Jul '21
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/uxtheme/scrollbar.c | 67 +++++++++++++++++++++++++++++++---------
1 file changed, 53 insertions(+), 14 deletions(-)
diff --git a/dlls/uxtheme/scrollbar.c b/dlls/uxtheme/scrollbar.c
index 40fdbf4b89a..386f0446049 100644
--- a/dlls/uxtheme/scrollbar.c
+++ b/dlls/uxtheme/scrollbar.c
@@ -75,12 +75,29 @@ void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTES
lowertrackstate = SCRBS_NORMAL;
thumbstate = SCRBS_NORMAL;
- if (hit_test == SCROLL_TOP_RECT)
- uppertrackstate = SCRBS_HOT;
- else if (hit_test == SCROLL_BOTTOM_RECT)
- lowertrackstate = SCRBS_HOT;
- else if (hit_test == SCROLL_THUMB)
- thumbstate = SCRBS_HOT;
+ if (vertical == tracking_info->vertical && hit_test == tracking_info->hit_test
+ && GetCapture() == hwnd)
+ {
+ if (hit_test == SCROLL_TOP_RECT)
+ uppertrackstate = SCRBS_PRESSED;
+ else if (hit_test == SCROLL_BOTTOM_RECT)
+ lowertrackstate = SCRBS_PRESSED;
+ else if (hit_test == SCROLL_THUMB)
+ thumbstate = SCRBS_PRESSED;
+ }
+ else
+ {
+ if (hit_test == SCROLL_TOP_RECT)
+ uppertrackstate = SCRBS_HOT;
+ else if (hit_test == SCROLL_BOTTOM_RECT)
+ lowertrackstate = SCRBS_HOT;
+ else if (hit_test == SCROLL_THUMB)
+ thumbstate = SCRBS_HOT;
+ }
+
+ /* Thumb is also shown as pressed when tracking */
+ if (tracking_info->win == hwnd && tracking_info->bar == bar)
+ thumbstate = SCRBS_PRESSED;
}
if (bar == SB_CTL)
@@ -96,10 +113,21 @@ void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTES
uparrowstate = ABS_UPNORMAL;
downarrowstate = ABS_DOWNNORMAL;
- if (hit_test == SCROLL_TOP_ARROW)
- uparrowstate = ABS_UPHOT;
- else if (hit_test == SCROLL_BOTTOM_ARROW)
- downarrowstate = ABS_DOWNHOT;
+ if (vertical == tracking_info->vertical && hit_test == tracking_info->hit_test
+ && GetCapture() == hwnd)
+ {
+ if (hit_test == SCROLL_TOP_ARROW)
+ uparrowstate = ABS_UPPRESSED;
+ else if (hit_test == SCROLL_BOTTOM_ARROW)
+ downarrowstate = ABS_DOWNPRESSED;
+ }
+ else
+ {
+ if (hit_test == SCROLL_TOP_ARROW)
+ uparrowstate = ABS_UPHOT;
+ else if (hit_test == SCROLL_BOTTOM_ARROW)
+ downarrowstate = ABS_DOWNHOT;
+ }
}
partrect = *rect;
@@ -150,10 +178,21 @@ void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTES
leftarrowstate = ABS_LEFTNORMAL;
rightarrowstate = ABS_RIGHTNORMAL;
- if (hit_test == SCROLL_TOP_ARROW)
- leftarrowstate = ABS_LEFTHOT;
- else if (hit_test == SCROLL_BOTTOM_ARROW)
- rightarrowstate = ABS_RIGHTHOT;
+ if (vertical == tracking_info->vertical && hit_test == tracking_info->hit_test
+ && GetCapture() == hwnd)
+ {
+ if (hit_test == SCROLL_TOP_ARROW)
+ leftarrowstate = ABS_LEFTPRESSED;
+ else if (hit_test == SCROLL_BOTTOM_ARROW)
+ rightarrowstate = ABS_RIGHTPRESSED;
+ }
+ else
+ {
+ if (hit_test == SCROLL_TOP_ARROW)
+ leftarrowstate = ABS_LEFTHOT;
+ else if (hit_test == SCROLL_BOTTOM_ARROW)
+ rightarrowstate = ABS_RIGHTHOT;
+ }
}
partrect = *rect;
--
2.30.2
1
0
20 Jul '21
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=39821
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/controls.h | 22 --
dlls/user32/hook.c | 1 +
dlls/user32/scroll.c | 47 +++-
dlls/user32/user_private.h | 3 +
dlls/uxtheme/scrollbar.c | 464 +++++--------------------------------
dlls/uxtheme/system.c | 1 +
dlls/uxtheme/uxthemedll.h | 4 +
include/winuser.h | 26 +++
8 files changed, 134 insertions(+), 434 deletions(-)
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index 25ff4fe05ff..bf32097f95c 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -180,28 +180,6 @@ extern void NC_GetSysPopupPos( HWND hwnd, RECT* rect ) DECLSPEC_HIDDEN;
/* scrollbar */
-/* Scroll-bar hit testing */
-enum SCROLL_HITTEST
-{
- SCROLL_NOWHERE, /* Outside the scroll bar */
- SCROLL_TOP_ARROW, /* Top or left arrow */
- SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
- SCROLL_THUMB, /* Thumb rectangle */
- SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
- SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
-};
-
-/* Scroll bar tracking information */
-struct SCROLL_TRACKING_INFO
-{
- HWND win; /* Tracking window */
- INT bar; /* SB_HORZ / SB_VERT / SB_CTL */
- INT thumb_pos; /* Thumb position */
- INT thumb_val; /* Current thumb value from thumb position */
- BOOL vertical; /* Is scroll bar vertical */
- enum SCROLL_HITTEST hit_test; /* Hit Test code of the last button-down event */
-};
-
extern void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical ) DECLSPEC_HIDDEN;
extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test,
const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows,
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 7921bc3d45a..f5b4c6ab8a1 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -84,6 +84,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
static struct user_api_hook original_user_api =
{
USER_DefDlgProc,
+ USER_ScrollBarDraw,
USER_ScrollBarProc,
};
static struct user_api_hook hooked_user_api;
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c
index 9a22e930332..c4c06476b9c 100644
--- a/dlls/user32/scroll.c
+++ b/dlls/user32/scroll.c
@@ -567,10 +567,10 @@ static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, INT nBar,
SelectObject( hdc, hSaveBrush );
}
-static void SCROLL_DoDrawScrollBar( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test,
- const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows,
- BOOL interior, RECT *rect, INT arrowSize, INT thumbPos,
- INT thumbSize, BOOL vertical )
+void WINAPI USER_ScrollBarDraw( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test,
+ const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows,
+ BOOL interior, RECT *rect, INT arrowSize, INT thumbPos,
+ INT thumbSize, BOOL vertical )
{
SCROLLBAR_INFO *infoPtr;
@@ -678,8 +678,8 @@ void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT bar, enum SCROLL_HITTEST hit_
tracking_info->thumb_val, tracking_info->vertical, tracking_info->hit_test, draw_arrows,
draw_interior, wine_dbgstr_rect(&rect), arrow_size, thumb_pos, thumb_size, vertical,
GetCapture());
- SCROLL_DoDrawScrollBar( hwnd, hdc, bar, hit_test, tracking_info, draw_arrows, draw_interior,
- &rect, arrow_size, thumb_pos, thumb_size, vertical );
+ user_api->pScrollBarDraw( hwnd, hdc, bar, hit_test, tracking_info, draw_arrows, draw_interior,
+ &rect, arrow_size, thumb_pos, thumb_size, vertical );
}
void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BOOL draw_vertical )
@@ -764,6 +764,7 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
enum SCROLL_HITTEST hittest;
HWND hwndOwner, hwndCtl;
+ TRACKMOUSEEVENT tme;
BOOL vertical;
INT arrowSize, thumbSize, thumbPos;
RECT rect;
@@ -771,7 +772,8 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
SCROLLBAR_INFO *infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, FALSE );
if (!infoPtr) return;
- if ((g_tracking_info.hit_test == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN))
+ if ((g_tracking_info.hit_test == SCROLL_NOWHERE)
+ && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE))
return;
if (nBar == SB_CTL && (GetWindowLongW( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX)))
@@ -821,8 +823,29 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
break;
case WM_MOUSEMOVE:
- hittest = SCROLL_HitTest( hwnd, nBar, pt, TRUE );
+ hittest = SCROLL_HitTest( hwnd, nBar, pt, vertical == g_tracking_info.vertical && GetCapture() == hwnd );
prevPt = pt;
+
+ if (nBar != SB_CTL)
+ break;
+
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_QUERY;
+ TrackMouseEvent( &tme );
+ if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd)
+ {
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ TrackMouseEvent( &tme );
+ }
+
+ break;
+
+ case WM_MOUSELEAVE:
+ if (nBar != SB_CTL)
+ return;
+
+ hittest = SCROLL_NOWHERE;
break;
case WM_LBUTTONUP:
@@ -847,6 +870,8 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
switch (g_tracking_info.hit_test)
{
case SCROLL_NOWHERE: /* No tracking in progress */
+ if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE)
+ SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE );
break;
case SCROLL_TOP_ARROW:
@@ -898,7 +923,7 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
{
SCROLL_DrawScrollBar( hwnd, hdc, nBar, SCROLL_NOWHERE, &g_tracking_info, FALSE, TRUE );
}
- else /* WM_MOUSEMOVE */
+ else if (msg == WM_MOUSEMOVE)
{
INT pos;
@@ -986,6 +1011,8 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
/* Terminate tracking */
g_tracking_info.win = 0;
SCROLL_MovingThumb = FALSE;
+ hittest = SCROLL_NOWHERE;
+ SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE );
}
ReleaseDC( hwnd, hdc );
@@ -1021,6 +1048,7 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue;
if (msg.message == WM_LBUTTONUP ||
msg.message == WM_MOUSEMOVE ||
+ msg.message == WM_MOUSELEAVE ||
(msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER))
{
pt.x = (short)LOWORD(msg.lParam) - rect.left;
@@ -1356,6 +1384,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA
break;
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
+ case WM_MOUSELEAVE:
case WM_SYSTIMER:
{
POINT pt;
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 8750008a5fb..7c4d9015976 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -389,5 +389,8 @@ struct png_funcs
extern struct user_api_hook *user_api DECLSPEC_HIDDEN;
LRESULT WINAPI USER_DefDlgProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
+void WINAPI USER_ScrollBarDraw(HWND, HDC, INT, enum SCROLL_HITTEST,
+ const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, INT, INT,
+ INT, BOOL) DECLSPEC_HIDDEN;
#endif /* __WINE_USER_PRIVATE_H */
diff --git a/dlls/uxtheme/scrollbar.c b/dlls/uxtheme/scrollbar.c
index 393b45a831d..40fdbf4b89a 100644
--- a/dlls/uxtheme/scrollbar.c
+++ b/dlls/uxtheme/scrollbar.c
@@ -20,8 +20,6 @@
*/
#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
@@ -32,299 +30,27 @@
#include "vssym32.h"
#include "wine/debug.h"
-/* Minimum size of the thumb in pixels */
-#define SCROLL_MIN_THUMB 6
-
-/* Minimum size of the rectangle between the arrows */
-#define SCROLL_MIN_RECT 4
-
-enum SCROLL_HITTEST
-{
- SCROLL_NOWHERE, /* Outside the scroll bar */
- SCROLL_TOP_ARROW, /* Top or left arrow */
- SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
- SCROLL_THUMB, /* Thumb rectangle */
- SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
- SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
-};
-
-static HWND tracking_win = 0;
-static enum SCROLL_HITTEST tracking_hot_part = SCROLL_NOWHERE;
-
WINE_DEFAULT_DEBUG_CHANNEL(theme_scroll);
-static void calc_thumb_dimensions(unsigned int size, SCROLLINFO *si, unsigned int *thumbpos, unsigned int *thumbsize)
+void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTEST hit_test,
+ const struct SCROLL_TRACKING_INFO *tracking_info,
+ BOOL draw_arrows, BOOL draw_interior, RECT *rect, INT arrowsize,
+ INT thumbpos, INT thumbsize, BOOL vertical)
{
- if (size <= SCROLL_MIN_RECT)
- *thumbpos = *thumbsize = 0;
- else if (si->nPage > si->nMax - si->nMin)
- *thumbpos = *thumbsize = 0;
- else {
- if (si->nPage > 0) {
- *thumbsize = MulDiv(size, si->nPage, si->nMax - si->nMin + 1);
- if (*thumbsize < SCROLL_MIN_THUMB) *thumbsize = SCROLL_MIN_THUMB;
- }
- else *thumbsize = GetSystemMetrics(SM_CXVSCROLL);
-
- if (size < *thumbsize)
- *thumbpos = *thumbsize = 0;
- else {
- int max = si->nMax - max(si->nPage - 1, 0);
- size -= *thumbsize;
- if (si->nMin >= max)
- *thumbpos = 0;
- else
- *thumbpos = MulDiv(size, si->nTrackPos - si->nMin, max - si->nMin);
- }
- }
-}
-
-static enum SCROLL_HITTEST hit_test(HWND hwnd, HTHEME theme, POINT pt)
-{
- RECT r;
- DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
- BOOL vertical = style & SBS_VERT;
- SIZE sz;
- SCROLLINFO si;
- unsigned int offset, size, upsize, downsize, thumbpos, thumbsize;
-
- GetWindowRect(hwnd, &r);
- OffsetRect(&r, -r.left, -r.top);
-
- if (vertical) {
- offset = pt.y;
- size = r.bottom;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_UPNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get up arrow size.\n");
- upsize = 0;
- } else
- upsize = sz.cy;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_DOWNNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get down arrow size.\n");
- downsize = 0;
- } else
- downsize = sz.cy;
- } else {
- offset = pt.x;
- size = r.right;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_LEFTNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get left arrow size.\n");
- upsize = 0;
- } else
- upsize = sz.cx;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_RIGHTNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get right arrow size.\n");
- downsize = 0;
- } else
- downsize = sz.cx;
- }
-
- if (pt.x < 0 || pt.x > r.right || pt.y < 0 || pt.y > r.bottom)
- return SCROLL_NOWHERE;
-
- if (size < SCROLL_MIN_RECT + upsize + downsize)
- upsize = downsize = (size - SCROLL_MIN_RECT)/2;
-
- if (offset < upsize)
- return SCROLL_TOP_ARROW;
-
- if (offset > size - downsize)
- return SCROLL_BOTTOM_ARROW;
-
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_CTL, &si)) {
- WARN("GetScrollInfo failed.\n");
- return SCROLL_NOWHERE;
- }
-
- calc_thumb_dimensions(size - upsize - downsize, &si, &thumbpos, &thumbsize);
-
- if (offset < upsize + thumbpos)
- return SCROLL_TOP_RECT;
- else if (offset < upsize + thumbpos + thumbsize)
- return SCROLL_THUMB;
- else
- return SCROLL_BOTTOM_RECT;
-}
-
-static void redraw_part(HWND hwnd, HTHEME theme, enum SCROLL_HITTEST part)
-{
- DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
- BOOL vertical = style & SBS_VERT;
- SIZE sz;
- RECT r, partrect;
- unsigned int size, upsize, downsize;
-
- if (part == SCROLL_NOWHERE) { /* redraw everything */
- InvalidateRect(hwnd, NULL, TRUE);
- return;
- }
-
- GetWindowRect(hwnd, &r);
- OffsetRect(&r, -r.left, -r.top);
-
- if (vertical) {
- size = r.bottom;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_UPNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get up arrow size.\n");
- upsize = 0;
- } else
- upsize = sz.cy;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_DOWNNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get down arrow size.\n");
- downsize = 0;
- } else
- downsize = sz.cy;
- } else {
- size = r.right;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_LEFTNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get left arrow size.\n");
- upsize = 0;
- } else
- upsize = sz.cx;
-
- if (FAILED(GetThemePartSize(theme, NULL, SBP_ARROWBTN, ABS_RIGHTNORMAL, NULL, TS_DRAW, &sz))) {
- WARN("Could not get right arrow size.\n");
- downsize = 0;
- } else
- downsize = sz.cx;
- }
-
- if (size < SCROLL_MIN_RECT + upsize + downsize)
- upsize = downsize = (size - SCROLL_MIN_RECT)/2;
-
- partrect = r;
-
- if (part == SCROLL_TOP_ARROW) {
- if (vertical)
- partrect.bottom = partrect.top + upsize;
- else
- partrect.right = partrect.left + upsize;
- } else if (part == SCROLL_BOTTOM_ARROW) {
- if (vertical)
- partrect.top = partrect.bottom - downsize;
- else
- partrect.left = partrect.right - downsize;
- } else {
- unsigned int thumbpos, thumbsize;
- SCROLLINFO si;
-
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
- if (!GetScrollInfo(hwnd, SB_CTL, &si)) {
- WARN("GetScrollInfo failed.\n");
- return;
- }
-
- calc_thumb_dimensions(size - upsize - downsize, &si, &thumbpos, &thumbsize);
-
- if (part == SCROLL_TOP_RECT) {
- if (vertical) {
- partrect.top = r.top + upsize;
- partrect.bottom = partrect.top + thumbpos;
- } else {
- partrect.left = r.left + upsize;
- partrect.right = partrect.left + thumbpos;
- }
- } else if (part == SCROLL_THUMB) {
- if (vertical) {
- partrect.top = r.top + upsize + thumbpos;
- partrect.bottom = partrect.top + thumbsize;
- } else {
- partrect.left = r.left + upsize + thumbpos;
- partrect.right = partrect.left + thumbsize;
- }
- } else if (part == SCROLL_BOTTOM_RECT) {
- if (vertical) {
- partrect.top = r.top + upsize + thumbpos + thumbsize;
- partrect.bottom = r.bottom - downsize;
- } else {
- partrect.left = r.left + upsize + thumbpos + thumbsize;
- partrect.right = r.right - downsize;
- }
- }
- }
-
- InvalidateRect(hwnd, &partrect, TRUE);
-}
-
-static void scroll_event(HWND hwnd, HTHEME theme, UINT msg, POINT pt)
-{
- enum SCROLL_HITTEST hittest;
- TRACKMOUSEEVENT tme;
-
- if (GetWindowLongW(hwnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX))
- return;
-
- hittest = hit_test(hwnd, theme, pt);
-
- switch (msg)
- {
- case WM_MOUSEMOVE:
- hittest = hit_test(hwnd, theme, pt);
- tracking_win = hwnd;
- break;
-
- case WM_MOUSELEAVE:
- if (tracking_win == hwnd) {
- hittest = SCROLL_NOWHERE;
- }
- break;
- }
-
- tme.cbSize = sizeof(tme);
- tme.dwFlags = TME_QUERY;
- TrackMouseEvent(&tme);
-
- if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) {
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = hwnd;
- TrackMouseEvent(&tme);
- }
-
- if (tracking_win != hwnd && msg == WM_MOUSELEAVE) {
- redraw_part(hwnd, theme, SCROLL_NOWHERE);
- return;
- }
-
- if (tracking_win == hwnd && hittest != tracking_hot_part) {
- enum SCROLL_HITTEST oldhotpart = tracking_hot_part;
-
- tracking_hot_part = hittest;
-
- if (hittest != SCROLL_NOWHERE)
- redraw_part(hwnd, theme, hittest);
- else
- tracking_win = 0;
-
- if (oldhotpart != SCROLL_NOWHERE)
- redraw_part(hwnd, theme, oldhotpart);
- }
-}
-
-static void paint_scrollbar(HWND hwnd, HTHEME theme)
-{
- HDC dc;
- PAINTSTRUCT ps;
- RECT r;
- DWORD style = GetWindowLongW(hwnd, GWL_STYLE);
- BOOL vertical = style & SBS_VERT;
BOOL disabled = !IsWindowEnabled(hwnd);
+ HTHEME theme;
+ DWORD style;
- GetWindowRect(hwnd, &r);
- OffsetRect(&r, -r.left, -r.top);
+ theme = bar == SB_CTL ? GetWindowTheme(hwnd) : OpenThemeData(NULL, WC_SCROLLBARW);
+ if (!theme)
+ {
+ user_api.pScrollBarDraw(hwnd, dc, bar, hit_test, tracking_info, draw_arrows, draw_interior,
+ rect, arrowsize, thumbpos, thumbsize, vertical);
+ return;
+ }
- dc = BeginPaint(hwnd, &ps);
-
- if (style & SBS_SIZEBOX || style & SBS_SIZEGRIP) {
+ style = GetWindowLongW(hwnd, GWL_STYLE);
+ if (bar == SB_CTL && (style & SBS_SIZEBOX || style & SBS_SIZEGRIP)) {
int state;
if (style & SBS_SIZEBOXTOPLEFTALIGN)
@@ -334,20 +60,12 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
if (IsThemeBackgroundPartiallyTransparent(theme, SBP_SIZEBOX, state))
DrawThemeParentBackground(hwnd, dc, NULL);
- DrawThemeBackground(theme, dc, SBP_SIZEBOX, state, &r, NULL);
+ DrawThemeBackground(theme, dc, SBP_SIZEBOX, state, rect, NULL);
} else {
- SCROLLINFO si;
- unsigned int thumbpos, thumbsize;
int uppertrackstate, lowertrackstate, thumbstate;
- RECT partrect, trackrect;
+ RECT partrect;
SIZE grippersize;
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd, SB_CTL, &si);
-
- trackrect = r;
-
if (disabled) {
uppertrackstate = SCRBS_DISABLED;
lowertrackstate = SCRBS_DISABLED;
@@ -357,20 +75,18 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
lowertrackstate = SCRBS_NORMAL;
thumbstate = SCRBS_NORMAL;
- if (tracking_win == hwnd) {
- if (tracking_hot_part == SCROLL_TOP_RECT)
- uppertrackstate = SCRBS_HOT;
- else if (tracking_hot_part == SCROLL_BOTTOM_RECT)
- lowertrackstate = SCRBS_HOT;
- else if (tracking_hot_part == SCROLL_THUMB)
- thumbstate = SCRBS_HOT;
- }
+ if (hit_test == SCROLL_TOP_RECT)
+ uppertrackstate = SCRBS_HOT;
+ else if (hit_test == SCROLL_BOTTOM_RECT)
+ lowertrackstate = SCRBS_HOT;
+ else if (hit_test == SCROLL_THUMB)
+ thumbstate = SCRBS_HOT;
}
- DrawThemeParentBackground(hwnd, dc, NULL);
+ if (bar == SB_CTL)
+ DrawThemeParentBackground(hwnd, dc, NULL);
if (vertical) {
- SIZE upsize, downsize;
int uparrowstate, downarrowstate;
if (disabled) {
@@ -380,50 +96,29 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
uparrowstate = ABS_UPNORMAL;
downarrowstate = ABS_DOWNNORMAL;
- if (tracking_win == hwnd) {
- if (tracking_hot_part == SCROLL_TOP_ARROW)
- uparrowstate = ABS_UPHOT;
- else if (tracking_hot_part == SCROLL_BOTTOM_ARROW)
- downarrowstate = ABS_DOWNHOT;
- }
+ if (hit_test == SCROLL_TOP_ARROW)
+ uparrowstate = ABS_UPHOT;
+ else if (hit_test == SCROLL_BOTTOM_ARROW)
+ downarrowstate = ABS_DOWNHOT;
}
- if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, uparrowstate, NULL, TS_DRAW, &upsize))) {
- WARN("Could not get up arrow size.\n");
- return;
- }
-
- if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, downarrowstate, NULL, TS_DRAW, &downsize))) {
- WARN("Could not get down arrow size.\n");
- return;
- }
-
- if (r.bottom - r.top - upsize.cy - downsize.cy < SCROLL_MIN_RECT)
- upsize.cy = downsize.cy = (r.bottom - r.top - SCROLL_MIN_RECT)/2;
-
- partrect = r;
- partrect.bottom = partrect.top + upsize.cy;
+ partrect = *rect;
+ partrect.bottom = partrect.top + arrowsize;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, uparrowstate, &partrect, NULL);
- trackrect.top = partrect.bottom;
-
- partrect.bottom = r.bottom;
- partrect.top = partrect.bottom - downsize.cy;
+ partrect.bottom = rect->bottom;
+ partrect.top = partrect.bottom - arrowsize;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, downarrowstate, &partrect, NULL);
- trackrect.bottom = partrect.top;
-
- calc_thumb_dimensions(trackrect.bottom - trackrect.top, &si, &thumbpos, &thumbsize);
-
if (thumbpos > 0) {
- partrect.top = trackrect.top;
- partrect.bottom = partrect.top + thumbpos;
+ partrect.top = rect->top + arrowsize;
+ partrect.bottom = rect->top + thumbpos;
DrawThemeBackground(theme, dc, SBP_UPPERTRACKVERT, uppertrackstate, &partrect, NULL);
}
if (thumbsize > 0) {
- partrect.top = trackrect.top + thumbpos;
+ partrect.top = rect->top + thumbpos;
partrect.bottom = partrect.top + thumbsize;
DrawThemeBackground(theme, dc, SBP_THUMBBTNVERT, thumbstate, &partrect, NULL);
@@ -438,14 +133,14 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
}
}
- if (thumbpos + thumbsize < trackrect.bottom - trackrect.top) {
- partrect.bottom = trackrect.bottom;
- partrect.top = trackrect.top + thumbsize + thumbpos;
-
+ partrect.bottom = rect->bottom - arrowsize;
+ if (thumbsize > 0)
+ partrect.top = rect->top + thumbpos + thumbsize;
+ else
+ partrect.top = rect->top + arrowsize;
+ if (partrect.bottom > partrect.top)
DrawThemeBackground(theme, dc, SBP_LOWERTRACKVERT, lowertrackstate, &partrect, NULL);
- }
} else {
- SIZE leftsize, rightsize;
int leftarrowstate, rightarrowstate;
if (disabled) {
@@ -455,50 +150,29 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
leftarrowstate = ABS_LEFTNORMAL;
rightarrowstate = ABS_RIGHTNORMAL;
- if (tracking_win == hwnd) {
- if (tracking_hot_part == SCROLL_TOP_ARROW)
- leftarrowstate = ABS_LEFTHOT;
- else if (tracking_hot_part == SCROLL_BOTTOM_ARROW)
- rightarrowstate = ABS_RIGHTHOT;
- }
+ if (hit_test == SCROLL_TOP_ARROW)
+ leftarrowstate = ABS_LEFTHOT;
+ else if (hit_test == SCROLL_BOTTOM_ARROW)
+ rightarrowstate = ABS_RIGHTHOT;
}
- if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, leftarrowstate, NULL, TS_DRAW, &leftsize))) {
- WARN("Could not get left arrow size.\n");
- return;
- }
-
- if (FAILED(GetThemePartSize(theme, dc, SBP_ARROWBTN, rightarrowstate, NULL, TS_DRAW, &rightsize))) {
- WARN("Could not get right arrow size.\n");
- return;
- }
-
- if (r.right - r.left - leftsize.cx - rightsize.cx < SCROLL_MIN_RECT)
- leftsize.cx = rightsize.cx = (r.right - r.left - SCROLL_MIN_RECT)/2;
-
- partrect = r;
- partrect.right = partrect.left + leftsize.cx;
+ partrect = *rect;
+ partrect.right = partrect.left + arrowsize;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, leftarrowstate, &partrect, NULL);
- trackrect.left = partrect.right;
-
- partrect.right = r.right;
- partrect.left = partrect.right - rightsize.cx;
+ partrect.right = rect->right;
+ partrect.left = partrect.right - arrowsize;
DrawThemeBackground(theme, dc, SBP_ARROWBTN, rightarrowstate, &partrect, NULL);
- trackrect.right = partrect.left;
-
- calc_thumb_dimensions(trackrect.right - trackrect.left, &si, &thumbpos, &thumbsize);
-
if (thumbpos > 0) {
- partrect.left = trackrect.left;
- partrect.right = partrect.left + thumbpos;
+ partrect.left = rect->left + arrowsize;
+ partrect.right = rect->left + thumbpos;
DrawThemeBackground(theme, dc, SBP_UPPERTRACKHORZ, uppertrackstate, &partrect, NULL);
}
if (thumbsize > 0) {
- partrect.left = trackrect.left + thumbpos;
+ partrect.left = rect->left + thumbpos;
partrect.right = partrect.left + thumbsize;
DrawThemeBackground(theme, dc, SBP_THUMBBTNHORZ, thumbstate, &partrect, NULL);
@@ -513,16 +187,18 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
}
}
- if (thumbpos + thumbsize < trackrect.right - trackrect.left) {
- partrect.right = trackrect.right;
- partrect.left = trackrect.left + thumbsize + thumbpos;
-
+ partrect.right = rect->right - arrowsize;
+ if (thumbsize > 0)
+ partrect.left = rect->left + thumbpos + thumbsize;
+ else
+ partrect.left = rect->left + arrowsize;
+ if (partrect.right > partrect.left)
DrawThemeBackground(theme, dc, SBP_LOWERTRACKHORZ, lowertrackstate, &partrect, NULL);
- }
}
}
- EndPaint(hwnd, &ps);
+ if (bar != SB_CTL)
+ CloseThemeData(theme);
}
LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
@@ -531,7 +207,6 @@ LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
const WCHAR* themeClass = WC_SCROLLBARW;
HTHEME theme;
LRESULT result;
- POINT pt;
TRACE("(%p, 0x%x, %lu, %lu, %d)\n", hwnd, msg, wParam, lParam, unicode);
@@ -560,23 +235,6 @@ LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
* which will do the repaint. */
break;
- case WM_PAINT:
- theme = GetWindowTheme(hwnd);
- if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
-
- paint_scrollbar(hwnd, theme);
- break;
-
- case WM_MOUSEMOVE:
- case WM_MOUSELEAVE:
- theme = GetWindowTheme(hwnd);
- if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
-
- pt.x = (short)LOWORD(lParam);
- pt.y = (short)HIWORD(lParam);
- scroll_event(hwnd, theme, msg, pt);
- break;
-
default:
return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
}
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index 83eda58c460..afae1e23f2b 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -1230,6 +1230,7 @@ BOOL WINAPI ThemeHooksInstall(void)
struct user_api_hook hooks;
hooks.pDefDlgProc = UXTHEME_DefDlgProc;
+ hooks.pScrollBarDraw = UXTHEME_ScrollBarDraw;
hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
return RegisterUserApiHook(&hooks, &user_api);
}
diff --git a/dlls/uxtheme/uxthemedll.h b/dlls/uxtheme/uxthemedll.h
index 67932f22f88..4b8f95764d6 100644
--- a/dlls/uxtheme/uxthemedll.h
+++ b/dlls/uxtheme/uxthemedll.h
@@ -103,6 +103,10 @@ extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN;
extern struct user_api_hook user_api DECLSPEC_HIDDEN;
LRESULT WINAPI UXTHEME_DefDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode) DECLSPEC_HIDDEN;
+void WINAPI UXTHEME_ScrollBarDraw(HWND hwnd, HDC dc, INT bar, enum SCROLL_HITTEST hit_test,
+ const struct SCROLL_TRACKING_INFO *tracking_info,
+ BOOL draw_arrows, BOOL draw_interior, RECT *rect, INT arrowsize,
+ INT thumbpos, INT thumbsize, BOOL vertical) DECLSPEC_HIDDEN;
LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
BOOL unicode) DECLSPEC_HIDDEN;
diff --git a/include/winuser.h b/include/winuser.h
index 7a45198411c..072f435c08e 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -4409,9 +4409,35 @@ WORD WINAPI SYSTEM_KillSystemTimer( WORD );
WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput );
/* Uxtheme hook functions and struct */
+
+/* Scroll bar hit testing */
+enum SCROLL_HITTEST
+{
+ SCROLL_NOWHERE, /* Outside the scroll bar */
+ SCROLL_TOP_ARROW, /* Top or left arrow */
+ SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
+ SCROLL_THUMB, /* Thumb rectangle */
+ SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
+ SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
+};
+
+/* Scroll bar tracking information */
+struct SCROLL_TRACKING_INFO
+{
+ HWND win; /* Tracking window */
+ INT bar; /* SB_HORZ/SB_VERT/SB_CTL */
+ INT thumb_pos; /* Thumb position */
+ INT thumb_val; /* Current thumb value from thumb position */
+ BOOL vertical; /* Is scroll bar vertical */
+ enum SCROLL_HITTEST hit_test; /* Hit Test code of the last button-down event */
+};
+
struct user_api_hook
{
LRESULT (WINAPI *pDefDlgProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
+ void (WINAPI *pScrollBarDraw)(HWND, HDC, INT, enum SCROLL_HITTEST,
+ const struct SCROLL_TRACKING_INFO *, BOOL, BOOL, RECT *, INT, INT,
+ INT, BOOL);
LRESULT (WINAPI *pScrollBarWndProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
};
--
2.30.2
1
0
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51137
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/Makefile.in | 2 -
dlls/comctl32/comctl32.h | 4 -
dlls/comctl32/commctrl.c | 7 +-
dlls/comctl32/theming.c | 157 ------------------
dlls/user32/defdlg.c | 35 +++-
dlls/user32/hook.c | 1 +
dlls/user32/user_private.h | 1 +
dlls/uxtheme/Makefile.in | 1 +
.../theme_dialog.c => uxtheme/dialog.c} | 25 ++-
dlls/uxtheme/system.c | 1 +
dlls/uxtheme/uxthemedll.h | 1 +
include/winuser.h | 1 +
12 files changed, 45 insertions(+), 191 deletions(-)
delete mode 100644 dlls/comctl32/theming.c
rename dlls/{comctl32/theme_dialog.c => uxtheme/dialog.c} (81%)
diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in
index bd99d8f0276..63bfbf0892c 100644
--- a/dlls/comctl32/Makefile.in
+++ b/dlls/comctl32/Makefile.in
@@ -37,8 +37,6 @@ C_SRCS = \
syslink.c \
tab.c \
taskdialog.c \
- theme_dialog.c \
- theming.c \
toolbar.c \
tooltips.c \
trackbar.c \
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h
index 66b341ae5ad..44d3b43ab9b 100644
--- a/dlls/comctl32/comctl32.h
+++ b/dlls/comctl32/comctl32.h
@@ -280,8 +280,4 @@ int MONTHCAL_MonthLength(int month, int year) DECLSPEC_HIDDEN;
int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace) DECLSPEC_HIDDEN;
LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) DECLSPEC_HIDDEN;
-extern void THEMING_Initialize(void) DECLSPEC_HIDDEN;
-extern void THEMING_Uninitialize(void) DECLSPEC_HIDDEN;
-extern LRESULT THEMING_CallOriginalClass(HWND, UINT, WPARAM, LPARAM) DECLSPEC_HIDDEN;
-
#endif /* __WINE_COMCTL32_H */
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c
index cb9c22a3a88..1c7718e2400 100644
--- a/dlls/comctl32/commctrl.c
+++ b/dlls/comctl32/commctrl.c
@@ -72,6 +72,7 @@
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
#include "comctl32.h"
+#include "uxtheme.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
@@ -208,14 +209,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
TREEVIEW_Register ();
UPDOWN_Register ();
- /* subclass user32 controls */
- THEMING_Initialize ();
+ /* Call IsThemeActive() so that delay-loaded uxtheme.dll is loaded for hooking user32 */
+ IsThemeActive();
break;
case DLL_PROCESS_DETACH:
if (lpvReserved) break;
- /* clean up subclassing */
- THEMING_Uninitialize();
/* unregister all common control classes */
ANIMATE_Unregister ();
diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c
deleted file mode 100644
index c74bcfc36a2..00000000000
--- a/dlls/comctl32/theming.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Theming - Initialization
- *
- * Copyright (c) 2005 by Frank Richter
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "comctl32.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(theming);
-
-typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM,
- ULONG_PTR);
-
-extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
- ULONG_PTR) DECLSPEC_HIDDEN;
-
-static const WCHAR dialogClass[] = L"#32770";
-
-static const struct ThemingSubclass
-{
- const WCHAR* className;
- THEMING_SUBCLASSPROC subclassProc;
-} subclasses[] = {
- /* Note: list must be sorted by class name */
- {dialogClass, THEMING_DialogSubclassProc},
-};
-
-#define NUM_SUBCLASSES (ARRAY_SIZE(subclasses))
-
-static WNDPROC originalProcs[NUM_SUBCLASSES];
-static ATOM atRefDataProp;
-static ATOM atSubclassProp;
-
-/* Generate a number of subclass window procs.
- * With a single proc alone, we can't really reliably find out the superclass,
- * so have one for each subclass. The subclass number is also stored in a prop
- * since it's needed by THEMING_CallOriginalClass(). Then, the subclass
- * proc and ref data are fetched and the proc called.
- */
-#define MAKE_SUBCLASS_PROC(N) \
-static LRESULT CALLBACK subclass_proc ## N (HWND wnd, UINT msg, \
- WPARAM wParam, LPARAM lParam) \
-{ \
- LRESULT result; \
- ULONG_PTR refData; \
- SetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp), (HANDLE)N); \
- refData = (ULONG_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atRefDataProp)); \
- TRACE ("%d; (%p, %x, %lx, %lx, %lx)\n", N, wnd, msg, wParam, lParam, \
- refData); \
- result = subclasses[N].subclassProc (wnd, msg, wParam, lParam, refData);\
- TRACE ("result = %lx\n", result); \
- return result; \
-}
-
-MAKE_SUBCLASS_PROC(0)
-
-static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
- subclass_proc0,
-};
-
-/***********************************************************************
- * THEMING_Initialize
- *
- * Register classes for standard controls that will shadow the system
- * classes.
- */
-void THEMING_Initialize (void)
-{
- unsigned int i;
-
- atSubclassProp = GlobalAddAtomW (L"CC32ThemingSubCl");
- atRefDataProp = GlobalAddAtomW (L"CC32ThemingData");
-
- for (i = 0; i < NUM_SUBCLASSES; i++)
- {
- WNDCLASSEXW class;
-
- class.cbSize = sizeof(class);
- if (!GetClassInfoExW (NULL, subclasses[i].className, &class))
- {
- ERR("Could not retrieve information for class %s\n",
- debugstr_w (subclasses[i].className));
- continue;
- }
- originalProcs[i] = class.lpfnWndProc;
- class.lpfnWndProc = subclassProcs[i];
-
- if (!class.lpfnWndProc)
- {
- ERR("Missing proc for class %s\n",
- debugstr_w (subclasses[i].className));
- continue;
- }
-
- if (!RegisterClassExW (&class))
- {
- ERR("Could not re-register class %s: %x\n",
- debugstr_w (subclasses[i].className), GetLastError ());
- }
- else
- {
- TRACE("Re-registered class %s\n",
- debugstr_w (subclasses[i].className));
- }
- }
-}
-
-/***********************************************************************
- * THEMING_Uninitialize
- *
- * Unregister shadow classes for standard controls.
- */
-void THEMING_Uninitialize (void)
-{
- unsigned int i;
-
- if (!atSubclassProp) return; /* not initialized */
-
- for (i = 0; i < NUM_SUBCLASSES; i++)
- {
- UnregisterClassW (subclasses[i].className, NULL);
- }
-}
-
-/***********************************************************************
- * THEMING_CallOriginalClass
- *
- * Determines the original window proc and calls it.
- */
-LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- INT_PTR subclass = (INT_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp));
- WNDPROC oldProc = originalProcs[subclass];
- return CallWindowProcW (oldProc, wnd, msg, wParam, lParam);
-}
diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c
index 00a73c6b927..4f44a93cd49 100644
--- a/dlls/user32/defdlg.c
+++ b/dlls/user32/defdlg.c
@@ -354,10 +354,7 @@ out:
return dlgInfo;
}
-/***********************************************************************
- * DefDlgProcA (USER32.@)
- */
-LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+static LRESULT USER_DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
DIALOGINFO *dlgInfo;
DLGPROC dlgproc;
@@ -411,11 +408,7 @@ LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
}
-
-/***********************************************************************
- * DefDlgProcW (USER32.@)
- */
-LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+static LRESULT USER_DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
DIALOGINFO *dlgInfo;
DLGPROC dlgproc;
@@ -468,3 +461,27 @@ LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
}
+
+LRESULT WINAPI USER_DefDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
+{
+ if (unicode)
+ return USER_DefDlgProcW( hwnd, msg, wParam, lParam );
+ else
+ return USER_DefDlgProcA( hwnd, msg, wParam, lParam );
+}
+
+/***********************************************************************
+ * DefDlgProcA (USER32.@)
+ */
+LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ return user_api->pDefDlgProc( hwnd, msg, wParam, lParam, FALSE );
+}
+
+/***********************************************************************
+ * DefDlgProcW (USER32.@)
+ */
+LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
+{
+ return user_api->pDefDlgProc( hwnd, msg, wParam, lParam, TRUE );
+}
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 9a1d010525a..7921bc3d45a 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -83,6 +83,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
static struct user_api_hook original_user_api =
{
+ USER_DefDlgProc,
USER_ScrollBarProc,
};
static struct user_api_hook hooked_user_api;
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 1e3786c2b1e..8750008a5fb 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -387,6 +387,7 @@ struct png_funcs
#endif
extern struct user_api_hook *user_api DECLSPEC_HIDDEN;
+LRESULT WINAPI USER_DefDlgProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
#endif /* __WINE_USER_PRIVATE_H */
diff --git a/dlls/uxtheme/Makefile.in b/dlls/uxtheme/Makefile.in
index f252f423a97..d272e049cf9 100644
--- a/dlls/uxtheme/Makefile.in
+++ b/dlls/uxtheme/Makefile.in
@@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
buffer.c \
+ dialog.c \
draw.c \
main.c \
metric.c \
diff --git a/dlls/comctl32/theme_dialog.c b/dlls/uxtheme/dialog.c
similarity index 81%
rename from dlls/comctl32/theme_dialog.c
rename to dlls/uxtheme/dialog.c
index 0f7835ae32f..043346b24e2 100644
--- a/dlls/comctl32/theme_dialog.c
+++ b/dlls/uxtheme/dialog.c
@@ -28,16 +28,11 @@
#include "wingdi.h"
#include "winuser.h"
#include "uxtheme.h"
+#include "uxthemedll.h"
#include "vssym32.h"
-#include "comctl32.h"
#include "wine/debug.h"
-/**********************************************************************
- * The dialog subclass window proc.
- */
-LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
- WPARAM wParam, LPARAM lParam,
- ULONG_PTR dwRefData)
+LRESULT WINAPI UXTHEME_DefDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
{
HTHEME theme = GetWindowTheme ( hWnd );
static const WCHAR themeClass[] = L"Window";
@@ -48,7 +43,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
switch (msg)
{
case WM_CREATE:
- result = THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ result = user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
theme = OpenThemeData( hWnd, themeClass );
return result;
@@ -56,7 +51,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
CloseThemeData ( theme );
SetWindowTheme( hWnd, NULL, NULL );
OpenThemeData( hWnd, NULL );
- return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
case WM_THEMECHANGED:
CloseThemeData ( theme );
@@ -65,7 +60,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
return 0;
case WM_ERASEBKGND:
- if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ if (!doTheming) return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
{
RECT rc;
WNDPROC dlgp = (WNDPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC);
@@ -82,7 +77,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
DrawThemeBackground (theme, (HDC)wParam, WP_DIALOG, 0, &rc,
NULL);
#endif
- return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
else
/* We might have gotten a TAB theme class, so check if we can
* draw as a tab page. */
@@ -90,13 +85,13 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
DrawThemeBackground (theme, (HDC)wParam, TABP_BODY, 0, &rc,
NULL);
else
- return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
}
return 1;
}
case WM_CTLCOLORSTATIC:
- if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ if (!doTheming) return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
{
WNDPROC dlgp = (WNDPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC);
LRESULT result = CallWindowProcW(dlgp, hWnd, msg, wParam, lParam);
@@ -121,7 +116,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
return (LRESULT)GetStockObject (NULL_BRUSH);
}
else
- return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
}
return result;
@@ -129,7 +124,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
default:
/* Call old proc */
- return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
+ return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
}
return 0;
}
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index 84b5cbc5fbc..83eda58c460 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -1229,6 +1229,7 @@ BOOL WINAPI ThemeHooksInstall(void)
{
struct user_api_hook hooks;
+ hooks.pDefDlgProc = UXTHEME_DefDlgProc;
hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
return RegisterUserApiHook(&hooks, &user_api);
}
diff --git a/dlls/uxtheme/uxthemedll.h b/dlls/uxtheme/uxthemedll.h
index 7a085b8a3f1..67932f22f88 100644
--- a/dlls/uxtheme/uxthemedll.h
+++ b/dlls/uxtheme/uxthemedll.h
@@ -102,6 +102,7 @@ extern void UXTHEME_InitSystem(HINSTANCE hInst) DECLSPEC_HIDDEN;
extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN;
extern struct user_api_hook user_api DECLSPEC_HIDDEN;
+LRESULT WINAPI UXTHEME_DefDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode) DECLSPEC_HIDDEN;
LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
BOOL unicode) DECLSPEC_HIDDEN;
diff --git a/include/winuser.h b/include/winuser.h
index 36ca3881e97..7a45198411c 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -4411,6 +4411,7 @@ WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RA
/* Uxtheme hook functions and struct */
struct user_api_hook
{
+ LRESULT (WINAPI *pDefDlgProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
LRESULT (WINAPI *pScrollBarWndProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
};
--
2.30.2
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
v2: Supersede 209350~209355. Use undocumented Un/RegisterUserApiHook() instead of adding private wine exports.
dlls/comctl32/Makefile.in | 1 -
dlls/comctl32/theming.c | 5 ----
dlls/user32/hook.c | 28 +++++++++++++++++++
dlls/user32/scroll.c | 13 +++++----
dlls/user32/user32.spec | 4 +--
dlls/user32/user_private.h | 3 ++
dlls/uxtheme/Makefile.in | 1 +
.../theme_scrollbar.c => uxtheme/scrollbar.c} | 21 +++++++-------
dlls/uxtheme/system.c | 18 ++++++++++++
dlls/uxtheme/uxtheme.spec | 4 +--
dlls/uxtheme/uxthemedll.h | 8 ++++++
include/winuser.h | 9 ++++++
12 files changed, 89 insertions(+), 26 deletions(-)
rename dlls/{comctl32/theme_scrollbar.c => uxtheme/scrollbar.c} (95%)
diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in
index 4ea068ea731..bd99d8f0276 100644
--- a/dlls/comctl32/Makefile.in
+++ b/dlls/comctl32/Makefile.in
@@ -38,7 +38,6 @@ C_SRCS = \
tab.c \
taskdialog.c \
theme_dialog.c \
- theme_scrollbar.c \
theming.c \
toolbar.c \
tooltips.c \
diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c
index 8078e661b76..c74bcfc36a2 100644
--- a/dlls/comctl32/theming.c
+++ b/dlls/comctl32/theming.c
@@ -35,8 +35,6 @@ typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM,
extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
ULONG_PTR) DECLSPEC_HIDDEN;
-extern LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND, UINT, WPARAM, LPARAM,
- ULONG_PTR) DECLSPEC_HIDDEN;
static const WCHAR dialogClass[] = L"#32770";
@@ -47,7 +45,6 @@ static const struct ThemingSubclass
} subclasses[] = {
/* Note: list must be sorted by class name */
{dialogClass, THEMING_DialogSubclassProc},
- {WC_SCROLLBARW, THEMING_ScrollbarSubclassProc}
};
#define NUM_SUBCLASSES (ARRAY_SIZE(subclasses))
@@ -78,11 +75,9 @@ static LRESULT CALLBACK subclass_proc ## N (HWND wnd, UINT msg, \
}
MAKE_SUBCLASS_PROC(0)
-MAKE_SUBCLASS_PROC(1)
static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
subclass_proc0,
- subclass_proc1,
};
/***********************************************************************
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 4c6dbcf7202..9a1d010525a 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -81,6 +81,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(hook);
WINE_DECLARE_DEBUG_CHANNEL(relay);
+static struct user_api_hook original_user_api =
+{
+ USER_ScrollBarProc,
+};
+static struct user_api_hook hooked_user_api;
+struct user_api_hook *user_api = &original_user_api;
+
struct hook_info
{
INT id;
@@ -961,3 +968,24 @@ BOOL WINAPI IsWinEventHookInstalled(DWORD dwEvent)
WARN("(%d)-stub!\n", dwEvent);
return TRUE;
}
+
+/* Undocumented RegisterUserApiHook() */
+BOOL WINAPI RegisterUserApiHook(const struct user_api_hook *new, struct user_api_hook *old)
+{
+ if (!new)
+ return FALSE;
+
+ USER_Lock();
+ hooked_user_api = *new;
+ user_api = &hooked_user_api;
+ if (old)
+ *old = original_user_api;
+ USER_Unlock();
+ return TRUE;
+}
+
+/* Undocumented UnregisterUserApiHook() */
+void WINAPI UnregisterUserApiHook(void)
+{
+ InterlockedExchangePointer((void **)&user_api, &original_user_api);
+}
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c
index 5561509c50c..9a22e930332 100644
--- a/dlls/user32/scroll.c
+++ b/dlls/user32/scroll.c
@@ -1317,11 +1317,7 @@ static BOOL SCROLL_SetScrollRange(HWND hwnd, INT nBar, INT minVal, INT maxVal)
return TRUE;
}
-
-/***********************************************************************
- * ScrollBarWndProc_common
- */
-LRESULT ScrollBarWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode )
+LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode )
{
if (!IsWindow( hwnd )) return 0;
@@ -1496,6 +1492,13 @@ LRESULT ScrollBarWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
return 0;
}
+/***********************************************************************
+ * ScrollBarWndProc_common
+ */
+LRESULT ScrollBarWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
+{
+ return user_api->pScrollBarWndProc( hwnd, msg, wParam, lParam, unicode );
+}
/*************************************************************************
* SetScrollInfo (USER32.@)
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 391e304a063..8d3ac70210c 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -612,7 +612,7 @@
@ stdcall RegisterTasklist (long)
@ stdcall RegisterTouchHitTestingWindow(long long)
@ stdcall RegisterTouchWindow(long long)
-# @ stub RegisterUserApiHook
+@ stdcall RegisterUserApiHook(ptr ptr)
@ stdcall RegisterWindowMessageA(str)
@ stdcall RegisterWindowMessageW(wstr)
@ stdcall ReleaseCapture()
@@ -784,7 +784,7 @@
# @ stub UnregisterMessagePumpHook
@ stdcall UnregisterPowerSettingNotification(ptr)
@ stdcall UnregisterTouchWindow(long)
-# @ stub UnregisterUserApiHook
+@ stdcall UnregisterUserApiHook()
@ stdcall UpdateLayeredWindow(long long ptr ptr long ptr long ptr long)
@ stdcall UpdateLayeredWindowIndirect(long ptr)
@ stub UpdatePerUserSystemParameters
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 0838ba28b32..1e3786c2b1e 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -386,4 +386,7 @@ struct png_funcs
#define assert(expr) ((void)0)
#endif
+extern struct user_api_hook *user_api DECLSPEC_HIDDEN;
+LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
+
#endif /* __WINE_USER_PRIVATE_H */
diff --git a/dlls/uxtheme/Makefile.in b/dlls/uxtheme/Makefile.in
index 61817ee5468..f252f423a97 100644
--- a/dlls/uxtheme/Makefile.in
+++ b/dlls/uxtheme/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
metric.c \
msstyles.c \
property.c \
+ scrollbar.c \
stylemap.c \
system.c \
uxini.c
diff --git a/dlls/comctl32/theme_scrollbar.c b/dlls/uxtheme/scrollbar.c
similarity index 95%
rename from dlls/comctl32/theme_scrollbar.c
rename to dlls/uxtheme/scrollbar.c
index 7cc59bbd1e5..393b45a831d 100644
--- a/dlls/comctl32/theme_scrollbar.c
+++ b/dlls/uxtheme/scrollbar.c
@@ -28,8 +28,8 @@
#include "wingdi.h"
#include "winuser.h"
#include "uxtheme.h"
+#include "uxthemedll.h"
#include "vssym32.h"
-#include "comctl32.h"
#include "wine/debug.h"
/* Minimum size of the thumb in pixels */
@@ -525,27 +525,26 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
EndPaint(hwnd, &ps);
}
-LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
- WPARAM wParam, LPARAM lParam,
- ULONG_PTR dwRefData)
+LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
+ BOOL unicode)
{
const WCHAR* themeClass = WC_SCROLLBARW;
HTHEME theme;
LRESULT result;
POINT pt;
- TRACE("(%p, 0x%x, %lu, %lu, %lu)\n", hwnd, msg, wParam, lParam, dwRefData);
+ TRACE("(%p, 0x%x, %lu, %lu, %d)\n", hwnd, msg, wParam, lParam, unicode);
switch (msg) {
case WM_CREATE:
- result = THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+ result = user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
OpenThemeData(hwnd, themeClass);
return result;
case WM_DESTROY:
theme = GetWindowTheme(hwnd);
CloseThemeData(theme);
- return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+ return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
case WM_THEMECHANGED:
theme = GetWindowTheme(hwnd);
@@ -556,14 +555,14 @@ LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
case WM_SYSCOLORCHANGE:
theme = GetWindowTheme(hwnd);
- if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+ if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
/* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
* which will do the repaint. */
break;
case WM_PAINT:
theme = GetWindowTheme(hwnd);
- if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+ if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
paint_scrollbar(hwnd, theme);
break;
@@ -571,7 +570,7 @@ LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
theme = GetWindowTheme(hwnd);
- if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+ if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
@@ -579,7 +578,7 @@ LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
break;
default:
- return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+ return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
}
return 0;
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index dcd2a660042..84b5cbc5fbc 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -55,6 +55,8 @@ static WCHAR szCurrentTheme[MAX_PATH];
static WCHAR szCurrentColor[64];
static WCHAR szCurrentSize[64];
+struct user_api_hook user_api = {0};
+
/***********************************************************************/
static BOOL CALLBACK UXTHEME_broadcast_msg_enumchild (HWND hWnd, LPARAM msg)
@@ -507,10 +509,12 @@ void UXTHEME_InitSystem(HINSTANCE hInst)
atDialogThemeEnabled = GlobalAddAtomW(L"ux_dialogtheme");
UXTHEME_LoadTheme();
+ ThemeHooksInstall();
}
void UXTHEME_UninitSystem(void)
{
+ ThemeHooksRemove();
MSSTYLES_SetActiveTheme(NULL, FALSE);
GlobalDeleteAtom(atWindowTheme);
@@ -1220,3 +1224,17 @@ HRESULT WINAPI CheckThemeSignature(LPCWSTR pszThemeFileName)
MSSTYLES_CloseThemeFile(pt);
return S_OK;
}
+
+BOOL WINAPI ThemeHooksInstall(void)
+{
+ struct user_api_hook hooks;
+
+ hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
+ return RegisterUserApiHook(&hooks, &user_api);
+}
+
+BOOL WINAPI ThemeHooksRemove(void)
+{
+ UnregisterUserApiHook();
+ return TRUE;
+}
diff --git a/dlls/uxtheme/uxtheme.spec b/dlls/uxtheme/uxtheme.spec
index 632129b8104..22b1fc4ac3c 100644
--- a/dlls/uxtheme/uxtheme.spec
+++ b/dlls/uxtheme/uxtheme.spec
@@ -29,8 +29,8 @@
31 stub -noname InitUserTheme
32 stub -noname InitUserRegistry
33 stub -noname ReestablishServerConnection
-34 stub -noname ThemeHooksInstall
-35 stub -noname ThemeHooksRemove
+34 stdcall -noname ThemeHooksInstall()
+35 stdcall -noname ThemeHooksRemove()
36 stub -noname RefreshThemeForTS
43 stub -noname ClassicGetSystemMetrics
44 stub -noname ClassicSystemParametersInfoA
diff --git a/dlls/uxtheme/uxthemedll.h b/dlls/uxtheme/uxthemedll.h
index fdf529b422a..7a085b8a3f1 100644
--- a/dlls/uxtheme/uxthemedll.h
+++ b/dlls/uxtheme/uxthemedll.h
@@ -21,6 +21,8 @@
#ifndef __WINE_UXTHEMEDLL_H
#define __WINE_UXTHEMEDLL_H
+#include <winuser.h>
+
typedef HANDLE HTHEMEFILE;
/**********************************************************************
@@ -93,10 +95,16 @@ HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
DWORD dwSizeNum, PTHEMENAMES pszColorNames) DECLSPEC_HIDDEN;
HRESULT WINAPI ParseThemeIniFile(LPCWSTR pszIniFileName, LPWSTR pszUnknown,
ParseThemeIniFileProc callback, LPVOID lpData) DECLSPEC_HIDDEN;
+BOOL WINAPI ThemeHooksInstall(void) DECLSPEC_HIDDEN;
+BOOL WINAPI ThemeHooksRemove(void) DECLSPEC_HIDDEN;
extern void UXTHEME_InitSystem(HINSTANCE hInst) DECLSPEC_HIDDEN;
extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN;
+extern struct user_api_hook user_api DECLSPEC_HIDDEN;
+LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
+ BOOL unicode) DECLSPEC_HIDDEN;
+
/* No alpha blending */
#define ALPHABLEND_NONE 0
/* "Cheap" binary alpha blending - but possibly faster */
diff --git a/include/winuser.h b/include/winuser.h
index 0b1571c0a95..36ca3881e97 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -4407,6 +4407,15 @@ WORD WINAPI SYSTEM_KillSystemTimer( WORD );
#ifdef __WINESRC__
WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput );
+
+/* Uxtheme hook functions and struct */
+struct user_api_hook
+{
+ LRESULT (WINAPI *pScrollBarWndProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
+};
+
+BOOL WINAPI RegisterUserApiHook(const struct user_api_hook *new, struct user_api_hook *old);
+void WINAPI UnregisterUserApiHook(void);
#endif
#ifdef __cplusplus
--
2.30.2
1
0