【问题标题】:Why isn't my Win32(c++, visual studio 2013) Window showing up?为什么我的 Win32(c++, visual studio 2013) 窗口不显示?
【发布时间】:2016-07-01 08:12:48
【问题描述】:

代码如下:

#include <windows.h>
#include <windowsx.h>


// the WindowProc callback function prototype
LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);

// win32 entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
    ///*
    // window handler
    HWND hwnd;

    // struct for window information
    WNDCLASSEX wc;

    // clear out the window class for use
    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    // setting wc struct with window values/properties
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "TestWindow";
    wc.lpfnWndProc = WindowProc;

    // register window before creation/use
    RegisterClassEx(&wc);

    // creating the window class
    hwnd = CreateWindowEx(NULL, "TestWindow", "First Win32 Program", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 1000, NULL, NULL, hInstance, NULL);

    // show the window 
    ShowWindow(hwnd, nCmdShow);//*/

}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam){
    return 0;
}

这是编译器/调试/运行时控制台输出:

'wintest.exe' (Win32): Loaded 
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\user32.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\lpk.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\usp10.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\advapi32.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sspicli.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cryptbase.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr120d.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\imm32.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msctf.dll'. Cannot find or open the PDB file.
'wintest.exe' (Win32): Loaded 'C:\Windows\SysWOW64\uxtheme.dll'. Cannot find or open the PDB file.
The program '[3484] wintest.exe' has exited with code 0 (0x0).

这是一个非常基本的简单程序,它所做的只是假设从左上角开始弹出一个大小为 1000x1000 的 win32 窗口。

【问题讨论】:

  • ...在尝试显示窗口后,您立即退出。 See here for how to loop.
  • 您不应将字符集的默认设置从 Unicode 更改为 MBCS。如果您不使用 Unicode,那么您将不必要地浪费资源来实现功能有限的应用程序。
  • 任何您发现的创建窗口的示例程序都将包含一个消息循环。您是如何设法忽略这一点的?
  • 找不到或打开 PDB 文件 Visual Studio 找不到调试信息。看到这个link你的代码还有其他问题——下面提到——但这不是这个错误。

标签: c++ winapi visual-studio-2013 window


【解决方案1】:

我可以看到的第一个错误是在您的窗口过程中。您未明确处理的任何消息都应传递给DefWindowProc

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    return DefWindowProc(hwnd, message, wparam, lparam);
}

这是窗口过程所需的绝对最小值。实际上,您至少需要处理 WM_CLOSEWM_DESTROY,然后在添加功能时处理更多。

在创建过程中向窗口发送WM_NCCREATE 消息时,您的损坏窗口过程会导致CreateWindowEx 失败。

另一个明显的问题是您根本不执行任何错误检查。通过忽略您进行的每个 API 调用的返回值,您将无法诊断您的程序出现故障的位置。

最后,您不包含消息循环。因此,即使您可以显示您的窗口,该过程也会立即终止。

此程序将显示一个窗口。显然还有更多工作要做,但这只是一个开始。

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    switch(message)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, message, wparam, lparam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, 
    int nCmdShow)
{
    WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "TestWindow";
    wc.lpfnWndProc = WindowProc;

    if (!RegisterClassEx(&wc))
        return 1;

    HWND hwnd = CreateWindowEx(0, "TestWindow", "First Win32 Program", 
        WS_OVERLAPPEDWINDOW, 100, 100, 1000, 1000, NULL, NULL, hInstance, NULL);
    if (!hwnd)
        return 1;

    ShowWindow(hwnd, nCmdShow);

    MSG msg;
    while (GetMessage(&msg, 0, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

【讨论】:

  • 错误的窗口过程为WM_NCCREATE返回0,导致对CreateWindowEx的调用返回NULL。正如您所建议的,在检查错误时可以轻松诊断出这一点。窗口没有出现,因为它永远不会离开地面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-21
  • 2015-02-16
  • 2017-08-22
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多