我写了一个应用程序。有一个名为APP 的类,带有窗口句柄,里面有消息循环,以及所有这些东西。
它旨在“运行”这个类的一些对象,每个对象都有一个基于标准窗口所需的一组变量的窗口。
允许公共使用消息循环,它由RunMessageLoop方法运行。 int nCmdShow - 当然,它用于告诉如何显示窗口。
现在,当我创建一些像这样的对象时:
vector <APP *> App;
for (int i=0; i<3; i++)
{
App.push_back(&APP(nCmdShow))
App[i]->RunMessageLoop();
}
程序等待每个消息循环在它开始另一个之前结束。
我想通过这种方式:
vector <APP *> App;
for (int i=0; i<3; i++)
{
App.push_back(&APP(nCmdShow))
}
for (int i=0; i<3; i++)
{
App[i]->RunMessageLoop();
}
当我知道启动时想要运行多少个窗口时,它似乎没问题。
但我不知道如何动态创建新窗口,完全独立于其他窗口。它应该调用消息循环并立即返回WinMain()而不结束消息循环。
我想到了多线程应用程序,每个应用程序类的一个实例的每个线程。但是,不知道如何构建多线程应用程序。
有关可能解决方案的任何想法吗?
答案 0 :(得分:1)
我看到你现在要做的事情,我已经在我的应用程序框架中实现了这一点,名为Lucid(它仍在进行中)。为了回答,您的窗口类将被称为Window
而不是APP
。
这是通过将全局过程传递给您创建的每个窗口来完成的。所有窗口都共享相同的过程。每当任何窗口收到消息时,该消息都会发送到全局过程,全局过程会检查HWND
是否属于您创建的Window
,如果是,则将消息发送给Window
s'程序。以下是对其工作原理的概述。
class Window
{
public:
// The contents of this function can vary from window to window
// provided that you make a subclass and override this method.
virtual LRESULT procedure(HWND wnd, UINT msg, WPARAM wp, LPARAM lp);
// When you create a Window object, add a pointer to it in this map.
// Eg. if (this->hwnd != NULL) createdWindows[this->hwnd] = this;
static map<HWND, Window*> createdWindows;
// When you create a window, make this its procedure.
static LRESULT CALLBACK routeMessage(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
if (createdWindows.find(wnd) != createdWindows.end()) {
// Message belongs to one of our 'Window' objects.
// Pass the message to that window and return the result.
return createdWindows[wnd]->procedure(wnd, msg, wp, lp);
} else {
// It seems you made 'routeMessage' the procedure
// of a window that doesn't belong in the map. Go ahead
// and process the message in the default manner.
return DefWindowProc(wnd, msg, wp, lp);
}
}
};
现在您只需要一个消息循环和一个线程。我有一个使用Lucid的测试项目,它使用单个消息循环在单个线程上创建具有不同过程的2个窗口:
#include "Lucid.h"
using namespace Lucid;
void sayBye(MessageEventArgs& e)
{
MessageBox(NULL, "Goodbye!", "Form 2", MB_OK);
e.handled = true;
}
void Program::onStart()
{
Form* myForm1 = new Form("Hello World!");
myForm1->show();
Form* myForm2 = new Form("Hello World!");
myForm2->addMessageHandler(WM_CLOSE, sayBye);
myForm2->show();
// This Program::onStart() function is called
// immediately before the single message loop is entered.
}
答案 1 :(得分:0)
创建_beginthreadex
等于您需要运行的窗口数的线程。然后,在线程过程中运行消息循环,并等待所有线程都以WaitForMultipleObjects
终止。