Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Using a Message-Only Window to Receive Device Change Notification Messages [modified]

Using a Message-Only Window to Receive Device Change Notification Messages [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
c++csharpvisual-studiocomhelp
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jim Fell
    wrote on last edited by
    #1

    I'm trying to get write a message-only window to receive device change notification messages for a USB device. I am using MFC, C++, and Visual Studio 2008. Everything compiles, and it runs without crashing or locking up, but the event handler is never triggered. The device of interest is installed on Windows as a virtual COM port. My main application instantiates the class described below then waits for a character input from the keyboard polling using a while loop. It is during this wait time that I remove and insert my USB device expecting the event to get fired.

    class CMessageOnlyWindow : public CWnd
    {
    DECLARE_DYNAMIC(CMessageOnlyWindow)
    private:
    DEV_BROADCAST_DEVICEINTERFACE * _pDevIF; // The notification filter.
    HDEVNOTIFY _hNotifyDev; // The device notification handle.
    public:
    CMessageOnlyWindow();
    virtual ~CMessageOnlyWindow();
    protected:
    afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
    private:
    void RegisterNotification( void );
    void UnregisterNotification( void );
    protected:
    DECLARE_MESSAGE_MAP() // Must be last.
    };

    For simplicity, I've removed all the cleanup and error-handling:

    DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, \
    0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

    IMPLEMENT_DYNAMIC(CMessageOnlyWindow, CWnd)

    CMessageOnlyWindow::CMessageOnlyWindow()
    {
    CString cstrWndClassName = ::AfxRegisterWndClass( NULL );
    BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
    L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
    this->RegisterNotification();
    }

    CMessageOnlyWindow::~CMessageOnlyWindow() {}

    BEGIN_MESSAGE_MAP(CMessageOnlyWindow, CWnd)
    ON_WM_DEVICECHANGE()
    END_MESSAGE_MAP()

    afx_msg BOOL CMessageOnlyWindow::OnDeviceChange( UINT nEventType, DWORD dwData )
    {
    switch ( nEventType ) // <-- Never gets here.
    {
    case DBT_DEVICEARRIVAL:
    break;

    case DBT\_DEVICEREMOVECOMPLETE:
        break;
    
    default:
        break;
    }
    
    return TRUE;
    

    }

    void CMessageOnlyWindow::RegisterNotification(void)
    {
    _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
    _hNotifyDev = Regi

    L 2 Replies Last reply
    0
    • J Jim Fell

      I'm trying to get write a message-only window to receive device change notification messages for a USB device. I am using MFC, C++, and Visual Studio 2008. Everything compiles, and it runs without crashing or locking up, but the event handler is never triggered. The device of interest is installed on Windows as a virtual COM port. My main application instantiates the class described below then waits for a character input from the keyboard polling using a while loop. It is during this wait time that I remove and insert my USB device expecting the event to get fired.

      class CMessageOnlyWindow : public CWnd
      {
      DECLARE_DYNAMIC(CMessageOnlyWindow)
      private:
      DEV_BROADCAST_DEVICEINTERFACE * _pDevIF; // The notification filter.
      HDEVNOTIFY _hNotifyDev; // The device notification handle.
      public:
      CMessageOnlyWindow();
      virtual ~CMessageOnlyWindow();
      protected:
      afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
      private:
      void RegisterNotification( void );
      void UnregisterNotification( void );
      protected:
      DECLARE_MESSAGE_MAP() // Must be last.
      };

      For simplicity, I've removed all the cleanup and error-handling:

      DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, \
      0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

      IMPLEMENT_DYNAMIC(CMessageOnlyWindow, CWnd)

      CMessageOnlyWindow::CMessageOnlyWindow()
      {
      CString cstrWndClassName = ::AfxRegisterWndClass( NULL );
      BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
      L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
      this->RegisterNotification();
      }

      CMessageOnlyWindow::~CMessageOnlyWindow() {}

      BEGIN_MESSAGE_MAP(CMessageOnlyWindow, CWnd)
      ON_WM_DEVICECHANGE()
      END_MESSAGE_MAP()

      afx_msg BOOL CMessageOnlyWindow::OnDeviceChange( UINT nEventType, DWORD dwData )
      {
      switch ( nEventType ) // <-- Never gets here.
      {
      case DBT_DEVICEARRIVAL:
      break;

      case DBT\_DEVICEREMOVECOMPLETE:
          break;
      
      default:
          break;
      }
      
      return TRUE;
      

      }

      void CMessageOnlyWindow::RegisterNotification(void)
      {
      _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
      memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
      _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
      _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
      _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
      _hNotifyDev = Regi

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      AFAIK the window will only get messages when it is "visible" and non-minimized, which means you should show it on the desktop, at any location you like, including (-1000,-1000) to keep it out of sight. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

      Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

      J 1 Reply Last reply
      0
      • L Luc Pattyn

        AFAIK the window will only get messages when it is "visible" and non-minimized, which means you should show it on the desktop, at any location you like, including (-1000,-1000) to keep it out of sight. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

        Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

        J Offline
        J Offline
        Jim Fell
        wrote on last edited by
        #3

        Thanks, Luc. I tried specifying a location with the same lackluster results:

        // BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
        // L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
        BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
        L"CMessageOnlyWindow", -1000, -1000, 100, 100, 0, HWND_MESSAGE, 0 );

        L 1 Reply Last reply
        0
        • J Jim Fell

          Thanks, Luc. I tried specifying a location with the same lackluster results:

          // BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
          // L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
          BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
          L"CMessageOnlyWindow", -1000, -1000, 100, 100, 0, HWND_MESSAGE, 0 );

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          I was thinking you had to actually show the window (hence the off-screen coordinates), howver my source code (which is C#) doesn't, and works well. I'm afraid I can't help you. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

          1 Reply Last reply
          0
          • J Jim Fell

            I'm trying to get write a message-only window to receive device change notification messages for a USB device. I am using MFC, C++, and Visual Studio 2008. Everything compiles, and it runs without crashing or locking up, but the event handler is never triggered. The device of interest is installed on Windows as a virtual COM port. My main application instantiates the class described below then waits for a character input from the keyboard polling using a while loop. It is during this wait time that I remove and insert my USB device expecting the event to get fired.

            class CMessageOnlyWindow : public CWnd
            {
            DECLARE_DYNAMIC(CMessageOnlyWindow)
            private:
            DEV_BROADCAST_DEVICEINTERFACE * _pDevIF; // The notification filter.
            HDEVNOTIFY _hNotifyDev; // The device notification handle.
            public:
            CMessageOnlyWindow();
            virtual ~CMessageOnlyWindow();
            protected:
            afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
            private:
            void RegisterNotification( void );
            void UnregisterNotification( void );
            protected:
            DECLARE_MESSAGE_MAP() // Must be last.
            };

            For simplicity, I've removed all the cleanup and error-handling:

            DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, \
            0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

            IMPLEMENT_DYNAMIC(CMessageOnlyWindow, CWnd)

            CMessageOnlyWindow::CMessageOnlyWindow()
            {
            CString cstrWndClassName = ::AfxRegisterWndClass( NULL );
            BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
            L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
            this->RegisterNotification();
            }

            CMessageOnlyWindow::~CMessageOnlyWindow() {}

            BEGIN_MESSAGE_MAP(CMessageOnlyWindow, CWnd)
            ON_WM_DEVICECHANGE()
            END_MESSAGE_MAP()

            afx_msg BOOL CMessageOnlyWindow::OnDeviceChange( UINT nEventType, DWORD dwData )
            {
            switch ( nEventType ) // <-- Never gets here.
            {
            case DBT_DEVICEARRIVAL:
            break;

            case DBT\_DEVICEREMOVECOMPLETE:
                break;
            
            default:
                break;
            }
            
            return TRUE;
            

            }

            void CMessageOnlyWindow::RegisterNotification(void)
            {
            _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
            memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
            _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
            _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
            _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
            _hNotifyDev = Regi

            L Offline
            L Offline
            Luc Pattyn
            wrote on last edited by
            #5

            Hi again, I happened to require detection of memory stick insertions (in C# again), and experimented a bit more. My conclusion is the app needs a window that is shown, non-minimized, possibly off-screen, and then overriding the wndProc yields the necessary events. So I chose "manual window position" with a bounding rectangle of (-32000,-32000,100,100) and it works well; it does not when minimized or not shown at all. :)

            Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

            Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups