C++ 在 Win32 程序中用 main() 函数替换 WinMain()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11785157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:32:33  来源:igfitidea点击:

Replacing WinMain() with main() function in Win32 programs

c++winapi

提问by MahanGM

I searched a little bit on StackOverflow and Google but couldn't get the idea. I want to start my application with this type of user programming:

我在 StackOverflow 和 Google 上搜索了一点,但无法理解。我想用这种类型的用户编程来启动我的应用程序:

int main()
{
  Window App("Test", 640, 480);

  while(App.IsOpen())
  {
    // Do the stuff
  }
}

But this isn't possible because I should pass the hInstanceand hPrevInstanceand other parameters to a WinMainfunction. Actually there is a Window class which I designed to make the window creation a little bit easier. I saw this implementation on SFML but I don't know how it did come to this.

但这是不可能的,因为我应该将hInstanceandhPrevInstance和其他参数传递给WinMain函数。实际上,我设计了一个 Window 类,使窗口创建更容易一些。我在 SFML 上看到了这个实现,但我不知道它是怎么做到的。

Right now I'm using the usual way:

现在我正在使用通常的方式:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR, int)
{
  Window App(hInst, hPrevInst, "Test", 640, 480);

  while(App.IsOpen())
  {
    // Do the stuff
  }
}

Thanks.

谢谢。

回答by jcoder

You can use standard mainin a "windows" app (that is, a GUI subsystem Windows application) even with the Microsoft tools, if you add the following to the Microsoft linker options:

main如果将以下内容添加到 Microsoft 链接器选项中,即使使用 Microsoft 工具,您也可以在“Windows”应用程序(即 GUI 子系统 Windows 应用程序)中使用标准:

/subsystem:windows /ENTRY:mainCRTStartup

Note that this is not necessary for the GNU toolchain.

请注意,这对于 GNU 工具链不是必需的。

Still for the Microsoft tools you can alternatively add this to your main file:

对于 Microsoft 工具,您也可以将其添加到主文件中:

#ifdef _MSC_VER
#    pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif

@James McNellis tells you how to get the hInstance.

@James McNellis 告诉您如何获取 hInstance。

回答by James McNellis

GetModuleHandle(NULL)will give you hInstance. hPrevInstanceis always NULL.

GetModuleHandle(NULL)会给你hInstancehPrevInstance总是NULL

回答by Cheers and hth. - Alf

First, GetModuleHandle(0)provides the executable's module handle, which is the same as the hInstanceargument of WinMain.

首先,GetModuleHandle(0)提供可执行文件的模块句柄,与 的hInstance参数相同WinMain

With the GNU toolchaing (g++ compiler), the standard-conforming code is OK.

使用 GNU 工具链(g++ 编译器),符合标准的代码就可以了。

The Microsoft toolchain, however, only accepts the standard-conforming code by default for a console subsystem executable. To create a GUI subsystem executable with this non-conforming toolchain, using a standard main, you have to specify a Microsoft runtime library entry point that calls the standard main, namely mainCRTStartup. For a command line invocation that means…

但是,默认情况下,Microsoft 工具链仅接受控制台子系统可执行文件的符合标准的代码。要使用此不符合标准的工具链创建 GUI 子系统可执行文件,使用标准main,您必须指定调用标准的 Microsoft 运行时库入口点main,即mainCRTStartup. 对于命令行调用,这意味着……

cl myApp.cpp /link /entry:mainCRTStartup /subsystem:windows user32.lib

As a practical matter, for working in the command line you can simply specify the entry point in the LINKenvironment variable:

实际上,为了在命令行中工作,您可以简单地在LINK环境变量中指定入口点:

set LINK=/entry:mainCRTStartup

cl myApp.cpp /link /subsystem:windows user32.lib

Creating a similar standard-conforming setup for Visual Studio is perhaps not desirable, since some Visual Studio project types (mainly MFC) requires use of Microsoft's non-standard WinMainor wWinMain.

为 Visual Studio 创建类似的符合标准的设置可能是不可取的,因为某些 Visual Studio 项目类型(主要是 MFC)需要使用 Microsoft 的非标准WinMainwWinMain.

回答by tenfour

hInstanceis one exception to the "never use global variables" rule-of-thumb. Normally no variable actually logically has scope that's module-wide. hInstance, however, has by definition exactly module-wide scope, so actually the most logical solution is to make a global variable for it and initialize it in WinMain.

hInstance是“从不使用全局变量”经验法则的一个例外。通常没有变量实际上在逻辑上具有模块范围的作用域。hInstance但是,根据定义,它具有完全模块范围的作用域,因此实际上最合乎逻辑的解决方案是为其创建一个全局变量并在WinMain.

As others have suggested, you can also use GetModuleHandle(NULL).

正如其他人所建议的,您也可以使用GetModuleHandle(NULL).