问题:
我试图用C设置Winapi,用最少的代码显示一个简单的窗口,我如何在我的源代码格式化的方式做这件事?
问题:
下面不打开一个窗口,它只是关闭,这是为什么呢?
/* window_s.h */
typedef struct {
WNDCLASS wc;
HINSTANCE hInstance;
HWND hwnd;
} WINDOW;
/* setUpWinProc.h */
LRESULT CALLBACK WindowProc( HWND hwnd,
UINT uMsg, WPARAM wParam,
LPARAM lParam) { }
/* registerWindow.c */
void registerWindow(WINDOW *window) {
const char CLASS_NAME[]
= "Window Class Name";
window->wc.lpfnWndProc = WindowProc;
window->wc.hInstance = window->wc.hInstance;
window->wc.lpszClassName = CLASS_NAME;
RegisterClass(&(window->wc));
}
/* createWindow.c */
int_fast64_t CreateWindow_(WINDOW *window) {
window->hwnd = CreateWindowEx(
0, // Optional window styles
window->wc.lpszClassName, // Window class
"Window", // Window text
WS_OVERLAPPEDWINDOW, //Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
window->hInstance, // Instance handle
NULL // Additional application data
);
if (window->hwnd == NULL)
return 0;
return window->hwnd;
}
/* Window_Main.c */
#include <windows.h>
#include "window_s.h"
#include "setUpWinProc.h"
#include "registerWindow.c"
#include "createWindow.c"
#include <stdio.h>
int WINAPI WinMain ( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR pCmdLine,
int nCmdShow ) {
WINDOW window = {{}, hInstance};
registerWindow(&window);
CreateWindow_(&window);
ShowWindow(window.hwnd, nCmdShow);
}
2条答案
按热度按时间e3bfsja21#
这是问题的一部分:
您认为在
ShowWindow
返回和WinMain
本身返回之后会发生什么?(提示:程序退出)。使用TranslateMessage + DispatchMessage将WinMain扩展到泵消息。
然后,您的消息进程至少需要处理WM_CLOSE和WM_PAINT,并且能够将它不处理的消息转发到默认窗口进程。
您的RegisterClass调用看起来也很可疑。让我们像这样初始化:
如果您有Visual Studio(和版本),则会有一个默认的Win32应用程序,它生成最少的存根应用程序,而这些存根应用程序完全可以完成您试图实现的功能。请在C++项目中查找"默认Windows应用程序"或类似内容。
unftdfkk2#
核心问题就在这里:
正如编译器警告的那样,这个函数需要返回一个值(但实际上并没有)。将其注册为窗口过程的行为是未定义的。它可能无法创建窗口;
CreateWindowEx()
在返回之前使用WM_NCCREATE
和WM_CREATE
消息调用窗口过程。消息处理程序必须返回特定值才能继续创建窗口。窗口类名也有类似的问题:它使用了一个局部变量,但是传递了一个指向它的指针。当
registerWindow()
返回时,CLASS_NAME
消失了。类注册成功,但是当创建窗口时,对CreateWindowEx()
的调用使用了垃圾作为窗口类名。第一个修正如下:
以及
这样就解决了窗口创建问题,尽管您不会长时间看到窗口(如果有的话),因为代码会立即退出
WinMain()
(它也需要返回一个值),从而导致进程终止。要解决这个问题,你必须在创建窗口的线程上发送消息。下面将解决这两个问题:
这是最基本的要求(除非你把
MessageBox()
算作 “打开窗口”),但是它不允许你退出应用程序,要添加这个功能,你需要添加一个WM_DESTROY
处理程序来通知消息循环结束,如下所示: