Thread affinity of user interface objects, part 3: Menus, icons, cursors, and accelerator tables

The remaining user interface objects in common use are menus, icons, cursors, and accelerator tables.

Menus do not have thread affinity. Any thread can use a menu. However, if two threads use a menu, it is the responsibility of those threads to coordinate among themselves how that menu will be used, so that one thread doesn't modify a menu while another is busy displaying it, for example. (More on this subject later.)

Icons, cursors, and accelerator tables behave like menus. They do not have thread affinity. They are easier to manage than menus since they cannot be modified once created, so the only thing you have to worry about is not to use one after it has been destroyed.

Next time, GDI objects and an expansion on the subject of thread safety.

Comments (3)
  1. Name required. Yeah yeah. says:

    Do people really do this kind of thing? Split their UI into several threads, I mean. I would expect it to lead to unpredicatable UI behaviour, which is one of the most basic usability no-nos.

  2. Norman Diamond says:

    Thursday, October 13, 2005 3:18 AM by Name required. Yeah yeah.

    > Do people really do this kind of thing?

    > Split their UI into several threads, I mean.

    Suppose a person starts out without that detailed knowledge of Windows APIs or MFC, but they know how to create separate threads to communicate with separate clients or read from separate devices. Maybe the person wants to display all of the events in a single window. The person might design it with a semaphore so that any thread who wants to append to the window takes the semaphore and updates the window. Oops. MFC’s documentation of the fact that this isn’t allowed seems to be published in assert statements instead of in MSDN. AFTER that, people learn not to split their UI into several threads.

  3. Mike says:

    Norman: It’s important to understand what it is that MFC doesn’t allow, and also to understand that it’s a limitation of MFC and not the Windows API. In addition, the limitation is plainly documented in MSDN, for example, at "Multithreading: Programming Tips" at

    MFC uses thread-local storage for its windows handle map (i.e., the map between a handle for a windows window and a C++ CWnd object). Thus, any MFC function (like CDocument::UpdateAllViews) that needs to map from a CWnd object to to a corresponding HWND will fail if called from a worker thread.

    That’s a limitation of MFC, but not a limitation of the API, for the reason that if you know the HWND directly, then it’s always possible to call the API function directly (i.e., without the MFC wrapper).

    As for whether it’s a good idea to split responsibility for the UI between different threads, well, that’s a different question.

Comments are closed.

Skip to main content