我看到很多教程和文章向我展示如何制作一个简单的Windows程序,这很棒,但没有一个向我展示如何制作多个窗口。
现在我有了创建和绘制分层窗口的工作代码,我可以使用GDI来绘制任何我想要的东西,拖动它,甚至使它透明等等。
但是我想要第二个矩形区域,我可以绘制,拖动等等。换句话说,第二个窗口。可能希望它成为一个儿童窗口。问题是,我该如何制作?
此外,如果有人知道任何好资源(在线优先),如Windows API中的窗口管理文章或教程,请分享。
答案 0 :(得分:9)
要创建多个窗口,请重复创建第一个窗口时执行的所有步骤以创建第二个窗口。执行此操作的一种好方法是复制并粘贴第一个窗口中的所有代码。然后执行搜索和替换,将第一个窗口的所有名称替换为第二个窗口的唯一名称。我正在执行的代码如下所示。
最重要的是要注意第二个窗口的windows类在代码中应该有一个唯一的名称 line“windowclassforwindow2.lpszClassName =”window class2“。如果它没有唯一名称,则Windows注册将失败。
#include <windows.h>
LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT message,WPARAM wParam,LPARAM lParam);
bool window1closed=false;
bool window2closed=false;
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
bool endprogram=false;
//create window 1
WNDCLASSEX windowclassforwindow1;
ZeroMemory(&windowclassforwindow1,sizeof(WNDCLASSEX));
windowclassforwindow1.cbClsExtra=NULL;
windowclassforwindow1.cbSize=sizeof(WNDCLASSEX);
windowclassforwindow1.cbWndExtra=NULL;
windowclassforwindow1.hbrBackground=(HBRUSH)COLOR_WINDOW;
windowclassforwindow1.hCursor=LoadCursor(NULL,IDC_ARROW);
windowclassforwindow1.hIcon=NULL;
windowclassforwindow1.hIconSm=NULL;
windowclassforwindow1.hInstance=hInst;
windowclassforwindow1.lpfnWndProc=(WNDPROC)windowprocessforwindow1;
windowclassforwindow1.lpszClassName=L"windowclass 1";
windowclassforwindow1.lpszMenuName=NULL;
windowclassforwindow1.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&windowclassforwindow1))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
HWND handleforwindow1=CreateWindowEx(NULL,
windowclassforwindow1.lpszClassName,
L"Parent Window",
WS_OVERLAPPEDWINDOW,
200,
150,
640,
480,
NULL,
NULL,
hInst,
NULL /* No Window Creation data */
);
if(!handleforwindow1)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(handleforwindow1,nShowCmd);
// create window 2
WNDCLASSEX windowclassforwindow2;
ZeroMemory(&windowclassforwindow2,sizeof(WNDCLASSEX));
windowclassforwindow2.cbClsExtra=NULL;
windowclassforwindow2.cbSize=sizeof(WNDCLASSEX);
windowclassforwindow2.cbWndExtra=NULL;
windowclassforwindow2.hbrBackground=(HBRUSH)COLOR_WINDOW;
windowclassforwindow2.hCursor=LoadCursor(NULL,IDC_ARROW);
windowclassforwindow2.hIcon=NULL;
windowclassforwindow2.hIconSm=NULL;
windowclassforwindow2.hInstance=hInst;
windowclassforwindow2.lpfnWndProc=(WNDPROC)windowprocessforwindow2;
windowclassforwindow2.lpszClassName=L"window class2";
windowclassforwindow2.lpszMenuName=NULL;
windowclassforwindow2.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&windowclassforwindow2))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed for window 2",
L"Window Class Failed",
MB_ICONERROR);
}
HWND handleforwindow2=CreateWindowEx(NULL,
windowclassforwindow2.lpszClassName,
L"Child Window",
WS_OVERLAPPEDWINDOW,
200,
150,
640,
480,
NULL,
NULL,
hInst,
NULL);
if(!handleforwindow2)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(handleforwindow2,nShowCmd);
SetParent(handleforwindow2,handleforwindow1);
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
while (endprogram==false) {
if (GetMessage(&msg,NULL,0,0));
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (window1closed==true && window2closed==true) {
endprogram=true;
}
}
MessageBox(NULL,
L"Both Windows are closed. Program will now close.",
L"",
MB_ICONINFORMATION);
return 0;
}
LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY: {
MessageBox(NULL,
L"Window 1 closed",
L"Message",
MB_ICONINFORMATION);
window1closed=true;
return 0;
}
break;
}
return DefWindowProc(handleforwindow,msg,wParam,lParam);
}
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY: {
MessageBox(NULL,
L"Window 2 closed",
L"Message",
MB_ICONINFORMATION);
window2closed=true;
return 0;
}
break;
}
return DefWindowProc(handleforwindow,msg,wParam,lParam);
}
更复杂的示例 - 使用函数创建窗口。
创建没有函数的每个窗口可能会使代码变得混乱 - 特别是如果它在if语句中。下面的代码使用单独的函数来创建每个窗口。前三个窗口有一个创建窗口按钮,用于创建下一个窗口。
#include <Windows.h>
LRESULT CALLBACK windowprocessforwindow1(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow3(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK windowprocessforwindow4(HWND handleforwindow1,UINT message,WPARAM wParam,LPARAM lParam);
#define createwindowbuttoninwindow1 101
#define createwindowbuttoninwindow2 201
#define createwindowbuttoninwindow3 301
bool window1open,window2open,window3open,window4open=false;
bool windowclass1registeredbefore,windowclass2registeredbefore,
windowclass3registeredbefore,windowclass4registeredbefore=false;
enum windowtoopenenumt {none,window2,window3,window4};
windowtoopenenumt windowtoopenenum=none;
void createwindow2(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd);
void createwindow3(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd);
void createwindow4(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd);
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
bool endprogram=false;
WNDCLASSEX windowclassforwindow2;
WNDCLASSEX windowclassforwindow3;
WNDCLASSEX windowclassforwindow4;
HWND handleforwindow2;
HWND handleforwindow3;
HWND handleforwindow4;
//create window 1
MSG msg;
WNDCLASSEX windowclassforwindow1;
ZeroMemory(&windowclassforwindow1,sizeof(WNDCLASSEX));
windowclassforwindow1.cbClsExtra=NULL;
windowclassforwindow1.cbSize=sizeof(WNDCLASSEX);
windowclassforwindow1.cbWndExtra=NULL;
windowclassforwindow1.hbrBackground=(HBRUSH)COLOR_WINDOW;
windowclassforwindow1.hCursor=LoadCursor(NULL,IDC_ARROW);
windowclassforwindow1.hIcon=NULL;
windowclassforwindow1.hIconSm=NULL;
windowclassforwindow1.hInstance=hInst;
windowclassforwindow1.lpfnWndProc=(WNDPROC)windowprocessforwindow1;
windowclassforwindow1.lpszClassName=L"window class 1";
windowclassforwindow1.lpszMenuName=NULL;
windowclassforwindow1.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&windowclassforwindow1))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
HWND handleforwindow1=CreateWindowEx(NULL,
windowclassforwindow1.lpszClassName,
L"Window 1",
WS_OVERLAPPEDWINDOW,
200,
150,
640,
480,
NULL,
NULL,
hInst,
NULL /* No Window Creation data */
);
if(!handleforwindow1)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(handleforwindow1,nShowCmd);
bool endloop=false;
while (endloop==false) {
if (GetMessage(&msg,NULL,0,0));
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (windowtoopenenum !=none) {
switch (windowtoopenenum) {
case window2:
if (window2open==false) {
createwindow2(windowclassforwindow2,handleforwindow2,hInst,nShowCmd);
}
break;
case window3:
if (window3open==false) {
createwindow3(windowclassforwindow3,handleforwindow3,hInst,nShowCmd);
}
break;
case window4:
if (window4open==false) {
createwindow4(windowclassforwindow4,handleforwindow4,hInst,nShowCmd);
}
break;
}
windowtoopenenum=none;
}
if (window1open==false && window2open==false && window3open==false && window4open==false)
endloop=true;
}
MessageBox(NULL,
L"All Windows are closed. Program will now close.",
L"Message",
MB_ICONINFORMATION);
}
void createwindow2(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) {
if (windowclass2registeredbefore==false) {
ZeroMemory(&wc,sizeof(WNDCLASSEX));
wc.cbClsExtra=NULL;
wc.cbSize=sizeof(WNDCLASSEX);
wc.cbWndExtra=NULL;
wc.hbrBackground=(HBRUSH)COLOR_WINDOW;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=NULL;
wc.hIconSm=NULL;
wc.hInstance=hInst;
wc.lpfnWndProc=(WNDPROC)windowprocessforwindow2;
wc.lpszClassName=L"wc2";
wc.lpszMenuName=NULL;
wc.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wc))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
else
windowclass2registeredbefore=true;
}
hwnd=CreateWindowEx(NULL,
wc.lpszClassName,
L"Window 2",
WS_OVERLAPPEDWINDOW,
200,
170,
640,
480,
NULL,
NULL,
hInst,
NULL /* No Window Creation data */
);
if(!hwnd)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(hwnd,nShowCmd);
}
void createwindow3(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) {
if (windowclass3registeredbefore==false) {
ZeroMemory(&wc,sizeof(WNDCLASSEX));
wc.cbClsExtra=NULL;
wc.cbSize=sizeof(WNDCLASSEX);
wc.cbWndExtra=NULL;
wc.hbrBackground=(HBRUSH)COLOR_WINDOW;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=NULL;
wc.hIconSm=NULL;
wc.hInstance=hInst;
wc.lpfnWndProc=(WNDPROC)windowprocessforwindow3;
wc.lpszClassName=L"window class 3";
wc.lpszMenuName=NULL;
wc.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wc))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
else
windowclass3registeredbefore=true;
}
hwnd=CreateWindowEx(NULL,
wc.lpszClassName,
L"Window 3",
WS_OVERLAPPEDWINDOW,
200,
190,
640,
480,
NULL,
NULL,
hInst,
NULL /* No Window Creation data */
);
if(!hwnd)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(hwnd,nShowCmd);
}
void createwindow4(WNDCLASSEX& wc,HWND& hwnd,HINSTANCE hInst,int nShowCmd) {
if (windowclass4registeredbefore==false) {
ZeroMemory(&wc,sizeof(WNDCLASSEX));
wc.cbClsExtra=NULL;
wc.cbSize=sizeof(WNDCLASSEX);
wc.cbWndExtra=NULL;
wc.hbrBackground=(HBRUSH)COLOR_WINDOW;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hIcon=NULL;
wc.hIconSm=NULL;
wc.hInstance=hInst;
wc.lpfnWndProc=(WNDPROC)windowprocessforwindow4;
wc.lpszClassName=L"window class 4";
wc.lpszMenuName=NULL;
wc.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClassEx(&wc))
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window class creation failed",
L"Window Class Failed",
MB_ICONERROR);
}
else
windowclass4registeredbefore=true;
}
hwnd=CreateWindowEx(NULL,
wc.lpszClassName,
L"Window 4",
WS_OVERLAPPEDWINDOW,
200,
210,
640,
480,
NULL,
NULL,
hInst,
NULL /* No Window Creation data */
);
if(!hwnd)
{
int nResult=GetLastError();
MessageBox(NULL,
L"Window creation failed",
L"Window Creation Failed",
MB_ICONERROR);
}
ShowWindow(hwnd,nShowCmd);
}
// windows process functions
LRESULT CALLBACK windowprocessforwindow1(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
switch(message) {
case WM_CREATE:
window1open=true;
CreateWindowEx(NULL,
L"BUTTON",
L"Open Window 2",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
50,
220,
150,
24,
hwnd,
(HMENU)createwindowbuttoninwindow1,
GetModuleHandle(NULL),
NULL);
break;
case WM_DESTROY:
window1open=false;
break;
case WM_COMMAND:
switch LOWORD(wParam) {
case createwindowbuttoninwindow1:
windowtoopenenum=window2;
break;
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK windowprocessforwindow2(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
switch(message) {
case WM_CREATE:
window2open=true;
CreateWindowEx(NULL,
L"BUTTON",
L"Open Window 3",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
50,
220,
150,
24,
hwnd,
(HMENU)createwindowbuttoninwindow2,
GetModuleHandle(NULL),
NULL);
break;
case WM_DESTROY:
window2open=false;
break;
case WM_COMMAND:
switch LOWORD(wParam) {
case createwindowbuttoninwindow2:
windowtoopenenum=window3;
break;
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK windowprocessforwindow3(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
switch(message) {
case WM_CREATE:
window3open=true;
CreateWindowEx(NULL,
L"BUTTON",
L"Open Window 4",
WS_TABSTOP|WS_VISIBLE|
WS_CHILD|BS_DEFPUSHBUTTON,
50,
220,
150,
24,
hwnd,
(HMENU)createwindowbuttoninwindow3,
GetModuleHandle(NULL),
NULL);
break;
case WM_DESTROY:
window3open=false;
break;
case WM_COMMAND:
switch LOWORD(wParam) {
case createwindowbuttoninwindow3:
windowtoopenenum=window4;
break;
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
LRESULT CALLBACK windowprocessforwindow4(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {
switch(message) {
case WM_DESTROY:
window4open=false;
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
如果您关闭并重新打开窗口该怎么办?
如果单击关闭按钮并重新打开同一窗口,请注意以下事项。关闭按钮关闭后窗口关闭时,它将被销毁。但是破坏窗口并不会破坏windows类。它只会从createwindow函数中销毁窗口。这使得上述程序中的if语句只有在第一次显示窗口时才创建Windows类。
一些附注
您只需使用一个Windows类即可创建多个窗口。但问题是你有一个Windows进程函数来处理多个窗口。在这个简单的例子中,这可行。但是窗口越异构,就越需要为每个窗口创建一个单独的窗口类。
此外,多个createwindow函数可以合并为一个函数。请注意,它们之间的唯一区别是wc.lpszClassName代码行。但是Windows可能彼此不同,因此将功能合并为一个并不是必需的 - 更多的是不要让代码重复。
进一步阅读
网站上的域名功能x的链接提供了有关Windows设计概念的更多详细信息。链接为here
functionx.com的主页具有良好的编程学习资源。 特别重要的是这个页面有一些编程参考资料,例如更改windows类,创建列表框和其他窗口控件。它也是win32编程学习的一个很好的资源。 functionx.com win32编程
答案 1 :(得分:8)
如果需要,可以多次点击CreateWindow()。 WinMain中的消息循环将事件传递给WinMain创建的所有窗口。您甚至可以创建两个重叠的窗口,如果需要,可以将第二个窗口的父窗口设置为第一个窗口的句柄。
答案 2 :(得分:3)
答案 3 :(得分:2)
您可以使用CreateWindow / CreateWindowEx创建任意数量的窗口,并根据需要创建它们之间的关系(所有者/孩子)。
你可以通过以下方式让一个窗口“拥有”:
SetWindowLongPtr(hwnd, GWLP_HWNDPARENT, (LONG_PTR) hwndParent);
要将窗口转换为子窗口,请使用SetParent
。
请注意,使用SetWindowLongPtr
的{{1}}调用不会像SetParent一样(我认为MSDN错误)。 GWLP_HWNDPARENT
不会将窗口转换为“子”,而是转换为“拥有”。
答案 4 :(得分:2)
我知道这已经得到了解答,但我只是编写了一个程序,通过for循环打开任意数量的窗口。
这是我的版本。基本上,它重用相同的类生成器来构建多个窗口。您可以根据需要创建任意数量的内容。只需确保相应地调整HWND []和WNDCLASSEX wc []数组。
注1:这段代码使用全局ApplicationInstance,它派生自WinMain函数。在WinMain中,将收到的hInstance分配给ApplicationInstance,在此示例中假定全局可用。这是您的主要应用程序窗口实例。
注意2:当然,您必须预先编写WinProc例程,并将其包含在另一个头文件中,或者仅在上面(本示例中未显示)。在此代码中,它被引用为WinProc,何时将其传递给PopulateClass(WNDPROC流程)
注3:SpawnWindow支持&#34;居中&#34;并且&#34;最大化&#34;标志。他们所做的是不言自明的。
此外,窗口类名称是自动生成的,因此您无需担心命名它,只需为其指定一个良好的基本名称。
int WindowCounter = 0;
WNDCLASSEX wc[1000];
HWND hwnd[1000];
char class_name[256]; // for auto class name generation
void PopulateClass(WNDPROC process) {
ZeroMemory(&wc[WindowCounter], sizeof(WNDCLASSEX));
wc[WindowCounter].cbSize = sizeof(WNDCLASSEX);
wc[WindowCounter].style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
wc[WindowCounter].lpfnWndProc = process;
wc[WindowCounter].cbClsExtra = 0;
wc[WindowCounter].cbWndExtra = 0;
wc[WindowCounter].hInstance = ApplicationInstance;
wc[WindowCounter].hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc[WindowCounter].hCursor = LoadCursor(nullptr, IDC_ARROW);
wc[WindowCounter].hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc[WindowCounter].lpszMenuName = nullptr;
sprintf(class_name, "WindowClass%d", WindowCounter);
wc[WindowCounter].lpszClassName = class_name;
wc[WindowCounter].hIconSm = nullptr;
}
现在,让我们通过提供SpawnWindow函数将它们放在一起!
HWND SpawnWindow(int x,
int y,
int width,
int height,
bool centered = false,
bool maximized = false) {
PopulateClass(WinProc);
RegisterClassEx(&wc[ WindowCounter ]);
int config_style = WS_OVERLAPPEDWINDOW;
if (maximized) { width = GetSystemMetrics(SM_CXFULLSCREEN); height = GetSystemMetrics(SM_CYFULLSCREEN); config_style = WS_OVERLAPPEDWINDOW | WS_MAXIMIZE; }
if (centered) { x = (GetSystemMetrics(SM_CXFULLSCREEN) / 2) - (width / 2); y = (GetSystemMetrics(SM_CYFULLSCREEN) / 2) - (height / 2); }
hwnd[WindowCounter] = CreateWindowEx(NULL,
wc[WindowCounter].lpszClassName,
config.namever(),
WS_OVERLAPPEDWINDOW,
x,
y,
width,
height,
nullptr,
nullptr,
ApplicationInstance,
nullptr);
HWND returnID = hwnd[WindowCounter];
ShowWindow(hwnd[WindowCounter++], SW_SHOW);
return returnID;
}
最后,只需一行代码就可以创建任意数量的窗口:
void CreateWindows() {
HWND PrimaryWindow1 = SpawnWindow(500, 500, 250, 250);
HWND PrimaryWindow2 = SpawnWindow(500, 500, 250, 250, true);
HWND PrimaryWindow3 = SpawnWindow(500, 500, 250, 250, true, true);
HWND PrimaryWindow4 = SpawnWindow(100, 100, 150, 150);
HWND PrimaryWindow5 = SpawnWindow(450, 500, 350, 150);
}
在进入主循环之前,从WinMain调用CreateWindows()。
希望这可以帮助那些人。
为所有窗口使用单个WinProc
注意,这将需要对上述代码进行额外修改。特别是,将自定义类名传递给SpawnWindow函数,表示每个窗口。例如:&#34; WindowClass_App&#34;,其中&#34; WindowClass _&#34;可以是名称的静态部分,实际的标识符只是:&#34; App&#34;,&#34;工具箱&#34;,&#34;边栏&#34;,&#34; AnotherCustomWindow&#34 ;等等。首先定义它们:
#define WindowClass_App 0
#define WindowClass_Layers 2
#define WindowClass_OpenGL 3
/* ...etc... */
我编写了一个将字符串转换为int ID的函数。此ID将用于在单个WinProc函数中分支,具体取决于已收到消息的窗口类:
int IdentifyWindowClassID(const char *lpClassName) {
int WindowClassID = -1;
// Convert string names to integers, because C++ switch does not support strings
if (strcmp(lpClassName, "WindowClass_App") == 0) WindowClassID = WindowClass_App;
if (strcmp(lpClassName, "WindowClass_Layers") == 0) WindowClassID = WindowClass_Layers;
if (strcmp(lpClassName, "WindowClass_OpenGL") == 0) WindowClassID = WindowClass_OpenGL;
/* etc */
return WindowClassID;
}
最后,WinProc本身:
long __stdcall WinProc(HWND hwnd, unsigned int msg, WPARAM wparam, LPARAM lparam)
{
char lpClassName[128];
GetClassName(hwnd, lpClassName, 128);
int WindowClassID = IdentifyWindowClassID( lpClassName );
switch (WindowClassID)
{
/* 1.) Main application window */
case WindowClass_App: {
switch (msg) {
case WM_CREATE: {
/* ...code... */
}
/* ...code... */
}
/* 2.) Layers window */
case WindowClass_Layers: {
switch (msg) {
case WM_CREATE: {
/* ...code... */
}
/* ...code... */
}
/* 3.) OpenGL view window... */
...
这是基本模式。当然,你可以用你想要的任何方式制作它,这就是我做的,它很简单,对我有用。