CMyWnd::CMyWnd() { ulSHChangeNotifyRegister = NULL; }BOOL CMyWnd::OnInitDialog() { CWnd::OnInitDialog(); // Request notification from shell of media insertion - // allows us to detect removable media or a multimedia card 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 - use // SHCNE_ALLEVENTS for all events WM_USER_MEDIACHANGED, // Notification message to be sent // upon the event 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.
ASSERT(m_ulSHChangeNotifyRegister != 0); // Shell notification failed } else ASSERT(FALSE); // Failed to get desktop location }Add a message handler to your message map for the notification message: Collapse | Copy CodeON_MESSAGE(WM_USER_MEDIACHANGED, OnMediaChanged)Together with the corresponding declaration: Collapse | Copy Codeafx_msg LRESULT OnMediaChanged(WPARAM, LPARAM);Then deal with the message as desired: Collapse | Copy Code// The lParam value contains the event SHCNE_xxxx // The wParam value supplies the SHNOTIFYSTRUCTtypedef 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;LRESULT CMyWnd::OnMediaChanged(WPARAM wParam, LPARAM lParam) { SHNOTIFYSTRUCT *shns = (SHNOTIFYSTRUCT *)wParam; CString strPath, strMsg; switch(lParam) { case SHCNE_MEDIAINSERTED: // media inserted event { strPath = GetPathFromPIDL(shns->dwItem1); if(!strPath.IsEmpty()) { // Process strPath as required, for now a simple message box strMsg.Format("Media inserted into %s", strPath); AfxMessageBox(strMsg); } } 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); AfxMessageBox(strMsg); } } //case SHCNE_xxxx: Add other events processing here } return NULL; }CString CMyWnd::GetPathFromPIDL(DWORD pidl) { char sPath[MAX_PATH]; CString strTemp = _T(""); if(SHGetPathFromIDList((struct _ITEMIDLIST *)pidl, sPath)) strTemp = sPath;
return strTemp; }Finally deregister your request when no longer required: Collapse | Copy Codevoid CMyWnd::OnDestroy() { if(m_ulSHChangeNotifyRegister) VERIFY(SHChangeNotifyDeregister(m_ulSHChangeNotifyRegister)); CWnd::OnDestroy(); }
{
ulSHChangeNotifyRegister = NULL;
}BOOL CMyWnd::OnInitDialog()
{
CWnd::OnInitDialog(); // Request notification from shell of media insertion -
// allows us to detect removable media or a multimedia card
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 - use // SHCNE_ALLEVENTS for all events
WM_USER_MEDIACHANGED, // Notification message to be sent // upon the event
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.
ASSERT(m_ulSHChangeNotifyRegister != 0); // Shell notification failed
}
else
ASSERT(FALSE); // Failed to get desktop location
}Add a message handler to your message map for the notification message: Collapse | Copy CodeON_MESSAGE(WM_USER_MEDIACHANGED, OnMediaChanged)Together with the corresponding declaration: Collapse | Copy Codeafx_msg LRESULT OnMediaChanged(WPARAM, LPARAM);Then deal with the message as desired: Collapse | Copy Code// The lParam value contains the event SHCNE_xxxx
// The wParam value supplies the SHNOTIFYSTRUCTtypedef 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;LRESULT CMyWnd::OnMediaChanged(WPARAM wParam, LPARAM lParam)
{
SHNOTIFYSTRUCT *shns = (SHNOTIFYSTRUCT *)wParam;
CString strPath, strMsg; switch(lParam)
{
case SHCNE_MEDIAINSERTED: // media inserted event
{
strPath = GetPathFromPIDL(shns->dwItem1);
if(!strPath.IsEmpty())
{
// Process strPath as required, for now a simple message box
strMsg.Format("Media inserted into %s", strPath);
AfxMessageBox(strMsg);
}
}
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);
AfxMessageBox(strMsg);
}
}
//case SHCNE_xxxx: Add other events processing here
}
return NULL;
}CString CMyWnd::GetPathFromPIDL(DWORD pidl)
{
char sPath[MAX_PATH];
CString strTemp = _T("");
if(SHGetPathFromIDList((struct _ITEMIDLIST *)pidl, sPath))
strTemp = sPath;
return strTemp;
}Finally deregister your request when no longer required: Collapse | Copy Codevoid CMyWnd::OnDestroy()
{
if(m_ulSHChangeNotifyRegister)
VERIFY(SHChangeNotifyDeregister(m_ulSHChangeNotifyRegister)); CWnd::OnDestroy();
}
这种监视方法特笨,不推荐使用。