반응형

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.

반응형
반응형

레지스트리 감시

 

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

 

레지스트리의 특정 키값을 변경을 통지 받을 수 있다.

 

LONG WINAPI RegNotifyChangeKeyValue(

  __in      HKEY hKey,

  __in      BOOL bWatchSubtree,

  __in      DWORD dwNotifyFilter,

  __in_opt  HANDLE hEvent,

  __in      BOOL fAsynchronous

);

 

아래는 Thread에서 특정 Registry Key를 감시하는 샘플이다.

int  MonitoringRegChange( WCHAR *pwKey )

{

   DWORD  dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET;

HKEY   hKey = NULL;

 

LONG lErrorCode = ::RegOpenKeyEx( HKEY_CURRENT_USER, pwKey, 0, KEY_NOTIFY, &hKey);

if ( lErrorCode != ERROR_SUCCESS )

{

if ( lErrorCode != ERROR_FILE_NOT_FOUND  )

{

return -1;

}

 

lErrorCode = RegCreateKeyEx( HKEY_CURRENT_USER, pwKey, 0, NULL, 0, KEY_NOTIFY,

NULL, &hKey, NULL) ;

if ( lErrorCode != ERROR_SUCCESS )

{

return -1;

}

}

 

HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

if (hEvent == NULL)

{

CloseHandle(hEvent);

RegCloseKey(hKey);

return -1;

}

 

HANDLE hEvents[2];

hEvents[0] = m_hExitEvent;

hEvents[1] = hEvent;

 

while( TRUE )

{

lErrorCode = RegNotifyChangeKeyValue( hKey, TRUE, dwFilter, hEvent, TRUE );

if (lErrorCode != ERROR_SUCCESS) // Reg감시중, key삭제되는경우의복구루틴

{

RegCloseKey(hKey);

            if ( lErrorCode != ERROR_KEY_DELETED )

            {

               return -1;

            }

         lErrorCode = RegCreateKeyEx( HKEY_CURRENT_USER, pwKey, 0, NULL, 0,

KEY_NOTIFY, NULL, &hKey, NULL) ;

            if ( lErrorCode != ERROR_SUCCESS )

            {

return -1;

            }

          

// Detect Registry Changed Key is Deleted

            continue;

}

 

if ( WaitForSingleObject( hEvent, 0 ) == WAIT_OBJECT_0 )

{

// 첫번째 RegNotifyChangeKeyValue() Call과두번째 RegNotifyChangeKeyValue()

// Call사이에 변경이있을경우, Envent가 바로활성화되어,

// 한번의 레지스트리 변경에 대해 두번의 noty를받게되는 문제 Fix

            // http://support.microsoft.com/kb/236570/en-us

            lErrorCode = RegNotifyChangeKeyValue( hKey, TRUE, dwFilter, hEvent, TRUE );

            if (lErrorCode != ERROR_SUCCESS)

            {

               CloseHandle(hEvent);

               RegCloseKey(hKey);

               return -1;

            }

}

 

DWORD dwResult = ::WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );

if ( dwResult == WAIT_FAILED )

{

CloseHandle(hEvent);

            RegCloseKey(hKey);

            return -1;

}

else if ( dwResult == WAIT_OBJECT_0 )

{

   // recevie Stop monitoring noty

      return 0;

 

}

else if ( dwResult == WAIT_OBJECT_0 + 1 )

{

// Detect Registry Changed

continue;

}

}

 

CloseHandle(hEvent);

RegCloseKey(hKey);

          

return 0;

}

 

 

반응형
반응형

UrlGetPart Function

Accepts a URL string and returns a specified part of that URL.

Syntax

Copy

HRESULT UrlGetPart(

  __in     PCTSTR pszIn,

  __out    PTSTR pszOut,

  __inout  DWORD *pcchOut,

  DWORD dwPart,

  DWORD dwFlags

);

Parameters

pszIn [in]

Type: PCTSTR

A null-terminated string of maximum length INTERNET_MAX_URL_LENGTH that contains the URL.

pszOut [out]

Type: PTSTR

A pointer to a buffer that, when this function returns successfully, receives a null-terminated string with the specified part of the URL.

pcchOut [in, out]

Type: DWORD*

A pointer to a value that, on entry, is set to the number of characters in the pszOut buffer. When this function returns successfully, the value depends on whether the function is successful or returns E_POINTER. For other return values, the value of this parameter is meaningless.

dwPart

Type: DWORD

The flags that specify which part of the URL to retrieve. It can have one of the following values.

URL_PART_HOSTNAME

The host name.

URL_PART_PASSWORD

The password.

URL_PART_PORT

The port number.

URL_PART_QUERY

The query portion of the URL.

URL_PART_SCHEME

The URL scheme.

URL_PART_USERNAME

The username.

dwFlags

Type: DWORD

A flag that can be set to keep the URL scheme, in addition to the part that is specified by dwPart.

URL_PARTFLAG_KEEPSCHEME

Keep the URL scheme.

Return Value

Type: HRESULT

Returns S_OK if successful. The value pointed to by pcchOut will be set to the number of characters written to the output buffer, excluding the terminating NULL. If the buffer was too small, E_POINTER is returned, and the value pointed to by pcchOut will be set to the minimum number of characters that the buffer must be able to contain, including the terminating NULL character. Otherwise, a COM error value is returned.

Requirements

Minimum supported client

Windows 2000 Professional, Windows XP

Minimum supported server

Windows 2000 Server

Header

Shlwapi.h

Library

Shlwapi.lib

DLL

Shlwapi.dll (version 5.0 or later)

Unicode and ANSI names

UrlGetPartW (Unicode) and UrlGetPartA (ANSI)

 

반응형

'Windows Programming' 카테고리의 다른 글

Shell_NotifyIcon, NOTIFYICONDATA struct Size  (1) 2010.03.03
레지스트리 감시  (0) 2010.02.26
Visual Studio 소스편집창 분할하기  (0) 2009.08.05
API Hooking - 2. PE File Format  (0) 2009.07.31
API Hooking - 1. Dll Injection  (0) 2009.07.22
반응형
반응형
반응형

Windows7 빠른실행(Quick Lunch)

 

Windows 7Windows Vista에 비교하면, 꽤 쓸만한 OS인 것 같다.

 

그런데 Windows 7을 설치하고, 약간은 당황스러웠던 건 TaskBarQuick Lunch 도구모음이 사라졌다는 거다.


이제는 Quick Lunck 도구모음이 없어도 그냥저냥 적응이 되긴 했지만, 그래도 있으면 좋은 게 사실이다. (적어도 나에게는 말이다.)

 

다음과 같은 절차로, TaskBar Quick Lunch 도구모음을 표시할 수 있다.

1. TaskBar를 우클릭하면 나오는 팝업메뉴에서 [ 도구모음>새 도구 모음(N)… ]을 선택한다.

 

 

2. C:\Users\[USER ID]\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch를 선택한 후, [폴더선택] 버튼을 누른다.

 

3. 새로 생성된 [User Pinned] 도구 모음에서 오른쪽 마우스를 눌러 팝업메뉴를 띄운 후, [텍스트 표시][제목표시] 항목을 체크 해제한다.

 


4.
새 영역에 기존의 Quick Lunch 도구모음처럼 ShotCut을 만들어 사용한다.

반응형
반응형

std::map



#include <map>

 

void map_function()

{

           using namespace std;

 

           // 선언

           typedef map< UINT, char * > HFILE_MAP;

           typedef HFILE_MAP::iterator HFILE_MAP_ITERATOR;

 

           HFILE_MAP MAP;

           HFILE_MAP_ITERATOR it;

 

           char *p1 = new char[16];

           char *p2 = new char[16];

 

           strcpy(p1, "A1");

           strcpy(p2, "A2");

 

           // 추가

           MAP.insert( HFILE_MAP::value_type( 1 , p1 ) );

           MAP.insert( HFILE_MAP::value_type( 2 , p2 ) );

          

           // 검색

           it = MAP.find( 1 );

           if ( it != MAP.end() )

           {

                     char *pFind = (char *)it->second; // "A1"

           }

           else

           {

                     // not exist

           }

 

           //순회

           for ( it = MAP.begin(); it != MAP.end(); it++)

           {

                     if ( strcmp(it->second, "A2") == 0 )

                     {

                                break;

                     }

           }

 

           // 삭제

           delete [] it->second;

           MAP.erase( it );

          

           // 순회 삭제

           for ( it = MAP.begin(); it != MAP.end(); )

           {

                     if ( it->second && IsConditionMatch )

                     {

                                delete [] it->second;

                                it->second = NULL;

                                it = MAP.erase(it++);

                     }

                     else

                     {

                               ++it;

                     }

           }

 

           // 모든항목삭제

           MAP.clear();

 

           // 항목갯수

           MAP.empty();

           MAP.size();

}

 

반응형

'C++' 카테고리의 다른 글

map 파일  (0) 2011.07.26
Format Specification  (0) 2011.04.20
std::vector  (0) 2009.08.26
strcpy_s등의 _s 류의 문자열 처리함수  (4) 2009.04.01
오버로드/오버라이드  (2) 2009.04.01

+ Recent posts