2

我是 C++ 的新手,我一直坚持显示窗口。我没有收到任何错误,但我的 Window 没有显示在桌面上。当我打开任务管理器时,它出现在“进程”选项卡下。我一直没有找到解决此问题的任何方法,因此不胜感激。谢谢!:)

**注意:我使用的是 Microsoft Visual Studio 2012 **注意:不完全是 C++ 的新手,但更多的是创建一个 win32 应用程序

#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

static TCHAR WindowClass[] = L"Window";

LRESULT CALLBACK WindowProc(
    HWND   WinH,
    UINT   Msg,
    WPARAM wParam,
    LPARAM lParam
    )
{
    switch (Msg)
    {
        PAINTSTRUCT pntStruct;
        static HDC hdc;

        case WM_PAINT:
        {
            BeginPaint(
                WinH,
                &pntStruct
            );
            TextOut(hdc,
                5, 5,
                L"Hello, World!", _tcslen(L"Hello, World!"));
            //pntStruct.rcPaint
            EndPaint(
                WinH,
                &pntStruct
            );

        } break;

        case WM_SIZE:
        {

        } break;

        case WM_MOVE:
        {

        } break;

        case WM_DESTROY:
        {

        } break;

        case WM_CLOSE:
        {

        } break;

        default:
        {
            return DefWindowProc(WinH, Msg, wParam, lParam);
        } break;

        case WM_ACTIVATEAPP:
        {
            if (WM_ACTIVATEAPP)
            {
                OutputDebugStringA("WM_ACTIVEAPP->TRUE");
            }
            else
            {
                OutputDebugStringA("WM_ACTIVEAPP->FALSE");
            }
        } break;

    }

    return 0;
};


int WINAPI WinMain(
    HINSTANCE Window,
    HINSTANCE PrevInstance,
    LPSTR     Cmd,
    int       CmdShow
    )
{

    WNDCLASSEX wclass;
        //wclass.cbSize =  sizeof(WNDCLASS);
        wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
        wclass.lpfnWndProc = WindowProc;
        wclass.cbClsExtra = 0;
        wclass.cbWndExtra = 0;
        wclass.hInstance = Window;
        //wclass.hIcon; TODO: CREATE ICON
        //wclass.hCursor;
        //wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wclass.lpszMenuName = NULL;
        wclass.lpszClassName = (LPCTSTR)WindowClass;
//      HICON     hIconSm;
        RegisterClassEx(&wclass);

    HWND CreateWin = CreateWindow(
        WindowClass,
        L"NAME OF WINDOW",
        WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,//WIDTH:[TODO]->Make custom width to fit window
        CW_USEDEFAULT,//HEIGHT:[TODO]->Make custom width to fit window
        0,
        0,
        Window,
        0
    );

    ShowWindow(CreateWin, CmdShow);
    UpdateWindow(CreateWin);

    MSG message;

    while (GetMessage(&message, NULL, 0, 0) > 0)
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    };

    return 0;
};
4

1 回答 1

10

这段代码有很多问题。

您声明WindowClass为 a TCHAR[],但使用 a 对其进行初始化wchar_t[]。与 的lpString参数相同TextOut()。仅当UNICODE为项目定义时才有效,否则您将收到编译器错误。使用 时TCHAR,您需要用TEXT()宏包装字符串文字,以便它们使用正确的字符类型。否则,停止使用TCHAR,只使用 Unicode API 来处理所有事情。TCHAR仅当您的代码需要同时支持 ANSI (Win9x/ME) 和 Unicode (NT4+) 编译时才需要使用。没有人真正支持 Win9x/Me,所以新代码应该只关注 Unicode API。

您没有将WNDCLASSEX结构的内容归零,因此您有意注释掉且未分配值的所有字段(最重要的是,该cbSize字段)都将包含堆栈中的随机值。这可能会导致RegisterClassEx()失败,而您没有检查。为避免此问题,请始终在使用 API 结构之前将其清零。这对于随时间增长的结构尤其重要(当较新的 Windows 版本引入新的结构字段时)。此类结构通常有一个cbSize字段,因此 API 知道您使用的是哪个版本的结构,因此您必须提供准确的值。并且您需要将所有未使用的字段清零,以免 API 出现意外行为。

您没有检查是否CreateWindow()失败,例如失败的副作用RegisterClassEx()

WindowProc()应该将未处理的消息传递给DefWindowProc(),但您没有这样做。您的大多数case块只是丢弃消息,因此 Windows 无法处理它们。那是你真正想要的吗?我对此表示怀疑。特别是DefWindowProc()for的默认行为WM_CLOSE是销毁窗口,触发WM_DESTROY消息。

您的WM_DESTROY处理程序没有调用PostQuitMessage()WM_QUIT消息放入调用线程的消息队列,因此GetMessage()可以返回 0 来中断消息循环并让应用退出。

您的WM_PAINT处理程序没有使用提供给您的HDCBeginPaint()您正在使用未初始化的HDC变量进行绘制。

说了这么多,试试这样的:

#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h> // Or: remove this

static TCHAR WindowClass[] = TEXT("Window");
// or: static WCHAR WindowClass[] = L"Window";

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_PAINT:
        {
            static const TCHAR* HelloWorld = TEXT("Hello, World!");
            // or: const WCHAR* HelloWorld = L"Hello, World!";

            PAINTSTRUCT pntStruct = {0};
            HDC hdc = BeginPaint(hWnd, &pntStruct);

            TextOut(hdc, 5, 5, HelloWorld, _tcslen(HelloWorld));
            // or: TextOutW(hdc, 5, 5, HelloWorld, lstrlenW(HelloWorld));

            EndPaint(hWnd, &pntStruct);
            break;
        }

        case WM_SIZE:
        {
            //...
            break;
        }

        case WM_MOVE:
        {
            //...
            break;
        }

        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }

        case WM_CLOSE:
        {
            //...
            break;
        }

        case WM_ACTIVATEAPP:
        {
            if (WM_ACTIVATEAPP)
            {
                OutputDebugString(TEXT("WM_ACTIVEAPP->TRUE"));
                // or: OutputDebugStringW(L"WM_ACTIVEAPP->TRUE");
            }
            else
            {
                OutputDebugString(TEXT("WM_ACTIVEAPP->FALSE"));
                // or: OutputDebugStringW(L"WM_ACTIVEAPP->FALSE");
            }

            break;
        }
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wclass = {0}; // Or: WNDCLASSEXW
    wclass.cbSize = sizeof(wclass);
    wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wclass.lpfnWndProc = &WindowProc;
    wclass.cbClsExtra = 0;
    wclass.cbWndExtra = 0;
    wclass.hInstance = hInstance;
    wclass.hIcon = NULL; // TODO: CREATE ICON
    wclass.hCursor = NULL;
    wclass.hbrBackground = NULL;//(HBRUSH)(COLOR_WINDOW+1);
    wclass.lpszMenuName = NULL;
    wclass.lpszClassName = WindowClass;
    wclass.hIconSm = NULL;

    if (!RegisterClassEx(&wclass)) // Or: RegisterClassExW()
    {
        // error! Use GetLastError() to find out why...
        return 0;
    }

    HWND hCreateWin = CreateWindow( // Or: CreateWindowW()
        WindowClass,
        TEXT("NAME OF WINDOW"), // Or: L"NAME OF WINDOW"
        WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,//WIDTH:[TODO]->Make custom width to fit window
        CW_USEDEFAULT,//HEIGHT:[TODO]->Make custom width to fit window
        0,
        0,
        hInstance,
        0
    );

    if (!hCreateWin)    
    {
        // error! Use GetLastError() to find out why...
        return 0;
    }

    ShowWindow(hCreateWin, nCmdShow);
    UpdateWindow(hCreateWin);

    MSG message;
    while (GetMessage(&message, NULL, 0, 0) > 0)
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    };

    return 0;
};
于 2015-05-30T23:05:51.060 回答