[PATCH 1/2] comctl32: Switch to using a structure for extra storage.
Dmitry Timoshkov
dmitry at baikal.ru
Sat May 4 07:01:39 CDT 2019
These patches aim to fix the bug 47018.
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
dlls/comctl32/static.c | 92 ++++++++++++++++++++++++++++++++++--------
1 file changed, 76 insertions(+), 16 deletions(-)
diff --git a/dlls/comctl32/static.c b/dlls/comctl32/static.c
index 5cc02ced97..d08710c06f 100644
--- a/dlls/comctl32/static.c
+++ b/dlls/comctl32/static.c
@@ -36,6 +36,7 @@
#include "winuser.h"
#include "commctrl.h"
+#include "wine/heap.h"
#include "wine/debug.h"
#include "comctl32.h"
@@ -50,10 +51,16 @@ static void STATIC_PaintBitmapfn( HWND hwnd, HDC hdc, DWORD style );
static void STATIC_PaintEnhMetafn( HWND hwnd, HDC hdc, DWORD style );
static void STATIC_PaintEtchedfn( HWND hwnd, HDC hdc, DWORD style );
-/* offsets for GetWindowLong for static private information */
-#define HFONT_GWL_OFFSET 0
-#define HICON_GWL_OFFSET (sizeof(HFONT))
-#define STATIC_EXTRA_BYTES (HICON_GWL_OFFSET + sizeof(HICON))
+struct static_extra_info
+{
+ HFONT hfont;
+ union
+ {
+ HICON hicon;
+ HBITMAP hbitmap;
+ HENHMETAFILE hemf;
+ } image;
+};
typedef void (*pfPaint)( HWND hwnd, HDC hdc, DWORD style );
@@ -80,6 +87,18 @@ static const pfPaint staticPaintFunc[SS_TYPEMASK+1] =
STATIC_PaintEtchedfn, /* SS_ETCHEDFRAME */
};
+static struct static_extra_info *get_extra_ptr( HWND hwnd, BOOL force )
+{
+ struct static_extra_info *extra = (struct static_extra_info *)GetWindowLongPtrW( hwnd, 0 );
+ if (!extra && force)
+ {
+ extra = heap_alloc_zero( sizeof(*extra) );
+ if (extra)
+ SetWindowLongPtrW( hwnd, 0, (ULONG_PTR)extra );
+ }
+ return extra;
+}
+
static BOOL get_icon_size( HICON handle, SIZE *size )
{
ICONINFO info;
@@ -111,6 +130,7 @@ static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
{
HICON prevIcon;
SIZE size;
+ struct static_extra_info *extra;
if ((style & SS_TYPEMASK) != SS_ICON) return 0;
if (hicon && !get_icon_size( hicon, &size ))
@@ -118,7 +138,12 @@ static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
WARN("hicon != 0, but invalid\n");
return 0;
}
- prevIcon = (HICON)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hicon );
+
+ extra = get_extra_ptr( hwnd, TRUE );
+ if (!extra) return 0;
+
+ prevIcon = extra->image.hicon;
+ extra->image.hicon = hicon;
if (hicon && !(style & SS_CENTERIMAGE) && !(style & SS_REALSIZECONTROL))
{
/* Windows currently doesn't implement SS_RIGHTJUST */
@@ -146,6 +171,7 @@ static HICON STATIC_SetIcon( HWND hwnd, HICON hicon, DWORD style )
static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
{
HBITMAP hOldBitmap;
+ struct static_extra_info *extra;
if ((style & SS_TYPEMASK) != SS_BITMAP) return 0;
if (hBitmap && GetObjectType(hBitmap) != OBJ_BITMAP)
@@ -153,7 +179,12 @@ static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
WARN("hBitmap != 0, but it's not a bitmap\n");
return 0;
}
- hOldBitmap = (HBITMAP)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hBitmap );
+
+ extra = get_extra_ptr( hwnd, TRUE );
+ if (!extra) return 0;
+
+ hOldBitmap = extra->image.hbitmap;
+ extra->image.hbitmap = hBitmap;
if (hBitmap && !(style & SS_CENTERIMAGE) && !(style & SS_REALSIZECONTROL))
{
BITMAP bm;
@@ -183,13 +214,23 @@ static HBITMAP STATIC_SetBitmap( HWND hwnd, HBITMAP hBitmap, DWORD style )
*/
static HENHMETAFILE STATIC_SetEnhMetaFile( HWND hwnd, HENHMETAFILE hEnhMetaFile, DWORD style )
{
+ HENHMETAFILE old_hemf;
+ struct static_extra_info *extra;
+
if ((style & SS_TYPEMASK) != SS_ENHMETAFILE) return 0;
if (hEnhMetaFile && GetObjectType(hEnhMetaFile) != OBJ_ENHMETAFILE)
{
WARN("hEnhMetaFile != 0, but it's not an enhanced metafile\n");
return 0;
}
- return (HENHMETAFILE)SetWindowLongPtrW( hwnd, HICON_GWL_OFFSET, (LONG_PTR)hEnhMetaFile );
+
+ extra = get_extra_ptr( hwnd, TRUE );
+ if (!extra) return 0;
+
+ old_hemf = extra->image.hemf;
+ extra->image.hemf = hEnhMetaFile;
+
+ return old_hemf;
}
/***********************************************************************
@@ -200,6 +241,8 @@ static HENHMETAFILE STATIC_SetEnhMetaFile( HWND hwnd, HENHMETAFILE hEnhMetaFile,
*/
static HANDLE STATIC_GetImage( HWND hwnd, WPARAM wParam, DWORD style )
{
+ struct static_extra_info *extra;
+
switch (style & SS_TYPEMASK)
{
case SS_ICON:
@@ -215,7 +258,22 @@ static HANDLE STATIC_GetImage( HWND hwnd, WPARAM wParam, DWORD style )
default:
return NULL;
}
- return (HANDLE)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET );
+
+ extra = get_extra_ptr( hwnd, FALSE );
+ return extra ? extra->image.hbitmap : 0;
+}
+
+static void STATIC_SetFont( HWND hwnd, HFONT hfont )
+{
+ struct static_extra_info *extra = get_extra_ptr( hwnd, TRUE );
+ if (extra)
+ extra->hfont = hfont;
+}
+
+static HFONT STATIC_GetFont( HWND hwnd )
+{
+ struct static_extra_info *extra = get_extra_ptr( hwnd, FALSE );
+ return extra ? extra->hfont : 0;
}
/***********************************************************************
@@ -327,6 +385,8 @@ static LRESULT CALLBACK STATIC_WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam,
case WM_NCDESTROY:
if (style == SS_ICON)
{
+ struct static_extra_info *extra = get_extra_ptr( hwnd, FALSE );
+ heap_free( extra );
/*
* FIXME
* DestroyIcon32( STATIC_SetIcon( wndPtr, 0 ) );
@@ -423,14 +483,14 @@ static LRESULT CALLBACK STATIC_WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam,
case WM_SETFONT:
if (hasTextStyle( full_style ))
{
- SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, wParam );
+ STATIC_SetFont( hwnd, (HFONT)wParam );
if (LOWORD(lParam))
RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
}
break;
case WM_GETFONT:
- return GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
+ return (LRESULT)STATIC_GetFont( hwnd );
case WM_NCHITTEST:
if (full_style & SS_NOTIFY)
@@ -508,7 +568,7 @@ static void STATIC_PaintOwnerDrawfn( HWND hwnd, HDC hdc, DWORD style )
dis.itemData = 0;
GetClientRect( hwnd, &dis.rcItem );
- font = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
+ font = STATIC_GetFont( hwnd );
if (font) oldFont = SelectObject( hdc, font );
SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hwnd );
SendMessageW( GetParent(hwnd), WM_DRAWITEM, id, (LPARAM)&dis );
@@ -572,7 +632,7 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style )
format |= DT_SINGLELINE | DT_WORD_ELLIPSIS;
}
- if ((hFont = (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET )))
+ if ((hFont = STATIC_GetFont( hwnd )))
hOldFont = SelectObject( hdc, hFont );
/* SS_SIMPLE controls: WM_CTLCOLORSTATIC is sent, but the returned
@@ -668,7 +728,7 @@ static void STATIC_PaintIconfn( HWND hwnd, HDC hdc, DWORD style )
GetClientRect( hwnd, &rc );
hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
- hIcon = (HICON)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET );
+ hIcon = STATIC_GetImage( hwnd, IMAGE_ICON, style );
if (!hIcon || !get_icon_size( hIcon, &size ))
{
FillRect(hdc, &rc, hbrush);
@@ -698,7 +758,7 @@ static void STATIC_PaintBitmapfn(HWND hwnd, HDC hdc, DWORD style )
hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
- if ((hBitmap = (HBITMAP)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET ))
+ if ((hBitmap = STATIC_GetImage( hwnd, IMAGE_BITMAP, style ))
&& (GetObjectType(hBitmap) == OBJ_BITMAP)
&& (hMemDC = CreateCompatibleDC( hdc )))
{
@@ -742,7 +802,7 @@ static void STATIC_PaintEnhMetafn(HWND hwnd, HDC hdc, DWORD style )
GetClientRect(hwnd, &rc);
hbrush = STATIC_SendWmCtlColorStatic(hwnd, hdc);
FillRect(hdc, &rc, hbrush);
- if ((hEnhMetaFile = (HENHMETAFILE)GetWindowLongPtrW( hwnd, HICON_GWL_OFFSET )))
+ if ((hEnhMetaFile = STATIC_GetImage( hwnd, IMAGE_ENHMETAFILE, style )))
{
/* The control's current font is not selected into the
device context! */
@@ -779,7 +839,7 @@ void STATIC_Register(void)
wndClass.style = CS_DBLCLKS | CS_PARENTDC | CS_GLOBALCLASS;
wndClass.lpfnWndProc = STATIC_WindowProc;
wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = STATIC_EXTRA_BYTES;
+ wndClass.cbWndExtra = sizeof(struct static_extra_info *);
wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
wndClass.hbrBackground = NULL;
wndClass.lpszClassName = WC_STATICW;
--
2.20.1
More information about the wine-devel
mailing list