我刚刚开始学习 C++ 的 Windows 编程。我有一个疯狂的想法,win32 编程是基于调用 Windows 函数并向它们发送参数和从它们发送参数的。就像,当你想创建窗口时,你调用一些处理 Windows GUI 的 win32 函数并说“嗨,请为我创建一个新窗口,100 x 100 px,带有两个按钮”,而该 GUI 函数会说“嗨,没问题” ,当发生某些事情时,比如用户单击一个按钮,我将更改位于该位置的变量 xy”。
所以,我认为它与控制台编程非常相似。但第一个指令让我感到惊讶。我一直认为每个程序都会首先执行 main() 函数。因此,当我启动应用程序时,Windows 将一些参数存储在堆栈顶部并运行该应用程序。所以我假设初始化 main() 只是一种 C++ 方式来告诉编译器第一条指令应该在哪里。
但是在win32编程中,首先启动的是一个名为WinMain()的函数。所以我有点困惑。我认为编译器必须从 main() 开始,main 只是定义它的开始位置,就像一些起点标识符一样。
那么,请问为什么有 WinMain() 函数而不是 main() 函数?当我认为 C++ 编程和汇编程序一样符合逻辑时,我再次感到困惑。
main()
与 WinMain()
一样是任意的入口点。为了保持一致性,该标准仅需要一个名为 main
的函数。入口点(无论是main
还是WinMain
)实际上是由一个隐藏函数调用的,该函数是real入口点。在某些平台上,“真正的”入口点被称为 _start
之类的东西。正是该函数完成了所有初始工作,例如初始化全局变量、设置环境等,并且 then 它调用 main()
。在 Windows 上,该启动函数会调用 WinMain()
(如果可用)。
编辑:查看这个答案以获得更详细的解释。
与通常的控制台应用程序相比,要了解 Win32 应用程序的工作原理需要付出额外的努力。
“我有一个疯狂的想法,win32 编程是基于调用 Windows 函数并向它们发送参数”
我的提示...
1)确实如此,而且 Windows 消息也是 Windows 应用程序的节拍,一些示例包括 WM_CREATE、WM_MOUSExx、WM_KEYxx、WM_PAINT,其中 xx 可以是 DOWN UP 等。 消息由 Windows 本身发送到您的应用程序,您可以定义一个特定的函数来捕获它们(“WindowFunc”)。 有数百条信息,幸运的是一开始不需要理解所有信息。
2)您可以想象在应用程序中创建的每个小部件都是一个“窗口”,您可以通过 CreateWindow 函数创建窗口。每个窗口将由一个 32 位整数值(所谓的窗口句柄(HWND))来标识
3 您可以想象有很多不同类别的窗口(主窗口、客户区域、编辑、按钮),它们可以从系统中获得,也可以由您自己创建...... 窗口是不同的,因为它们属于不同的 WindowClass ...
要定义 WindowClass,您必须填充 WNDCLASS c 结构并调用 RegisterClass 结构体中的字段是指向 WindowFunc 的指针
4 WindowFunc 是一个带有 4 个输入参数(HWND、WM_XX、wParam、lParam)的函数 一旦有关该窗口(HWND)的事情发生,系统就会调用该函数
说让我重写你的陈述
“就像,当你想创建窗口时,你调用一些处理 Windows GUI 的 win32 函数并说“嗨,请为我创建一个新窗口,100 x 100 px,带有两个按钮”,并且 GUI 函数说“嗨,没问题,当发生某些事情时,比如用户单击一个按钮, ...当用户单击时,我将向您发送一条消息到 windowFunc...请自行检查消息类型,如果它是您正在等待的 WM_MOUSEDOWN,则更改 xy 的值
还有什么?我建议查看 sdk 中的一些简单示例,以对 win 32 应用程序流程充满信心
干杯
这只是本机 Win32 程序的约定。您可以轻松更改它,MSVC 链接器接受 /ENTRY:main 命令行选项 将入口点名称更改为“main”。然而,您还必须更改 main() 函数的签名,它需要不同的参数:
int APIENTRY main(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// etc..
}
我想这就是 20 年前给它起一个不同名字的意义所在。