본문 바로가기

망각/Windows Shell

SHChangeNotifyRegister 사용에 대해

폴더의 이름 변경을 알기위해 ::SHChangeNotifyRegister() 함수를 사용하려 한다. 이 함수는 지정 이벤트가 일어날 경우 보내질 메시지와 메시지를 받을 핸들을 받는다.
ULONG SHChangeNotifyRegister(
    HWND hwnd,
    int fSources,
    LONG fEvents,
    UINT wMsg,
    int cEntries,
    const SHChangeNotifyEntry *pshcne
);

MSDN에는 이 함수와 관련 함수들에 대해 설명이 부족하다(내가 못 찾는 건가!). 일단 이벤트가 발생해서 윈도우로 메시지가 전달됐다고 하자. 관련 정보는 어떻게 얻을 수 있는건가? 메시지의 WPARAM, LPARAM 값은 어떻게 사용해야 하나? 관련 정보가 MSDN에 없다;

구글링으로 찾아본 codeproject의 글의 코드에서 WPARAM와 LPARAM 값을 어떻게 사하는지 알 수 있었다. 발생한 이벤트 종류로서 LPARAM을 사용하고, WPARAM값은 변경 정보로서 직접 정의한 SHNOTIFYSTRUCT 구조체의 포인터로 변경해 사용하고 있다.

typedef struct {
    DWORD dwItem1;    // dwItem1 contains the previous PIDL or name of the folder. 
    DWORD dwItem2;    // dwItem2 contains the new PIDL or name of the folder. 
} SHNOTIFYSTRUCT;
....
  SHNOTIFYSTRUCT *shns = (SHNOTIFYSTRUCT *)wParam;

도대체 이런 것을 어떻게 아는거지? 저 구조체를 보니 ::SHChangeNotify() 함수의 매개변수값과 비슷하다.
void SHChangeNotify(
    LONG wEventId,
    UINT uFlags,
    LPCVOID dwItem1,
    LPCVOID dwItem2
);


저 글에서 이상한건 ::SHChangeNotifyRegister의 두번째 매개변수의 값으로 SHCNE_DISKEVENTS을 사용했다는 것이다. MSDN에 적혀 있는 값들은 다음과 같다.

저 글의 코드로 테스트해보진 않았는데 리플에 별다른 내용들이 안보이는 걸로 보니 되긴 되나보다.
어쨋든 어떻게 변경 정보를 얻는지 알아내긴 했지만, MSDN에도 제대로 언급안된 것들은 도대체 사용하라는 건지 말라는 건지....
너무 하잖아!



의문 또는 고려사항

  • SHCNE_RENAMEFOLDER 이벤트에 등록한 메시지가 여러번 전달됨
    • 바탕화면이나 내문서처럼 가상폴더에도 물려있는 폴더의 경우에 메시지가 여러번 전달되는 듯 함
  • x64 환경
    • SHNOTIFYSTRUCT 구조체 멤버들의 데이터타입은 LPCVOID로 바껴야 함