【问题标题】:WINAPI window not showingWINAPI 窗口未显示
【发布时间】:2021-05-29 06:40:16
【问题描述】:

所以我是一名大学生,本学期正在使用 OpenGL,并尝试使用 WINAPI 根据课程说明显示一个窗口。我一步一步地按照教授给出的代码运行,代码运行没有错误,但是当我在调试模式下运行它时,我看不到我告诉视觉工作室显示的控制台或窗口。这是在使用 c++ 的 Visual Studio 2019 中。我知道代码是正确的,因为我看到它在教授机器上运行。我想知道是否有人知道发生了什么。

#include "Main.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   //callbacks for winapi
   switch (msg)
   {
   case WM_CLOSE:
       DestroyWindow(hwnd);
       break;
   case WM_DESTROY:
       PostQuitMessage(0);
       break;
   case WM_KEYDOWN:
       if (wParam == 27)
       {
           PostQuitMessage(0);
       }
       break;
   default:
       return DefWindowProc(hwnd, msg, wParam, lParam);
       break;
   }
   return 0;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
   //Initialize Window ----------------------------------------------------------------------
#pragma region Window Initialization
   if (AllocConsole())
   {
       FILE* stream;
       _wfreopen_s(&stream, TEXT("CONIN"), TEXT("rb"), stdin);
       _wfreopen_s(&stream, TEXT("CONOUT"), TEXT("wb"), stdout);
       _wfreopen_s(&stream, TEXT("CONIN"), TEXT("rb"), stderr);
   }

   WNDCLASSEX wc; //Window information Container
   wc.cbSize = sizeof(WNDCLASSEX);
   wc.style = 0;
   wc.lpfnWndProc = WndProc;
   wc.cbClsExtra = 0;
   wc.cbWndExtra = 0;
   wc.hInstance = hInstance;
   wc.hIcon = LoadIcon(wc.hInstance, (LPCTSTR)IDI_ICON);
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
   wc.lpszMenuName = NULL;
   wc.lpszClassName = L"MEWINDOW";
   wc.hIconSm = LoadIcon(wc.hInstance, (LPCTSTR)IDI_ICON);

   if (!RegisterClassEx(&wc))
   {
       MessageBox(NULL, L"Window registration failed!", L"Error!!!", MB_ICONEXCLAMATION | MB_OK);
       exit(0);
       return E_FAIL;
   }

   DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
   DWORD dwWindowStyle = WS_OVERLAPPEDWINDOW;

   RECT rc = { (long)0, (long)0, (long)600, (long)600 };
   AdjustWindowRectEx(&rc, dwWindowStyle, FALSE, dwExStyle);

   LPCWSTR windowName = L"OpenGL - Window";

   HWND hWindowHandler = CreateWindowEx(dwExStyle,
       L"MEWINDOW",
       windowName,
       dwWindowStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
       100, 100,
       600, 600,
       NULL, NULL,
       hInstance,
       NULL);
   if (hWindowHandler == NULL)
   {
       MessageBox(NULL, L"Window creation failed!", L"Error!!!", MB_ICONEXCLAMATION | MB_OK);
       exit(0);
       return E_FAIL;
   }

   ShowWindow(hWindowHandler, nCmdShow);
   UpdateWindow(hWindowHandler);
#pragma endregion

   //OpenGL Init ----------------------------------------------------------------------
#pragma region OpenGL Initialization
#pragma endregion

   //Shader Compilation ----------------------------------------------------------------------
#pragma region Shader Initialization
#pragma endregion

   //Shape Configuration ----------------------------------------------------------------------
#pragma region Shape Initialization
#pragma endregion

   //Game Loop ----------------------------------------------------------------------
#pragma region Game Loop
#pragma endregion

   std::cout << "Hello World\n";
   getchar();
   return 0;
}

【问题讨论】:

  • 你的message loop呢?
  • @rustyx 这是教授在视频中运行的代码,他得到一个控制台说“Hello World”和一个我们初始化的空白窗口
  • @Ron 不幸的是,我们被告知使用我在问题中提供的代码库。这就是为什么我很困惑为什么什么都没有出现
  • 您的项目中是否包含资源文件,其中包含带有IDI_ICON 标识符的图标?如果没有,那么这可能会导致您的程序无法运行。
  • @RyanXLVI 没有message loop,你的WndProc 是没用的。

标签: c++ visual-studio winapi


【解决方案1】:
    _wfreopen_s(&stream, TEXT("CONIN"), TEXT("rb"), stdin);
    _wfreopen_s(&stream, TEXT("CONOUT"), TEXT("wb"), stdout);

名称都缺少最后的'$'。它们应该是 "CONIN$""CONOUT$",请参阅 Console Handles 了解更多详情。

    _wfreopen_s(&stream, TEXT("CONIN"), TEXT("rb"), stderr);

改为"CONOUT$""wb",您不想在读取模式下打开stderr 进行输入。 "b" 部分假设您确实想在二进制模式下使用标准 I/O 流。

只要您将代码构建为 Unicode GUI 应用程序,代码基本上应该可以与上述更改一起使用。也就是说,将通用文本代码(TEXT(...)CreateWindowEx 等)与纯 Unicode 代码(wWinMain_wfreopen_s 等)混合是不寻常的,也不建议这样做。


[ EDIT ] 代码中关于OpenGL游戏循环的cmets提示在真实代码的其他地方可能存在消息循环.但要让发布的 sn-p 完全工作,修改 WM_KEYDOWN 处理程序以关闭 GUI,并在 wWinMain 中添加一个简单的消息循环就足够了。

   case WM_KEYDOWN:
       if (wParam == VK_ESCAPE)
           DestroyWindow(hwnd);
       break;
    for(MSG msg; GetMessage(&msg, 0, 0, 0); )
    {   TranslateMessage(&msg); DispatchMessage(&msg); }

    std::cout << "Hello World\n";
    getchar();

通过上述操作,应用程序将打开控制台和 GUI 窗口,等待在 GUI 中按下 ESC,然后打印 Hello World 并等待控制台中的 Enter 键。

【讨论】:

    猜你喜欢
    • 2019-03-25
    • 1970-01-01
    • 2015-02-20
    • 2011-05-18
    • 1970-01-01
    • 2022-12-23
    • 2021-12-18
    • 1970-01-01
    • 2017-03-28
    相关资源
    最近更新 更多