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. Other Discussions
  3. Clever Code
  4. IsWindow/DestroyWindow Threading Issue

IsWindow/DestroyWindow Threading Issue

Scheduled Pinned Locked Moved Clever Code
c++jsonhelptutorial
3 Posts 3 Posters 2 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.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    Ack. Just been bitten by an old classic that some people may not be aware of. I have a multi-threaded ATL app, and one of the threads needs to create a hidden window in order to intercept messages from a PDF driver. To keep resources to a minimum, this window is created the first time it is needed, rather than on startup. All seemed to be working OK, except, when the app closes, an assert was being thrown by the following code found in the destructor of the class that created the window:

    if (notify_wnd_ != NULL)
    notify_wnd_.DestroyWindow()

    On inspecting the ATL CWindow::DestroyWindow (in atlwin.h) I came across the following:

    ATLASSERT(::IsWindow(m_hWnd));

    This explains my mistake - the thread that created the window is different to the one used to destroy it, which, according to the MSDN docs, is a no-no - in fact, the IsWindow and DestroyWindow pages both make specific mention of this. While frameworks such as ATL, MFC, WTL, etc. are incredibly useful, it is always worth knowing what they are doing under the hood, as this example shows. A little knowledge of the Win32 API is still essential IMHO, even with a variety of frameworks available that are designed to hide the details away. I hope someone else finds this useful.


    Kicking squealing Gucci little piggy.

    A 1 Reply Last reply
    0
    • L Lost User

      Ack. Just been bitten by an old classic that some people may not be aware of. I have a multi-threaded ATL app, and one of the threads needs to create a hidden window in order to intercept messages from a PDF driver. To keep resources to a minimum, this window is created the first time it is needed, rather than on startup. All seemed to be working OK, except, when the app closes, an assert was being thrown by the following code found in the destructor of the class that created the window:

      if (notify_wnd_ != NULL)
      notify_wnd_.DestroyWindow()

      On inspecting the ATL CWindow::DestroyWindow (in atlwin.h) I came across the following:

      ATLASSERT(::IsWindow(m_hWnd));

      This explains my mistake - the thread that created the window is different to the one used to destroy it, which, according to the MSDN docs, is a no-no - in fact, the IsWindow and DestroyWindow pages both make specific mention of this. While frameworks such as ATL, MFC, WTL, etc. are incredibly useful, it is always worth knowing what they are doing under the hood, as this example shows. A little knowledge of the Win32 API is still essential IMHO, even with a variety of frameworks available that are designed to hide the details away. I hope someone else finds this useful.


      Kicking squealing Gucci little piggy.

      A Offline
      A Offline
      Ami Bar
      wrote on last edited by
      #2

      As far as I know its has something to do with Windows 3.1 behavior, which the following Windows inherited. Note that in .NET you have the same issue, if you create a control in one thread, for example label on a form, the label can only be update on the same thread that it was created. In .NET 1.1 it works, but in .NET 2.0 it throws an exception. Frameworks or not, you must know what Windows does. Ami

      S 1 Reply Last reply
      0
      • A Ami Bar

        As far as I know its has something to do with Windows 3.1 behavior, which the following Windows inherited. Note that in .NET you have the same issue, if you create a control in one thread, for example label on a form, the label can only be update on the same thread that it was created. In .NET 1.1 it works, but in .NET 2.0 it throws an exception. Frameworks or not, you must know what Windows does. Ami

        S Offline
        S Offline
        Shog9 0
        wrote on last edited by
        #3

        Ami Bar wrote:

        Note that in .NET you have the same issue, if you create a control in one thread, for example label on a form, the label can only be update on the same thread that it was created.

        AFAIK, this is a different issue - the subsystem isn't threadsafe, so you could run into problems trying to (say) change window text from two different threads at once. .NET 2.0 disallows it simply because of the problems it can cause...

        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