|
Hi, I am creating a library for a native programming language to be able to create windows forms controls. However, many of the features of the controls such as docking and other things do not work. After searching around, it appears that windows forms controls need a special windows forms message loop, which can be created by calling Application::Run, but this requires that the controls be on a separate thread. 1. Is there a simpler way to get the controls to work correctly, such as using the native window's thread to pass on messages to the controls? 2. If I have to create a new application context, is there a way to use a native window as the form detemining the lifespan of the application context. 3. How do I create controls on a specific application context? I thought originally that the controls had to be created from that context's thread, but the examples I have seen override the ApplicationContext class and create the controls in the constructor, but then the constructor is called in the main thread. 4. If I have to create the controls on a separate thread, what is the best method for setting the controls properties from the main thread? 5. Any other constructive input is appreciated! | | Diggsey Monday, September 28, 2009 6:20 PM | Please ask only one question per thread. A native Windows program imposes a programming model that is very difficult to escape. Code runs in response to events, triggered by the user interacting with the UI. If there are no events, then no code runs. Simply because there is nothing useful to do. If you do have something else to do in your native programming language, that code must run on a separate thread. Whether you actually call Application::Run() on a separate thread is not really relevant. You do have to make sure that the thread is initialized properly by calling Thread::SetApartmentState() to make it an STA thread. 1. It is important that it is actually the Windows Forms message loop that dispatches the messages. Stuff stops working if some other loop does it. This is mostly related to keyboard handling, shortcuts and tabbing. 2. An ApplicationContext keeps the message loop alive until you call its ExitThread() method. 3. Control creation has nothing to do with an ApplicationContext. They are normally created in the Form constructor, it calls InitializeComponent(). The thread that does this doesn't actually matter, the rule is that the thread that creates the form's Handle locks in the association. The first call to CreateWindowEx() creates the message queue. That queue must then be pumped by that same thread. Which is normally the thread that calls Application::Run(). However, you can shoot yourself in the foot if the constructor references properties that require the Handle to be created. Since you can't control that code, you should create the form instance on the UI thread. 4. You can't, the code that does this must run on the same thread that called Application::Run(). You can use the plumbing provided by Control.Invoke() to marshal the call. That will however only work properly if the form handle is created and the UI thread is otherwise idle.
Hans Passant. | | nobugz Tuesday, September 29, 2009 2:04 AM | Thanks for the help, however I still can't get it to work correctly. Here is what I am doing now: - Create a new thread - Set the mode to STA - Start the thread - The thread then creates a derivative of NativeWindow to wrap the unmanaged application window - The thread creates a form with TransparencyKey set to the backcolor to make it transparent - The thread sets the properties of the form, and then shows it with the native window as the parent - The thread calls Application::Run on the form. This works, but it does not solve any of the original issues. Also, none of the controls are able to keep focus for more than about a second, which makes menu strips and textboxes useless. | | Diggsey Tuesday, September 29, 2009 5:59 PM | You are not giving us any relevant info that would help us help you. At least chase the focus problem, what window gets the focus? Use Spy++ to look at message traffic.
Hans Passant. | | nobugz Tuesday, September 29, 2009 7:01 PM | Sorry. It is the native window which is receiving the focus every time. I found that it only happens if focus moves from the native window to the form. If another window is focused first, and then focus is returned to the form, it does not lose focus. Some extra information: - The native window is a directx window. - Because it is procedural rather than event based, I think it uses the PeekMessage command instead of having a dedicated message pump
| | Diggsey Tuesday, September 29, 2009 7:23 PM | Hi Diggsey, Based on my understanding, you want to have WinForm application works together with the DirectX API. We can use managed directx to achieve this goal. The document below shows how to use managed DirectX: http://msdn.microsoft.com/en-us/magazine/cc164112.aspxRegards, Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. | | Aland Li Wednesday, September 30, 2009 5:52 AM | The managed DirectX wrappers have been deprecated for quite a while.
Hans Passant. | | nobugz Wednesday, September 30, 2009 12:08 PM | @Aland Li No, I am trying to make a dll for a native application, which exposes commands to create managed winforms controls. The native application is the one created by the programming language, and I have no control over its internal workings. If you're interested, the programming language is called DarkBasic Professional, and is essentially a BASIC style programming language exposing the directx api in an easy to use way. The programming language allows developers to expand the language by creating dlls which expose new commands. That is what I am doing here. @nobugz Is there any other information I can give you? I don't know how to find out what is causing the lack of focus. Is there a way I can find this out? | | Diggsey Wednesday, September 30, 2009 5:18 PM | I don't know either. For all I know, the engine might be intentionally setting the focus back. If this has something to do with the DarkSDK, these kind of problems don't surprise me. Use the vendor's support forum for help.
Hans Passant. | | nobugz Wednesday, September 30, 2009 5:57 PM | I'm fairly sure it's not the engine, since I have used native controls and forms on it without issue. | | Diggsey Wednesday, September 30, 2009 5:59 PM |
|