c 中的 Winapi Window 没有响应
Winapi Window in c not responding
我一直在尝试使用 WinAPI 制作一个简单的 window,它编译并 links 带有一些警告,当我打开程序时 window 出现了,但是当我尝试与它交互时,会播放 windows 警告音,它不允许我使用 window,甚至无法关闭它,我必须使用任务管理器。
为了编译它,我在命令行中使用了微软的“cl.exe”:
cl /c window.c
警告是:
window.c(39): warning C4133: 'function': incompatible types, from 'LPSTR' to 'HINSTANCE'
window.c(40): warning C4133: 'function': incompatible types, from 'LPSTR' to 'HINSTANCE'
window.c(41): warning C4047: '=': 'HBRUSH' differs in levels of indirection from 'int'
至 link 我在命令行中使用 crinkler:
crinkler /NODEFAULTLIB /ENTRY:main /SUSBYSTEM:WINDOWS /TINYHEADER /TINYIMPORT /OUT:c.exe window.obj kernel32.lib user32.lib
警告是:
: warning LNK: Entry point not at start of section, jump necessary
我使用的代码是:
#include <windows.h>
#define WINDOW_STYLE WS_VISIBLE+WS_OVERLAPPEDWINDOW-WS_THICKFRAME-WS_MAXIMIZE
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
static const char* window_name = "My Window";
RECT window_rect = {0, 0, WINDOW_HEIGHT, WINDOW_WIDTH};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcA(hwnd, uMsg, wParam, lParam);
}
int main()
{
int ret = 0;
HMODULE instance = GetModuleHandleA(NULL);
AdjustWindowRect(&window_rect, WINDOW_STYLE, FALSE);
WNDCLASSEXA window_class;
window_class.cbSize = 48;
window_class.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
window_class.lpfnWndProc = WindowProc;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = instance;
window_class.hIcon = LoadIconA(IDI_APPLICATION, 0);
window_class.hCursor = LoadCursorA(IDI_APPLICATION, 0);
window_class.hbrBackground = COLOR_WINDOW;
window_class.lpszMenuName = 0;
window_class.lpszClassName = window_name;
window_class.hIconSm = 0;
if (RegisterClassExA(&window_class)) {
HWND window = CreateWindowExA(
0,
window_name,
window_name,
WINDOW_STYLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
0,
0,
instance,
NULL);
ShowWindow(window, SW_SHOW);
UpdateWindow(window);
MSG msg;
while(1)
{
if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
ExitProcess(0);
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
} else {
ret = 1;
}
ExitProcess(0);
return ret;
}
有人知道怎么解决吗?谢谢。
以下行与您认为的不一样:
#define WINDOW_STYLE WS_VISIBLE+WS_OVERLAPPEDWINDOW-WS_THICKFRAME-WS_MAXIMIZE
虽然有点常见,有时甚至会产生正确的值,但它是一种非常脆弱的位操作实现方式。在这种特殊情况下,表达式扩展为:
0x10000000L + 0x00CF0000L - 0x00040000L - 0x01000000L
这会产生值 0xFFCB0000L
1(由于不小心使用 WS_MAXIMIZE
而不是 WS_MAXIMIZEBOX
)。这转换为具有以下样式的 window:
WS_POPUP
WS_CHILD
(注意,这已经与 WS_POPUP
互斥了)
WS_ICONIC
WS_VISIBLE
WS_DISABLED
- ...
作为documented:
WS_DISABLED
: The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use the EnableWindow
function.
这就解释了为什么您无法与您的 window 互动。解决方法很简单:使用按位运算符进行位操作而不是算术运算符:
#define WINDOW_STYLE (WS_VISIBLE | WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZE)
1 撇开有符号溢出的行为未定义这一事实。
我一直在尝试使用 WinAPI 制作一个简单的 window,它编译并 links 带有一些警告,当我打开程序时 window 出现了,但是当我尝试与它交互时,会播放 windows 警告音,它不允许我使用 window,甚至无法关闭它,我必须使用任务管理器。
为了编译它,我在命令行中使用了微软的“cl.exe”:
cl /c window.c
警告是:
window.c(39): warning C4133: 'function': incompatible types, from 'LPSTR' to 'HINSTANCE'
window.c(40): warning C4133: 'function': incompatible types, from 'LPSTR' to 'HINSTANCE'
window.c(41): warning C4047: '=': 'HBRUSH' differs in levels of indirection from 'int'
至 link 我在命令行中使用 crinkler:
crinkler /NODEFAULTLIB /ENTRY:main /SUSBYSTEM:WINDOWS /TINYHEADER /TINYIMPORT /OUT:c.exe window.obj kernel32.lib user32.lib
警告是:
: warning LNK: Entry point not at start of section, jump necessary
我使用的代码是:
#include <windows.h>
#define WINDOW_STYLE WS_VISIBLE+WS_OVERLAPPEDWINDOW-WS_THICKFRAME-WS_MAXIMIZE
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
static const char* window_name = "My Window";
RECT window_rect = {0, 0, WINDOW_HEIGHT, WINDOW_WIDTH};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcA(hwnd, uMsg, wParam, lParam);
}
int main()
{
int ret = 0;
HMODULE instance = GetModuleHandleA(NULL);
AdjustWindowRect(&window_rect, WINDOW_STYLE, FALSE);
WNDCLASSEXA window_class;
window_class.cbSize = 48;
window_class.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
window_class.lpfnWndProc = WindowProc;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = instance;
window_class.hIcon = LoadIconA(IDI_APPLICATION, 0);
window_class.hCursor = LoadCursorA(IDI_APPLICATION, 0);
window_class.hbrBackground = COLOR_WINDOW;
window_class.lpszMenuName = 0;
window_class.lpszClassName = window_name;
window_class.hIconSm = 0;
if (RegisterClassExA(&window_class)) {
HWND window = CreateWindowExA(
0,
window_name,
window_name,
WINDOW_STYLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
0,
0,
instance,
NULL);
ShowWindow(window, SW_SHOW);
UpdateWindow(window);
MSG msg;
while(1)
{
if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
ExitProcess(0);
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
} else {
ret = 1;
}
ExitProcess(0);
return ret;
}
有人知道怎么解决吗?谢谢。
以下行与您认为的不一样:
#define WINDOW_STYLE WS_VISIBLE+WS_OVERLAPPEDWINDOW-WS_THICKFRAME-WS_MAXIMIZE
虽然有点常见,有时甚至会产生正确的值,但它是一种非常脆弱的位操作实现方式。在这种特殊情况下,表达式扩展为:
0x10000000L + 0x00CF0000L - 0x00040000L - 0x01000000L
这会产生值 0xFFCB0000L
1(由于不小心使用 WS_MAXIMIZE
而不是 WS_MAXIMIZEBOX
)。这转换为具有以下样式的 window:
WS_POPUP
WS_CHILD
(注意,这已经与WS_POPUP
互斥了)WS_ICONIC
WS_VISIBLE
WS_DISABLED
- ...
作为documented:
WS_DISABLED
: The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has been created, use theEnableWindow
function.
这就解释了为什么您无法与您的 window 互动。解决方法很简单:使用按位运算符进行位操作而不是算术运算符:
#define WINDOW_STYLE (WS_VISIBLE | WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZE)
1 撇开有符号溢出的行为未定义这一事实。