【问题标题】:c++ use of winmain()c++winmain()的使用
【发布时间】:2010-03-07 21:10:26
【问题描述】:

我刚开始学习 c++ 中的 windows 编程。我有一个疯狂的形象,win32 编程是基于调用 windows 函数并从它们发送参数。就像,当你想创建窗口时,你调用一些处理 windows GUI 的 win32 函数并说“嗨,请给我创建一个新窗口,100 x 100 像素,有两个按钮”,然后那个 GUI 函数说“嗨,没问题,当发生某些事情时,例如用户单击一个按钮,我将更改位于此位置的变量 xy”。

所以,我认为它与控制台编程非常相似。但是第一条指令让我感到惊讶。我一直认为每个程序都会先执行 main() 函数。因此,当我启动应用程序时,Windows 会在堆栈顶部存储一些参数并运行该应用程序。所以我假设初始化 main() 只是一种 C++ 方法来告诉编译器第一条指令应该在哪里。

但是在 win32 编程中,有一个名为 WinMain() 的函数首先启动。所以我有点困惑。我认为编译器必须以 main() 开头的规则,main 只是定义它的开始位置,例如一些起点标识符。

那么,请问为什么有 WinMain() 函数而不是 main()?当我认为 C++ 编程与汇编程序一样合乎逻辑时,它再次让我感到困惑。

【问题讨论】:

  • 您可以拥有一个以main() 开头的Win32 程序。控制台程序执行此操作。
  • 哦,你可能想把这片铅海分解成段落。
  • 没有winmain,有WinMain
  • @sbi,你把最后一条评论从我的指尖拿走了。
  • @avakar:我刚刚长大,看到这样的东西会感到眼睛酸痛。当我年轻的时候,我遇到了比这些更糟糕的问题......:)

标签: c++ winapi winmain


【解决方案1】:

main()WinMain() 一样是任意入口点。该标准只需要一个名为main 的函数以保持一致性。入口点(无论是main 还是WinMain)实际上由一个隐藏函数调用,该函数是real 入口点。在某些平台上,“真正的”入口点称为_start。正是这个函数完成了所有初始工作,例如初始化全局变量、设置环境等,然后它调用main()。在 Windows 上,该启动函数恰好调用 WinMain()(如果可用)。

编辑:查看this answer 以获得更详细的说明。

【讨论】:

    【解决方案2】:

    与通常的控制台应用程序相比,要了解 Win32 应用程序的工作原理需要额外的努力。

    “我有一个疯狂的形象,win32 编程是基于调用 windows 函数和向它们发送参数”

    我的提示...

    1) 是的,还有作为 Windows 应用程序节拍的 Windows 消息,一些示例包括 WM_CREATE、WM_MOUSExx、WM_KEYxx、WM_PAINT,其中 xx 可以是 DOWN UP 等等。 消息由 Windows 本身发送到您的应用程序,您可以定义一个特定的函数来捕获它们(“WindowFunc”)。 有数百条消息,幸运的是,一开始并不需要全部了解。

    2) 您可以想象在您的应用程序中创建的每个小部件都是一个“窗口”,您可以通过 CreateWindow 函数创建窗口。每个窗口将由一个 32 位整数值标识,即所谓的窗口句柄 (HWND)

    3 您可以想象到许多不同类别的窗口(主窗口、客户端区域、编辑、按钮),它们既可以从系统中使用,也可以由您自己创建... Windows 是不同的,因为它们属于不同的 WindowClass ...

    要定义一个 WindowClass,你必须填写一个 WNDCLASS c 结构并调用 RegisterClass 结构中的字段是指向 WindowFunc 的指针

    4 WindowFunc 是一个接受 4 个输入参数 (HWND,WM_XX,wParam,lParam) 的函数 一旦与该窗口(HWND)有关的事情发生,系统就会调用该函数

    说让我重写你的陈述

    “就像,当你想创建窗口时,你调用一些处理 windows GUI 的 win32 函数并说“嗨,请给我创建一个新窗口,100 x 100 像素,有两个按钮”,然后那个 GUI 函数说“嗨,没问题,当发生某些事情时,例如用户单击一个按钮, ...当用户单击时,我会向 windowFunc 发送一条消息...请自行检查消息类型,如果是您等待的 WM_MOUSEDOWN,则更改 xy 的值

    还有什么?我建议查看 sdk 中的一些简单示例,以了解 win 32 应用程序流程是怎样的

    干杯

    【讨论】:

      【解决方案3】:

      这只是本机 Win32 程序的约定。您可以轻松更改它,MSVC 链接器接受/ENTRY:main command line option 将入口点名称更改为“main”。但是,您还必须更改 main() 函数的签名,它需要不同的参数:

      int APIENTRY main(HINSTANCE hInstance,
                           HINSTANCE hPrevInstance,
                           LPTSTR    lpCmdLine,
                           int       nCmdShow)
      {
        // etc..
      }
      

      我想这就是 20 年前给它起一个不同名字的意义所在。

      【讨论】:

      • 其实入口点没有接收任何参数。库版本调用 GetCommandLine 和 GetStartupInfo 等 API,然后调用 main 或 WinMain(或 wmain 或 _wWinMain)。此外,“Win3”不适合表示“16 位 Windows”,因为 Windows NT 3.x 本身就是 32 位的。
      • IIRC hPrevInstance 是 Windows 1 的遗产,而不是 3。
      【解决方案4】:

      您可以从 Microsoft 开发人员处查看 this articleanother one。简单来说有几个原因:名称随意,windows 的 WinMain 需要不同的签名,windows 早于 c++ 标准化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-13
        • 1970-01-01
        • 2020-02-07
        • 1970-01-01
        • 2012-12-02
        • 1970-01-01
        • 2010-09-29
        相关资源
        最近更新 更多