多次显示同一窗口

show the same window several times

本文关键字:窗口 显示      更新时间:2023-10-16

我需要多次显示相同的窗口。但是,第二次显示该窗口时,对 RegisterClassEx 的调用中会出现一个错误,该错误ERROR_CLASS_ALREADY_EXISTS似乎是合理的。如果我要多次显示同一窗口,我可以忽略此错误并继续该程序吗?

#include <Windows.h>
#include <tchar.h>
#include <WinUser.h>
#include <sstream>
#include <Commctrl.h>
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "comctl32.lib")
#define WIDTH_WINDOW 378
#define HEIGHT_WINDOW 171
#define LEFT_BUTTON_YES 170
#define TOP_BUTTON_YES 96
#define WIDTH_BUTTON_YES 88
#define HEIGHT_BUTTON_YES 26

void test();
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void show_message(HWND parent,int wndState);
WORD result;
HWND YesButton;
void show_message(HWND parent,int wndState) {
MSG messages;
WNDCLASSEX wincl;
ZeroMemory(&wincl, sizeof(wincl));
wincl.hInstance = GetModuleHandle(NULL);
HINSTANCE instance = wincl.hInstance;
wincl.lpszClassName = L"WindowsApp";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(wincl);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClassEx (&wincl)) {
auto err = GetLastError();
std::wostringstream ss;
wchar_t *text = L"error: ";
ss << text << err;
MessageBox(NULL,ss.str().c_str(),L"RegisterClassEx",0);
return;
}
HWND hwnd = CreateWindow(L"WindowsApp", L"Some Error", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |WS_POPUP|WS_CLIPSIBLINGS,CW_USEDEFAULT, CW_USEDEFAULT,  WIDTH_WINDOW, HEIGHT_WINDOW, parent,  NULL,  instance,NULL 
);
YesButton = CreateWindow(L"BUTTON",L"&Yes",BS_DEFPUSHBUTTON |WS_TABSTOP | WS_VISIBLE | WS_CHILD,LEFT_BUTTON_YES,TOP_BUTTON_YES,WIDTH_BUTTON_YES,HEIGHT_BUTTON_YES, hwnd, NULL, instance,NULL);
ShowWindow(hwnd, wndState);
UpdateWindow(hwnd);
while (GetMessage(&messages, NULL, 0, 0) >0)
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdcStatic = (HDC)wParam;
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch(HIWORD(wParam)) {
case BN_CLICKED:
if((HWND)lParam == YesButton) {
result = IDYES;
}
break;
}
DestroyWindow(hwnd);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
void test() {
size_t times = 2;
do {
show_message(NULL,1);
if(result == IDYES) {
result = 0;
MessageBox(NULL,L"yes",L"button",0);
}
Sleep(2000);
}while(--times);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
test();
return 0;
}

提取RegisterClassEx的功能并将其放在应用程序的开头。正如评论所说,你只需要执行一次,当应用程序终端时就会取消注册。

#include <Windows.h>
#include <tchar.h>
#include <WinUser.h>
#include <sstream>
#include <Commctrl.h>
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "comctl32.lib")
#define WIDTH_WINDOW 378
#define HEIGHT_WINDOW 171
#define LEFT_BUTTON_YES 170
#define TOP_BUTTON_YES 96
#define WIDTH_BUTTON_YES 88
#define HEIGHT_BUTTON_YES 26

void test();
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void show_message(HWND parent, int wndState);
WORD result;
HWND YesButton;
void MyRegisterClass()
{
WNDCLASSEX wincl;
ZeroMemory(&wincl, sizeof(wincl));
wincl.hInstance = GetModuleHandle(NULL);
HINSTANCE instance = wincl.hInstance;
wincl.lpszClassName = L"WindowsApp";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(wincl);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClassEx(&wincl)) {
auto err = GetLastError();
std::wostringstream ss;
wchar_t text[] = L"error: ";
ss << text << err;
MessageBox(NULL, ss.str().c_str(), L"RegisterClassEx", 0);
}
return;
}
void show_message(HWND parent, int wndState) {
MSG messages;
HWND hwnd = CreateWindow(L"WindowsApp", L"Some Error", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_POPUP | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, WIDTH_WINDOW, HEIGHT_WINDOW, parent, NULL, GetModuleHandle(NULL), NULL);
YesButton = CreateWindow(L"BUTTON", L"&Yes", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_VISIBLE | WS_CHILD, LEFT_BUTTON_YES, TOP_BUTTON_YES, WIDTH_BUTTON_YES, HEIGHT_BUTTON_YES, hwnd, NULL, GetModuleHandle(NULL), NULL);
ShowWindow(hwnd, wndState);
UpdateWindow(hwnd);
while (GetMessage(&messages, NULL, 0, 0) > 0)
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdcStatic = (HDC)wParam;
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch (HIWORD(wParam)) {
case BN_CLICKED:
if ((HWND)lParam == YesButton) {
result = IDYES;
}
break;
}
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
void test() {
size_t times = 2;
do {
show_message(NULL, 1);
if (result == IDYES) {
result = 0;
MessageBox(NULL, L"yes", L"button", 0);
}
Sleep(2000);
} while (--times);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MyRegisterClass();
test();
return 0;
}