3

私はWinAPIを学び、TicTacToeゲームを書こうとしています。X、O、または空の画像が表示されるボタンを使用しています。動的配列(HWND)に格納されているボタン。このすべてのボタンが同じIDを持っているのはなぜですか。

if(GetDlgCtrlID(hBtns[0][0]) == GetDlgCtrlID(hBtns[0][1]))
    MessageBox(hWndDlg,_T("TheSame"),_T(""),NULL);

MessageBoxが表示されます!、なぜ。助けてください。

//KA_SHAG
//Miwa_Mikitin
//XXXOOO
#include<windows.h>
#include<tchar.h>
#include"resource.h"

//Main Proc
BOOL CALLBACK DialogProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam);
//EnumChildProc
BOOL CALLBACK DisableEnableButtons(HWND hwnd,LPARAM lParam);

HWND** hBtns;//Global Dynamic Array of Buttons
int size = 150;//Size of Side of field, Button Size = size/nButtons

//BITMAPS
HBITMAP hBmpX,hBmpO,hBmpNone;
/////////

void CreateButtons(HWND hWndDlg,int nBtnsOld,int nBtnsNew);
void LoadBitmaps();


INT WINAPI WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR cmdLine,INT nShowCmd)
{   
    HWND hWndDlg = CreateDialog(hIns,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DialogProc);

    MSG msg;
    ShowWindow(hWndDlg,1);

    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

BOOL CALLBACK DialogProc(HWND hWndDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
    HINSTANCE hIns = GetModuleHandle(0);            
    static int nBtnsOld = 5;//intitial N of Buttons on a row|col
    static int nBtnsNew;//next update N of Buttons on a row|col
    static BOOL isPlaying = false;
    static BOOL isMyMove = true;

    switch(message)
    {
    case WM_INITDIALOG:
        {       
            LoadBitmaps();
            CreateButtons(hWndDlg,nBtnsOld,nBtnsOld);
        }
        return true;

    case WM_COMMAND:
        if(HIWORD(wParam) == BN_CLICKED)
        {
            //Resize the Button field
            if(LOWORD(wParam) == IDC_BTNSETSIZE)
            {       
                //Determine wich RadioBtn is Checked
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO33))
                    nBtnsNew = 3;//set new nBtns
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO44))
                    nBtnsNew = 4;//set new nBtns
                if(IsDlgButtonChecked(hWndDlg,IDC_RADIO55))
                    nBtnsNew = 5;//set new nBtns
                ///////////////////////////////////////////
                //If no difference than ignore
                //else Create new Array of Btns
                if(nBtnsOld != nBtnsNew)
                {
                    CreateButtons(hWndDlg,nBtnsOld,nBtnsNew);
                    nBtnsOld = nBtnsNew;
                }
                /////////////////////////////////////////
                return true;
            }
            if(LOWORD(wParam) == IDC_BTNBEGIN)
            {   
                //Enum Buttons,CheckBox,RadioBtns
                //then Disable or Enable them depending on isPlaying var
                //if TRUE - ENABLE
                //else Disable
                EnumChildWindows(hWndDlg,DisableEnableButtons,isPlaying);
                //switch isPlaying )
                isPlaying = !isPlaying;
                //switch begin Button Text
                if(isPlaying)
                    SetWindowText(GetDlgItem(hWndDlg,IDC_BTNBEGIN),_T("Закінчити гру"));
                else
                    SetWindowText(GetDlgItem(hWndDlg,IDC_BTNBEGIN),_T("Почати гру"));
                /////////////////////////////////////////////////////////////////////
                return true;
            }
            //When Playing
            if(isPlaying)
            {
                //Determine HWND of Pressed Btn
                HWND pressedBtn = GetDlgItem(hWndDlg,LOWORD(wParam));
                HBITMAP propBmp;
                if(isMyMove)
                    propBmp = hBmpX;
                else
                    propBmp = hBmpO;
                //Change BMP
                SendMessage(pressedBtn,
                    BM_SETIMAGE,IMAGE_BITMAP,
                    (LPARAM)propBmp);
                //WHY???
                if(GetDlgCtrlID(hBtns[0][0]) == GetDlgCtrlID(hBtns[0][1]))
                    MessageBox(hWndDlg,_T("TheSame"),_T(""),NULL);

                return true;
            }
        }
        return true;
    case WM_CLOSE:
        DestroyWindow(hWndDlg);
        PostQuitMessage(0);
        return TRUE;
    }

    return FALSE;
}

void CreateButtons(HWND hWndDlg,int nBtnsOld,int nBtnsNew)
{

    HINSTANCE hIns = GetModuleHandle(0);//main instance

    //Destroy Buttons
    if(hBtns)
    {
        for(int i=0;i<nBtnsOld;i++)
            for(int j=0;j<nBtnsOld;j++)
                DestroyWindow(hBtns[i][j]);
        ////////////////////////////////    
        //Free memory
        for(int n=0;n<nBtnsOld;n++)
            delete[]hBtns[n];
        delete[]hBtns;  
    }
    /////////////////////////////////
    //Allocate new memory
    hBtns = new HWND*[nBtnsNew];
    for(int n=0;n<nBtnsNew;n++)
        hBtns[n] = new HWND[nBtnsNew];
    ////////////////////////////////
    int x =0;//offset x
    int y =0;//offset y
    //tchar[] for diff name s of btns

    //Create Buttons & assign to hBtns Array
    for(int i=0;i<nBtnsNew;i++)
    {
        for(int j=0;j<nBtnsNew;j++)
        {

            hBtns[i][j] = CreateWindowEx(
                NULL,_T("Button"),
                NULL,
                WS_CHILD | WS_VISIBLE | BS_BITMAP | BS_NOTIFY ,
                x,y,size/nBtnsNew,size/nBtnsNew,
                hWndDlg,NULL,
                hIns,NULL);
            //Set Default Image On Btns
            SendMessage(hBtns[i][j],BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBmpNone);

            x+=size/nBtnsNew;

        }
        y+=size/nBtnsNew;
        x=0;
    }
}

BOOL CALLBACK DisableEnableButtons(HWND hwnd,LPARAM lParam)
{
    //Lparam is a BOOL if true Button will be Enabled
    //else Buttons will be Disabled
    if( GetDlgCtrlID(hwnd) == IDC_RADIO33 ||
        GetDlgCtrlID(hwnd) == IDC_RADIO44 ||
        GetDlgCtrlID(hwnd) == IDC_RADIO55 ||
        GetDlgCtrlID(hwnd) == IDC_CHECKMOVE ||
        GetDlgCtrlID(hwnd) == IDC_BTNSETSIZE)
        EnableWindow(hwnd,lParam);//<---lParam is BOOL

    return TRUE;
}

//BOOL CALLBACK DrawBmpOnBtn(HWND hwnd,LPARAM lParam)
//{
//
//  SendMessage(hwnd,BM_SETIMAGE,
//  return TRUE;
//}

void LoadBitmaps()
{
    HINSTANCE hIns = GetModuleHandle(0);//main instance

    hBmpX = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_X));
    hBmpO = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_O));
    hBmpNone = LoadBitmap(hIns,MAKEINTRESOURCE(IDB_BMP_NONE));
}

プロジェクト(VS2008)はこちら:http ://www.filehosting.org/file/details/372626/XXXOOO.rar

PSプログラムを実行するとき-下のボタンは青いボタンを描画でき、上のボタンは青いボタンの量を設定しますが、いくつかのradioBtnを確認してください。

4

2 に答える 2

4

ボタンのハンドルは同じではありませんが、コントロールIDを設定していません。これを行うには、呼び出しに次を追加しますCreateWindowEx

hBtns[i][j] = CreateWindowEx(
                NULL, _T("Button"),
                NULL,
                WS_CHILD | WS_VISIBLE | BS_BITMAP | BS_NOTIFY,
                x, y, size/nBtnsNew, size/nBtnsNew,
                hWndDlg,
               (HMENU)<your_control_id>,
                hIns, NULL);

<your_control_id>ボタンごとに一意のIDでパーツを置き換える必要があります。

私の推測では、呼び出しは失敗し、したがって0をGetDlgCtrlID()返します。GetDlgCtrlID()CreateWindowEx()

于 2012-09-05T16:43:26.997 に答える
2

コントロールIDは自動的に割り当てられません。コントロールIDをHMENUパラメーターとしてに渡しますCreateWindow(これについては、詳細は説明していませんが、のドキュメントに記載さCreateWindowれています)。

HWNDもちろん、それらを設定する通常の方法は、リソースエディタでダイアログを作成し、各子ウィンドウにコントロールIDを指定することです。これを使用して、実行時に各子ウィンドウを検索します。ただし、子ウィンドウを自分で作成する場合は、それぞれHWNDがすでに手元にあるので、直接使用する方がよいでしょう。これはコーディングが難しくありませんが、上に保持するのははるかに簡単です。たとえば、コントロールを追加する場合は、どこにでもIDを追加する必要はありません。

WM_COMMANDにウィンドウのダイアログIDを含むメッセージを受信すると、からWPARAMを取得し、代わりにその方法で子ウィンドウを識別できます。のドキュメントを参照してください。HWNDLPARAMWM_COMMAND

于 2012-09-05T16:46:01.257 に答える