如何从 DLL 正确启动 winforms 表单?
还有另一个问题与我的类似,但我想收集一些细节:
我想创建一个从非托管代码调用的 DLL。当DLL中调用非托管函数时,我想收集信息并以某种形式显示出来。
我想做的是,当调用 DllMain() 时,原因是DLL_PROCESS_ATTACH,我想实例化一个表单。该表单应该在单独的线程上运行。当我的 DLL 中的函数 FOO() 被调用时,我想从 FOO() 中获取信息,将其分派到表单进行渲染。
因此,更具体地说:
i) 创建 DLL 项目并能够使设计器中创建的 Windows 窗体可供 DLL 使用的正确方法是什么?
< strong>ii) 为该表单提供自己的线程和消息处理循环的正确方法是什么?
iii) 如何从将非托管 DLL 函数传递给表单,或者可以更新其自身状态和表单的托管类?
DLL 内的表单有点像传入和传出 DLL 的数据的“监视器”,这样我就可以跟踪错误/bug,但不能更改可用 DLL 函数的核心功能。
There's another question similar to mine, but I wanted to gather some specifics:
I want to create a DLL that is called from unmanaged code. When the unmanaged functions are called in the DLL, I want to collect information and show it in a kind of form.
What I'd like to do is, when DllMain() is called, and the reason is DLL_PROCESS_ATTACH, I would like to instantiate a form. This form should be run on a separate thread. When my function FOO() inside my DLL is called, I would like to take the information from FOO(), dispatch it to the form for rendering.
So, more specifically:
i) What is the proper way to create a DLL project and have the ability to have Windows forms created in the designer be available to the DLL?
ii) What is the correct way to give this form its own thread and message processing loop?
iii) How do I dispatch information from the unmanaged DLL functions to the form, or, alternatively a managed class that can update its own state and the form?
The form inside the DLL is sort of a "monitor" for data passing in and out of the DLL, so I can keep track of errors/bugs, but not change the core functionality of the DLL functions that are available.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 DllMain 中执行操作时应该非常小心(不能调用 LoadLibrary 或其他获取加载程序锁的函数)
You should be very careful when doing things in DllMain (You CANNOT call LoadLibrary or other functions that acquire the loader lock)
一个应用程序只能有一个消息处理循环 - 所有 UI 必须存在于单个线程上。您可以创建一个位于应用程序 UI 线程上的无模式表单,但如果 UI 线程“繁忙”,它不会将消息分派到您的表单,因此它不会是交互式的。
恕我直言,避免麻烦的最简单方法是编写一个单独的 .exe 来处理表单,并让您的 dll 只需启动它,以便整个表单作为单独的常规 WinForms 进程运行。然后,您可以使用套接字、WM_USER 消息,甚至只是共享文件,将命令和数据从您的 dll 发送到表单的进程。 (套接字的优点是您也可以在不同的 PC 上运行监控表单)
An application can only have one message processing loop - all your UI must exist on a single thread. You can create a modeless form that sits on the application's UI thread, but if the UI thread is "busy" it won't dispatch messages to your form, so it won't be interactive.
IMHO the easiest way to avoid trouble would be to write a separate .exe to handle the form and have your dll simply launch it so that the whole form runs as a separate regular WinForms process. Then you could use Sockets, WM_USER messages, or even just shared files to send commands and data to the form's process from your dll. (A socket would have the advantage that you could run the monitoring form on a different PC, too)
我的做法如下:
首先,将回调设置为 Form.Handle。然后,您可以通过覆盖 .NET 表单中的 WndProc 来调用 checkForInformation(),也可以设置一个计时器来定期调用 checkForInformation。一旦您的表单准备好信息,请调用retrieveInformation() 并检查表单的窗口处理程序中是否有一条神奇消息(WM_USER + 您的偏移量)。
Here's what I do:
First, set the callback to Form.Handle. Thenyou can either call checkForInformation() by overriding the WndProc in a .NET form OR you can set a timer to periodically call checkForInformation. Once your form is ready for the info call retrieveInformation() and check in the Form's window handler for a magic message (WM_USER + your offset).