관리 메뉴

kisoo

MEDIA(CD-ROM,USB) 탈/부착 이벤트 받기 WM_USER_MEDIACHANGED 본문

01.About Programming /12.Default knowledge

MEDIA(CD-ROM,USB) 탈/부착 이벤트 받기 WM_USER_MEDIACHANGED

JamesK78 2009. 9. 17. 18:32

오늘은 윈도우에 CD-ROM / USB 등과 같은 미디어를 탈/부착 했을 때에 이벤트를 처리 하는
부분에 대해서 설명 하고자 한다.
개발을 하다보면 다양한 부분을 처리 할 경우가 있는데 이번 경우는 특정 USB 를 부착 할 경우에
CD-ROM 으로 인식 되는 이 USB 내부의 프로세스를 실행 시켜 주는 개발 작업 이었다.
다른건 다 생략 하고 WM_USER_MEDIACHANGED 이벤트 메세지를 받는 부분만 설명 하도록 하겠다.

소스 구현부를 보면 쉽게 이해가 될것으로 보인다. 너무 간단하므로.....

***********************************************************************
소스 구현 부
***********************************************************************
ULONG m_ulSHChangeNotifyRegister;

CNotifyWnd::CNotifyWnd()
{
 m_ulSHChangeNotifyRegister = 0;
}

CNotifyWnd::~CNotifyWnd()
{
 if(m_ulSHChangeNotifyRegister)
  VERIFY(SHChangeNotifyDeregister(m_ulSHChangeNotifyRegister));
}
BEGIN_MESSAGE_MAP(CNotifyWnd, CWnd)
 ON_MESSAGE(WM_USER_MEDIACHANGED, OnMediaChanged)
END_MESSAGE_MAP()

// MEDIA 탈/부착 이벤트를 받기 위한 초기화
BOOL CNotifyWnd::InitShellNotifyEvent()
{

 HWND hWnd = GetSafeHwnd();
 LPITEMIDLIST ppidl;

    if(SHGetSpecialFolderLocation(hWnd, CSIDL_DESKTOP, &ppidl) == NOERROR)
    {
        SHChangeNotifyEntry shCNE;
        shCNE.pidl = ppidl;
        shCNE.fRecursive = TRUE;

        // Returns a positive integer registration identifier (ID).
        // Returns zero if out of memory or in response to invalid parameters.
        m_ulSHChangeNotifyRegister = SHChangeNotifyRegister(hWnd,   // Hwnd to receive notification
         SHCNE_DISKEVENTS,                                                          // Event types of interest (sources)
         SHCNE_MEDIAINSERTED|SHCNE_MEDIAREMOVED,              // Events of interest - 
                                                                                            // SHCNE_ALLEVENTS for all events
         WM_USER_MEDIACHANGED,                               // Notification message to 
         1,                                                                           // Number of entries in the pfsne array
         &shCNE);  // Array of SHChangeNotifyEntry structures that                          
                         // contain the notifications. This array should                          
                        // always be set to one when calling SHChnageNotifyRegister
                        // or SHChangeNotifyDeregister will not work properly.
   
        return TRUE;
 }
    else
        return FALSE;

 return FALSE;
}
//MEDIA 이벤트를 받을 메세지 FUNCTION
LRESULT CNotifyWnd::OnMediaChanged(WPARAM wParam, LPARAM lParam)
{

    SHNOTIFYSTRUCT *shns = (SHNOTIFYSTRUCT *)wParam;
    CString strPath, strMsg;

    switch(lParam)
    {
        case SHCNE_MEDIAINSERTED:        // media inserted event
        {
            strPath = GetPathFromPIDL(shns->dwItem1);
            strMsg.Format("Media removed from %s", strPath);
            ....
            ....
            ....
             break;
        }

        case SHCNE_MEDIAREMOVED:        // media removed event
        {
            strPath = GetPathFromPIDL(shns->dwItem1);
            if(!strPath.IsEmpty())
            {
                // Process strPath as required, for now a simple message box
                strMsg.Format("Media removed from %s", strPath);
                ....
                ....
            }
        }
  break;
  
  //event 를 더 추가 해도 된다. 필요 하면...
  default: break;
    }
    return NULL;
}
//탈/부착 된 MEDIA 의 볼륨을 가져온다.
CString CNotifyWnd::GetPathFromPIDL(DWORD pidl)
{
    char sPath[MAX_PATH];
    CString strTemp = _T("");
    if(SHGetPathFromIDList((struct _ITEMIDLIST *)pidl, sPath))
        strTemp = sPath;
   
    return strTemp;
}

Comments