关于 NOTIFYICONDATA 的 cbSize 成员的 MSDN 文档

发布于 2024-07-17 04:17:36 字数 3432 浏览 3 评论 0原文

我正在阅读 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

强辩 2024-07-24 04:17:36

通过平台 sdk 标头可用的功能由 _WIN32_WINNT 控制,应将其定义到您所针对的操作系统的较低版本。

来自 http://msdn.microsoft.com/en-us/library/6sehtctf .aspx 正确的值为:

Windows 2000 为 0x0500
操作系统,Windows XP 为 0x0501,0x0502
对于 Windows Server 2003 和 0x0600
适用于 Windows Vista。

因此,NOTIFYICONDATA_V1_SIZE 引用任何低于 2K 的版本,NOTIFYICONDATA_V2_SIZE 引用 2K,NOTIFYICONDATA_V3_SIZE 引用 XP,没有引用 Vista(在这种情况下,您可以使用 sizeof (通知图标数据))。

如果您将 _WIN32_WINNT 设置为最新版本来编译项目,并检测您在运行时运行的 shell.dll 版本,则可以将 .cbSize 设置为正确的大小,其余字段将是被忽略。

像这样的东西应该有效:

NOTIFYICONDATA notify;
ZeroMemory(¬ify, sizeof(notify)); 
if(version >= VISTA) {
  notify.cbSize = sizeof(NOTIFYICONDATA);
}
else if(version >= XP) {
  notify.cbSize = NOTIFYICONDATA_V3_SIZE;
}
else if(version >= 2K) {
  notify.cbSize = NOTIFYICONDATA_V2_SIZE;
}
else {
  notify.cbSize = NOTIFYICONDATA_V1_SIZE;
}

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:

0x0500 for Windows 2000
operating system, 0x0501 for Windows XP, 0x0502
for Windows Server 2003, and 0x0600
for Windows Vista.

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:

NOTIFYICONDATA notify;
ZeroMemory(¬ify, sizeof(notify)); 
if(version >= VISTA) {
  notify.cbSize = sizeof(NOTIFYICONDATA);
}
else if(version >= XP) {
  notify.cbSize = NOTIFYICONDATA_V3_SIZE;
}
else if(version >= 2K) {
  notify.cbSize = NOTIFYICONDATA_V2_SIZE;
}
else {
  notify.cbSize = NOTIFYICONDATA_V1_SIZE;
}
哑剧 2024-07-24 04:17:36

这取决于您编译的最低 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.

叫思念不要吵 2024-07-24 04:17:36

“这取决于您编译的最低 Windows 版本。您不能动态设置大小。您可以根据支持的最低 Windows 版本设置大小。”

其实并不是。 只需尝试针对 VISTA 进行构建并在 XP 下运行即可。 您将获得 64+ 字节消息大小的空工具提示字符串。 安全的解决方案是构建 (_WIN32_WINNT >= 0x0600) 并设置 cbSize = NOTIFYICONDATA_V3_SIZE;

正确的解决方案是在运行时检查 shell32.dll 版本。 6.0.6000 - Vista+6.0.0 - XP5.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 set cbSize = 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文