关于 NOTIFYICONDATA 的 cbSize 成员的 MSDN 文档
我正在阅读 MSDN 中的 NOTIFYICONDATA 文档。
它说NOTIFYICONDATA结构有一个cbSize成员应该设置为该结构的大小,但是NOTIFYICONDATA结构的大小在每个Shell32.dll中都有不同的大小,因此在设置cbSize之前应该获取Shell32.dll的版本。
以下引用自MSDN:
如果是5.0以上版本,则按如下方式初始化cbSize成员。
nid.cbSize = sizeof(NOTIFYICONDATA);
将 cbSize 设置为此值可启用所有版本 5.0 和 6.0 增强功能。 对于早期版本,6.0 之前的结构的大小由 NOTIFYICONDATA_V2_SIZE 常量给出,5.0 之前的结构由 NOTIFYICONDATA_V1_SIZE 常量给出。 按如下方式初始化 cbSize 成员。 nid.cbSize = NOTIFYICONDATA_V2_SIZE;
使用 cbSize 的此值将允许您的应用程序将 NOTIFYICONDATA 与早期的 Shell32.dll 版本一起使用,尽管没有 6.0 版增强功能。
我发现它有点模糊,因为“sizeof(NOTIFYICONDATA)”在Win98(使用Shell32.dll版本4.x)、Win2K(版本5.0)和WinXP(版本6.0)中具有不同的值。 它如何“启用所有版本 5.0 和 6.0 增强功能”?
所以我查找了NOTIFYICONDATA_V1_SIZE的定义(源代码如下),我看到:
NOTIFYICONDATA_V1_SIZE适用于Win 2K(不包括2K)
NOTIFYICONDATA_V2_SIZE适用于Win XP
NOTIFYICONDATA_V3_SIZE适用于Vista
(不确定我是否正确)
这是完全不同的从MSDN说的? Win2K 没有吗?
所以,我现在完全困惑了。 如何根据Shell32.dll版本设置cbSize成员?
//= = = = = = = = ShellAPI.h = = = = = = = =
typedef struct _NOTIFYICONDATAA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (NTDDI_VERSION < NTDDI_WIN2K)
CHAR szTip[64];
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
CHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion; // used with NIM_SETVERSION, values 0, 3 and 4
} DUMMYUNIONNAME;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
GUID guidItem;
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
HICON hBalloonIcon;
#endif
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
typedef struct _NOTIFYICONDATAW {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (NTDDI_VERSION < NTDDI_WIN2K)
WCHAR szTip[64];
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
WCHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
WCHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion; // used with NIM_SETVERSION, values 0, 3 and 4
} DUMMYUNIONNAME;
WCHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
GUID guidItem;
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
HICON hBalloonIcon;
#endif
} NOTIFYICONDATAW, *PNOTIFYICONDATAW;
#define NOTIFYICONDATAA_V1_SIZE FIELD_OFFSET(NOTIFYICONDATAA, szTip[64])
#define NOTIFYICONDATAW_V1_SIZE FIELD_OFFSET(NOTIFYICONDATAW, szTip[64])
#ifdef UNICODE
#define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAW_V1_SIZE
#else
#define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAA_V1_SIZE
#endif
#define NOTIFYICONDATAA_V2_SIZE FIELD_OFFSET(NOTIFYICONDATAA, guidItem)
#define NOTIFYICONDATAW_V2_SIZE FIELD_OFFSET(NOTIFYICONDATAW, guidItem)
#ifdef UNICODE
#define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAW_V2_SIZE
#else
#define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAA_V2_SIZE
#endif
#define NOTIFYICONDATAA_V3_SIZE FIELD_OFFSET(NOTIFYICONDATAA, hBalloonIcon)
#define NOTIFYICONDATAW_V3_SIZE FIELD_OFFSET(NOTIFYICONDATAW, hBalloonIcon)
#ifdef UNICODE
#define NOTIFYICONDATA_V3_SIZE NOTIFYICONDATAW_V3_SIZE
#else
#define NOTIFYICONDATA_V3_SIZE NOTIFYICONDATAA_V3_SIZE
#endif
(看起来代码在网站上看起来不太好,但它来自 ShellAPI.h,都一样)
I am reading the NOTIFYICONDATA documentation in MSDN.
It says the NOTIFYICONDATA structure has a cbSize member should be set to the size of the structure, but NOTIFYICONDATA structure's size has different size in every Shell32.dll, so you should get the Shell32.dll version before setting cbSize.
The following quotes from MSDN:
If it is version 5.0 or later, initialize the cbSize member as follows.
nid.cbSize = sizeof(NOTIFYICONDATA);
Setting cbSize to this value enables all the version 5.0 and 6.0 enhancements. For earlier versions, the size of the pre-6.0 structure is given by the NOTIFYICONDATA_V2_SIZE constant and the pre-5.0 structure is given by the NOTIFYICONDATA_V1_SIZE constant. Initialize the cbSize member as follows.
nid.cbSize = NOTIFYICONDATA_V2_SIZE;
Using this value for cbSize will allow your application to use NOTIFYICONDATA with earlier Shell32.dll versions, although without the version 6.0 enhancements.
I found it a bit of vague, because 'sizeof(NOTIFYICONDATA)' has different value in Win98 (using Shell32.dll version 4.x), Win2K (version 5.0) and WinXP (version 6.0). How could it 'enable all version 5.0 and 6.0 enhancements'?
So I looked for the definition of NOTIFYICONDATA_V1_SIZE (source code as below), I see:
NOTIFYICONDATA_V1_SIZE is for Win 2K (doesn't include 2K)
NOTIFYICONDATA_V2_SIZE is for Win XP
NOTIFYICONDATA_V3_SIZE is for Vista
(not sure if I am right)
It's completely different from what MSDN says? and none for Win2K?
So, I am totally confused right now. How should I set the cbSize member according to Shell32.dll version?
//= = = = = = = = ShellAPI.h = = = = = = = =
typedef struct _NOTIFYICONDATAA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (NTDDI_VERSION < NTDDI_WIN2K)
CHAR szTip[64];
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
CHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion; // used with NIM_SETVERSION, values 0, 3 and 4
} DUMMYUNIONNAME;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
GUID guidItem;
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
HICON hBalloonIcon;
#endif
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
typedef struct _NOTIFYICONDATAW {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (NTDDI_VERSION < NTDDI_WIN2K)
WCHAR szTip[64];
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
WCHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
WCHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion; // used with NIM_SETVERSION, values 0, 3 and 4
} DUMMYUNIONNAME;
WCHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
GUID guidItem;
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
HICON hBalloonIcon;
#endif
} NOTIFYICONDATAW, *PNOTIFYICONDATAW;
#define NOTIFYICONDATAA_V1_SIZE FIELD_OFFSET(NOTIFYICONDATAA, szTip[64])
#define NOTIFYICONDATAW_V1_SIZE FIELD_OFFSET(NOTIFYICONDATAW, szTip[64])
#ifdef UNICODE
#define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAW_V1_SIZE
#else
#define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAA_V1_SIZE
#endif
#define NOTIFYICONDATAA_V2_SIZE FIELD_OFFSET(NOTIFYICONDATAA, guidItem)
#define NOTIFYICONDATAW_V2_SIZE FIELD_OFFSET(NOTIFYICONDATAW, guidItem)
#ifdef UNICODE
#define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAW_V2_SIZE
#else
#define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAA_V2_SIZE
#endif
#define NOTIFYICONDATAA_V3_SIZE FIELD_OFFSET(NOTIFYICONDATAA, hBalloonIcon)
#define NOTIFYICONDATAW_V3_SIZE FIELD_OFFSET(NOTIFYICONDATAW, hBalloonIcon)
#ifdef UNICODE
#define NOTIFYICONDATA_V3_SIZE NOTIFYICONDATAW_V3_SIZE
#else
#define NOTIFYICONDATA_V3_SIZE NOTIFYICONDATAA_V3_SIZE
#endif
(Seems like the code doesn't look good on the web site, but it from ShellAPI.h, all the same)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
通过平台 sdk 标头可用的功能由
_WIN32_WINNT
控制,应将其定义到您所针对的操作系统的较低版本。来自 http://msdn.microsoft.com/en-us/library/6sehtctf .aspx 正确的值为:
因此,
NOTIFYICONDATA_V1_SIZE
引用任何低于 2K 的版本,NOTIFYICONDATA_V2_SIZE
引用 2K,NOTIFYICONDATA_V3_SIZE
引用 XP,没有引用 Vista(在这种情况下,您可以使用 sizeof (通知图标数据))。如果您将
_WIN32_WINNT
设置为最新版本来编译项目,并检测您在运行时运行的 shell.dll 版本,则可以将 .cbSize 设置为正确的大小,其余字段将是被忽略。像这样的东西应该有效:
Which features are available through platform sdk headers are controlled by
_WIN32_WINNT
, which should be defined to the lower version of the operating system you are targeting.From http://msdn.microsoft.com/en-us/library/6sehtctf.aspx the correct values are:
So
NOTIFYICONDATA_V1_SIZE
refer to any version lower than 2K,NOTIFYICONDATA_V2_SIZE
to 2K,NOTIFYICONDATA_V3_SIZE
to XP and none to Vista (in this case you can use sizeof(NOTIFYICONDATA)).If you compile your project with
_WIN32_WINNT
set to the latest version, and detect which version of shell.dll you are running on runtime you can set .cbSize to the correct size, the rest of the fields will be ignored.Something like this should work:
这取决于您编译的最低 Windows 版本。 您不动态设置大小。 您可以根据支持的最低 Windows 版本设置大小。
It depends on the lowest Windows version you compile for. You don't set the size dynamically. You set the size according to the lowest version of Windows you support.
“这取决于您编译的最低 Windows 版本。您不能动态设置大小。您可以根据支持的最低 Windows 版本设置大小。”
其实并不是。 只需尝试针对 VISTA 进行构建并在 XP 下运行即可。 您将获得 64+ 字节消息大小的空工具提示字符串。 安全的解决方案是构建
(_WIN32_WINNT >= 0x0600)
并设置cbSize = NOTIFYICONDATA_V3_SIZE
;正确的解决方案是在运行时检查
shell32.dll
版本。6.0.6000 - Vista+
、6.0.0 - XP
、5.0.0 - W2K
"It depends on the lowest Windows version you compile for. You don't set the size dynamically. You set the size according to the lowest version of Windows you support."
actually not. just try build against VISTA and run under XP. You will get an empty tooltip string on 64+ bytes message size. the safe solution is to build for
(_WIN32_WINNT >= 0x0600)
and setcbSize = NOTIFYICONDATA_V3_SIZE
;the right solution is to check
shell32.dll
version in run-time.6.0.6000 - Vista+
,6.0.0 - XP
,5.0.0 - W2K