WIN32汇编列表框的使用

这两天学习了列表框的使用,同样令人头疼的问题就是列表框的消息(都是这个复杂的消息,水太深),我在用ResEdit编辑资源文件的时候,在行为那一行好多属性有的不知道怎么用,刚开始就简单的加上了几个表面需要实现的几个控件:两个列表框(listbox),两个按钮(pushbutton,defpushbutton),一个文本框(ltext),一个竖向滚动条。第一个列表框(IDC_LISTBOX1)因为是单选的,不需要定义多选属性(LBS_MULTIPLESEL:允许多选,如果不定义的话则是单选列表框),当时就因为这个属性搞得程序的可执行文件,选中列表框2的一些项目,再点击“查看”按钮,程序出错退出的情况。在编写资源文件的时候,WS_TABSTOP这个属性就是允许使用Tab键在每个控件之间切换(顺序就是在资源文件中定义的先后顺序),有一点疑问的是 button类控件IDOK 不用定义WS_TABSTOP 就能有Tab停留位?其他的控件都需要定义WS_TABSTOP  才可以拥有Tab停留位,我感觉应该是windows已经定义好了。下面看一下资源文件源代码:

// Generated by ResEdit 1.6.6
// Copyright (C) 2006-2015
// http://www.resedit.net


#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#define  IDD_DIALOG1                             1
#define  IDI_ICON1                               103
#define  IDC_LISTBOX1                            100
#define  IDC_LISTBOX2                            101
#define  IDC_RESET                               104
#define  IDC_TEXT1                               102
//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "列表框控件示例"
FONT 9, "宋体"
{
    LISTBOX         IDC_LISTBOX1 , 7, 9, 48, 65, WS_TABSTOP | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_SORT | LBS_NOTIFY, WS_EX_DLGMODALFRAME
    LISTBOX         IDC_LISTBOX2, 70, 9, 107, 65, WS_TABSTOP | LBS_STANDARD | LBS_MULTIPLESEL, WS_EX_DLGMODALFRAME
    LTEXT           "", IDC_TEXT1 , 4, 82, 25, 12, WS_TABSTOP | SS_LEFT, WS_EX_LEFT
    PUSHBUTTON      "复位", IDC_RESET, 105, 79, 31, 14, 0,WS_EX_LEFT
    DEFPUSHBUTTON   "查看", IDOK, 149, 79, 33, 14, 0, WS_DISABLED
}
//
// Icon resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDI_ICON1          ICON           "icon2.ico"




下面看一下 程序实现代码注意做注释的地方,这些是比较有意思的地方:

                

 .386
                 .model flat,stdcall
                 option casemap:none
;--------------------------------------------------------------
;include文件
;--------------------------------------------------------------
include         windows.inc
include         user32.inc
includelib      user32.lib
include         kernel32.inc
includelib      kernel32.lib
;--------------------------------------------------------------
;等值定义
;--------------------------------------------------------------
IDD_DIALOG1     equ         1
IDI_ICON1       equ         103
IDC_LISTBOX1    equ         100
IDC_LISTBOX2    equ         101
IDC_RESET       equ         104
IDC_TEXT1       equ         102
;--------------------------------------------------------------
;数据段
;--------------------------------------------------------------
                .data?
hInstance       dd          ?
                .const
szText1         db          '项目1',0
szText2         db          '项目2',0
szText3         db          '项目3',0
szPath          db          '*.*',0                               ;此处的标号的含义很有意思
szMessage       db          '选择结果:%s',0            ;注意此种显示方式
szTitle         db          '您的选择',0
szSelect        db          '您选择了以下项目:',0
szReturn        db          0dh,0ah,0
;--------------------------------------------------------------
;代码段
;--------------------------------------------------------------


                .code
;--------------------------------------------------------------
_ProcDlgMain    proc        uses ebx edi esi hWnd,wMsg,wParam,lParam
                LOCAL       @szBuffer[128] :byte
                LOCAL       @szBuffer1[128] :byte
                LOCAL       @szTextBuffer[2048] :byte
                LOCAL       @dwCount
                
                mov         eax,wMsg
                .if         eax ==  WM_CLOSE
                   invoke  EndDialog,hWnd,NULL
                .elseif     eax ==  WM_INITDIALOG
                   invoke  LoadIcon,hInstance,IDI_ICON1
                   invoke  SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
;---------------------------------------------------------------
;初始化列表框
;---------------------------------------------------------------
                            invoke SendDlgItemMessage,hWnd,IDC_LISTBOX1,LB_ADDSTRING,0,addr szText1
                            invoke SendDlgItemMessage,hWnd,IDC_LISTBOX1,LB_ADDSTRING,0,addr szText2
                            invoke SendDlgItemMessage,hWnd,IDC_LISTBOX1,LB_ADDSTRING,0,addr szText3
                            invoke SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_DIR,DDL_ARCHIVE or DDL_DRIVES or DDL_DIRECTORY,addr szPath
;---------------------------------------------------------------
                .elseif     eax ==  WM_COMMAND
                   mov     eax,wParam
                   .if     ax == IDOK
                           invoke  SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_GETSELCOUNT,0,0
                           mov     @dwCount,eax
                           invoke  SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_GETSELITEMS,128/4,addr @szBuffer    ;此处忘记 addr  。。。
                           invoke  lstrcpy,addr @szTextBuffer,addr szSelect
                           lea     esi,@szBuffer
                           .while  @dwCount
                              lodsd
                              lea  ecx,@szBuffer1         ;此处需要品味
                              invoke  SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_GETTEXT,eax,ecx
                              invoke  lstrcat,addr @szTextBuffer,addr szReturn
                              invoke  lstrcat,addr @szTextBuffer,addr @szBuffer1
                              dec @dwCount
                           .endw
                           invoke  MessageBox,hWnd,addr @szTextBuffer,addr szTitle,MB_OK
                   .elseif ax  == IDC_RESET
                           invoke  SendDlgItemMessage,hWnd,IDC_LISTBOX2,LB_SETSEL,FALSE,-1
                   .elseif ax  == IDC_LISTBOX1
                      shr eax,16
                      .if ax  ==  LBN_SELCHANGE
;-----------------------------------------------------------------
;将鼠标点击结果显示在文本框中
;-----------------------------------------------------------------
                       invoke  SendMessage,lParam,LB_GETCURSEL,0,0
                       lea     ecx,@szBuffer
                       invoke  SendMessage,lParam,LB_GETTEXT,eax,ecx
                       invoke  SetDlgItemText,hWnd,IDC_TEXT1,addr @szBuffer
;-----------------------------------------------------------------
;双击项目则弹出对话框
;-----------------------------------------------------------------
                                    .elseif ax  ==  LBN_DBLCLK
                                       invoke  SendMessage,lParam,LB_GETCURSEL,0,0
                                       lea     ecx,@szBuffer
                                       invoke  SendMessage,lParam,LB_GETTEXT,eax,ecx
                                       invoke  wsprintf,addr @szBuffer1,addr szMessage,addr @szBuffer
                                       invoke  MessageBox,hWnd,addr @szBuffer1,addr szTitle,MB_OK 
                      .endif
;-----------------------------------------------------------------
                            .elseif ax  ==  IDC_LISTBOX2
                               shr     eax,16
                               .if     ax  ==  LBN_SELCHANGE
                                       invoke  SendMessage,lParam,LB_GETSELCOUNT,0,0
                                       mov     ebx,eax
                                  invoke  GetDlgItem,hWnd,IDOK
                                  invoke  EnableWindow,eax,ebx       ;此处有意思
                               .endif 
                      
                            .endif   
                .else
                   mov     eax,FALSE
                   ret
                .endif
                mov         eax,TRUE
                ret
                
_ProcDlgMain    endp
;------------------------------------------------------------------
start:
                invoke      GetModuleHandle,NULL
                mov         hInstance,eax
                invoke      DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMain,NULL
                invoke      ExitProcess,NULL
;------------------------------------------------------------------
                end         start


关于程序代码实现过程中需要注意的就是3个API函数,和几个陌生的语句,和几个变量的理解:


首先是:lodsd

这个命令还是第一次接触,功能是:

是以esi为首地址,每次(注意这个每次,我在写代码理解的时候就理解错了,纠结了好久,没正确理解在程序处理点击查看按钮的操作,记住是每次拷贝,而不是一次性拷贝)拷贝4个字节,把这4个字节放到eax中,然后esi自动+4,


然后是:hInstance,hWnd,handle    (不知道其他人是否纠结过这个问题:在编写WIN32汇编程序的时候总有一个全局变量hInstance,在每个API函数的参数中基本都会出现这个hWnd参数,这个问题对于我这种初学者来说确实会有疑问,这家伙是干什么的,怎么哪都有他,他就没有个具体的定义?)这里来总结一下:

HINSTANCE是应用程序实例句柄,
HWND是窗口对象句柄,
HANDLE是任意对象的句柄,
CWnd是MFC中的窗口类。


下面介绍一下几个API函数:


LsTrcpy()
功能:
该函数复制一个字符串到缓冲区
原型:
LPTSTR lstrcpy(LPTSTR lpString1,LPCTSTR lpString2);
参数:
lpString1:指向接收由参数lpString2指向字符串内容的缓冲区。缓冲区必须足够大来容纳字符串,还包括最后的NULL终止符。

lpString2:指向待复制的以NULL为终止符的字符串。

返回值:若函数运行成功,返回值是缓冲区的指针;若函数运行失败,返回值是NULL。

Lstrcat()
功能:
该函数将一个字符串附加在另一个字符串后面。
原型:
LPTSTR lstrcat(LPTSTR lpString1,LPCTSTR lpString2);
参数:
lpString1:一个以NULL为终止符字符串指针。这个缓冲区必须足够大能包含两个字符串。

lpString2:一个以NULL为终止符字符串指针,它将追加在由lpString1中指定。这个缓冲区必须足够大能包含两个字符串。


返回值:若函数运行成功,返回值指向缓冲区;若失败,则返回值为NULL。

SetDlgItemText()
功能:
该函数设置对话框中控件的文本和标题
原型:
BOOLSetDlgltemText(HWND hDlg,int nlDDlgltem,LPCTSTR IpString);
参数:
hDlg:指定含有控件的对话框。

nlDDlgltem:标识带有将被设置的标题和文本的控件。

IpString:指向一个以NULL结尾的字符串指针,该字符串指针包含了将被复制到控件的文本。

返回值:

如果函数调用成功,则返回值为非零值。如果函数调用失败,则返回值为零。



      
                   

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页