HWND的动态数组中的ID相同
The same ID in dynamic array of HWND
我正在学习WinAPI,并试图编写一个Tic-Tac-Toe游戏。我正在使用将显示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
p.S.当执行程序时-下按钮允许绘制蓝色按钮,上按钮设置蓝色按钮的数量,但检查一些radioBtn。
按钮句柄不相等,但您尚未为它们设置控件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。
我的猜测是GetDlgCtrlID()
调用失败,因此返回0。阅读有关GetDlgCtrlID()
和CreateWindowEx()
的更多信息
控件ID不会自动分配。将控件ID作为HMENU
参数传递给CreateWindow
(这在CreateWindow
的文档中有提及,但没有详细说明)。
当然,设置它们的常用方法只是在资源编辑器中创建对话框,并为每个子窗口提供一个控件ID,然后在运行时使用该控件ID查找每个子窗口的HWND
。但是,当您自己创建子窗口时,您手头已经有了每个HWND
,所以您还不如直接使用它。这并不难编码,但更容易掌握——例如,如果你添加了更多的控件,就不需要在任何地方添加更多的ID。
当收到WM_COMMAND
消息时,其中包括WPARAM
中的窗口对话框ID,您可以从LPARAM
获取HWND
,并以这种方式标识您的子窗口。请参阅WM_COMMAND
的文档。
- std::具有相同基类的类的变体
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 不断收到相同的错误...怎么了?C++
- 具有最大子序列大小的序列,每个元素都相同
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何避免重复具有相同产品 ID 的产品
- 堆栈分配的类类型.为什么两个 ID 实例的地址相同?
- 为什么if(fork()==0){getpid()}和popen()进程返回相同的进程id
- C 不同的线程在FreeBSD 10上具有相同的线程ID
- 与上一个线程具有相同ID的线程同步
- GlcreatHader给出了相同的ID
- c++需要字符串的唯一ID,但无论顺序如何都必须相同
- 奇怪的错误:标签'loopend'使用但未定义," if "之前应为非限定 id("goto"和" '}' token "错误相同
- HWND的动态数组中的ID相同
- 在linux上接受时使用相同的SOCKET id
- 相同的线程 ID
- C++编译时唯一ID生成器总是返回相同的值
- 组合相同的唯一ID项