2017-08-06 8 views
-2

WinAPIを試している間に、ボタンを操作してウィンドウが表示されました。コードは私のウィンドウプロシージャに入れ、このように見えた。WinAPIボタンを作成する関数を呼び出しても何もしません

std::vector<HWND> buttons; 
HWND window; 

LRESULT CALLBACK CSwindowProc(HWND window, unsigned int message, WPARAM shortParam, LPARAM longParam) { 
    switch (message) { 
    case WM_CREATE: 
     buttons.push_back(
      CreateWindow(_T("BUTTON"), _T("OK"), WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 
       10, 10, 100, 100, window, NULL, (HINSTANCE)GetWindowLongPtr(window, GWL_HINSTANCE), NULL) 
     ); 
     break; 
    case WM_DESTROY: PostQuitMessage(0); break; 
    default: return DefWindowProc(window, message, shortParam, longParam); break; 
    } 
    return 0; 
} 

「ボタン」を注意してくださいHWNDベクトルと「ウィンドウ」でのcreateWindowで初期化だけHWNDです。これらのスニペットへのコンテキストは、この質問の最後のコードと同じです。

私が持っているものを単純化するために、ボタン作成コードを新しい関数(CSnewButton)に移すことにしました。次に、ウィンドウプロシージャからボタン作成コードを削除し、CSnewButton()への呼び出しを追加しました。この時点で、コードは次のように見えた:

std::vector<HWND> buttons; 
HWND window; 

void CSnewButton() { 
    buttons.push_back(
     CreateWindow(_T("BUTTON"), _T("OK"), WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 
      10, 10, 100, 100, window, NULL, (HINSTANCE)GetWindowLongPtr(window, GWL_HINSTANCE), NULL) 
    ); 
} 

LRESULT CALLBACK CSwindowProc(HWND window, unsigned int message, WPARAM shortParam, LPARAM longParam) { 
    switch (message) { 
    case WM_CREATE: 
     CSnewButton(); 
     break; 
    case WM_DESTROY: PostQuitMessage(0); break; 
    default: return DefWindowProc(window, message, shortParam, longParam); break; 
    } 
    return 0; 
} 

驚くべきことに、ボタンがウィンドウにはもはや存在しませんでした。コードをプロシージャから呼び出された関数に移動するだけで、ボタンは消えました。 いくつかの問題を除外するために、すばやくデバッグを行いました。関数にメッセージボックスを追加し、メッセージボックスが表示されたので、関数が呼び出されました。 C++インライン修飾子は、CSnewButton関数に追加した私のケースを助けませんでした。コンパイル時でも実行時でもエラーも警告も表示されません。

私はC++や積極的なC++コンパイラ(私は驚くことはありません)、WinAPI(おそらく犯人)や何かの誤解が非常に明らかに私のコードで間違っていると思いますどちらも驚かない)。とにかく、ボタン作成コードを関数に移動すると、コードの機能が取り除かれ、この問題の解決策(可能な場合)がなぜ必要なのかを知りたいと思います。

問題を紹介する全コード:

#include <windows.h> 
#include <tchar.h> 
#include <vector> 

HINSTANCE instance; 
HWND window; 

std::vector<HWND> buttons; 

//This function inexplicably does not create the button, however, if you were 
//to take it's contents and paste them over a call to this function, it works 
//fine. 
void CSnewButton() { 
    buttons.push_back(
     CreateWindow(_T("BUTTON"), _T("OK"), WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 
      10, 10, 100, 100, window, NULL, (HINSTANCE)GetWindowLongPtr(window, GWL_HINSTANCE), NULL) 
    ); 
} 

LRESULT CALLBACK CSwindowProc(HWND window, unsigned int message, WPARAM shortParam, LPARAM longParam) { 
    switch (message) { 
    case WM_CREATE: 
     CSnewButton(); // Issue Here 
     break; 
    case WM_DESTROY: PostQuitMessage(0); break; 
    default: return DefWindowProc(window, message, shortParam, longParam); break; 
    } 
    return 0; 
} 

void CScreateWindow() { 
    WNDCLASSEX cclass = { 
     sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, 
     CSwindowProc, 0, 0, instance, NULL, LoadCursor(NULL, IDC_ARROW), 
     (HBRUSH)(COLOR_WINDOW + 1), NULL, _T("MyClass"), NULL 
    }; 
    if (!RegisterClassEx(&cclass)) { 
     MessageBox(NULL, _T("CSControlApp failed to register window."), _T("CSControlApp failure"), MB_OK | MB_ICONERROR); return; 
    } 
    window = CreateWindow(cclass.lpszClassName, _T("My Window"), WS_OVERLAPPEDWINDOW^WS_THICKFRAME, 
     CW_USEDEFAULT, CW_USEDEFAULT, 600, 600, NULL, NULL, instance, NULL); 
    if (!window) { 
     MessageBox(NULL, _T("CSControlApp failed to create window."), _T("CSControlApp failure"), MB_OK | MB_ICONERROR); return; 
    } 
} 

int CALLBACK WinMain(HINSTANCE h, HINSTANCE p, LPSTR cmd, int show) { 
    instance = h; 
    CScreateWindow(); 
    ShowWindow(window, show); 
    UpdateWindow(window); 
    MSG msg; 
    while (GetMessage(&msg, NULL, 0, 0)) { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
    return 0; 
} 
+2

コードを画像ではなくコードとして掲載してください。 – Ron

+0

私は、コードのスクリーンショットを取って、コピー&ペーストだけではなく、質問にアップロードすることがより難しいと考える必要があります。私はちょうど人々がそれをやっている理由を得ることはできません。 – pinkfloydx33

+0

私は終わった。下部のコードはボタンを表示しません。ボタンを表示するには、CSnewButtonの内容をCSwindowProcのCSnewButtonの呼び出しに貼り付けます。再び、私の希望する動作は、CSnewButtonから呼び出されてもボタンを表示させることです。 –

答えて

2

これは、C言語の問題です。あなたは同じ名前の2つの別々の変数を持っており、それらを混乱させています。 CSWindowProcインサイド

HWND window; // This is a global variable 

LRESULT CALLBACK CSwindowProc(HWND window, ...) // This is a parameter 

あなたは、パラメータを取得するwindow言うとき。 外部CsWindowProcwindowと言うときは、グローバル変数を取得します。グローバル変数は、使用しようとしている時点でまだ初期化されていません。 (CScreateWindowCreateWindowへの呼び出しがまだ戻っていない。)

あなたはCSnewButtonに引数を与えることによって、問題を解決することができます

void CSnewButton(HWND window) 

し、それに応じてそれを呼び出す:

case WM_CREATE: 
    CSnewButton(window); 
    break; 

を避けるために将来類似の混乱が起きる場合は、グローバル変数を完全に削除することをお勧めします。

関連する問題