Windowsモニタデバイスのホットスワップ

5648 ワード

今回は、システムにusbデバイス、ワイヤレスカードを挿入するなど、デバイスのホットスワップを検出する方法を共有し、後続の作業を決定することができます.ある種類のデバイスインタフェース、ファイルシステム、OEMまたはIHVメーカーがカスタマイズしたデバイス、エンドElデバイス(シリアルまたはパラレル)、論理ディスクディスクボリュームを含むコンピュータハードウェアの抜去を検出することを研究する.常用設備インタフェース類GUIDは、必要に応じて登録する.主にWM_を使用DEVICECHANGEメッセージは、フレームワークがこの関数を呼び出してアプリケーションまたはデバイスドライバデバイスのハードウェア構成またはコンピュータの構成が変更されたことを通知し、このメッセージは最上位フォーム(CWnd)のプログラムのみがこのメッセージを受信することができる.シリアルポート、ディスクが変更された場合にのみ、このメッセージがプログラムごとにブロードキャストされるため、RegisterDeviceNotification()APIを呼び出して他のタイプのデバイス変更を登録するか、あなたのプログラムがサービスプログラムであり、最上位フォームのないプログラムである必要があります.
  • WM_DEVICECHANGEメッセージは、OnDeviceChange()メッセージ応答関数を介した方法のみを紹介し、WindowProcを介して紹介を展開することもできます. 

  •        1.メッセージ処理関数を追加するには、次の手順に従います.
    afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );

            2.メッセージのマッピング:
    BEGIN_MESSAGE_MAP(OGrgFrmRepair, CDialog)
    
        ON_WM_DEVICECHANGE()
    
    END_MESSAGE_MAP()
  • 常用機器インタフェース類GUIDhttps://blog.csdn.net/jhqin/article/details/6775321
  • 実装:
  •        1.OnInitDialog()にデバイスタイプのインタフェースを登録する
    //           
    	static const GUID GUID_DEVINTERFACE_LIST[] =
    	{
            //GUID_DEVINTERFACE_MOUSE,
            //GUID_DEVINTERFACE_KEYBOARD
    		{ 0X378DE44C, 0X56EF, 0X11D1, { 0XBC,0X8C,0X00,0XA0,0XC9,0X14,0X05,0XDD}},
    		{ 0X884B96C3, 0X56EF, 0X11D1, { 0XBC,0X8C,0X00,0XA0,0XC9,0X14,0X05,0XDD}}
    	};
    	HDEVNOTIFY hDevNotify;
    	DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    	ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
    	NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    	NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    	for (int i = 0; iGetSafeHwnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
    		if (!hDevNotify)
    		{
    			AfxMessageBox(CString("Can't register device notification: ")
    				+ _com_error(GetLastError()).ErrorMessage(), MB_ICONEXCLAMATION);
    			return FALSE;
    		}
    	}

              2.OnDeviceChange(UINT nEventType,DWORD_PTR dwData)関数の実装
    この関数はMessageBoxTimeOutと同じですが、表示時間を設定し、時間になると自動的に閉じることができます.次のコードを追加して使用する必要があります.これを使うのはテストのためだけで、実際のプロジェクト開発では、抜き差しを検出した後、あなたが行いたい操作コードを加えればいいのです.
    //   MessageBoxTimeOut
    extern "C"
    {
        int WINAPI MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
        int WINAPI MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
    };
    #ifdef UNICODE
    #define MessageBoxTimeout MessageBoxTimeoutW
    #else
    #define MessageBoxTimeout MessageBoxTimeoutA
    #endif
    BOOL CDeviceChangeDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
    {
    	CString Msg;
    	PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)dwData;
    	switch (nEventType)
    	{
    	case DBT_DEVICEREMOVECOMPLETE://    
    	{
    		switch (pHdr->dbch_devicetype)
    		{
    		case DBT_DEVTYP_DEVICEINTERFACE:
    		{
    			PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
    			if (pDevInf->dbcc_classguid == GUID_DEVINTERFACE_MOUSE)
    			{
    				MessageBoxTimeout(NULL, _T("     "), _T("  "), MB_OK, 0, 1000);
    				//::MessageBox(NULL, _T("     "), _T("  "), MB_ICONINFORMATION | MB_OK);
    			}
    			else if (pDevInf->dbcc_classguid == GUID_DEVINTERFACE_KEYBOARD)
    			{
    				MessageBoxTimeout(NULL, _T("     "), _T("  "), MB_OK, 0, 1000);
    				//::MessageBox(NULL, _T("     "), _T("  "), MB_ICONINFORMATION | MB_OK);
    			}
    		}
    		break;
    		case DBT_DEVTYP_VOLUME:
    		{
    			PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
    			switch (pDevVolume->dbcv_flags)
    			{
    			case 0://U 
    			{
    				CString strDriver;
    				strDriver= FirstDriveFromMask(pDevVolume->dbcv_unitmask);
    				Msg.Format(_T("%s   !"), strDriver.GetBuffer(0));
    				m_Edit.SetWindowText(Msg);//m_Edit   CEdit     ,              Edit,          
    			}
    			break;
    			case DBTF_MEDIA:    //  
    				break;
    			}
    		}
    		break;
    		}
    	}
    	break;
    	
    	case DBT_DEVICEARRIVAL://    
    	{
    		switch (pHdr->dbch_devicetype)
    		{
    		case DBT_DEVTYP_DEVICEINTERFACE:
    		{
    			PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
    			if (pDevInf->dbcc_classguid == GUID_DEVINTERFACE_MOUSE)
    			{
    				MessageBoxTimeout(NULL,_T("     "), _T("  "), MB_OK, 0, 1000);
    				//::MessageBox(NULL, _T("     "), _T("  "), MB_ICONINFORMATION | MB_OK);
    			}
    			else if (pDevInf->dbcc_classguid == GUID_DEVINTERFACE_KEYBOARD)
    			{
    				MessageBoxTimeout(NULL, _T("     "), _T("  "), MB_OK, 0, 1000);
    				//::MessageBox(NULL, _T("     "), _T("  "), MB_ICONINFORMATION | MB_OK);
    			}
    		}
    		break;
    		case DBT_DEVTYP_VOLUME:
    		{
    			PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
    			switch (pDevVolume->dbcv_flags)
    			{
    			case 0://U 
    			{
    				CString strDriver;
    				strDriver = GetDrive(pDevVolume->dbcv_unitmask);//GetDrive         
    				Msg.Format(_T("%s   !"), strDriver.GetBuffer(0));
    				m_Edit.SetWindowText(Msg);
    			}
    			break;
    			case DBTF_MEDIA:    //  
    				break;
    			}
    		}
    		break;
    		}
    	}
    	break;
    	default:
    		break;
    	}
    	return TRUE;
    }
    char CDeviceChangeDlg::GetDrive(ULONG unitmask) //    
    {
    	char i;
        for (i = 0; i < 26; ++i)
        {
            if (unitmask & 0x1)
                break;
            unitmask = unitmask >> 1;
        }
        return (i + 'A');
    }

    見終わったら役に立つことを望んでいます.ありがとうございます.