Win32 API 打开新窗口
Posted
技术标签:
【中文标题】Win32 API 打开新窗口【英文标题】:Win32 API open new window 【发布时间】:2020-07-24 13:20:29 【问题描述】:我正在学习 Win32 API。在我的主/第一个窗口中,我想要一个打开窗口 2 按钮,然后打开一个新窗口。 所以想法是,当按下按钮时,会调用一个函数来打开窗口 2。 但是我不确定如何在这里调用这个函数:
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
case WM_COMMAND:
switch(wParam)
case OPEN_WINDOW2_BUTTON:
// <------------------------- what do I put here?
case WM_CREATE:
AddControls1(hwnd);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
return 0;
这是我的全部代码:
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <iostream>
#include <tchar.h>
#include <windows.h>
#define OPEN_WINDOW2_BUTTON 1
using namespace std;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT message,WPARAM wParam,LPARAM lParam);
void AddControls1(HWND);
void createwindow2 (WNDCLASSEX wincl_2, HWND& hwnd, HINSTANCE hThisInstance, int nCmdShow);
HWND hMainWindow, hwnd, hHeader;
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");
int WINAPI WinMain(HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
bool endprogram=false;
//create window 1
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl_1; /* Data structure for the windowclass */
/* The Window structure */
wincl_1.hInstance = hThisInstance;
wincl_1.lpszClassName = szClassName;
wincl_1.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl_1.style = CS_DBLCLKS; /* Catch double-clicks */
wincl_1.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl_1.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl_1.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl_1.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl_1.lpszMenuName = NULL; /* No menu */
wincl_1.cbClsExtra = 0; /* No extra bytes after the window class */
wincl_1.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl_1.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
//----
if (!RegisterClassEx (&wincl_1))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Code::Blocks Template Windows App"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
1800, /* The programs width */
920, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow(hwnd,nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
void createwindow2 (WNDCLASSEX wincl_2, HWND& hwnd, HINSTANCE hThisInstance, int nCmdShow)
if (!RegisterClassEx (&wincl_2))
wincl_2.hInstance = hThisInstance;
wincl_2.lpszClassName = szClassName;
wincl_2.lpfnWndProc = (WNDPROC)windowprocessforwindow2; /* This function is called by windows */
wincl_2.style = CS_DBLCLKS; /* Catch double-clicks */
wincl_2.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl_2.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl_2.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl_2.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl_2.lpszMenuName = NULL; /* No menu */
wincl_2.cbClsExtra = 0; /* No extra bytes after the window class */
wincl_2.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl_2.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
HWND handleforwindow2 = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Code::Blocks Template Windows App"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
330, /* The programs width */
320, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow(handleforwindow2,nCmdShow);
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
case WM_COMMAND:
switch(wParam)
case OPEN_WINDOW2_BUTTON:
// <------------------------- what do I put here?
case WM_CREATE:
AddControls1(hwnd);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
return 0;
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2,UINT msg,WPARAM wParam,LPARAM lParam)
switch(msg)
case WM_COMMAND:
switch(wParam)
case WM_CREATE:
AddControls1(hwnd);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc(handleforwindow2,msg,wParam,lParam);
return 0;
void AddControls1(HWND hwnd)
CreateWindowW(L"Button",L" Open Window 2", WS_VISIBLE | WS_CHILD, 215,285,300,30,hwnd, (HMENU)OPEN_WINDOW2_BUTTON,NULL,NULL);
任何帮助将不胜感激。谢谢!
【问题讨论】:
如果你有第二个窗口,那么你必须像第一个窗口一样。创建它,然后显示它。 修复 AddControls1 以创建类似于您最初所做的子窗口并在您的按钮处理程序中调用 AddControls1。看起来您已经在 WM_CREATE 中调用它但没有显示它(ShowWindow)。 您还需要指定新窗口的行为,我的意思是您希望新窗口替换旧窗口还是像弹出窗口一样 【参考方案1】:首先,可以通过GetWindowLong
函数获取应用的实例句柄。
然后创建一个WNDCLASSEX
结构并将其传递给您的createwindow2
函数。
最后在OPEN_WINDOW2_BUTTON
消息中调用(原createwindow2
函数中的hwnd
参数不需要了)。
修改后的代码如下:
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#include <tchar.h>
#include <iostream>
#include <tchar.h>
#include <windows.h>
#define OPEN_WINDOW2_BUTTON 1
using namespace std;
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2, UINT message, WPARAM wParam, LPARAM lParam);
void AddControls1(HWND);
void createwindow2(WNDCLASSEX& wincl_2, HINSTANCE& hThisInstance, int nCmdShow);
void AddControls2(HWND hwnd);
HWND hMainWindow, hwnd, hHeader;
TCHAR szClassName[] = _T("CodeBlocksWindowsApp");
TCHAR szClassName2[] = _T("CodeBlocksWindowsApp2");
int WINAPI WinMain(HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
bool endprogram = false;
//create window 1
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl_1; /* Data structure for the windowclass */
/* The Window structure */
wincl_1.hInstance = hThisInstance;
wincl_1.lpszClassName = szClassName;
wincl_1.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl_1.style = CS_DBLCLKS; /* Catch double-clicks */
wincl_1.cbSize = sizeof(WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl_1.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl_1.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl_1.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl_1.lpszMenuName = NULL; /* No menu */
wincl_1.cbClsExtra = 0; /* No extra bytes after the window class */
wincl_1.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl_1.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
//----
if (!RegisterClassEx(&wincl_1))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx(
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Code::Blocks Template Windows App"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
1800, /* The programs width */
920, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow(hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage(&messages, NULL, 0, 0))
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
void createwindow2(WNDCLASSEX &wincl_2,HINSTANCE &hThisInstance, int nCmdShow)
wincl_2.hInstance = hThisInstance;
wincl_2.lpszClassName = szClassName2;
wincl_2.lpfnWndProc = (WNDPROC)windowprocessforwindow2; /* This function is called by windows */
wincl_2.style = CS_DBLCLKS; /* Catch double-clicks */
wincl_2.cbSize = sizeof(WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl_2.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl_2.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl_2.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl_2.lpszMenuName = NULL; /* No menu */
wincl_2.cbClsExtra = 0; /* No extra bytes after the window class */
wincl_2.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl_2.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
if (!RegisterClassEx(&wincl_2))
return;
HWND handleforwindow2 = CreateWindowEx(
0, /* Extended possibilites for variation */
szClassName2, /* Classname */
_T("Code::Blocks Template Windows App"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
330, /* The programs width */
320, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow(handleforwindow2, nCmdShow);
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
static HINSTANCE hInstance;
case WM_COMMAND:
switch (wParam)
case OPEN_WINDOW2_BUTTON:
WNDCLASSEX w2;
hInstance = (HINSTANCE)::GetWindowLong(hwnd, GWL_HINSTANCE);
createwindow2(w2, hInstance,SW_SHOW);
// <------------------------- what do I put here?
case WM_CREATE:
AddControls1(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
return 0;
LRESULT CALLBACK windowprocessforwindow2(HWND handleforwindow2, UINT msg, WPARAM wParam, LPARAM lParam)
switch (msg)
case WM_COMMAND:
switch (wParam)
return 0;
case WM_CREATE:
AddControls2(handleforwindow2);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(handleforwindow2, msg, wParam, lParam);
return 0;
void AddControls1(HWND hwnd)
CreateWindowW(L"Button", L" Open Window 2", WS_VISIBLE | WS_CHILD, 215, 285, 300, 30, hwnd, (HMENU)OPEN_WINDOW2_BUTTON, NULL, NULL);
void AddControls2(HWND hwnd)
CreateWindowW(L"Button", L" A NEW WINDOW", WS_VISIBLE | WS_CHILD, 215, 285, 300, 30, hwnd, (HMENU)2, NULL, NULL);
【讨论】:
非常感谢 :) 它现在有效,我明白了。 是的,我做到了。所以我现在测试你的代码。打开的第二个窗口与第一个窗口具有相同的按钮。第二个窗口怎么会有不同的按钮? 在windowprocessforwindow2
函数中,您可以将AddControls1
函数更改为其他创建函数来创建您需要的按钮或其他窗口。
所以在 LRESULT CALLBACK windowprocessforwindow2 中,在 WM_CREATE 的情况下,我添加了一个新的 AddControls2 函数。但是窗口 2 仍然只显示 Addcontrols1 按钮。在调试器中,我看到这个 LRESULT CALLBACK windowprocessforwindow2 从未被执行。
你应该在wincl_2
的定义之后调用RegisterClassEx
函数,记住AddControl
传入的参数应该是handleforwindow2
。以上是关于Win32 API 打开新窗口的主要内容,如果未能解决你的问题,请参考以下文章
widnows 使用WIN32 APi 实现修改另一打开程序的窗口显示方式
包装 Win32 的库不会在 Visual Studio 中打开窗口