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
4c2c3eff
Commit
4c2c3eff
authored
Mar 30, 2010
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Pack the systray data structure to allow crossing 32/64 boundaries.
parent
3cd9f971
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
116 additions
and
64 deletions
+116
-64
systray.c
dlls/shell32/systray.c
+64
-27
systray.c
programs/explorer/systray.c
+52
-37
No files found.
dlls/shell32/systray.c
View file @
4c2c3eff
...
@@ -38,6 +38,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(systray);
...
@@ -38,6 +38,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(systray);
static
const
WCHAR
classname
[]
=
/* Shell_TrayWnd */
{
'S'
,
'h'
,
'e'
,
'l'
,
'l'
,
'_'
,
'T'
,
'r'
,
'a'
,
'y'
,
'W'
,
'n'
,
'd'
,
'\0'
};
static
const
WCHAR
classname
[]
=
/* Shell_TrayWnd */
{
'S'
,
'h'
,
'e'
,
'l'
,
'l'
,
'_'
,
'T'
,
'r'
,
'a'
,
'y'
,
'W'
,
'n'
,
'd'
,
'\0'
};
struct
notify_data
/* platform-independent format for NOTIFYICONDATA */
{
LONG
hWnd
;
UINT
uID
;
UINT
uFlags
;
UINT
uCallbackMessage
;
WCHAR
szTip
[
128
];
DWORD
dwState
;
DWORD
dwStateMask
;
WCHAR
szInfo
[
256
];
union
{
UINT
uTimeout
;
UINT
uVersion
;
}
u
;
WCHAR
szInfoTitle
[
64
];
DWORD
dwInfoFlags
;
GUID
guidItem
;
/* data for the icon bitmap */
UINT
width
;
UINT
height
;
UINT
planes
;
UINT
bpp
;
};
/*************************************************************************
/*************************************************************************
* Shell_NotifyIcon [SHELL32.296]
* Shell_NotifyIcon [SHELL32.296]
* Shell_NotifyIconA [SHELL32.297]
* Shell_NotifyIconA [SHELL32.297]
...
@@ -103,7 +127,8 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
...
@@ -103,7 +127,8 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
{
{
HWND
tray
;
HWND
tray
;
COPYDATASTRUCT
cds
;
COPYDATASTRUCT
cds
;
char
*
buffer
=
NULL
;
struct
notify_data
data_buffer
;
struct
notify_data
*
data
=
&
data_buffer
;
BOOL
ret
;
BOOL
ret
;
TRACE
(
"dwMessage = %d, nid->cbSize=%d
\n
"
,
dwMessage
,
nid
->
cbSize
);
TRACE
(
"dwMessage = %d, nid->cbSize=%d
\n
"
,
dwMessage
,
nid
->
cbSize
);
...
@@ -127,6 +152,8 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
...
@@ -127,6 +152,8 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
if
(
!
tray
)
return
FALSE
;
if
(
!
tray
)
return
FALSE
;
cds
.
dwData
=
dwMessage
;
cds
.
dwData
=
dwMessage
;
cds
.
cbData
=
sizeof
(
*
data
);
memset
(
data
,
0
,
sizeof
(
*
data
)
);
/* FIXME: if statement only needed because we don't support interprocess
/* FIXME: if statement only needed because we don't support interprocess
* icon handles */
* icon handles */
...
@@ -137,6 +164,7 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
...
@@ -137,6 +164,7 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
BITMAP
bmColour
;
BITMAP
bmColour
;
LONG
cbMaskBits
;
LONG
cbMaskBits
;
LONG
cbColourBits
;
LONG
cbColourBits
;
char
*
buffer
;
if
(
!
GetIconInfo
(
nid
->
hIcon
,
&
iconinfo
))
if
(
!
GetIconInfo
(
nid
->
hIcon
,
&
iconinfo
))
goto
noicon
;
goto
noicon
;
...
@@ -149,9 +177,9 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
...
@@ -149,9 +177,9 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
goto
noicon
;
goto
noicon
;
}
}
cbMaskBits
=
(
bmMask
.
bmPlanes
*
bmMask
.
bmWidth
*
bmMask
.
bmHeight
*
bmMask
.
bmBitsPixel
)
/
8
;
cbMaskBits
=
(
bmMask
.
bmPlanes
*
bmMask
.
bmWidth
*
bmMask
.
bmHeight
*
bmMask
.
bmBitsPixel
+
15
)
/
16
*
2
;
cbColourBits
=
(
bmColour
.
bmPlanes
*
bmColour
.
bmWidth
*
bmColour
.
bmHeight
*
bmColour
.
bmBitsPixel
)
/
8
;
cbColourBits
=
(
bmColour
.
bmPlanes
*
bmColour
.
bmWidth
*
bmColour
.
bmHeight
*
bmColour
.
bmBitsPixel
+
15
)
/
16
*
2
;
cds
.
cbData
=
nid
->
cbSize
+
2
*
sizeof
(
BITMAP
)
+
cbMaskBits
+
cbColourBits
;
cds
.
cbData
=
sizeof
(
*
data
)
+
cbMaskBits
+
cbColourBits
;
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
cds
.
cbData
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
cds
.
cbData
);
if
(
!
buffer
)
if
(
!
buffer
)
{
{
...
@@ -159,38 +187,47 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
...
@@ -159,38 +187,47 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
DeleteObject
(
iconinfo
.
hbmColor
);
DeleteObject
(
iconinfo
.
hbmColor
);
return
FALSE
;
return
FALSE
;
}
}
cds
.
lpData
=
buffer
;
data
=
(
struct
notify_data
*
)
buffer
;
mem
cpy
(
buffer
,
nid
,
nid
->
cbSize
);
mem
set
(
data
,
0
,
sizeof
(
*
data
)
);
buffer
+=
nid
->
cbSize
;
data
->
width
=
bmColour
.
bmWidth
;
memcpy
(
buffer
,
&
bmMask
,
sizeof
(
bmMask
))
;
data
->
height
=
bmColour
.
bmHeight
;
buffer
+=
sizeof
(
bmMask
)
;
data
->
planes
=
bmColour
.
bmPlanes
;
memcpy
(
buffer
,
&
bmColour
,
sizeof
(
bmColour
))
;
data
->
bpp
=
bmColour
.
bmBitsPixel
;
buffer
+=
sizeof
(
bmColour
);
buffer
+=
sizeof
(
*
data
);
GetBitmapBits
(
iconinfo
.
hbmMask
,
cbMaskBits
,
buffer
);
GetBitmapBits
(
iconinfo
.
hbmMask
,
cbMaskBits
,
buffer
);
buffer
+=
cbMaskBits
;
buffer
+=
cbMaskBits
;
GetBitmapBits
(
iconinfo
.
hbmColor
,
cbColourBits
,
buffer
);
GetBitmapBits
(
iconinfo
.
hbmColor
,
cbColourBits
,
buffer
);
/* Reset pointer to allocated block so it can be freed later.
* Note that cds.lpData cannot be passed to HeapFree since it
* points to nid when no icon info is found. */
buffer
=
cds
.
lpData
;
DeleteObject
(
iconinfo
.
hbmMask
);
DeleteObject
(
iconinfo
.
hbmMask
);
DeleteObject
(
iconinfo
.
hbmColor
);
DeleteObject
(
iconinfo
.
hbmColor
);
}
}
else
{
noicon:
noicon:
cds
.
cbData
=
nid
->
cbSize
;
data
->
hWnd
=
HandleToLong
(
nid
->
hWnd
);
cds
.
lpData
=
nid
;
data
->
uID
=
nid
->
uID
;
data
->
uFlags
=
nid
->
uFlags
;
if
(
data
->
uFlags
&
NIF_MESSAGE
)
data
->
uCallbackMessage
=
nid
->
uCallbackMessage
;
if
(
data
->
uFlags
&
NIF_TIP
)
lstrcpynW
(
data
->
szTip
,
nid
->
szTip
,
sizeof
(
data
->
szTip
)
/
sizeof
(
WCHAR
)
);
if
(
data
->
uFlags
&
NIF_STATE
)
{
data
->
dwState
=
nid
->
dwState
;
data
->
dwStateMask
=
nid
->
dwStateMask
;
}
if
(
data
->
uFlags
&
NIF_INFO
)
{
lstrcpynW
(
data
->
szInfo
,
nid
->
szInfo
,
sizeof
(
data
->
szInfo
)
/
sizeof
(
WCHAR
)
);
lstrcpynW
(
data
->
szInfoTitle
,
nid
->
szInfoTitle
,
sizeof
(
data
->
szInfoTitle
)
/
sizeof
(
WCHAR
)
);
data
->
u
.
uTimeout
=
nid
->
u
.
uTimeout
;
data
->
dwInfoFlags
=
nid
->
dwInfoFlags
;
}
}
if
(
data
->
uFlags
&
NIF_GUID
)
data
->
guidItem
=
nid
->
guidItem
;
/* FIXME: balloon icon */
cds
.
lpData
=
data
;
ret
=
SendMessageW
(
tray
,
WM_COPYDATA
,
(
WPARAM
)
nid
->
hWnd
,
(
LPARAM
)
&
cds
);
ret
=
SendMessageW
(
tray
,
WM_COPYDATA
,
(
WPARAM
)
nid
->
hWnd
,
(
LPARAM
)
&
cds
);
if
(
data
!=
&
data_buffer
)
HeapFree
(
GetProcessHeap
(),
0
,
data
);
/* FIXME: if statement only needed because we don't support interprocess
* icon handles */
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
return
ret
;
return
ret
;
}
}
programs/explorer/systray.c
View file @
4c2c3eff
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <assert.h>
#include <assert.h>
#define UNICODE
#define UNICODE
#define NONAMELESSUNION
#define _WIN32_IE 0x500
#define _WIN32_IE 0x500
#include <windows.h>
#include <windows.h>
#include <commctrl.h>
#include <commctrl.h>
...
@@ -35,6 +36,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(systray);
...
@@ -35,6 +36,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(systray);
#define IS_OPTION_FALSE(ch) \
#define IS_OPTION_FALSE(ch) \
((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
struct
notify_data
/* platform-independent format for NOTIFYICONDATA */
{
LONG
hWnd
;
UINT
uID
;
UINT
uFlags
;
UINT
uCallbackMessage
;
WCHAR
szTip
[
128
];
DWORD
dwState
;
DWORD
dwStateMask
;
WCHAR
szInfo
[
256
];
union
{
UINT
uTimeout
;
UINT
uVersion
;
}
u
;
WCHAR
szInfoTitle
[
64
];
DWORD
dwInfoFlags
;
GUID
guidItem
;
/* data for the icon bitmap */
UINT
width
;
UINT
height
;
UINT
planes
;
UINT
bpp
;
};
static
int
(
CDECL
*
wine_notify_icon
)(
DWORD
,
NOTIFYICONDATAW
*
);
static
int
(
CDECL
*
wine_notify_icon
)(
DWORD
,
NOTIFYICONDATAW
*
);
/* an individual systray icon, unpacked from the NOTIFYICONDATA and always in unicode */
/* an individual systray icon, unpacked from the NOTIFYICONDATA and always in unicode */
...
@@ -346,52 +371,46 @@ static void cleanup_destroyed_windows(void)
...
@@ -346,52 +371,46 @@ static void cleanup_destroyed_windows(void)
static
BOOL
handle_incoming
(
HWND
hwndSource
,
COPYDATASTRUCT
*
cds
)
static
BOOL
handle_incoming
(
HWND
hwndSource
,
COPYDATASTRUCT
*
cds
)
{
{
struct
icon
*
icon
=
NULL
;
struct
icon
*
icon
=
NULL
;
const
struct
notify_data
*
data
;
NOTIFYICONDATAW
nid
;
NOTIFYICONDATAW
nid
;
DWORD
cbSize
;
int
ret
=
FALSE
;
int
ret
=
FALSE
;
if
(
cds
->
cbData
<
NOTIFYICONDATAW_V1_SIZE
)
return
FALSE
;
if
(
cds
->
cbData
<
sizeof
(
*
data
))
return
FALSE
;
cbSize
=
((
PNOTIFYICONDATAW
)
cds
->
lpData
)
->
cbSize
;
data
=
cds
->
lpData
;
if
(
cbSize
<
NOTIFYICONDATAW_V1_SIZE
)
return
FALSE
;
nid
.
cbSize
=
sizeof
(
nid
);
ZeroMemory
(
&
nid
,
sizeof
(
nid
));
nid
.
hWnd
=
LongToHandle
(
data
->
hWnd
);
memcpy
(
&
nid
,
cds
->
lpData
,
min
(
sizeof
(
nid
),
cbSize
));
nid
.
uID
=
data
->
uID
;
nid
.
uFlags
=
data
->
uFlags
;
nid
.
uCallbackMessage
=
data
->
uCallbackMessage
;
nid
.
hIcon
=
0
;
nid
.
dwState
=
data
->
dwState
;
nid
.
dwStateMask
=
data
->
dwStateMask
;
nid
.
u
.
uTimeout
=
data
->
u
.
uTimeout
;
nid
.
dwInfoFlags
=
data
->
dwInfoFlags
;
nid
.
guidItem
=
data
->
guidItem
;
lstrcpyW
(
nid
.
szTip
,
data
->
szTip
);
lstrcpyW
(
nid
.
szInfo
,
data
->
szInfo
);
lstrcpyW
(
nid
.
szInfoTitle
,
data
->
szInfoTitle
);
nid
.
hBalloonIcon
=
0
;
/* FIXME: if statement only needed because we don't support interprocess
/* FIXME: if statement only needed because we don't support interprocess
* icon handles */
* icon handles */
if
((
nid
.
uFlags
&
NIF_ICON
)
&&
(
cds
->
cbData
>=
nid
.
cbSize
+
2
*
sizeof
(
BITMAP
)
))
if
((
nid
.
uFlags
&
NIF_ICON
)
&&
cds
->
cbData
>
sizeof
(
*
data
))
{
{
LONG
cbMaskBits
;
LONG
cbMaskBits
;
LONG
cbColourBits
;
LONG
cbColourBits
;
BITMAP
bmMask
;
const
char
*
buffer
=
(
const
char
*
)(
data
+
1
);
BITMAP
bmColour
;
const
char
*
buffer
=
cds
->
lpData
;
buffer
+=
nid
.
cbSize
;
cbMaskBits
=
(
data
->
width
*
data
->
height
+
15
)
/
16
*
2
;
cbColourBits
=
(
data
->
planes
*
data
->
width
*
data
->
height
*
data
->
bpp
+
15
)
/
16
*
2
;
memcpy
(
&
bmMask
,
buffer
,
sizeof
(
bmMask
));
if
(
cds
->
cbData
<
sizeof
(
*
data
)
+
cbMaskBits
+
cbColourBits
)
buffer
+=
sizeof
(
bmMask
);
memcpy
(
&
bmColour
,
buffer
,
sizeof
(
bmColour
));
buffer
+=
sizeof
(
bmColour
);
cbMaskBits
=
(
bmMask
.
bmPlanes
*
bmMask
.
bmWidth
*
bmMask
.
bmHeight
*
bmMask
.
bmBitsPixel
)
/
8
;
cbColourBits
=
(
bmColour
.
bmPlanes
*
bmColour
.
bmWidth
*
bmColour
.
bmHeight
*
bmColour
.
bmBitsPixel
)
/
8
;
if
(
cds
->
cbData
<
nid
.
cbSize
+
2
*
sizeof
(
BITMAP
)
+
cbMaskBits
+
cbColourBits
)
{
{
WINE_ERR
(
"buffer underflow
\n
"
);
WINE_ERR
(
"buffer underflow
\n
"
);
return
FALSE
;
return
FALSE
;
}
}
nid
.
hIcon
=
CreateIcon
(
NULL
,
data
->
width
,
data
->
height
,
data
->
planes
,
data
->
bpp
,
/* sanity check */
if
((
bmColour
.
bmWidth
!=
bmMask
.
bmWidth
)
||
(
bmColour
.
bmHeight
!=
bmMask
.
bmHeight
))
{
WINE_ERR
(
"colour and mask bitmaps aren't consistent
\n
"
);
return
FALSE
;
}
nid
.
hIcon
=
CreateIcon
(
NULL
,
bmColour
.
bmWidth
,
bmColour
.
bmHeight
,
bmColour
.
bmPlanes
,
bmColour
.
bmBitsPixel
,
buffer
,
buffer
+
cbMaskBits
);
buffer
,
buffer
+
cbMaskBits
);
}
}
...
@@ -400,7 +419,7 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds)
...
@@ -400,7 +419,7 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds)
{
{
if
(
wine_notify_icon
&&
((
ret
=
wine_notify_icon
(
cds
->
dwData
,
&
nid
))
!=
-
1
))
if
(
wine_notify_icon
&&
((
ret
=
wine_notify_icon
(
cds
->
dwData
,
&
nid
))
!=
-
1
))
{
{
if
(
nid
.
uFlags
&
NIF_ICON
)
DestroyIcon
(
nid
.
hIcon
);
if
(
nid
.
hIcon
)
DestroyIcon
(
nid
.
hIcon
);
return
ret
;
return
ret
;
}
}
ret
=
FALSE
;
ret
=
FALSE
;
...
@@ -422,11 +441,7 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds)
...
@@ -422,11 +441,7 @@ static BOOL handle_incoming(HWND hwndSource, COPYDATASTRUCT *cds)
break
;
break
;
}
}
/* FIXME: if statement only needed because we don't support interprocess
if
(
nid
.
hIcon
)
DestroyIcon
(
nid
.
hIcon
);
* icon handles */
if
(
nid
.
uFlags
&
NIF_ICON
)
DestroyIcon
(
nid
.
hIcon
);
return
ret
;
return
ret
;
}
}
...
...
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