【发布时间】:2021-08-09 16:22:33
【问题描述】:
我有一个简单的 WIN3API 应用程序, 起初它完全可以工作,当我决定通过添加 cmets 和空格来进行代码清理以使代码对自己更具可读性时,我可以轻松地添加更多功能,接下来我知道代码不起作用。当主函数运行'Mainhwnd'返回'NULL'并关闭时,我认为它可能是类注册,虽然它似乎不是问题,任何帮助将不胜感激!谢谢, 这是一个代码sn-p:
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
const wchar_t MainWndClass[] = L"MainWndClass"; // Creating And Registering Main Class
WNDCLASS MainClass = { };
MainClass.lpfnWndProc = WindowProc;
MainClass.hInstance = hInstance;
MainClass.lpszClassName = MainWndClass;
if (!RegisterClass(&MainClass))
{
MessageBox(NULL, L"Error Registering Window Class", L"Error Registering Window", MB_OK | MB_ICONEXCLAMATION);
return 0;
}
Mainhwnd = CreateWindowEx
(
0, // Optional window styles.
MainWndClass, // Window class
L"Main Wnd", // Window text
WS_VISIBLE, // Window style
CW_USEDEFAULT, // XPos
CW_USEDEFAULT, // YPos
MainWindWidth, // Width
MainWindHeight, // Height
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (Mainhwnd == NULL) // Quit If Error
{
MessageBox(NULL, L"Error Creating Window; Window Handle Is NULL", L"Error Creating Window", MB_OK | MB_ICONEXCLAMATION);
return 0;
}
完整代码
// Includes
#include <iostream>
#include <windows.h>
// Definitions
#define BUTTON_ONE_ID 0001
#define BUTTON_TWO_ID 0002
#define BUTTON_THREE_ID 0003
#define BUTTON_FOUR_ID 0004
#ifndef UNICODE
#define UNICODE
#endif
// Global Variables
HWND Mainhwnd;
HMENU hMenu;
HWND ButtonOne;
HWND ButtonTwo;
HWND ButtonThree;
HWND ButtonFour;
INT MainWindWidth = 800;
INT MainWindHeight = 600;
INT ButtonWidth = MainWindWidth/4;
INT ButtonHeight = 100;
// Prototypes
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void AddMenus(HWND);
void AddControls(HWND);
// Entry Point
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
const wchar_t MainWndClass[] = L"MainWndClass"; // Creating And Registering Main Class
WNDCLASS MainClass = { };
MainClass.lpfnWndProc = WindowProc;
MainClass.hInstance = hInstance;
MainClass.lpszClassName = MainWndClass;
if (!RegisterClass(&MainClass))
{
MessageBox(NULL, L"Error Registering Window Class", L"Error Registering Window", MB_OK | MB_ICONEXCLAMATION);
return 0;
}
Mainhwnd = CreateWindowEx
(
0, // Optional window styles.
MainWndClass, // Window class
L"Main Wnd", // Window text
WS_VISIBLE, // Window style
CW_USEDEFAULT, // XPos
CW_USEDEFAULT, // YPos
MainWindWidth, // Width
MainWindHeight, // Height
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (Mainhwnd == NULL) // Quit If Error
{
MessageBox(NULL, L"Error Creating Window; Window Handle Is NULL", L"Error Creating Window", MB_OK | MB_ICONEXCLAMATION);
return 0;
}
ShowWindow(Mainhwnd, nCmdShow); // Show Window
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// Create Window Procedure
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (wParam)
{
case BUTTON_ONE_ID:
std::cout << "B1" << std::endl;
return 0;
case BUTTON_TWO_ID:
std::cout << "B2" << std::endl;
return 0;
case BUTTON_THREE_ID:
std::cout << "B3" << std::endl;
return 0;
case BUTTON_FOUR_ID:
std::cout << "B4" << std::endl;
return 0;
}
return 0;
case WM_CREATE:
AddMenus(hwnd);
AddControls(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 2));
EndPaint(hwnd, &ps);
}
default:
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void AddMenus(HWND hwnd) // Add Menus Function
{
hMenu = CreateMenu();
HMENU hFileMenu = CreateMenu();
SetMenu(hwnd, hMenu);
}
void AddControls(HWND hwnd) // Add Controls Function
{
ButtonOne = CreateWindowW
(
L"Button", L"Button1", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 475, ButtonWidth, 100, hwnd, (HMENU)BUTTON_ONE_ID, NULL, NULL
);
ButtonTwo = CreateWindowW
(
L"Button", L"Button2", WS_CHILD | WS_VISIBLE | WS_BORDER, ButtonWidth, 475, ButtonWidth, 100, hwnd, (HMENU)BUTTON_TWO_ID, NULL, NULL
);
ButtonThree = CreateWindowW
(
L"Button", L"Button3", WS_CHILD | WS_VISIBLE | WS_BORDER, ButtonWidth * 2, 475, ButtonWidth, 100, hwnd, (HMENU)BUTTON_THREE_ID, NULL, NULL
);
ButtonFour = CreateWindowW
(
L"Button", L"Button4", WS_CHILD | WS_VISIBLE | WS_BORDER, ButtonWidth * 3, 475, ButtonWidth, 100, hwnd, (HMENU)BUTTON_FOUR_ID, NULL, NULL
);
}
【问题讨论】:
-
您没有收到任何编译器警告吗?
-
首先要做的是阅读documentation。它说“如果函数失败,则返回值为 NULL。要获取扩展的错误信息,请调用 GetLastError。”
-
default: return 0;是错误。它可以防止 DefWindowProc() 被调用。所以 WM_NCCREATE 没有得到处理。也没有错误,您明确表示您自己处理。删掉就好了。 -
这能回答你的问题吗? Why CreateWindowEx() return NULL
-
FWIW 在
#define <windows.h>之后更改UNICODE的定义是一个非常糟糕的主意...
标签: c++ visual-studio winapi