반응형

Shell_NotifyIcon, NOTIFYICONDATA struct Size

{

NOTIFYICONDATA nid;

ZeroMemory(&nid, sizeof(nid));
nid.cbSize =
sizeof
(NOTIFYICONDATA);
nid.hWnd = g_hWnd;
nid.uFlags = NIF_ICON | NIF_TIP | NIF_INFO;
nid.hIcon = LoadIcon( g_hInst, IDR_MAINFRAME );
lstrcpy( nid.szTip,
"TipText"
);
lstrcpy(nid.szInfo,
"BalloonText"
);

Shell_NotifyIcon(NIM_ADD, &nid);

}


위의 코드를 통해, 트레이 아이콘의 팝업설명과 풍선도움말을 띄울수 있다.

하지만, (WindowsXP에서의 테스트를 가정할때) VC6.0 & PSDK2003으로 빌드한 실행파일은 정상 동작 하지만, VS2008로 빌드한 실행파일은 풍선 도움말이 팝업되지 않는다
.

왜 이런 차이가 발생하는 것일까? 이유인 즉슨
,
Shell_NofifyIcon()
NOTIFYICONDATA.cbSize를 통해, 입력받은 NOTIFYICONDATA를 어떻게 해석해야 할지를 결정하게 되는데(많은 수의 Windows API struct의 정의를 확인하기 위해 이러한 방식을 사용하고 있다.) PSDK2003 VC2008에 정의된 NOTIFYICONDATA구조체가 상이하게 정의 되어 있기 때문이다
.
(VC2008
과 함께깔리는 SDK(ShellAPI.h)NOTIFYICONDATA 정의가 이전버전의 확장버전이다
.)

VC2008 로 컴파일 하는 순간, NOTIFYICONDATA 는 확장된 구조체 정의를 사용하게 되며
,
이 구조체는 이전 버전의(WindowsXP) Shell32.dllParshing할 수 없는 알수없는 구조체가 되어 버린다고 생각할 수 있다
..

[ PSDK2003 ] - ShellAPI.h

typedef struct _NOTIFYICONDATAA {
DWORD cbSize;

HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;

HICON hIcon;
#if (_WIN32_IE < 0x0500)
   CHAR szTip[64];

#else
   CHAR szTip[128];
#endif
#if
(_WIN32_IE >= 0x0500)
   DWORD dwState;
   DWORD dwStateMask;
   CHAR szInfo[256];
   union
{
      UINT uTimeout;
      UINT uVersion;
   } DUMMYUNIONNAME;
   CHAR szInfoTitle[64];
   DWORD dwInfoFlags;
#endif
#if
(_WIN32_IE >= 0x600)
   GUID guidItem;
#endif
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;

[VS2008 SDK] - 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_LONGHORN)
  
HICON
hBalloonIcon;
#endif
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;


1
차적인 책임은 이런 애매한 상황을 만들어 놓은 MS에 있다고 보여지지만, 또 반대로 MS라고 해서 이후의 모든 확장에 대해서 대비할 수는 없지 않겠나?

* MSDN의 아래 내용을 참고하면, Shell32.dll의 버전을 근거로, 유효한 NOTIFYICONDATA.cbSize 를 지정해 주는 방법을 확인 할 수 있다.

아래의 링크를 통해 알게된 사실....많은 수의 Shell Dll들이 버전을 확인 할수 있도록 DllGetVersion함수를 Export하고 있다.



http://msdn.microsoft.com/en-us/library/bb773352(VS.85).aspx

NOTIFYICONDATA Structure

Note that you must initialize the structure with its size. If you use the size of the currently defined structure, the application might not run with earlier versions of Shell32.dll, which expect a smaller structure. You can run your application against earlier versions of Shell32.dll by defining the appropriate version number (see
Shell and Common Controls Versions). However, this might cause problems if your application also needs to run on more recent systems.

You can maintain application compatibility with all Shell32.dll versions while still using the current header files by setting the size of the NOTIFYICONDATA structure appropriately. Before you initialize the structure, use DllGetVersion to determine which Shell32.dll version is installed on the system and initialize cbSize with one of these values:

Shell32.dll Version

cbSize

6.0.6 or higher (Windows Vista and later)

sizeof(NOTIFYICONDATA)

6.0 (Windows XP)

NOTIFYICONDATA_V3_SIZE

5.0 (Windows 2000)

NOTIFYICONDATA_V2_SIZE

Versions lower than 5.0 (Microsoft Windows NT 4.0, Windows 95, Windows 98)

NOTIFYICONDATA_V1_SIZE

Using this value for cbSize allows your application to use NOTIFYICONDATA in a method compatible with earlier Shell32.dll versions.

반응형

+ Recent posts