多次显示同一个窗口
Posted
技术标签:
【中文标题】多次显示同一个窗口【英文标题】:show the same window several times 【发布时间】:2019-12-15 19:14:49 【问题描述】:我需要。但是,第二次显示窗口时,调用 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
一次(同一班)
为什么投反对票?
Get Started with Win32 and C++.
第二次调用RegisterClassEx
失败,因为该类已经注册。因此,只需在程序开始时调用一次RegisterClassEx
。
【参考方案1】:
提取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;
【讨论】:
以上是关于多次显示同一个窗口的主要内容,如果未能解决你的问题,请参考以下文章