|
|
|
|
Forum
Please
Log In
to post a new message or reply to an existing one. If you are not registered, please
register.
NOTE: Some forums may be read-only if you are not currently subscribed to
our technical support services.
Subject |
Author |
Date |
|
Jeroen Walter
|
Nov 18, 2009 - 6:36 AM
|
Hi I’ve noticed that ProfUis (using 2.85) doesn’t support controls that are created in a separate UI thread. One of the things that goes wrong is that CExtHookSpy has no regard for threads and just uses some global static arrays and maps to store information related to CWnd classes such as the profuis controls. For this reason the hooking mechanism in the main thread accesses information that is only available in the other thread. For instance, the MFC macro ASSERT_VALID is called from the profuis controls from for instance CExtScrollBar::OnHookSpyPreTranslateMessage(). This macro tries to find the CWnd corresponding with a HWND in the calling thread. MFC does this correctly, it maintains thread specific maps with CWnd to HWND mapping etc. Therefore, if CExtScrollBar::OnHookSpyPreTranslateMessage is called from a thread other than the thread in which the CExtScrollBar was created (which profuis does unfortunately...), this method will crash the application. Our application uses multiple ui threads, which is supported by MFC. I find it therefore very annoying that a library such as ProfUIS which builds heavily on MFC has no support for multiple ui threads. For us it is not an option to not use multiple ui threads. Do you plan to add support for multiple ui threads in the future? If so, when? Kind regards, Jeroen Walter
|
|
Jeroen Walter
|
Nov 23, 2009 - 3:59 AM
|
I gathered as much and I understand it is not a change that can be implemented easily. I’ve been able to rewrite my code to use only 1 thread, but I don’t like the consequences it had for my application. So my question still stands, are you planning on providing multitheaded support, even if it has the same restrictions as MFC? If so, when? If not, why not?
|
|
Technical Support
|
Nov 23, 2009 - 9:37 AM
|
The main difficulties are hidden in testing - not in development. But this is not why we didn’t get into multithreading yet and this is why latest Microsoft’s also keeping UI single threaded. The UI theming code contains enough large bitmap based skinning elements. The HBITMAP handles are not thread safe because GDI is not multithreaded. Prof-UIS solves this problem. The CExtBitmap class is handle-less. We can potentially keep one paint manager with all the skinning bitmaps in one thread. But making the painting code based on synchronization locks is not really a good idea. So, we think we had to keep one paint manager instance for one thread and do not think about amount of allocated memory. For instance, the XML/PNG skins are defined by approximately 300 bitmaps and this count an only grow with next releases. This means the multithreaded Prof-UIS paint managers will allocate enough small memory only for themes like classic Windows 2000, Windows XP theme API based and non-bitmap-based themes like Office XP, Office 2003, Studio 2005/2008.
We are thinking about multithreaded implementation details right now. This task raises some additional tasks. For instance, automatic synchronization of paint managers installed in different threads.
|
|
Jeroen Walter
|
Nov 24, 2009 - 3:24 AM
|
Alright, thanks. Painting using locks is indeed not something you want to do :) I’m glad you’re considering making a multithreaded implementation.
|
|
Technical Support
|
Nov 18, 2009 - 2:04 PM
|
Adding multiple UI thread support for us means moving all the global variables into thread local storage (TLS) data areas. But the __declspec( thread ) specification has serious limitations: it cannot be applied to classes which have member functions and it’s not safe for dynamically loaded DLLs. This automatically means we should replace all the global smart pointer objects (command manager, resource manager, paint manager) with the thread aware smart pointers. Most of the MFC classes and features, are limited for using inside one thread only: all the window wrappers, CObject and, as result, ASSERT_VALID too. The CWnd::FromHandle() API returns different CWnd* pointers in different threads. I.e. different threads are using different global MFC states including even runtime class descriptions. Simply and dirty saying, different threads are using different copies of MFC. Besides, the GDI library is not multithread safe. All the bitmaps, brushes and fonts stored inside the currently installed paint manager can be used only in one thread where they are created. It’s possible to make Prof-UIS multithreaded, but this requires very strong and heavy testing.
|
|