1

まず、これが私が与えられた文書からの説明です。注: 私がしなければならなかったのは、これらの要件を満たすために既存のコードを変更することだけでした

コードを変更して、デモに示すように編成された 4 つのウィンドウを作成します。ユーザーがウィンドウを閉じたときに、他のウィンドウがまだ開いている場合、プログラムは強制終了されません。プログラムを停止するには、ユーザーはそれらすべてを閉じる必要があります。

開いているウィンドウの数を追跡する必要があります (閉じている場合は減算します)。グローバルは許可されていません。静的は許可されていません。

さらに、プログラムは lParam と CREATESTRUCT を使用してカウントを初期化する必要があります。

Possible functions and structs:

SetWindowLong()
GetWindowLong()
SetClassLong()
GetClassLong()
CREATESTRUCT

さて、これが私が終わったものです。必要な 4 つのウィンドウを開くことができ、1 つのウィンドウを閉じても (WM_DESTROY メッセージを送信して) プログラム全体が終了しないようにしました。私が混乱しているのは、lParam の受け渡しと CREATESTRUCT の使用です。

ここに私のwndproc.cがあります:

 LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
    HDC     hdc;
    PAINTSTRUCT ps;
    RECT    rect;
    int number = GetClassLongPtr(hwnd, 0);

    switch (message){
        case WM_CREATE:
            if(number == 0){
                SetClassLongPtr(hwnd, 0, (LONG)((CREATESTRUCT*)lParam)->lpCreateParams);
            }
            number++;
            return 0;

        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);

            GetClientRect(hwnd, &rect);
            DrawText(hdc, TEXT("Unique yet the same!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER);

            EndPaint(hwnd, &ps);
            return 0;

        case WM_DESTROY:
            number--;
            if(number == 0){
                PostQuitMessage(0);
            }
            return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);

作成された最初のウィンドウの lParam として渡す変数を Class Extra として設定しようとしています。それは理にかなっていますか?ここに私のmain.cがあります:

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCMLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloApplication"); HWND hwnd; MSG メッセージ; WNDCLASS wndclass; LONG* カウント。

wndclass.style      = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = HelloWndProc;
wndclass.cbClsExtra = 5;
wndclass.cbWndExtra = 0;
wndclass.hInstance  = hInstance;
wndclass.hIcon      = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor    = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;


if (!RegisterClass (&wndclass)){
    MessageBox (NULL, TEXT ("This program requires Windows 95/98/NT"),
                szAppName, MB_ICONERROR);
    return 0;
}

hwnd = CreateWindow(szAppName,      
                    TEXT("Hello World for Windows"), 
                    WS_OVERLAPPEDWINDOW,    
                    100,        
                    50,     
                    400,        
                    300,        
                    NULL,               
                    NULL,           
                    hInstance,          
                    count = 0);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

助けていただければ幸いです。私はすでにクラスでこの情報についてクイズを受けましたが、理解できませんでした。私は自分の理解のためだけにこの質問を投稿しています。

ありがとう。

4

3 に答える 3

2

同じウィンドウクラスのウィンドウ(インスタンス)の数をカウントする必要があるため、必要なカウンターはウィンドウクラスの静的データメンバーと見なすことができます。

したがって、目標は、ウィンドウクラスにいくつかの追加データ(ここでは整数カウンター)を追加することです。そのためには、この余分なデータを割り当てるようにWindowsに指示する必要があります。これは、正しい値をに渡すことで実現できますRegisterClass()。必要なカウンターについては、参照が渡されるcbClsExtraタイプの構造体のメンバーを整数カウンターのサイズに設定します。WNDCLASSRegisterClass()

メッセージディスパッチャのコールバックメソッドでWindowsクラスの静的データ(および整数カウンタ)にアクセスするには、を使用しますGetClassLongPtr()

これは宿題だと思うので、ゲームの残りの部分は演習として残します... ;-)

于 2012-09-18T12:02:06.200 に答える
1

間違っている、彼らが何もしない眼鏡!

  • 自動変数をに渡すことはできず、(実際に渡す値ではなく)その変数のアドレスCreateWindowExが通過することを期待できます。
  • 自動変数に値を割り当て(int number = GetClassLongPtr(hwnd、0);)、その変数に変更を加えて、それらが永続的であることを期待することはできません。

要するに:

  • CreateWindowEx値ではなく、へのポインタを渡す
  • そこに格納されている値を変更する場合は、そのポインターを間接参照します

ポインタに関する知識を更新する必要があるかもしれません。

于 2012-09-18T07:56:34.103 に答える
1

SetClassLongPtr-この関数は、ウィンドウのクラスに関連付けられているメモリで動作します。これは本質的に静的変数です。実際、開いているウィンドウの単純な静的カウンターがあります。煙幕の下に隠れているだけです。

技術的には、C / C ++の観点から、あなたのカウンターはそうではありませんstatic/global variable。しかし、概念的な観点からは、そうです。

lParamとCREATESTRUCTは、ここでは重要ではありません。

于 2012-09-18T06:17:07.623 に答える