【发布时间】:2016-10-06 12:06:40
【问题描述】:
在 Windows API 中,制作窗口需要消息泵来保持窗口运行和更新。现在写一个message pump由一个while循环组成,它支配着整个程序,不允许执行其他的东西,这是个大问题。
考虑一下我的代码,它是一个名为CFrame.h 的头文件(因为在里面我创建了一个名为CFrame 的类,它旨在模仿Java 中的JFrame)。换句话说,我希望可以创建多个 CFrame 实例,以便显示多个窗口,并且消息循环不会在创建第一个窗口后停止窗口。
我为函数ThreadExecution()创建了一个新线程,由于某种原因程序刚刚终止,为什么?
#define UNICODE
#include <windows.h>
const wchar_t CLASS_NAME[] = L"Window Class";
static int nWindows = 0; // Number of ongoing windows
class Size { // Size of the window
private:
int width;
int height;
public:
Size(int width, int height) :width(width), height(height) {}
int getWidth() {
return width;
}
int getHeight() {
return height;
}
};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY: nWindows--; break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void RegisterDetails(HINSTANCE hInstance) { // Registers WNDCLASS
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
}
void startMessageLoop() { // This is the message loop which must be in a separate thread
MSG msg;
while (nWindows) {
GetMessage(&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
HWND CreateAWindow(LPCWSTR title, Size size, HINSTANCE hInstance) {
if (nWindows == 0) { // The WNDCLASS only needs to be registered once
RegisterDetails(hInstance);
}
HWND hwnd = CreateWindowEx(0, CLASS_NAME, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, size.getWidth(), size.getHeight(), NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, 5);
return hwnd;
}
void ThreadExecution(HWND hwnd, LPCWSTR title, Size size, HINSTANCE hInstance) {
hwnd = CreateAWindow(title, size, hInstance);
nWindows++;
if (nWindows == 1) // If only one window has been created, the message loop will be called
{
startMessageLoop();
}
}
class CFrame {
private:
HINSTANCE hInstance;
Size size;
HWND hwnd;
public:
CFrame() {
}
CFrame(LPCWSTR title, Size size, HINSTANCE hInstance) :size(size), hInstance(hInstance)
{
std::thread t1(ThreadExecution, hwnd, title, size, hInstance);
t1.detach();
}
};
【问题讨论】:
-
也许将您的工作转移到另一个线程而不是消息循环?
-
你的问题是什么?
-
@appleapple:这很清楚。显示的消息泵没有返回,因此
CFramector 也没有返回,这就解释了为什么不能在同一个线程上创建两个CFrame对象。 -
@MSalters 好吧,我只想在 @MarkoCrush 中添加一些错误说明
-
您的做法完全错误。了解系统的工作原理。不要与之抗争。
标签: c++ windows multithreading winapi