求教!(急!!!)~~~~button按钮变化颜色或者贴图

时间:2021-12-27 22:17:05
我编了个串口通讯的程序,现在我的程序有几十个按钮,需要根据状态位buf[3]=2或者buf[3]=3来判断要把id号为buf[2]的按钮的颜色变换成红色或者蓝色,或者把一幅红色或者蓝色的图赋给id号为buf[2]的按钮啊。
我想请问一下怎么样给button控件贴图或者令他变换成我需要的蓝色以及红色这两种颜色?
我是个新手不太懂,如果可以的话请讲详细点,谢谢!!

36 个解决方案

#1


没有设置颜色的么?

#2


用自绘按钮.下面的链接可以找到很多自绘按钮的例子
http://www.codeproject.com/buttonctrl/

#3


我不太清楚你说没有设置颜色的么是指什么,
但是我这程序是根据收到的状态位来改变按钮的样子,即可以改变按钮的颜色或者给按钮贴图上去以识别按钮是否已经按下没,如果按下就变换按钮的颜色或者贴一张图到按钮上去啊。

恩,好的,那网站我现在去看看。谢谢!!
希望懂的人多多指教!

#4


直接用 MFC的 CBitmapButton 就可以了.

#5


DentistryDoctor(不在无聊中无奈,就在沉默中变态) ( ) 信誉
刚才你发给我的那网站是不是要收费的啊?下载不了啊。好象上面也没有看见有注册的啊。

#6


用CBitmapButton比较简单

#7


CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CButton* pBtn = (CButton*)GetDlgItem(IDC_BUTTON1);
pBtn->SetButtonStyle(pBtn->GetButtonStyle() | BS_BITMAP | BS_CENTER);
pBtn->SetBitmap(bitmap);
bitmap.Detach();

#8


DentistryDoctor(不在无聊中无奈,就在沉默中变态) ( ) 信誉
不好意思啊。刚才没有注意到那注册的啊。

iicup(双杯献酒) ( ) 信誉:100    Blog 
直接用 MFC的 CBitmapButton 就可以了??

不过好象用这个是要鼠标点他或者是聚焦的时候才有反应啊,不是有四个状态判断的吗?一个是focus、disable 、up、down四种嘛。

我的要是是当我从串口里接受到数据时我根据一个状态为buf[3]来判断要把某个按钮变成红色或者蓝色啊,或者把一幅蓝色或红色的图显示在按钮上啊。可以让人直观的知道是 那个按钮有什么反应了嘛。而那个某个按钮是有 buf[2]决定是那个按钮的啊。我有很多个按钮的嘛。

还是这个 CBitmapButton 可以做的话请说详细一点啊。我是个新手不太会用。

#9


使用CBitmapButton实现如下(假如按钮在对话框中,ID为IDC_BUTTON1):
1、插入两个位图资源IDB_RED和IDB_BLUE。

2、在按钮的属性中将Owner Draw 和Bitmap选上。

3、在按钮所在对话框类加入CBitmapButton类型成员变量m_btn如下:
CBitmapButton m_btn;

4、初始化时(OnInitDialog函数),调用AutoLoad()函数将按钮与CBitmapButton类对象关联:
m_btn.AutoLoad(IDC_BUTTON1, this);

5、在你需要修改位图的地方如下调用:

m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();

m_btn.LoadBitmaps(IDB_BLUE);
m_btn.RedrawWindow();


来实现更换位图显示。

#10


不好意思啊,在按钮所在对话框类加入CBitmapButton类型成员变量m_btn如下:
是指在那里啊?
还有就是说我的是一个类似于模拟键盘的程序啊,我发消息的时候要可以看到这键盘啊,如果把按钮搞成owener draw的话那那些按钮全都不可以见了啊。那怎么解决这问题啊。
我是想做的界面就是我们可以用鼠标点那界面发消息啊,当受到串口消息的时候可以在程序上显示是那个键盘按钮发来消息的啊。所以就用图来替换按钮表示该按钮有动作发出啊。

#11


加在对话框类声明中。

如果你的按钮不仅做指示状态用,还有文字, 不想让文字消失。我想有两种方法:
1。就是按我说的方法,但是两个位图在制作时,就加上想要的文字。另外,为按钮选上一个边框什么的属性,让他看起来对用户可见。

2。还是用普通的按钮,不能使用位图,而改变他的背景色。不过对于按钮来说,改变背景色很麻烦,不能像文本框等响应OnCtrlColor,而只能对应新增一个从CButton派生的类,在类中重载DrawItem函数来画。

#12


我照你最上面那程序做了编译没有错啊,但是运行不了那程序,有错!



2。还是用普通的按钮,不能使用位图,而改变他的背景色。不过对于按钮来说,改变背景色很麻烦,不能像文本框等响应OnCtrlColor,而只能对应新增一个从CButton派生的类,在类中重载DrawItem函数来画。

如果单单改变需要改变按钮的背景色是最好啊。
你说要是新增类怎么实现啊?可以说下嘛?

#13


还是你哪步不对了。这是我自己在vc6,xp下正常运行的代码。

#14


如果你想用第二种方法,看一下随机的MSDN 关于 CButton类的DrawItem()函数。

#15


不清楚啊。不过我都是照你说的一步步来啊。
我先在对话框上画两个按钮,一个就是IDC_BUTTON1,我把他的性中将Owner Draw 和Bitmap选上;
还有一个是IDC_BUTTON20啊,我双击他后如下;
void CButtonDlg::OnButton20() 
{
// TODO: Add your control notification handler code here
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();

}
我在BOOL CButtonDlg::OnInitDialog()里的 // TODO: Add extra initialization here下面填上
m_btn.AutoLoad(IDC_BUTTON1, this);

我在头文件buttonDlg.h里的class CButtonDlg : public CDialog下的protected:HICON m_hIcon;下添加CBitmapButton m_btn;

另外对话框还自带了两个按钮一个是确定一个是取消;

上面的应该都和你说的一样啊。应该没有错啊。

我也不清楚怎么回事!

哦。好的。我会看DrawItem()函数的,谢谢

#16


在OnInitDialog()里的

m_btn.AutoLoad(IDC_BUTTON1, this);

后面也要调用
m_btn.LoadBitmaps();

先加载一个默认的位图。

#17


或者在你在每个需要改变图片的时候写成
if(btn.m_hWnd == NULL)
{
btn.AutoLoad(IDC_BUTTON1, this);
}
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();

保证只加载一次。就不会出错了。

#18


恩。我在在OnInitDialog()里的
m_btn.AutoLoad(IDC_BUTTON1, this);
后面也调用
m_btn.LoadBitmaps();
就可以了啊。谢谢啊。现在是可以变图片了啊。
不过我还有个问题就是说我是想要把id号为buf[2]的按钮改变图片啊,我有很多按钮嘛。而buf[2]里存的就是button的UINT nID号啊。那我怎么样连续起来啊?就是可以指向随便那个button都可以啊?谢谢

#19


在需要改变的时候:
CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
pBtn->LoadBitmaps(IDB_NEW); // 改变图

#20


iicup(双杯献酒) ( ) 信誉:100    Blog 
不可以啊,当我加入你这语句时程序就出错死了啊。如果不加则可以显示啊,下面是我的一个判断颜色的语句,
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);//红图显示
// CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
// pBtn->LoadBitmaps(IDB_RED); // 改变图
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
m_btn.LoadBitmaps(IDB_BLUE);
m_btn.RedrawWindow();
}
else 
{
m_btn.LoadBitmaps(IDB_GRAY);
m_btn.RedrawWindow();
}

#21


因为在在OnInitDialog()里的
m_btn.AutoLoad(IDC_BUTTON1, this);
所以他是默认是button1发生改变啊。有什么办法可以让发生改变的按钮号是有buf[2]里的啊。而不是他指定的button1啊。

#22


没有人了吗?呜呜。。。


还是楼上
 iicup(双杯献酒) ( ) 信誉:100    Blog  2006-9-21 14:29:50  得分: 0  
 在需要改变的时候:
CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
pBtn->LoadBitmaps(IDB_NEW); // 改变图

我改了以后就会有错啊。当我把
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();
这两句注释掉后换上你
CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
pBtn->LoadBitmaps(IDB_NEW); // 改变图
编译时没有错,但是运行时按钮没有变化啊,也会错误。
  
 

#23


先用ClassWizard为你需要改变图片的按钮都关联一个CBitmapButton类型的控件变量。当然ClassWizard不直接支持,你可以先关联CButton类型,然后手动修改。


在在OnInitDialog()里分别设置按钮默认位图如下:

m_btn1.LoadBitmaps(IDB_GRAY);
m_btn2.LoadBitmaps(IDB_GRAY);
m_btn3.LoadBitmaps(IDB_GRAY);
... ...



判断颜色的语句:


CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);//红图显示
pBtn->LoadBitmaps(IDB_RED); 
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
pBtn->LoadBitmaps(IDB_BLUE);
}
else 
{
pBtn->LoadBitmaps(IDB_GRAY);
}
pBtn->RedrawWindow();

#24


上面设置变量,目的是为了让MFC为我们自动在类对象与按钮之间建立关联。当然也可以在对话框类直接定义一些CBitmapButton类型的变量。
然后在OnInitDialog函数中创建关联,如下:
btn1.AutoLoad(IDC_BUTTON1, this);
btn1.LoadBitmaps(IDB_GRAY);

btn2.AutoLoad(IDC_BUTTON2, this);
btn2.LoadBitmaps(IDB_GRAY);

btn3.AutoLoad(IDC_BUTTON3, this);
btn3.LoadBitmaps(IDB_GRAY);
是一样的。

#25


楼主是否可以这样考虑:用画刷来改变颜色,每变换一次就用重新paint一次。
第二种方式:加载位图的方式,每变换一次就加载一次位图。

#26


wangpanli(沉睡的狮子) 
我在OnInitDialog函数中创建关联,如下:
btn1.AutoLoad(IDC_BUTTON1, this);
btn1.LoadBitmaps(IDB_GRAY);

btn2.AutoLoad(IDC_BUTTON2, this);
btn2.LoadBitmaps(IDB_GRAY);

btn3.AutoLoad(IDC_BUTTON3, this);
btn3.LoadBitmaps(IDB_GRAY);
又在// keyboardcheckDlg.h : header file里定义了CBitmapButton m_btn,btn1,btn2,btn3;然后把判断颜色的换成你的语句。
但是我一从串口发消息过去程序就错误了啊,程序自动关闭了。我从串口发消息时是没有错误的啊,发来的消息是buf数组存。


当我不在OnInitDialog函数中创建关联;
// m_btn.AutoLoad(IDC_BUTTON2, this);
// m_btn.LoadBitmaps(IDB_GRAY);
然后我在判断颜色的时候不用你的那语句而用下面这语句时,
m_btn.AutoLoad((buf[2]+1000), this); //这时才根据buf[2]值创建关联,buf[2]+1000为我的按钮的id号
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);
// CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]+1000); // 得到按钮句柄
// pBtn->LoadBitmaps(IDB_RED);
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
// CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]+1000); // 得到按钮句柄
// pBtn->LoadBitmaps(IDB_BLUE);

m_btn.LoadBitmaps(IDB_BLUE);
m_btn.RedrawWindow();
}
else 
{
m_btn.LoadBitmaps(IDB_GRAY);
m_btn.RedrawWindow();
m_recmsg = "";
}

则我串口发出消息时程序第一次可根据buf[2]的值来变换按钮的颜色,但是从第2次时起再发时会有出错的提示框出现,如果我忽略错误时则按钮会继续根据buf[2]值和buf[3]的值发生相应的变化。
错误提示框debug assertion failed!
program:...?我的应用程序位置
file:wincore.cpp
line:311
for information on how your program can cause an assertion failure,see the visual C++ documentation on asserts.
(Press retry to debug the application)

如果要是没有那错误提示框的话他也可以根据buf[2]来显示按钮的颜色了啊。

#27


tanmeining(Dream) ( ) 信誉:100    Blog  2006-09-21 17:54:00  得分: 0  
    楼主是否可以这样考虑:用画刷来改变颜色,每变换一次就用重新paint一次。
第二种方式:加载位图的方式,每变换一次就加载一次位图。
  
 恩。这个也可以,不过我刚接触不久不懂呢。我再找下资料。谢谢。
谁要是有什么好的办法可以说下。

#28


buf[2] 的值是变化的吗?

m_btn.AutoLoad被调用后,不能在调用第二次。你的这句代码

  m_btn.AutoLoad((buf[2]+1000), this); //这时才根据buf[2]值创建关联,buf[2]+1000为我的按钮的id

有问题,肯定出错。

  你不应该重复使用的函数中调用,应该只初始化一次。最好按我说的,用ClassWizard为每一个按钮加一个对应的CBitmapButton类型变量。我试过了,没错。
  
  你出错的原因可能:
   1。buf[2]+1000的值不是按钮的ID

      2。ID值为buf[2]+1000的按钮尚未与一个CBitmapButton的对象相联系,导致

   CBitmapButton* pBtn (CBitmapButton*)GetDlgItem(buf[2]+1000);

   这句执行类型转换时出错。



#29


哦。谢谢啊!!
我现在有办法搞图标上去了啊。我用seticon啊
if(buf[3]==2)
{str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{ str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{ m_recmsg = "";
//((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

不过我现在想当图片显示一段时间后就使用((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));使他恢复原来的gray颜色啊。不过我用定时器就有错啊。

我是这样用的啊。不知道那里出错了,
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{
m_recmsg = "";
//((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

m_recmsg=str;
UpdateData(false);
SetTimer(100,1000,NULL);
}



void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
CDialog::OnTimer(nIDEvent);
}

#30


但是我要用定时器就错了啊。我象上面用应该没有错吧?

我是这样用的啊。不知道那里出错了,
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{
m_recmsg = "";
//((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

m_recmsg=str;
UpdateData(false);
SetTimer(100,1000,NULL);
}



void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
CDialog::OnTimer(nIDEvent);
}

#31


出错信息为:
--------------------Configuration: keyboardcheck - Win32 Debug--------------------
Compiling...
keyboardcheckDlg.cpp
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(281) : error C2039: 'OnButton1' : is not a member of 'CKeyboardcheckDlg'
        c:\documents and settings\administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckdlg.h(14) : see declaration of 'CKeyboardcheckDlg'
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(290) : error C2065: 'UpdateData' : undeclared identifier
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(312) : error C2660: 'GetDlgItem' : function does not take 1 parameters
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(312) : error C2227: left of '->GetCheck' must point to class/struct/union
Error executing cl.exe.

keyboardcheckDlg.obj - 4 error(s), 0 warning(s)

但是原先我没有用定时器前程序都正确啊,象我这样用定时器有错吗?谢谢指教!!

#32


上面的出错信息与你给出的代码没关系。OnButton1没在头文件中定义。

另外,SetTimer()用在函数中,每次调用函数都会会重新设置一个定时器。最好应该用完之后
使用KillTimer()将定时器删除了。
void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
   ((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

         KillTimer(100);

CDialog::OnTimer(nIDEvent);
}

#33


但是如果我不用定时器的话就没有错误啊。
我的很多东西都是在OnButton1里面判断的啊。
没有定时器就没有错啊。一有就报错了。

有没有用什么办法可以先((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
隔几秒再((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));就是按钮先红色再灰色啊。


我用这样看不见啊。debug可以看见啊。不过exe很快就过去了。看不了颜色变化
/*CTime t = CTime::GetCurrentTime(); //获取系统日期
int d=t.GetDay(); //获得几号
int y=t.GetYear(); //获取年份
int m=t.GetMonth(); //获取当前月份
int h=t.GetHour(); //获取当前为几时
int mm=t.GetMinute(); //获取分钟
int s=t.GetSecond(); //获取秒
//int y,m,d,h,mm,s;
CTime t1( y, m, d, h, mm, s );
CTimeSpan span=t-t1; //计算当前系统时间与时间t1的间隔
int iSec=span.GetTotalSeconds();//获取总共有多少秒 
while(iSec<1)
{
t = CTime::GetCurrentTime();
CTimeSpan span=t-t1; 
 iSec=span.GetTotalSeconds();
}*/
//AfxMessageBox(str);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
//AfxMessageBox("mmmmmmmmmess");

#34


贴图直接用 CBitmapButton 即可.

#35


谢谢各位的指教啊,非常谢谢啊!
特别是谢谢wangpanli(沉睡的狮子)!!


现在程序我已经把那错误搞定了.。
不过很奇怪的啊,原来我程序是有下面这两句话的,但是当加定时器后会程序会自动消失掉下面这两句话,要我手动补回,补回来就正常正确显示了.当我撤消掉加入定时器时下面这两句就又有回来了。证明应该是我一加定时器就消失了这两句话,中间我没有做其他动作。
//afx_msg void OnButton1(UINT nID);       //在keyboardcheckDlg.h
//ON_COMMAND_RANGE(IDC_BUTTON1,IDC_BUTTON32,OnButton1)  // 在keyboardcheckDlg.cpp

不过wangpanli(沉睡的狮子)说的OnButton1没在头文件中定义,我想我应该已经定义了啊,因为我在member variables里已经定义IDC_BUTTON1是cbutton Typeta型的拉。还定义了一个Mmember 为m_button00;


还有个问题就是现在我是当灯灭掉的时候我是我是起定时器一下子全都灭掉了啊,(注:IDI_GRAY表示灭掉啊。)
for (int i=0;i<32;i++)
{    ((CButton *)GetDlgItem(i+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY)); ////IDI_GRAY表示灭掉;
}
现在我是想做当按键按下去灯亮后然后灯灭时是按照按按键的先后顺序一个接着一个灭掉啊。 不知道改成下面可以不可以啊,我试了好象没有效果的啊.如果各位有什么高见的话那请多指教啊.谢谢!!
原来程序是:
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{ //record[r++]=buf[2]; //r为全局变量初值为0;
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{ //record[r++]=buf[2];
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{m_recmsg = "";
}
m_recmsg=str;
UpdateData(false);
SetTimer(100,2000,NULL);
}

void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{ // TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{ for (int i=0;i<32;i++)
{   ((CButton *)GetDlgItem(i+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
}
KillTimer(100);
CDialog::OnTimer(nIDEvent);
}

我改成了下面这样,我是想做当按键按下去灯亮后然后灯灭时是按照按按键的先后顺序一个接着一个灭掉啊。如果有错或是有什么好的方法的话请告诉我啊.谢了.
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{ record[r]=buf[2];    //r为全局变量初值为0;//注:下班前我用的是record[r++]试过不行,现在record[r]是我现在想的
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
SetTimer(100,2000,NULL);
r++;
}
else if (buf[3]==3)
{ record[r]=buf[2];    //r为全局变量初值为0;//注:下班前我用的是record[r++]试过不行,现在record[r]是我现在想的
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
SetTimer(100,2000,NULL);
r++;
}
else 
{m_recmsg = "";
}
m_recmsg=str;
UpdateData(false);

}

void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{ // TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
 ((CButton *)GetDlgItem(record[r]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
KillTimer(100);
CDialog::OnTimer(nIDEvent);
}
不知道这样行不行啊。我就想如果传过来定时器的话是不是r这个全局变量又等于初始值0了啊?
由于下班了我也回来了没有试呢.原来试的时候void CKeyboardcheckDlg::OnRecBuf()里的是record[r++]而不是record[r];但是我试时好象没有反应也.先在这问下我这样写有没有什么问题啊.因为现在回来没有串口卡试了,不清楚对不对现在了.想跟大家讨论下行不行先。


#36


我试了还是不行,应该是定时器里的cord[r]值没有传过到定时器里吧。由于现在又开始做其他东西了没有时间来调这程序了。不过我想用指针或者指针数组来存过来应该没有问题啊。
谢谢大家啊!特别是wangpanli(沉睡的狮子)啊。谢谢了。

#1


没有设置颜色的么?

#2


用自绘按钮.下面的链接可以找到很多自绘按钮的例子
http://www.codeproject.com/buttonctrl/

#3


我不太清楚你说没有设置颜色的么是指什么,
但是我这程序是根据收到的状态位来改变按钮的样子,即可以改变按钮的颜色或者给按钮贴图上去以识别按钮是否已经按下没,如果按下就变换按钮的颜色或者贴一张图到按钮上去啊。

恩,好的,那网站我现在去看看。谢谢!!
希望懂的人多多指教!

#4


直接用 MFC的 CBitmapButton 就可以了.

#5


DentistryDoctor(不在无聊中无奈,就在沉默中变态) ( ) 信誉
刚才你发给我的那网站是不是要收费的啊?下载不了啊。好象上面也没有看见有注册的啊。

#6


用CBitmapButton比较简单

#7


CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
CButton* pBtn = (CButton*)GetDlgItem(IDC_BUTTON1);
pBtn->SetButtonStyle(pBtn->GetButtonStyle() | BS_BITMAP | BS_CENTER);
pBtn->SetBitmap(bitmap);
bitmap.Detach();

#8


DentistryDoctor(不在无聊中无奈,就在沉默中变态) ( ) 信誉
不好意思啊。刚才没有注意到那注册的啊。

iicup(双杯献酒) ( ) 信誉:100    Blog 
直接用 MFC的 CBitmapButton 就可以了??

不过好象用这个是要鼠标点他或者是聚焦的时候才有反应啊,不是有四个状态判断的吗?一个是focus、disable 、up、down四种嘛。

我的要是是当我从串口里接受到数据时我根据一个状态为buf[3]来判断要把某个按钮变成红色或者蓝色啊,或者把一幅蓝色或红色的图显示在按钮上啊。可以让人直观的知道是 那个按钮有什么反应了嘛。而那个某个按钮是有 buf[2]决定是那个按钮的啊。我有很多个按钮的嘛。

还是这个 CBitmapButton 可以做的话请说详细一点啊。我是个新手不太会用。

#9


使用CBitmapButton实现如下(假如按钮在对话框中,ID为IDC_BUTTON1):
1、插入两个位图资源IDB_RED和IDB_BLUE。

2、在按钮的属性中将Owner Draw 和Bitmap选上。

3、在按钮所在对话框类加入CBitmapButton类型成员变量m_btn如下:
CBitmapButton m_btn;

4、初始化时(OnInitDialog函数),调用AutoLoad()函数将按钮与CBitmapButton类对象关联:
m_btn.AutoLoad(IDC_BUTTON1, this);

5、在你需要修改位图的地方如下调用:

m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();

m_btn.LoadBitmaps(IDB_BLUE);
m_btn.RedrawWindow();


来实现更换位图显示。

#10


不好意思啊,在按钮所在对话框类加入CBitmapButton类型成员变量m_btn如下:
是指在那里啊?
还有就是说我的是一个类似于模拟键盘的程序啊,我发消息的时候要可以看到这键盘啊,如果把按钮搞成owener draw的话那那些按钮全都不可以见了啊。那怎么解决这问题啊。
我是想做的界面就是我们可以用鼠标点那界面发消息啊,当受到串口消息的时候可以在程序上显示是那个键盘按钮发来消息的啊。所以就用图来替换按钮表示该按钮有动作发出啊。

#11


加在对话框类声明中。

如果你的按钮不仅做指示状态用,还有文字, 不想让文字消失。我想有两种方法:
1。就是按我说的方法,但是两个位图在制作时,就加上想要的文字。另外,为按钮选上一个边框什么的属性,让他看起来对用户可见。

2。还是用普通的按钮,不能使用位图,而改变他的背景色。不过对于按钮来说,改变背景色很麻烦,不能像文本框等响应OnCtrlColor,而只能对应新增一个从CButton派生的类,在类中重载DrawItem函数来画。

#12


我照你最上面那程序做了编译没有错啊,但是运行不了那程序,有错!



2。还是用普通的按钮,不能使用位图,而改变他的背景色。不过对于按钮来说,改变背景色很麻烦,不能像文本框等响应OnCtrlColor,而只能对应新增一个从CButton派生的类,在类中重载DrawItem函数来画。

如果单单改变需要改变按钮的背景色是最好啊。
你说要是新增类怎么实现啊?可以说下嘛?

#13


还是你哪步不对了。这是我自己在vc6,xp下正常运行的代码。

#14


如果你想用第二种方法,看一下随机的MSDN 关于 CButton类的DrawItem()函数。

#15


不清楚啊。不过我都是照你说的一步步来啊。
我先在对话框上画两个按钮,一个就是IDC_BUTTON1,我把他的性中将Owner Draw 和Bitmap选上;
还有一个是IDC_BUTTON20啊,我双击他后如下;
void CButtonDlg::OnButton20() 
{
// TODO: Add your control notification handler code here
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();

}
我在BOOL CButtonDlg::OnInitDialog()里的 // TODO: Add extra initialization here下面填上
m_btn.AutoLoad(IDC_BUTTON1, this);

我在头文件buttonDlg.h里的class CButtonDlg : public CDialog下的protected:HICON m_hIcon;下添加CBitmapButton m_btn;

另外对话框还自带了两个按钮一个是确定一个是取消;

上面的应该都和你说的一样啊。应该没有错啊。

我也不清楚怎么回事!

哦。好的。我会看DrawItem()函数的,谢谢

#16


在OnInitDialog()里的

m_btn.AutoLoad(IDC_BUTTON1, this);

后面也要调用
m_btn.LoadBitmaps();

先加载一个默认的位图。

#17


或者在你在每个需要改变图片的时候写成
if(btn.m_hWnd == NULL)
{
btn.AutoLoad(IDC_BUTTON1, this);
}
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();

保证只加载一次。就不会出错了。

#18


恩。我在在OnInitDialog()里的
m_btn.AutoLoad(IDC_BUTTON1, this);
后面也调用
m_btn.LoadBitmaps();
就可以了啊。谢谢啊。现在是可以变图片了啊。
不过我还有个问题就是说我是想要把id号为buf[2]的按钮改变图片啊,我有很多按钮嘛。而buf[2]里存的就是button的UINT nID号啊。那我怎么样连续起来啊?就是可以指向随便那个button都可以啊?谢谢

#19


在需要改变的时候:
CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
pBtn->LoadBitmaps(IDB_NEW); // 改变图

#20


iicup(双杯献酒) ( ) 信誉:100    Blog 
不可以啊,当我加入你这语句时程序就出错死了啊。如果不加则可以显示啊,下面是我的一个判断颜色的语句,
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);//红图显示
// CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
// pBtn->LoadBitmaps(IDB_RED); // 改变图
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
m_btn.LoadBitmaps(IDB_BLUE);
m_btn.RedrawWindow();
}
else 
{
m_btn.LoadBitmaps(IDB_GRAY);
m_btn.RedrawWindow();
}

#21


因为在在OnInitDialog()里的
m_btn.AutoLoad(IDC_BUTTON1, this);
所以他是默认是button1发生改变啊。有什么办法可以让发生改变的按钮号是有buf[2]里的啊。而不是他指定的button1啊。

#22


没有人了吗?呜呜。。。


还是楼上
 iicup(双杯献酒) ( ) 信誉:100    Blog  2006-9-21 14:29:50  得分: 0  
 在需要改变的时候:
CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
pBtn->LoadBitmaps(IDB_NEW); // 改变图

我改了以后就会有错啊。当我把
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();
这两句注释掉后换上你
CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
pBtn->LoadBitmaps(IDB_NEW); // 改变图
编译时没有错,但是运行时按钮没有变化啊,也会错误。
  
 

#23


先用ClassWizard为你需要改变图片的按钮都关联一个CBitmapButton类型的控件变量。当然ClassWizard不直接支持,你可以先关联CButton类型,然后手动修改。


在在OnInitDialog()里分别设置按钮默认位图如下:

m_btn1.LoadBitmaps(IDB_GRAY);
m_btn2.LoadBitmaps(IDB_GRAY);
m_btn3.LoadBitmaps(IDB_GRAY);
... ...



判断颜色的语句:


CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]); // 得到按钮句柄
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);//红图显示
pBtn->LoadBitmaps(IDB_RED); 
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
pBtn->LoadBitmaps(IDB_BLUE);
}
else 
{
pBtn->LoadBitmaps(IDB_GRAY);
}
pBtn->RedrawWindow();

#24


上面设置变量,目的是为了让MFC为我们自动在类对象与按钮之间建立关联。当然也可以在对话框类直接定义一些CBitmapButton类型的变量。
然后在OnInitDialog函数中创建关联,如下:
btn1.AutoLoad(IDC_BUTTON1, this);
btn1.LoadBitmaps(IDB_GRAY);

btn2.AutoLoad(IDC_BUTTON2, this);
btn2.LoadBitmaps(IDB_GRAY);

btn3.AutoLoad(IDC_BUTTON3, this);
btn3.LoadBitmaps(IDB_GRAY);
是一样的。

#25


楼主是否可以这样考虑:用画刷来改变颜色,每变换一次就用重新paint一次。
第二种方式:加载位图的方式,每变换一次就加载一次位图。

#26


wangpanli(沉睡的狮子) 
我在OnInitDialog函数中创建关联,如下:
btn1.AutoLoad(IDC_BUTTON1, this);
btn1.LoadBitmaps(IDB_GRAY);

btn2.AutoLoad(IDC_BUTTON2, this);
btn2.LoadBitmaps(IDB_GRAY);

btn3.AutoLoad(IDC_BUTTON3, this);
btn3.LoadBitmaps(IDB_GRAY);
又在// keyboardcheckDlg.h : header file里定义了CBitmapButton m_btn,btn1,btn2,btn3;然后把判断颜色的换成你的语句。
但是我一从串口发消息过去程序就错误了啊,程序自动关闭了。我从串口发消息时是没有错误的啊,发来的消息是buf数组存。


当我不在OnInitDialog函数中创建关联;
// m_btn.AutoLoad(IDC_BUTTON2, this);
// m_btn.LoadBitmaps(IDB_GRAY);
然后我在判断颜色的时候不用你的那语句而用下面这语句时,
m_btn.AutoLoad((buf[2]+1000), this); //这时才根据buf[2]值创建关联,buf[2]+1000为我的按钮的id号
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);
// CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]+1000); // 得到按钮句柄
// pBtn->LoadBitmaps(IDB_RED);
m_btn.LoadBitmaps(IDB_RED);
m_btn.RedrawWindow();
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
// CBitmapButton* pBtn = (CBitmapButton*)GetDlgItem(buf[2]+1000); // 得到按钮句柄
// pBtn->LoadBitmaps(IDB_BLUE);

m_btn.LoadBitmaps(IDB_BLUE);
m_btn.RedrawWindow();
}
else 
{
m_btn.LoadBitmaps(IDB_GRAY);
m_btn.RedrawWindow();
m_recmsg = "";
}

则我串口发出消息时程序第一次可根据buf[2]的值来变换按钮的颜色,但是从第2次时起再发时会有出错的提示框出现,如果我忽略错误时则按钮会继续根据buf[2]值和buf[3]的值发生相应的变化。
错误提示框debug assertion failed!
program:...?我的应用程序位置
file:wincore.cpp
line:311
for information on how your program can cause an assertion failure,see the visual C++ documentation on asserts.
(Press retry to debug the application)

如果要是没有那错误提示框的话他也可以根据buf[2]来显示按钮的颜色了啊。

#27


tanmeining(Dream) ( ) 信誉:100    Blog  2006-09-21 17:54:00  得分: 0  
    楼主是否可以这样考虑:用画刷来改变颜色,每变换一次就用重新paint一次。
第二种方式:加载位图的方式,每变换一次就加载一次位图。
  
 恩。这个也可以,不过我刚接触不久不懂呢。我再找下资料。谢谢。
谁要是有什么好的办法可以说下。

#28


buf[2] 的值是变化的吗?

m_btn.AutoLoad被调用后,不能在调用第二次。你的这句代码

  m_btn.AutoLoad((buf[2]+1000), this); //这时才根据buf[2]值创建关联,buf[2]+1000为我的按钮的id

有问题,肯定出错。

  你不应该重复使用的函数中调用,应该只初始化一次。最好按我说的,用ClassWizard为每一个按钮加一个对应的CBitmapButton类型变量。我试过了,没错。
  
  你出错的原因可能:
   1。buf[2]+1000的值不是按钮的ID

      2。ID值为buf[2]+1000的按钮尚未与一个CBitmapButton的对象相联系,导致

   CBitmapButton* pBtn (CBitmapButton*)GetDlgItem(buf[2]+1000);

   这句执行类型转换时出错。



#29


哦。谢谢啊!!
我现在有办法搞图标上去了啊。我用seticon啊
if(buf[3]==2)
{str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{ str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{ m_recmsg = "";
//((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

不过我现在想当图片显示一段时间后就使用((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));使他恢复原来的gray颜色啊。不过我用定时器就有错啊。

我是这样用的啊。不知道那里出错了,
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{
m_recmsg = "";
//((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

m_recmsg=str;
UpdateData(false);
SetTimer(100,1000,NULL);
}



void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
CDialog::OnTimer(nIDEvent);
}

#30


但是我要用定时器就错了啊。我象上面用应该没有错吧?

我是这样用的啊。不知道那里出错了,
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{
m_recmsg = "";
//((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

m_recmsg=str;
UpdateData(false);
SetTimer(100,1000,NULL);
}



void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
CDialog::OnTimer(nIDEvent);
}

#31


出错信息为:
--------------------Configuration: keyboardcheck - Win32 Debug--------------------
Compiling...
keyboardcheckDlg.cpp
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(281) : error C2039: 'OnButton1' : is not a member of 'CKeyboardcheckDlg'
        c:\documents and settings\administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckdlg.h(14) : see declaration of 'CKeyboardcheckDlg'
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(290) : error C2065: 'UpdateData' : undeclared identifier
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(312) : error C2660: 'GetDlgItem' : function does not take 1 parameters
C:\Documents and Settings\Administrator\桌面\正确-—按钮颜色变换_06.09.22\keyboardcheckDlg.cpp(312) : error C2227: left of '->GetCheck' must point to class/struct/union
Error executing cl.exe.

keyboardcheckDlg.obj - 4 error(s), 0 warning(s)

但是原先我没有用定时器前程序都正确啊,象我这样用定时器有错吗?谢谢指教!!

#32


上面的出错信息与你给出的代码没关系。OnButton1没在头文件中定义。

另外,SetTimer()用在函数中,每次调用函数都会会重新设置一个定时器。最好应该用完之后
使用KillTimer()将定时器删除了。
void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
   ((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}

         KillTimer(100);

CDialog::OnTimer(nIDEvent);
}

#33


但是如果我不用定时器的话就没有错误啊。
我的很多东西都是在OnButton1里面判断的啊。
没有定时器就没有错啊。一有就报错了。

有没有用什么办法可以先((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
隔几秒再((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));就是按钮先红色再灰色啊。


我用这样看不见啊。debug可以看见啊。不过exe很快就过去了。看不了颜色变化
/*CTime t = CTime::GetCurrentTime(); //获取系统日期
int d=t.GetDay(); //获得几号
int y=t.GetYear(); //获取年份
int m=t.GetMonth(); //获取当前月份
int h=t.GetHour(); //获取当前为几时
int mm=t.GetMinute(); //获取分钟
int s=t.GetSecond(); //获取秒
//int y,m,d,h,mm,s;
CTime t1( y, m, d, h, mm, s );
CTimeSpan span=t-t1; //计算当前系统时间与时间t1的间隔
int iSec=span.GetTotalSeconds();//获取总共有多少秒 
while(iSec<1)
{
t = CTime::GetCurrentTime();
CTimeSpan span=t-t1; 
 iSec=span.GetTotalSeconds();
}*/
//AfxMessageBox(str);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
//AfxMessageBox("mmmmmmmmmess");

#34


贴图直接用 CBitmapButton 即可.

#35


谢谢各位的指教啊,非常谢谢啊!
特别是谢谢wangpanli(沉睡的狮子)!!


现在程序我已经把那错误搞定了.。
不过很奇怪的啊,原来我程序是有下面这两句话的,但是当加定时器后会程序会自动消失掉下面这两句话,要我手动补回,补回来就正常正确显示了.当我撤消掉加入定时器时下面这两句就又有回来了。证明应该是我一加定时器就消失了这两句话,中间我没有做其他动作。
//afx_msg void OnButton1(UINT nID);       //在keyboardcheckDlg.h
//ON_COMMAND_RANGE(IDC_BUTTON1,IDC_BUTTON32,OnButton1)  // 在keyboardcheckDlg.cpp

不过wangpanli(沉睡的狮子)说的OnButton1没在头文件中定义,我想我应该已经定义了啊,因为我在member variables里已经定义IDC_BUTTON1是cbutton Typeta型的拉。还定义了一个Mmember 为m_button00;


还有个问题就是现在我是当灯灭掉的时候我是我是起定时器一下子全都灭掉了啊,(注:IDI_GRAY表示灭掉啊。)
for (int i=0;i<32;i++)
{    ((CButton *)GetDlgItem(i+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY)); ////IDI_GRAY表示灭掉;
}
现在我是想做当按键按下去灯亮后然后灯灭时是按照按按键的先后顺序一个接着一个灭掉啊。 不知道改成下面可以不可以啊,我试了好象没有效果的啊.如果各位有什么高见的话那请多指教啊.谢谢!!
原来程序是:
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{ //record[r++]=buf[2]; //r为全局变量初值为0;
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
}
else if (buf[3]==3)
{ //record[r++]=buf[2];
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
}
else 
{m_recmsg = "";
}
m_recmsg=str;
UpdateData(false);
SetTimer(100,2000,NULL);
}

void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{ // TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{ for (int i=0;i<32;i++)
{   ((CButton *)GetDlgItem(i+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
}
KillTimer(100);
CDialog::OnTimer(nIDEvent);
}

我改成了下面这样,我是想做当按键按下去灯亮后然后灯灭时是按照按按键的先后顺序一个接着一个灭掉啊。如果有错或是有什么好的方法的话请告诉我啊.谢了.
void CKeyboardcheckDlg::OnRecBuf()
{ CString str;
if(buf[3]==2)
{ record[r]=buf[2];    //r为全局变量初值为0;//注:下班前我用的是record[r++]试过不行,现在record[r]是我现在想的
str.Format("%d键接受请求",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_RED));
SetTimer(100,2000,NULL);
r++;
}
else if (buf[3]==3)
{ record[r]=buf[2];    //r为全局变量初值为0;//注:下班前我用的是record[r++]试过不行,现在record[r]是我现在想的
str.Format("%d键开门",buf[2]);
((CButton *)GetDlgItem(buf[2]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_BLUE));
SetTimer(100,2000,NULL);
r++;
}
else 
{m_recmsg = "";
}
m_recmsg=str;
UpdateData(false);

}

void CKeyboardcheckDlg::OnTimer(UINT nIDEvent) 
{ // TODO: Add your message handler code here and/or call default
if(nIDEvent==100)
{
 ((CButton *)GetDlgItem(record[r]+1000))->SetIcon(AfxGetApp()->LoadIcon(IDI_GRAY));
}
KillTimer(100);
CDialog::OnTimer(nIDEvent);
}
不知道这样行不行啊。我就想如果传过来定时器的话是不是r这个全局变量又等于初始值0了啊?
由于下班了我也回来了没有试呢.原来试的时候void CKeyboardcheckDlg::OnRecBuf()里的是record[r++]而不是record[r];但是我试时好象没有反应也.先在这问下我这样写有没有什么问题啊.因为现在回来没有串口卡试了,不清楚对不对现在了.想跟大家讨论下行不行先。


#36


我试了还是不行,应该是定时器里的cord[r]值没有传过到定时器里吧。由于现在又开始做其他东西了没有时间来调这程序了。不过我想用指针或者指针数组来存过来应该没有问题啊。
谢谢大家啊!特别是wangpanli(沉睡的狮子)啊。谢谢了。