2

私は c++ の初心者で、ウィンドウの表示に固執しています。エラーは発生していませんが、ウィンドウがデスクトップに表示されません。タスク マネージャーを開くと、[プロセス] タブの下に表示されます。この問題の解決策を見つけていないので、助けていただければ幸いです。ありがとう!:)

**注: 私は 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

このコードには多くの問題があります。

として宣言していますがWindowClassTCHAR[]で初期化してい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呼び出しているわけではないため、0 を返してメッセージ ループを中断し、アプリを終了させることができます。PostQuitMessage()WM_QUITGetMessage()

あなたのWM_PAINTハンドラーはあなたHDCに提供するを使用していません。初期化されていない変数BeginPaint()を使用して描画しています。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 に答える