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
Replacing WinMain() with main() function in Win32 programs
提问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 hInstance
and hPrevInstance
and other parameters to a WinMain
function. 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.
但这是不可能的,因为我应该将hInstance
andhPrevInstance
和其他参数传递给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 main
in 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
. hPrevInstance
is always NULL
.
GetModuleHandle(NULL)
会给你hInstance
。 hPrevInstance
总是NULL
。
回答by Cheers and hth. - Alf
First, GetModuleHandle(0)
provides the executable's module handle, which is the same as the hInstance
argument 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 LINK
environment 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 WinMain
or wWinMain
.
为 Visual Studio 创建类似的符合标准的设置可能是不可取的,因为某些 Visual Studio 项目类型(主要是 MFC)需要使用 Microsoft 的非标准WinMain
或wWinMain
.
回答by tenfour
hInstance
is 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)
.