从 C++ 弹出进度条对话框的最简单方法DLL(视窗)
我正在编写一个 dll,它是另一个 dll(内部 dll)的 COM 包装器,没有 COM 支持。内部 dll 执行冗长的计算,并通过回调函数让外部 dll 了解进度。外部 dll 只是使函数通过 COM 可见。
但是,我需要外部 dll 来弹出进度条对话框(我所服务的 COM 客户端由于各种原因本身无法执行此操作)。那么我该怎么做呢?到目前为止,我看到的所有示例都围绕具有 WinMain
入口点的 Win32 应用程序;如果在需要对话框时我们已经在 dll 调用中该怎么办?
我是 Windows GUI 编程的新手,所以这里超出了我的深度。现有代码包含在下面 - 关于在哪里调用什么的具体建议将不胜感激。我猜我可能需要启动第二个线程来刷新进度对话框。
内部 dll .h 文件(用于隐式链接):
#define INNER_API extern "C" __declspec(dllimport)
//create calculation, passing callbacks for warning messages and progress bar
INNER_API Calculation* __stdcall calc_create(...blah...,
int (__cdecl *set_progressor_callback)(long),
int (__cdecl *print_warning_callback)(const char*));
INNER_API void __stdcall calc_run(Calculation *c);
然后在外部 dll 中,com 包装器 ComWrapperObject.cpp:
int my_progressor_callback(long progress)
{
//set progressor to equal progress, but how?
return 0;
}
STDMETHODIMP ComWrapperObject::do_calculation()
{
//fire up progress bar and message window here, but how?
Calculation *calc = calc_create(...blah..., &my_progressor_callback);
calc_run(calc);
//wait for user to dismiss message window, but how?
return S_OK;
}
I am writing a dll which is a COM wrapper for another dll (the inner dll) without COM support. The inner dll performs a lengthy computation and lets the outer dll know how progress is going via a callback function. The outer dll just makes the functions visible over COM.
However, I need the outer dll to pop up a progress bar dialog (the COM client I'm serving can't do this itself for various reasons). So how do I go about doing that? All examples I have seen so far revolve around Win32 apps which have a WinMain
entry point; what can be done if we're already in a dll call when the dialog is needed?
I'm new to windows GUI programming, so quite out of my depth here. The existing code is included below - specific suggestions on what to call where would be appreciated. I'm guessing I may need to fire off a second thread to refresh the progress dialog.
Inner dll .h file (for implicit linking):
#define INNER_API extern "C" __declspec(dllimport)
//create calculation, passing callbacks for warning messages and progress bar
INNER_API Calculation* __stdcall calc_create(...blah...,
int (__cdecl *set_progressor_callback)(long),
int (__cdecl *print_warning_callback)(const char*));
INNER_API void __stdcall calc_run(Calculation *c);
Then in the outer dll, the com wrapper, ComWrapperObject.cpp:
int my_progressor_callback(long progress)
{
//set progressor to equal progress, but how?
return 0;
}
STDMETHODIMP ComWrapperObject::do_calculation()
{
//fire up progress bar and message window here, but how?
Calculation *calc = calc_create(...blah..., &my_progressor_callback);
calc_run(calc);
//wait for user to dismiss message window, but how?
return S_OK;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我正在发布一个与您更新的问题更相关的新答案(并且为了有资格获得赏金)。首先考虑包含进度条的常规可执行文件的最小源代码:
如果您愿意,我可以发布该程序的相关
.rc
资源文件,尽管代码主要是为了让您获得正确的概念理解。因此,快速总结一下,该程序:从图形上看,它看起来像这样:
您的问题是如何从 DLL 中增加此进度条。您需要做的是允许 DLL 以某种方式与包含进度条的窗口进行通信。我不太确定如何加载 DLL,但假设它是通过 DLL 注入完成的,这是我会采取的方法:
GetProcAddress
和CreateRemoteThread
来调用此初始化例程。HWND
。具体来说,初始化例程如下所示:
客户端代码可能如下所示:
现在您在 DLL 中拥有了客户端的
HWND
,因此您可以通过一种方式进行通信。然后,您可以在客户端中指定自定义消息来更改进度条:同时在
DialogFunc
中添加相应的情况(我们现在可以删除WM_TIMER
代码,因为那只是演示如何与进度条交互):现在要触发客户端进度条的更改,DLL 只需要做:
请注意,需要在 DLL 中将
WM_UPDATE_PROGRESS_BAR
重新定义为 出色地。为了使这一切与您当前的代码相适应:
I'm posting a new answer which is more relevant to your updated question (and in order to be eligible for the bounty). Consider first this minimal source for a regular executable which contains a progress bar:
If you like, I can post the relevant
.rc
resource file for this program although the code is mostly for you to gain the correct conceptual understanding. So to quickly summarise, this program:Graphically, it looks like this:
Your question is how to increment this bar from a DLL instead. What you need to do is to allow some way for the DLL to communicate with the window containing the progress bar. I'm not quite sure how you are loading the DLL, but this is the approach I would take assuming it is done through DLL injection:
GetProcAddress
andCreateRemoteThread
from the client to invoke this initialisation routine.HWND
of the client.Concretely, the intialisation routine would look like this:
The client code might be something like this:
So now you have the
HWND
of the client in the DLL and hence a way for you to do the communication. You can then specify a custom message in the client to change the progress bar:Also add the corresponding case in the
DialogFunc
(we can remove theWM_TIMER
code now because that was only there to demonstrate how to interact with progress bars):And now to trigger changes in the progress bar of the client, the DLL simply has to do:
Note that
WM_UPDATE_PROGRESS_BAR
needs to be redefined in the DLL as well.To fit this all in with your current code:
既然您声明 DLL 没有 GUI 并且客户端处理所有用户交互,那么为什么不将进度信息发送到客户端并在那里显示呢?
如果要在 DLL 中显示对话框,则可以按照与在常规可执行文件中完全相同的方式进行操作。绝对没有区别。如果您希望 DLL 在更新进度条时继续工作,您可以使用 CreateThread 启动一个新线程。
如果您显示一些代码,我们将能够更直接地为您提供帮助。
Since you state that the DLL has no GUI and the client handles all the user interaction, why don't you send the progress information to the client instead and have it displayed there?
If you want to display the dialog in the DLL, you do so in exactly the same way as you would within a regular executable. There is absolutely no difference. If you want the DLL to continue working while it updates the progress bar, you can just kick off a new thread with CreateThread.
If you show some code, we'll be able to help you more directly.