用Win32程序中的main()函数替换WinMain()

时间:2012-08-02 20:22:36

标签: c++ winapi

我在StackOverflow和谷歌上搜索了一下但是无法理解。我想用这种类型的用户编程启动我的应用程序:

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

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

但这是不可能的,因为我应该将hInstancehPrevInstance以及其他参数传递给WinMain函数。实际上有一个Window类,我设计用于使窗口创建更容易一些。我在SFML上看到了这个实现,但我不知道它是如何实现的。

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

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

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

感谢。

4 个答案:

答案 0 :(得分:37)

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

/subsystem:windows /ENTRY:mainCRTStartup

请注意,GNU工具链不需要这样做。

仍然可以使用Microsoft工具将其添加到主文件中:

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

@James McNellis告诉你如何获得hInstance。

答案 1 :(得分:18)

GetModuleHandle(NULL)会给你hInstancehPrevInstance始终为NULL

答案 2 :(得分:13)

首先,GetModuleHandle(0)提供可执行文件的模块句柄,它与hInstance的{​​{1}}参数相同。

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

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

main

实际上,要在命令行中工作,您只需在mainCRTStartup环境变量中指定入口点:

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

...

LINK

为Visual Studio创建类似的符合标准的设置可能并不可取,因为某些Visual Studio项目类型(主要是MFC)需要使用Microsoft的非标准set LINK=/entry:mainCRTStartup cl myApp.cpp /link /subsystem:windows user32.lib

答案 3 :(得分:5)

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

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