winapi win32 - C++:なぜこのウィンドウのタイトルは切り捨てられるのですか?



main createwindow (6)

あなたの最後のケースでは、あなたのL "Sample"はまだUnicodeのままですね。 あなたは_T()マクロを使うことができます、それは自動的にプロジェクトのUnuicode設定に応じてL接頭辞を追加または削除します。

そして@Peteがすでに述べたように、Unicode Lの "Sample"は、ASCIIでは "S \ 0 ..."であるため、1つの記号だけが表示されます。

ビジュアルC ++ 2012 RC、Win7

中国語(簡体字

プロジェクトのプロパティ>マルチバイト文字セットを使用

このプログラムを実行すると、ウィンドウのタイトルに "Sample"という単語が表示されるのではなく、 "S"が表示されます。

#pragma comment(linker, "/SubSystem:Windows")

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int) {
    WNDCLASSW wc = { 0 };

    wc.style            = CS_VREDRAW | CS_HREDRAW;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIcon(nullptr, IDI_APPLICATION);
    wc.hCursor          = LoadCursor(nullptr, IDC_ARROW);
    wc.hbrBackground    = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
    wc.lpszClassName    = L"MyWindowClass";

    wc.lpfnWndProc = [](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        if (uMsg - WM_DESTROY)
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
        else {
            PostQuitMessage(0);
            return HRESULT();
        }
    };

    RegisterClassW(&wc);

    CreateWindowExW(0, L"MyWindowClass", L"Sample",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, SW_SHOW, CW_USEDEFAULT, 0,
        nullptr, nullptr, hInstance, nullptr);

    for (MSG msg; GetMessage(&msg, nullptr, 0, 0); DispatchMessage(&msg));
}

Unicode(Project Properties)を使用している場合は、ソースコードを変更しないでください。ウィンドウのタイトルに "Sample"と表示され、正しいように見えます。

マルチバイトを使用している場合、ソースコードでWNDCLASS = {...、 "MyWindowClass"}とRegisterClassAを使用し、CreateWindowExWを変更せずに、ウィンドウのタイトルに "Sample"と表示され、正しいように見えます。

マルチバイトを使用している場合、ソースコードでCreateWindowExA( "MyWindowClass"、 "Sample")を使用し、WNDCLASSWとRegisterClassWを変更せずにウィンドウタイトルに "S"を表示します。

それが単一の "S"を表示するのはなぜですか、私は何か悪いことをしていますか?

追加

すべてを変更しない、つまりマルチバイトを使用し、上記のコードを使用すると、ウィンドウのタイトルに文字 "S"が表示されます。

(このプログラムを実行し、ウィンドウタイトルに「S」ではなく「サンプル」が表示される場合は、vc ++ 2012(またはOS)のchsバージョンで発生する可能性が高いです。)


これはとても素敵なものです、何か新しいことを学びました!

変更する必要があります

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

if(IsWindowUnicode(hWnd))  
  return DefWindowProcW(hWnd, uMsg, wParam, lParam);  
else  
  return DefWindowProcA(hWnd, uMsg, wParam, lParam);

もっと良いのは、1文字エンコーディングに固執することです。 せいぜいRegisterClassやCreateWindowExなどを使用して、コンパイラに正しいUnicode関数またはANSI関数を使用させるだけです。


私はこれを見つけてうれしいです。 私は答えを探していましたが、Googleなどで正しく見つけるのはかなり難しいようです。私は特定のプログラムについて同様の問題が報告されているのを見つけました。

WndProcの問題はCreateWindowExやRegisterClassExの呼び出しにはどこにも及ばないため、これは狂気です。

ところで、私は明示的に-W接尾辞を使用します。どちらの方法で構築されたプログラムに対しても機能する1つのDLLを作成するか、追加しているプログラムの非Unicode設定を克服したいからです。


コードの問題は、 DefWindowProc代わりにDefWindowProcWを使用していることです。 それを変更するとコードが修正されます。

理想的には、マルチバイト文字セットではなく、Unicodeを使用するようにプロジェクト設定を変更する必要があります。 これによりすべてが単純化され、Unicode / ANSIバージョンを明示的に使用する代わりに、 CreateWindowExRegisterClassExなどのマクロを使用できます。

他の人が言っているように、これは文字セット間の不一致です。

相互作用するすべてのAPI呼び出しの間で文字セットを一致させるのが理想的です。 したがって、 CreateWindowExWを使用する場合は、 RegisterClassExWDefWindowProcWDispatchMessageW ...も使用する必要があります。


RegisterClassmsdnページはここで失敗の理由を示唆していると思います、備考のセクションであなたがワイド​​文字かansiサポートのどちらかを使うならそれがこのフォーマットで内部テキストパラメータ/メッセージを渡す方法を述べます(wide char / ANSI)。 たぶんそれはウィンドウタイトルで起こっていることです、私達がCreateWindowExA使うと言っても、これは内部的には動作しませんWindows SDKはワイド文字列としてその文字列をエンコードし、 CreateWinowExAはあたかもそれがそうであるかのように出力しようとしますAnsi文字列です。

あなたがそうするための正当な理由がない限り、手短に言えば、WとAのメソッドを混在させてはいけません、そして、ワイド文字サポートがあなたのUNICODEマクロを定義したいならば、あなたに代わってwindowsヘッダに任せます。


なぜ仮想メソッドがC ++で必要なのでしょうか?

素早い回答:

  1. これは、 オブジェクト指向プログラミングのために必要な「成分」 1の1つを提供します

Bjarne Stroustrup C ++プログラミング:原則と実践、(14.3):

仮想関数は、基本クラスに関数を定義し、ユーザーが基本クラス関数を呼び出すときに呼び出される派生クラスに同じ名前と型の関数を持つことができます。 呼び出される関数は、実行時に、使用されるオブジェクトのタイプに基づいて決定されるため、 ランタイム ポリモーフィズム動的ディスパッチ 、またはランタイムディスパッチと呼ばれることがあります。

  1. 仮想関数呼び出しが必要な場合は、最も効率的な実装が最も高速です2

仮想呼を処理するためには、 派生オブジェクト 3に関する1つまたは複数のデータが必要である。 通常行われる方法は、関数のテーブルのアドレスを追加することです。 このテーブルは通常仮想テーブルまたは仮想関数テーブルと呼ばれ、そのアドレスはしばしば仮想ポインタと呼ばれます 。 各仮想関数は、仮想テーブル内のスロットを取得します。 呼び出し側のオブジェクト(派生)型に応じて、仮想関数はそれぞれのオーバーライドを呼び出します。

1. オブジェクト指向プログラミングの最も一般的な定義は、継承、実行時多型、およびカプセル化の使用です。

2.ランタイムに選択肢の中から選択するために、他の言語機能を使用して、より速くなるように機能をコード化したり、メモリを少なくしたりすることはできません。 Bjarne Stroustrup C ++プログラミング:原則と実践(14.3.1)

3.仮想関数を含む基本クラスを呼び出すときに実際にどの関数が呼び出されるかを示すためのもの。





c++ winapi