31

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

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

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

但这是不可能的,因为我应该将hInstanceandhPrevInstance和其他参数传递给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

4 回答 4

46

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

/subsystem:windows /ENTRY:mainCRTStartup

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

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

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

James McNellis 告诉您如何获取 hInstance。

于 2012-08-02T21:02:43.137 回答
21

GetModuleHandle(NULL)会给你hInstancehPrevInstance总是NULL

于 2012-08-02T20:28:33.813 回答
14

首先,GetModuleHandle(0)提供可执行文件的模块句柄,hInstanceWinMain.

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

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

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

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

set LINK=/entry:mainCRTStartup

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

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

于 2012-08-02T21:04:54.027 回答
5

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

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

于 2012-08-02T21:10:54.113 回答