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

Mah*_*nGM 26 c++ winapi

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

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

  while(App.IsOpen())
  {
    // Do the stuff
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,这是不可能的,因为,我应该通过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
  }
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

jco*_*der 39

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

/subsystem:windows /ENTRY:mainCRTStartup
Run Code Online (Sandbox Code Playgroud)

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

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

#ifdef _MSC_VER
#    pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
Run Code Online (Sandbox Code Playgroud)

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

  • 编辑:我纠正了它,而不是抱怨误导性的答案. (2认同)

Jam*_*lis 19

GetModuleHandle(NULL)会给你的hInstance. hPrevInstance永远NULL.


Che*_*Alf 13

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

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

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

cl myApp.cpp /link /entry:mainCRTStartup /subsystem:windows user32.lib
Run Code Online (Sandbox Code Playgroud)

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

set LINK=/entry:mainCRTStartup
Run Code Online (Sandbox Code Playgroud)

...

cl myApp.cpp /link /subsystem:windows user32.lib
Run Code Online (Sandbox Code Playgroud)

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


ten*_*our 5

hInstance是"从不使用全局变量"的经验法则的一个例外.通常情况下,变量实际上没有逻辑上具有模块范围的范围.hInstance但是,根据定义,确切地说是模块范围的范围,因此实际上最合乎逻辑的解决方案是为它创建一个全局变量并将其初始化WinMain.

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