注册 登录
编程论坛 汇编论坛

如何数组中的值依次赋值给自定义的Button?

misslucky 发布于 2009-08-16 14:45, 1584 次点击
我首先在资源文件里定义了10个自定义Button
……DAYTEXT
……
CONTROL DAYTEXT,Day1,"Button",WS_CHILDWINDOW|WS_VISIBLE|BS_BOTTOM|BS_CENTER|BS_OWNERDRAW,12,45,18,15
CONTROL DAYTEXT,Day2,"Button",WS_CHILDWINDOW|WS_VISIBLE|BS_BOTTOM|BS_CENTER|BS_OWNERDRAW,30,45,18,15
……
并定义了一个数组
days db 10 dup(0)               
在初始化对话框的时候,通过自己写的函数改变了数组的值,并想用SetDlgItemText函数来将改变后的值依次显示对应每个Button上
mov esi,offset days
xor ecx,ecx
.while ecx<10
     invoke SetDlgItemText,hWnd,DAYTEXT,DWORD ptr[esi+ecx]
     inc ecx
这样可行吗?
9 回复
#2
东海一鱼2009-08-16 16:04
恐怕有些问题。

因为根据SetDlgItemText的声明:

BOOL SetDlgItemText(  
HWND hDlg,  
int nIDDlgItem,  
LPCTSTR lpString);

nIDDlgItem  
[in] Identifies the control with a title or text that is to be set.  

你的DAYTEXT这个控件ID在循环中并没有改变,也就是说所有的作用都在一个按钮上。
#3
misslucky2009-08-16 16:11
我把按钮的ID换成不同的
……
CONTROL "",ID1,"Button",WS_CHILDWINDOW|WS_VISIBLE|BS_BOTTOM|BS_CENTER|BS_OWNERDRAW,12,45,18,15
CONTROL "",ID2,"Button",WS_CHILDWINDOW|WS_VISIBLE|BS_BOTTOM|BS_CENTER|BS_OWNERDRAW,30,45,18,15
CONTROL "",ID3,"Button",WS_CHILDWINDOW|WS_VISIBLE|BS_BOTTOM|BS_CENTER|BS_OWNERDRAW,30,45,18,15  

……

invoke SetDlgItemText,hWnd,ID1,DWORD ptr[esi+1]
invoke SetDlgItemText,hWnd,ID2,DWORD ptr[esi+2]
invoke SetDlgItemText,hWnd,ID3,DWORD ptr[esi+3]
……
可以吗?
如果定义的按钮一多,有没有简单的方法?
#4
misslucky2009-08-16 16:13
修正一下 是invoke SetDlgItemText,hWnd,ID1,BYTE ptr[esi+1]
……
#5
东海一鱼2009-08-16 16:51
当然可以,很灵活的。

假如:IDT1 = 1000,IDT2 = 1001.......IDT10 = 1009;

mov esi,offset days //放入数据首址

//xor ecx,ecx             //不一定都要0啊,呵呵

mov ecx,IDT1             //计数器初始化为第一个ID

.while ecx < IDT10 + 1     //越线否?
     push ecx           //下面的系统API可不会给你保存ecx,所以自己先保存一下

     invoke SetDlgItemText,hWnd,ecx,DWORD ptr[esi+ecx]

     pop ecx            //恢复计数器
     inc ecx            //加一,移向下一个ID
.endw
#6
misslucky2009-08-16 17:11
有个问题,就是我的days都是BYTE类型的,不是应该取字节吗?
还有为什么在.while循环里要保存ecx呢?调用函数SetDlgItemText会改变ecx的值吗?,而且invoke里前一个ecx是ID,后一个是偏移量,两者不同吧?
不知这样可否?
mov esi,offset everyMonth            ;放入数据首址
        mov ecx,Day1        ;计数器初始化为第一个天数按钮的ID
        xor ebx,ebx                ;放偏移量
        .while ecx<Day42+1
            invoke SetDlgItemText,hDlg,ecx,BYTE ptr[esi+ebx]
                            inc ebx
            inc ecx
        .endw

[ 本帖最后由 misslucky 于 2009-8-16 17:32 编辑 ]
#7
东海一鱼2009-08-16 17:41
有个问题,就是我的days都是BYTE类型的,不是应该取字节吗?

是的,我没仔细看你上面的代码,我上面只是个比方。不过如果是字符串的话应该是 esi + i啊,是地址。

你的xx ptr[esi + i]是求值了。而SetDlgItemText的第3参数 LPCTSTR 显然是个字符串指针类型。

还有为什么在.while循环里要保存ecx呢?调用函数SetDlgItemText会改变ecx的值吗?

是的,因为ecx\eax\edx不是约定寄存器,所以任何代码都可以自由使用。某些C++编译器对ecx例外。

#8
东海一鱼2009-08-16 17:44
xor ebx,ebx                ;放偏移量

呵呵,寄存器就是给你服务的,当然可以随心使用。不过记得对约定寄存器保护就好。
#9
misslucky2009-08-16 18:07
谢谢
“并定义了一个数组
days db 10 dup(0)               
在初始化对话框的时候,通过自己写的函数改变了数组的值,并想用SetDlgItemText函数来将改变后的值依次显示对应每个Button上”


我是想把每个按钮改变后的的数字显示在按钮上,如果要写成字符串的话还要对数字进行一下转换,有没有可以直接显示数字的函数呢?
如果是字符串的话怎么初始化?10个“”?
#10
东海一鱼2009-08-16 19:35
我是想把每个按钮改变后的的数字显示在按钮上,如果要写成字符串的话还要对数字进行一下转换,有没有可以直接显示数字的函数?

似乎没有,不过你可以用api的wsprintf或c runtime的itoa先转换一下。

如果是字符串的话怎么初始化?10个“”?

days db 10 dup(0)          //就是这样

有句俗话:‘汇编无类型’。其实任何数据类型你都可以定成 Data  db sizeof(数据类型) dup (?)这种形式。

在使用时怎末解释数据类型是汇编程序员的责任。数据组织非常灵活:

我也可以这样组织字符串:

days db "1",0
     db "2",0
     db "3",0
     db "4",0
     ........

或者直接在一块Buf中用代码构建这样的形式。
1