Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f54570fd
Commit
f54570fd
authored
Apr 03, 2008
by
Jason Edmeades
Committed by
Alexandre Julliard
Apr 03, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
comctl32: Add basic custom draw support for tooltips.
parent
825baa23
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
229 additions
and
3 deletions
+229
-3
tooltips.c
dlls/comctl32/tests/tooltips.c
+173
-0
tooltips.c
dlls/comctl32/tooltips.c
+56
-3
No files found.
dlls/comctl32/tests/tooltips.c
View file @
f54570fd
/*
* Copyright 2005 Dmitry Timoshkov
* Copyright 2008 Jason Edmeades
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -60,9 +61,181 @@ static void test_create_tooltip(void)
DestroyWindow
(
parent
);
}
/* try to make sure pending X events have been processed before continuing */
static
void
flush_events
(
int
waitTime
)
{
MSG
msg
;
int
diff
=
waitTime
;
DWORD
time
=
GetTickCount
()
+
waitTime
;
while
(
diff
>
0
)
{
if
(
MsgWaitForMultipleObjects
(
0
,
NULL
,
FALSE
,
min
(
100
,
diff
),
QS_ALLEVENTS
)
==
WAIT_TIMEOUT
)
break
;
while
(
PeekMessage
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
))
DispatchMessage
(
&
msg
);
diff
=
time
-
GetTickCount
();
}
}
static
int
CD_Stages
;
static
LRESULT
CD_Result
;
static
HWND
g_hwnd
;
#define TEST_CDDS_PREPAINT 0x00000001
#define TEST_CDDS_POSTPAINT 0x00000002
#define TEST_CDDS_PREERASE 0x00000004
#define TEST_CDDS_POSTERASE 0x00000008
#define TEST_CDDS_ITEMPREPAINT 0x00000010
#define TEST_CDDS_ITEMPOSTPAINT 0x00000020
#define TEST_CDDS_ITEMPREERASE 0x00000040
#define TEST_CDDS_ITEMPOSTERASE 0x00000080
#define TEST_CDDS_SUBITEM 0x00000100
static
LRESULT
CALLBACK
CustomDrawWndProc
(
HWND
hWnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
switch
(
msg
)
{
case
WM_DESTROY
:
PostQuitMessage
(
0
);
break
;
case
WM_NOTIFY
:
if
(((
NMHDR
*
)
lParam
)
->
code
==
NM_CUSTOMDRAW
)
{
NMTTCUSTOMDRAW
*
ttcd
=
(
NMTTCUSTOMDRAW
*
)
lParam
;
ok
(
ttcd
->
nmcd
.
hdr
.
hwndFrom
==
g_hwnd
,
"Unexpected hwnd source %x (%x)
\n
"
,
(
int
)
ttcd
->
nmcd
.
hdr
.
hwndFrom
,
(
int
)
g_hwnd
);
ok
(
ttcd
->
nmcd
.
hdr
.
idFrom
==
0x1234ABCD
,
"Unexpected id %x
\n
"
,
(
int
)
ttcd
->
nmcd
.
hdr
.
idFrom
);
switch
(
ttcd
->
nmcd
.
dwDrawStage
)
{
case
CDDS_PREPAINT
:
CD_Stages
|=
TEST_CDDS_PREPAINT
;
break
;
case
CDDS_POSTPAINT
:
CD_Stages
|=
TEST_CDDS_POSTPAINT
;
break
;
case
CDDS_PREERASE
:
CD_Stages
|=
TEST_CDDS_PREERASE
;
break
;
case
CDDS_POSTERASE
:
CD_Stages
|=
TEST_CDDS_POSTERASE
;
break
;
case
CDDS_ITEMPREPAINT
:
CD_Stages
|=
TEST_CDDS_ITEMPREPAINT
;
break
;
case
CDDS_ITEMPOSTPAINT
:
CD_Stages
|=
TEST_CDDS_ITEMPOSTPAINT
;
break
;
case
CDDS_ITEMPREERASE
:
CD_Stages
|=
TEST_CDDS_ITEMPREERASE
;
break
;
case
CDDS_ITEMPOSTERASE
:
CD_Stages
|=
TEST_CDDS_ITEMPOSTERASE
;
break
;
case
CDDS_SUBITEM
:
CD_Stages
|=
TEST_CDDS_SUBITEM
;
break
;
default:
CD_Stages
=
-
1
;
}
if
(
ttcd
->
nmcd
.
dwDrawStage
==
CDDS_PREPAINT
)
return
CD_Result
;
}
/* drop through */
default:
return
DefWindowProcA
(
hWnd
,
msg
,
wParam
,
lParam
);
}
return
0L
;
}
static
void
test_customdraw
(
void
)
{
static
struct
{
LRESULT
FirstReturnValue
;
int
ExpectedCalls
;
}
expectedResults
[]
=
{
/* Valid notification responses */
{
CDRF_DODEFAULT
,
TEST_CDDS_PREPAINT
},
{
CDRF_SKIPDEFAULT
,
TEST_CDDS_PREPAINT
},
{
CDRF_NOTIFYPOSTPAINT
,
TEST_CDDS_PREPAINT
|
TEST_CDDS_POSTPAINT
},
/* Invalid notification responses */
{
CDRF_NOTIFYITEMDRAW
,
TEST_CDDS_PREPAINT
},
{
CDRF_NOTIFYPOSTERASE
,
TEST_CDDS_PREPAINT
},
{
CDRF_NOTIFYSUBITEMDRAW
,
TEST_CDDS_PREPAINT
},
{
CDRF_NEWFONT
,
TEST_CDDS_PREPAINT
}
};
int
iterationNumber
;
WNDCLASSA
wc
;
LRESULT
lResult
;
/* Create a class to use the custom draw wndproc */
wc
.
style
=
CS_HREDRAW
|
CS_VREDRAW
;
wc
.
cbClsExtra
=
0
;
wc
.
cbWndExtra
=
0
;
wc
.
hInstance
=
GetModuleHandleA
(
NULL
);
wc
.
hIcon
=
NULL
;
wc
.
hCursor
=
LoadCursorA
(
NULL
,
IDC_ARROW
);
wc
.
hbrBackground
=
GetSysColorBrush
(
COLOR_WINDOW
);
wc
.
lpszMenuName
=
NULL
;
wc
.
lpszClassName
=
"CustomDrawClass"
;
wc
.
lpfnWndProc
=
CustomDrawWndProc
;
RegisterClass
(
&
wc
);
for
(
iterationNumber
=
0
;
iterationNumber
<
sizeof
(
expectedResults
)
/
sizeof
(
expectedResults
[
0
]);
iterationNumber
++
)
{
HWND
parent
,
hwndTip
;
TOOLINFO
toolInfo
=
{
0
};
/* Create a main window */
parent
=
CreateWindowEx
(
0
,
"CustomDrawClass"
,
NULL
,
WS_CAPTION
|
WS_SYSMENU
|
WS_MINIMIZEBOX
|
WS_MAXIMIZEBOX
|
WS_VISIBLE
,
50
,
50
,
300
,
300
,
NULL
,
NULL
,
NULL
,
0
);
ok
(
parent
!=
NULL
,
"Creation of main window failed
\n
"
);
/* Make it show */
ShowWindow
(
parent
,
SW_SHOWNORMAL
);
flush_events
(
100
);
/* Create Tooltip */
hwndTip
=
CreateWindowEx
(
WS_EX_TOPMOST
,
TOOLTIPS_CLASS
,
NULL
,
TTS_NOPREFIX
|
TTS_ALWAYSTIP
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
parent
,
NULL
,
GetModuleHandleA
(
NULL
),
0
);
ok
(
hwndTip
!=
NULL
,
"Creation of tooltip window failed
\n
"
);
/* Set up parms for the wndproc to handle */
CD_Stages
=
0
;
CD_Result
=
expectedResults
[
iterationNumber
].
FirstReturnValue
;
g_hwnd
=
hwndTip
;
/* Make it topmost, as per the MSDN */
SetWindowPos
(
hwndTip
,
HWND_TOPMOST
,
0
,
0
,
0
,
0
,
SWP_NOMOVE
|
SWP_NOSIZE
|
SWP_NOACTIVATE
);
/* Create a tool */
toolInfo
.
cbSize
=
sizeof
(
TOOLINFO
);
toolInfo
.
hwnd
=
parent
;
toolInfo
.
hinst
=
GetModuleHandleA
(
NULL
);
toolInfo
.
uFlags
=
TTF_SUBCLASS
;
toolInfo
.
uId
=
(
UINT_PTR
)
0x1234ABCD
;
toolInfo
.
lpszText
=
(
LPSTR
)
"This is a test tooltip"
;
toolInfo
.
lParam
=
0xdeadbeef
;
GetClientRect
(
parent
,
&
toolInfo
.
rect
);
lResult
=
SendMessage
(
hwndTip
,
TTM_ADDTOOL
,
0
,
(
LPARAM
)
&
toolInfo
);
ok
(
lResult
,
"Adding the tool to the tooltip failed
\n
"
);
/* Make tooltip appear quickly */
SendMessage
(
hwndTip
,
TTM_SETDELAYTIME
,
(
WPARAM
)
TTDT_INITIAL
,
(
LPARAM
)
MAKELONG
(
1
,
0
));
/* Put cursor inside window, tooltip will appear immediately */
SetCursorPos
(
100
,
100
);
flush_events
(
200
);
/* Check CustomDraw results */
ok
(
CD_Stages
==
expectedResults
[
iterationNumber
].
ExpectedCalls
,
"CustomDraw run %d stages %x, expected %x
\n
"
,
iterationNumber
,
CD_Stages
,
expectedResults
[
iterationNumber
].
ExpectedCalls
);
/* Clean up */
DestroyWindow
(
hwndTip
);
DestroyWindow
(
parent
);
}
}
START_TEST
(
tooltips
)
{
InitCommonControls
();
test_create_tooltip
();
test_customdraw
();
}
dlls/comctl32/tooltips.c
View file @
f54570fd
...
...
@@ -202,6 +202,44 @@ TOOLTIPS_InitSystemSettings (TOOLTIPS_INFO *infoPtr)
infoPtr
->
hTitleFont
=
CreateFontIndirectW
(
&
nclm
.
lfStatusFont
);
}
/* Custom draw routines */
static
void
TOOLTIPS_customdraw_fill
(
NMTTCUSTOMDRAW
*
lpnmttcd
,
const
HWND
hwnd
,
HDC
hdc
,
const
RECT
*
rcBounds
,
UINT
uFlags
)
{
TOOLTIPS_INFO
*
infoPtr
=
TOOLTIPS_GetInfoPtr
(
hwnd
);
ZeroMemory
(
lpnmttcd
,
sizeof
(
NMTTCUSTOMDRAW
));
lpnmttcd
->
uDrawFlags
=
uFlags
;
lpnmttcd
->
nmcd
.
hdr
.
hwndFrom
=
hwnd
;
lpnmttcd
->
nmcd
.
hdr
.
code
=
NM_CUSTOMDRAW
;
if
(
infoPtr
->
nCurrentTool
!=
-
1
)
{
TTTOOL_INFO
*
toolPtr
=
&
infoPtr
->
tools
[
infoPtr
->
nCurrentTool
];
lpnmttcd
->
nmcd
.
hdr
.
idFrom
=
toolPtr
->
uId
;
}
lpnmttcd
->
nmcd
.
hdc
=
hdc
;
lpnmttcd
->
nmcd
.
rc
=
*
rcBounds
;
/* FIXME - dwItemSpec, uItemState, lItemlParam */
}
static
inline
DWORD
TOOLTIPS_notify_customdraw
(
DWORD
dwDrawStage
,
NMTTCUSTOMDRAW
*
lpnmttcd
)
{
LRESULT
result
=
CDRF_DODEFAULT
;
lpnmttcd
->
nmcd
.
dwDrawStage
=
dwDrawStage
;
TRACE
(
"Notifying stage %d, flags %x, id %x
\n
"
,
lpnmttcd
->
nmcd
.
dwDrawStage
,
lpnmttcd
->
uDrawFlags
,
lpnmttcd
->
nmcd
.
hdr
.
code
);
result
=
SendMessageW
(
GetParent
(
lpnmttcd
->
nmcd
.
hdr
.
hwndFrom
),
WM_NOTIFY
,
0
,
(
LPARAM
)
lpnmttcd
);
TRACE
(
"Notify result %x
\n
"
,
(
unsigned
int
)
result
);
return
result
;
}
static
void
TOOLTIPS_Refresh
(
HWND
hwnd
,
HDC
hdc
)
{
...
...
@@ -213,6 +251,8 @@ TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
UINT
uFlags
=
DT_EXTERNALLEADING
;
HRGN
hRgn
=
NULL
;
DWORD
dwStyle
=
GetWindowLongW
(
hwnd
,
GWL_STYLE
);
NMTTCUSTOMDRAW
nmttcd
;
DWORD
cdmode
;
if
(
infoPtr
->
nMaxTipWidth
>
-
1
)
uFlags
|=
DT_WORDBREAK
;
...
...
@@ -224,6 +264,13 @@ TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
oldBkMode
=
SetBkMode
(
hdc
,
TRANSPARENT
);
SetTextColor
(
hdc
,
infoPtr
->
clrText
);
hOldFont
=
SelectObject
(
hdc
,
infoPtr
->
hFont
);
/* Custom draw - Call PrePaint once initial properties set up */
/* Note: Contrary to MSDN, CDRF_SKIPDEFAULT still draws a tooltip */
TOOLTIPS_customdraw_fill
(
&
nmttcd
,
hwnd
,
hdc
,
&
rc
,
uFlags
);
cdmode
=
TOOLTIPS_notify_customdraw
(
CDDS_PREPAINT
,
&
nmttcd
);
uFlags
=
nmttcd
.
uDrawFlags
;
if
(
dwStyle
&
TTS_BALLOON
)
{
...
...
@@ -259,6 +306,7 @@ TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
RECT
rcTitle
=
{
rc
.
left
,
rc
.
top
,
rc
.
right
,
rc
.
bottom
};
int
height
;
BOOL
icon_present
;
HFONT
prevFont
;
/* draw icon */
icon_present
=
infoPtr
->
hTitleIcon
&&
...
...
@@ -270,9 +318,9 @@ TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
rcTitle
.
bottom
=
rc
.
top
+
ICON_HEIGHT
;
/* draw title text */
hOld
Font
=
SelectObject
(
hdc
,
infoPtr
->
hTitleFont
);
prev
Font
=
SelectObject
(
hdc
,
infoPtr
->
hTitleFont
);
height
=
DrawTextW
(
hdc
,
infoPtr
->
pszTitle
,
-
1
,
&
rcTitle
,
DT_BOTTOM
|
DT_SINGLELINE
|
DT_NOPREFIX
);
SelectObject
(
hdc
,
hOld
Font
);
SelectObject
(
hdc
,
prev
Font
);
rc
.
top
+=
height
+
BALLOON_TITLE_TEXT_SPACING
;
}
}
...
...
@@ -286,8 +334,13 @@ TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
}
/* draw text */
hOldFont
=
SelectObject
(
hdc
,
infoPtr
->
hFont
);
DrawTextW
(
hdc
,
infoPtr
->
szTipText
,
-
1
,
&
rc
,
uFlags
);
/* Custom draw - Call PostPaint after drawing */
if
(
cdmode
&
CDRF_NOTIFYPOSTPAINT
)
{
TOOLTIPS_notify_customdraw
(
CDDS_POSTPAINT
,
&
nmttcd
);
}
/* be polite and reset the things we changed in the dc */
SelectObject
(
hdc
,
hOldFont
);
SetBkMode
(
hdc
,
oldBkMode
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment