1

WinMain とは異なる cpp ファイルにある関数があり、呼び出されるとウィンドウが作成されます。ただし、その新しいウィンドウのウィンドウ クラスは、WinMain 内で宣言および登録されています。ここで、別の関数でウィンドウを作成すると、CreateWindowEx 関数の 2 番目と 3 番目の変数を再宣言する必要があります。

_In_opt_  LPCTSTR lpClassName,
_In_opt_  LPCTSTR lpWindowName,

実際に作成を行っている関数の場所は、WinMain で作成された変数にアクセスできないためです。さて... 私の疑問は、私のプログラムが WinMain に登録したウィンドウ クラスを実際に使用しているのかということです。私が知っている限りでは、これらの変数を再宣言し、WinMain 関数から離れた場所に関数を作成すると、コンパイラが他の標準ウィンドウ クラスを採用する可能性があります。私のプログラムは、WinMain に登録したウィンドウ クラスを実際に使用していますか?

編集: もう少しコードを与える

//++++++++++++++++++++++++++++++++++++++ win main の cpp ファイル:

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

...//previous code made the main window of the program and so forth

const char g_szClassName2[] = "windowClass2";//name of the window class
WNDCLASSEX winClass2;
HWND invisHWnd;

winClass2.cbSize         = sizeof(WNDCLASSEX);
winClass2.style          = 0;
winClass2.lpfnWndProc    = WndProcedure2;
winClass2.cbClsExtra     = 0;
winClass2.cbWndExtra     = 0;
winClass2.hInstance     = hInstance;
winClass2.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
winClass2.hCursor       = LoadCursor(NULL, IDC_ARROW);
winClass2.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
winClass2.lpszMenuName  = NULL;
winClass2.lpszClassName = g_szClassName2;
winClass2.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&winClass2);

... //other code irrelevant to issue

}

//++++++++++++++++++++++++++++++++++++++ その他の cpp ファイル:

void otherCppFile::creatingWindow()
{

    const char g_szClassName2[] = "windowClass2";//name of the window class
    const char WndName2[] = "winClass2";//name of the window class

    HWND windowHandle = CreateWindowEx(0,
                      g_szClassName2,
                      WndName2,
                      WS_OVERLAPPEDWINDOW,
                      0,
                      0,
                      800,
                      500,
                      NULL,
                      NULL,
                      NULL,
                      NULL);
}

この最後の関数は、WinMain に配置されておらず、一部の変数が関数で再宣言されていますが、WinMain に登録されているウィンドウ クラスを使用していますか?

4

1 に答える 1

2

ウィンドウ クラスを登録することの要点は、それが一意であり、必要なときにいつでも使用できるようにすることです。関数を使用してウィンドウ クラスを登録する場合RegisterClass[Ex]、それを識別するための 2 つのオプションがあります。

  • 関数に渡したウィンドウ クラス名 (文字列)。
  • 関数によって返されるATOM(整数値)。

99.9% の場合、 を忘れATOMて文字列だけを使用します。ウィンドウ クラスを作成するには文字列が必要なので、文字列についていき、それを使用してそのクラスのウィンドウを作成することもできます。

技術的には、あなたがしていることは大丈夫です。複数の変数がありますが、それらにはすべてまったく同じ文字列値が含まれているため、すべてが正しく機能しています。しかし、これはメンテナンスの悪夢であり、DRY (同じことを繰り返さないでください) ルールにも違反しています。ウィンドウ クラスの名前を変更したい場合はどうすればよいでしょうか。それを宣言したすべてのファイルを見つけて、更新したことを確認する必要があります。その後、多数のファイルに触れたため、プロジェクト全体が再コンパイルされるまで永遠に待たなければなりません。ダメ。

代わりに、この変数をグローバルスコープで宣言して、ウィンドウを作成するプロジェクトのすべてのファイルで使用できるようにします。すべてのコード ファイルに含める共通のヘッダー ファイルに配置するか、個別のWindow.hヘッダーまたはそのような性質のものを作成して、適切な場所に含めます。

このウィンドウ クラス名が定数として宣言されていることを確認してください。アプリケーションの実行中に変更する必要はありません。

C++ でグローバル定数の宣言や使用に苦労している場合は、この質問に対する回答を確認するか、スタック オーバーフローで独自の検索を行うことができます。この部分は、Windows プログラミングに固有のものではありません。それは単なる基本的な C++ です。

もちろん、グローバル変数はよくないという話をよく耳にします。それは十分に真実です。あなたが書いているコードは実際には C++ ではありません。それは C です。Windows API は C API であるため、自然に C++ で C コードを作成するようになります。本当に C++ コードを書きたい場合は、C ベースの Windows API の C++ ラッパーを見つける (または独自に作成する) 必要があります。たとえば、ウィンドウを表すクラスを記述し、そのクラスには、ウィンドウ クラスの名前を保持するクラス レベルの静的定数が含まれます。クラスはすべての新しいウィンドウの作成を担当するため、その情報や実装の詳細を複数のコード ファイルに分散させる必要はありません。

ウィンドウ名に関しては、これはまったく異なります。Windows はこれを使用してウィンドウを識別しません。実際、これはCreateWindow[Ex]関数の完全にオプションのパラメーターです。ウィンドウに名前を付ける必要さえありません。これは、実際にはウィンドウのタイトル バーに表示される名前です。ユーザーがウィンドウを識別するために使用します。そのため、多くの場合、ローカライズする必要があり、ソース コードではなく、プロジェクトのリソース ファイルに保存する必要があります。LoadString関数を使用して、プロジェクトのリソース ファイルから文字列を読み込みます。ウィンドウを作成するときはいつでも、これを動的に行うことができます。その特定のウィンドウのキャプションとして使用したい文字列をロードするだけです。

于 2014-08-22T13:28:20.470 に答える