事件处理

 

VB程序中处理随机事件

  在程序设计过程中,如何轻松地处理众多的随机事件,往往是制作大型系统首先要考虑的问题之一。用C语言开发Windows程序时,可以方便地使用消息机制(Message),但是,设计VB程序时,就没有这样的方便条件了。例如,多个窗口同时打开同一个表(Table),当在一个窗口中对数据进行了修改,而其他的窗口也能够随之进行数据更新,这时就需要有一条说明数据改变了的消息在所有的窗口间进行广播。如果使用的语言是C,只需要定义一条用户消息(UserMessage),就可以实现这一点。可是如果是用VB编程,做起来就不是那么简单了。VB5.0企业版中增添了许多强有力的特性,有几点特性,正好可以帮助我们解决难题。先介绍一下这几个特性:

  1.用户自定义事件:在类模块中,可以使用Event关键字来定义用户自定义事件,使用RaiseEvent语句来产生该事件,这一机制给处理随机事件带来极大的方便。当收到需要广播的消息时,产生一个预定义的事件,而需要处理消息的客体对象,只需截获该事件,就完成了消息的传递。

  2.ActiveX EXE部件:利用VB,可以方便地将共享代码封装在ActiveX部件之中。将消息广播引擎实现于一个ActiveX部件之中,不仅方便了在程序中使用,而且更为重要的一点是,可以实现跨进程间的消息传递。因为ActiveX部件有内部(DLL)外部(EXE)两种,对于外部部件,可以对模块内的全局数据实现共享(关于ActiveX两种代码部件的

  区别,请阅读VB的联机帮助文件)。

  3.远程自动化连接:ActiveX部件,是一种标准的客户机/服务器结构,利用Windows平台的COM模型,VB已能方便地将这种结构扩展到整个网络的范围。所以,我们的消息广播设计,在实现了进程间的消息传递之后,进而实现网络上的消息传递,也成为可能。

  通过上面的几点介绍,这一方式的设计思想也就比较清楚了,在具体设计时,通过四个模块之间的相互协作,完成了消息的发送、广播及接收,并将这四个模块封装在一个ActiveXEXE部件之中。下面就是这三个类模块的简单介绍及源代码:

  类模块之一:Msg.cls----在该模块中,定义了消息数据结构VbMsg类,它是消息传递中的载体。这里只是一个简单的例子,如果想实现更多的功能,如建立两点间的数据通道,而不是单纯的广播消息,则可能需要对该结构进行一些扩充。

  Option Explicit

  / 说 明:

  / 消 息 类: 定 义全 局 的 消 息 结 构

  Public iType As Long      /消 息 类 型 编 号

  Public iName As String     /消 息 名

  Public iSource As String    / 消 息 源 说 明

  Public iDescription As String /消 息 说 明

  Dim iT As Date     / 消 息 发 生 时 间

  /返 回 日 期 型 时间

  Public Property Get iTime() As Date

  iTime = iT

  End Property

  /返 回 字 符 型 时间

  Public Property Get iTimeStr() As String

  iTimeStr = Format(iT, "yyyy.mm.dd hh:mm:ss")

  End Property

  / 在 对 象 被 建立 时, 设 置 消 息 发 生 时 间

  Private Sub Class_Initialize()

  iT = Now()

  End Sub

  类模块之二:MsgCli.cls ---- 本模块是对客户接收端MsgClient类的定义,这相当于一

  个消息接收器。在这个类中定义的一个RecMsg事件,当接收器收到消息时(过程SetMsg被

  调用),就产生这一事件.接收器的建立者就截获这一事件,并处理消息。为了避免接收不

  必要的消息,声明了minMsg、maxMsg两个变量,以便对VbMsg中的iType属性进行过

  滤。

  Option Explicit

  ′ 说 明:

  ′ 客 户 消 息 接收 类

  ′ 定 义 接 收 消息 事 件, 该 对 象 的 宿 主 类 应 截 获 该 事 件,

  并 处 理接 收 到 的 消 息。

  Public Event RecMsg(ByVal msg As VbMsg)

  ′ 通 过 设 置 消息 的 接 收 范 围, 可 以 过 滤 掉 不 需 要 的 消息

  Public minMsg As Long

  Public maxMsg As Long

  ′ 该 对 象 的 标志 编 号, 使 用 时 不 应 修 改 该 值

  Public ID As Long

  ′ 事 件 产 生 过程, 只 应 由 消 息 服 务 器(MsgServer) 调 用

  Public Sub SetMsg(msg As VbMsg)

  If msg.iType >= minMsg And msg.iType <= maxMsg Then RaiseEvent RecMsg(msg)

  End If End Sub ′ ′

  根 据ID, 返 回 对象 的 关 键 字, 只 应 由 消 息 服 务 器(MsgServer)调 用

  Public Property Get Key() As String Key="ID:" & ID End Property

  类模块之三:Global.bas ---- 本模块声明了两个全局变量,一个是接收器(MsgClient)列表(Clients),一个是接收器计数器,以为每个接收器分配一个唯一的ID标志。把变量放在单独的模块中,是为了实现数据在进程间的共享,是跨进程间消息传递的关键所在。(应保证在编译时工程是单线程的,否则数据共享则不能实现。)。

  Option Explicit

  / 说 明:

  / 消 息 服 务 器全 局 变 量

  /消 息 接 收 客 户列 表

  Public Clients As New Collection

  / 消 息 接 收 客户ID 计 数 器

  Public CliCount As Long

  类模块之四:MsgSrv.cls----本模块中定义了消息服务器类MsgServer,该类是消息广播引擎的主体,它主要管理维护消息接收器列表(Clients),将发送来的消息(调用SendMsg过程)依次发送给列表中的所有接收器。注意,这个类被声明为公共全局类,这主要是为了方便使用(不必在每个程序中再建立该类,过程名全局有效)。

  Option Explicit

  /说 明:

  /消 息 服 务 器 类

  /发 送 消 息

  Public Sub SendMsg(msg As VbMsg)

  Dim c As MsgClient

  For Each c In Clients

  c.SetMsg msg

  DoEvents

  Next c

  End Sub

  /增 删 消 息 接 收客 户

  Public Sub AddMsgClient(c As MsgClient)

  CliCount = CliCount + 1

  c.Id = CliCount

  Clients.Add c, c.Key

  End Sub

  Public Sub DelMsgClient(c As MsgClient)

  Clients.Remove c.Key

  If Clients.Count = 0 Then CliCount = 0

  End Sub

  到这里,一个小巧灵活的消息广播引擎就完成了,它的使用范围很广,用起来也很方便,只需在工程中引入编译过的ActiveX部件,就可以直接调用SendMsg发送消息,可能在安装消息接收器(MsgClient)时会稍许有点麻烦,下面举一个简单的应用例子大致说明一下:

  在设计Windows程序时,往往会感觉到程序的实际运行过程与你想象的相差甚远,调试时就非常希望看到程序运行时后台的一些情况。利用VB的单步执行或Debug命令,都会受到一些限制。利用消息广播引擎,制作一个通用的实时消息事件查看程序,就可以很好地解决这一问题。查看程序的主要工作就是捕捉一组事先定义好的消息事件,并将消息的内容显示在列表框内,可以只用一个窗体完成,大体样子如下:

  Const MsgInfoID=101

  Private WithEvents mClient As MsgClient

  Private Sub Form_Load()

  Set mClient = New MsgClient

  MClient.minMsg= MsgInfoID

  MClient.maxMsg= MsgInfoID

  AddMsgClient mClient

  End Sub

  Private Sub Form_Unload(Cancel As Integer)

  DelMsgClient mClient

  End Sub

  Private Sub mClient _RecMsg(ByVal msg As VbMsgSrv.VbMsg)

  List1.AddItem msg.iTimeStr & Chr(9) & msg.iName & Chr(9) & msg.iDescription

  End Sub

  在被调试的程序中,为了调用方便,可以编写一个全局过程,象下面这个样子:

  Const MsgInfoID=101

  Public Sub MsgInfo(iName As String,iDes As String)

  Dim msg As New MsgClient

  With msg

  .iName = iName

  . iDescription = iDes

  End With

  SendMsg msg

  End Sub

  在程序的重点需要了解的环节插入MsgInfo过程,运行时信息就会在事件查看程序的窗口中被显示出来。这种方法尤其适合调试多程序协作的软件系统。当软件系统正式交给用 户时,插入的MsgInfo过程也不一定要全部删掉,只要将实时查看变为写入日志文件,这些运行时的信息也是日后软件维护的第一手资料。

 

VB窗口的消息驱动机制

在Windows系统中,不同的窗口都有不同的功能和行为,比如单击开始按钮将打开开始菜单,单击任务栏时钟旁边的QQ图标将打开QQ窗口,单击VB程序中的一个命令按钮将执行我们自己编写的一个VB事件过程,那么,Windows是如何让每个窗口都运行起来,能够让它们都接收鼠标和键盘事件,并实现各自不同功能的呢?

在Windows系统中的每个窗口都拥有自己的一个程序,称为“窗口程序”。窗口的各种功能,包括响应鼠标或键盘事件,窗口外观控制如按钮被按下或抬起的效果等,都是通过执行“窗口程序”中的代码来实现的,单击一次鼠标,或者按键盘上的一个键,这些都将被Windows统一接收,并转换成一个个的“消息”,然后Windows再将“消息”发送到对应窗口的“窗口程序”中。“窗口程序”根据接收到的“消息”的不同,会执行不同的动作,对同一个消息,不同窗口的窗口程序也可以有不同的动作。

 

VB窗口子类技术

子类技术是增强Windows窗口功能的一种技术,是实现许多复杂功能的基础,在Windows编程中应用十分普遍。“子类技术”已经触及到了Windows的核心,在许多介绍高级VB程序设计或API编程的书籍中,都或多或少有所提及。然而教科书中着重介绍的是子类技术的原理,其实现程序一般是不能被直接应用到大型软件的开发中。

在谈论子类技术之前,首先来谈论一下窗口,窗口这个概念,想必我们都不陌生,窗口的英文就是Window,而我们日常用的操作系统则被命名为Windows,可见“窗口”在Windows操作系统中的重要地位。那么究竟什么是窗口呢?

如果说屏幕上出现的一个个矩形框,有标题栏,有最大化,最小化,关闭按钮的,就是窗口,那么只回答对了一半。因为在Windows操作系统中,窗口概念的范围要远远比这广泛很多。除了我们常见的矩形框式的窗口外,各种控件如文本框,列表框,命令按钮,滚动条等都是窗口,桌面上的任务栏,时钟旁边通知区域的一个个小图标也都是窗口,甚至桌面背景也是一个大的窗口,还有很多窗口在屏幕上看不到,它们在后台运行着,不奇怪为什么微软把操作系统起名叫Windows了吧,困然名副其实。

如此众多的窗口,系统如何来管理呢,一个国家有很多人,政府是如何来管理的呢,政府每个人颁发一个身份证,而且身份证上都有一个惟一标识每个人的号码身份证号,一个身份证号惟一标识一个人,决不能有两个人使用同样的一个号码。用编号作为惟一标识来管理大量的人或事物是很常见也是很有效的,像银行卡账号,超市里各种物品的条形码,每个人的手机号,QQ号等都是一个个的编号。那么Windows中的窗口也不例外,Windows系统为每一个窗口分配一个惟一可以标识这个窗口的编号(一个长整数的数字),在一个系统中,任何两个窗口的编号也一定是不同的,这个编号在Windows系统中有一个名称,称为“句柄”。那么惟一标识窗口的编号就被称为窗口句柄,在使用VB编写程序的时候,很多窗体或者控件都有一个hWnd属性,这就是窗口的句柄,hWnd就是Handle to a Window的缩写。可以这样说,拥有hWnd属性的窗体或者控件都是“窗口”,没有hWnd属性的窗体或者控件就不是“窗口”了。

在Windows中,是通过窗口的句柄来操控每个窗口的,而不是通过窗口的名字来操控即Windows只认句柄,不认名字,这与在VB中编程时是不同的。

需要说明的是,窗口的句柄在程序“设计”时是不存在的,因为程序还在编写中,窗口还有没有被创建,只有在程序“运行”时,真正创建了窗口,窗口的句柄才存在也才有效。而且,窗口的句柄是在程序运行后由Windows动态分配的,就像新出生的小孩在他满18岁时经给他分配一个身份证号,我们新申请一个QQ号码也要由服务器为我们新分配一个QQ号,而每次申请QQ号,所得到的号码是不同的,由于这个原因,在不同的计算机上,或者在同一个计算机的不同时刻运行程序,窗口的句柄一般也是不同的,也就是说窗口的句柄是动态变化的。在上面的例子中,如果两次运行程序,或者在不同的计算机上,不同的时刻运行程序,窗口的句柄根本不固定,因此不要在程序中使用常量来保存一个窗口的句柄。

 

VB Windows编程之消息的组织和发送

每个消息在Windows中都用一个惟一的长整数表示,称为消息编号,消息编号一般定义为常量,比如,获得输入焦点,的消息的编号为7,就定义为WM_SETFOCUS常量值为7以表示这条消息。“WM_”是Windows Message的缩写,表示该常量是用于窗口消息的常量。在VB的API浏览器中选择“常数”,然后输入“WM_”,可以看到有大量的以“WM_”开头的常量,这些常量是很惊人的,这些都是消息。

消息的发送

发送消息到指定的窗口,可以由Windows系统自动发送,也可以在程序中通过执行代码来向指定的窗口发送消息,这是通过API函数SendMessage或PostMessage进行的。

当在程序中需要向指定的窗口发送消息时,都可以调用这两个函数,这两个函数的参数是相同的,都分别是要发送到窗口的句柄hwnd,消息编号wMsg和消息的两个参数wParam,IParam,这两个函数的功能也都是向指定窗口发送一条消息,区别在于SendMessage在发送消息时,要等待目标 窗口的窗口程序处理完这条消息后再返回主调程序,而PostMessage在发送消息后,立即返回主调程序,而此时目标 窗口的窗口程序可能还没处理完这条消息。

对发送不同的消息,SendMessage函数的返回值也是不同的,与消息参数的具体含义需要查阅手册获得类似,SendMessage函数返回值的具体含义,也要通过发送消息后不等待处理而立即返回的特点。而PostMessage函数由于不等待消息处理完毕就立即返回,所以它的返回值有固定的含义,返回非0值表示成功,返回0表示失败。

 

SendMessage(PostMessage)详解

SendMessage

函数原形

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

四个参数的含义和说明如下:

1.hWnd

对象的句柄。希望将消息传送给哪个对象,就把该对象的句柄作为实参传送,在 VB 中可以简单地用“对象.hWnd”获得某个对象的句柄,如 Text1.hWnd和 Form1.hWnd分别可以得到 Text1和Form1的句柄。它是一个长整型数。Windows给每个控件一个编号,这个编号就称为窗口句柄。有了这个句柄,我们就可告诉 Windows 我们要控制哪个控件,所以这个句柄在 API 调用中至关重要。VB 的大多数控件都包括hwnd属性,如下拉框、TreeView等,窗体也有这个属性。但也有一些控件没有这个属性,如标签控件。

没有这个属性就无法利用Windows API函数,但可以节省系统资源。

2.wMsg

被发送的消息。根据具体需求和不同的对象,将不同的消息作为实参传送,以产生预期的动作。使SendMessage 传递消息,大多是为了完成以下几个工作:

设置控件的一些选项,象我们要使用的CB_SETDROPPEDWIDTH的就属于这种情况。尽管VB的每个控件都提供了许多属性,但仍然有许多控件的选项没有包括在其中。而这些选项中的大多数都可以利用该函数进行设置

获得控件的一些设置。同上一种情况相反,有时我们需要获得控件的一些设置,相当于读取属性。

例如,如果想知道一个下拉框的下拉部分的宽度是多少,就可以向控件发送CB_GETDROPPEDWIDTH消息。

对于这种情况,SendMessage函数的返回值就是结果。

执行一定的操作。例如,我们要在下拉框中寻找是否有“ABC”这个字符串,当然,我们可以编写一个循环,逐条比较看是否存在这样的字符串。如果使用API,我们只需要向下拉框发送CB_FINDSTRING消息,这条消息就会自动进行查找工作并返回结果。

模拟用户操作。我们有时希望模拟用户的操作,比如关闭其他应用程序的窗口。其实只要我们能知道那个窗口的句柄,我们就可以发送WM_CLOSE消息给那个窗口,窗口接受到这条消息就会关闭,如同用户关闭窗口一样

3.wParam、4.lParam:

附加的消息信息。这两个是可选的参数,用来提供关于wMsg消息更多的信息,不同的wMsg可能使用这两个参数中的0、1或2个,如果不需要哪个附加参数,则将实参赋为NULL(在VB中赋为0)。

lParam定义为Any类型。指定 Any类型可禁止VB进行类型检查,从而允许将任意数据类型传递给该过程。由于每条消息对参数的类型和传递方式的要求都不同:有的可能要求为Long型,有的可能要求为自定义类型;大多数要求按传值方式传递,但也有一些要求按传地址方式。为了满足各种要求,我们将这个参
数定义为Any类型。比如,我们要传递一个Long型变量lData。如果消息要求传地址方式传递,可以使用:

SendMessage ……, lData

而如果要求传值方式传递,则使用

SendMessage ……, ByVal lData

如果传递常数,我们则需要使用类型后缀来指定常数的类型,比如"0&",表示Long型的常数0,如

SendMessage ……, ByVal 0&

我们也可以使用类型转换函数CLng将常数指定为Long型,如CLng(0)。

程序中,有时定义 lParam As Any,有时定义 ByVal lParam As String。这是为什么呢对于SendMessage函数,lParam的使用是很灵活的,在一般情况下,lParam是一个指针,它指向的数据类型有三种:长整形、自定义数据结构类型、字符串类型。对于前两种类型,需要将 lParam定义为 lParam As Any,从而将 lParam 数据的指针传递到 SendMessage 函数。对于字符串类型,则需要定义 Byval lParam As String,因为字符串类型数据不同,只有定义 ByVal,得到的才是字符串的指针,如果没有ByVal,得到的将是指向字符串指针的指针。

另外对于少数的消息来说,SendMessage 函数需要的只是lParam 本身的值,这时就需要将 lParam定义为 Byval lParam As Long,或者在程序调用时在 lParam之前加 ByVal

 

当用户在编辑控件上进行各种操作时,其父窗口将收到 WM_COMMAND 通知消息,lParam带控件句柄(hWnd),同时 wParam 的低16位带控件的 ID,高16位带有如下表的消息代码:

常用编辑控件消息:

EC_LEFTMARGIN(&H1) EC_USEFONTINF 设置左边距时使用

EC_RIGHTMARGIN EC_USEFONTINF 设置右边距时使用

EC_USEFONTINF,O,边距设置编辑控件的左、右边距,当wParam含EC_LEFTMARGIN时在lParam的低16位指定左边距点数,当wParam含 EC_RIGHTMARGIN时在lParam的高16位指定右边距点数。当指定wParam为EC_USEFONTINFO时,则用当前字体的字符 "A"的宽度指定右边距和字符"C"的宽度指定左边距lParam被忽略。

EM_CHARFROMPOS(&HD7=215),0, 取得编辑控件中指定位置的字符相对于文本头部的偏移量。使用本操作应先在第4个参数的高16位指定行号,低16位指定列号(或一个POINTAPI结构),行列是按编辑控件的客户区左上角为原点(0,0)计算的。如果指定的位置超出控件客户区则返回-1

EM_CANUNDO(&HC6=198),0,0  决定前一次编辑操作是否能够撤消:检测控件撤消缓冲区是否为空,通常控件把最后一次在控件的编辑操作保存在一个撤消缓冲区,如果缓冲区非空则返回TRUE 表示上次操作可以撤消,否则返回FALSE,应用程序可以利用该返回值来禁止或允许菜单或工具条的"撤消"项。

EM_EMPTYUNDOBUFFER(&HCD=205 ),0,0 清除控件的撤消缓冲区,使其不能撤消前一次编辑操作

EM_FMTLINES(&HC8=200)   决定是否在取回的文本宇串中包含软回车字符

EM_GETFIRSTVISIBLEINE(&HCE=206),0,0 获得文本控件中处于可见位置的最顶部的文本所在的行号

EM_GETLINE(&HC4=196 ),行号,ByVal 变量获取编辑控件某一行的内容,变量须预先赋空格

EM_GETLINECOUNT(&HBA=186,0,0 获取编辑控件的总行数

EM_GETMODIFY(&HB8=184),0,0 判断编辑控件的内容是否已发生变化,返回TRUE则控件文本已被修改,返回FALSE则未变。

EM_GETPASSWORDCHAR( ),0,0  获取编辑控件的密码字符,返回NULL表示没有字符

EM_GETRECT(&HB2=178),0,结构   获取编辑控件的格式化矩形

EM_GETTHUMB(&HBE=190),0,0 取得多行文本编辑控件的滚动框的当前位置(注意:是象素值)

EM_GETSEL(&HB0=176),0,变量获取光标位置(以字节数表示),或:(缓冲区起点,缓冲区终点)取得编辑控件中选定内容的范围,返回值中低16位为起点,高16位为终点

EM_GETHANDLE(&HBD=189),0,0 取得文本缓冲区

EM_GETWORDBREAKPROC(&HD1=209),0,0 取得整字换行回调函数EditWordBreakProc指针

EM_GETLIMITTEXT(WM_USER+37=1061),0,0 获取一个编辑控件中文本的最大长度

EM_GETMARGINS( ),0,0 获取编辑控件的左、右边距,返回值低16位为左边距,高16位为右边距(不得用于NT3.51)

EM_LIMITTEXT(&HC5=197),最大值,0 设置编辑控件中的文本长度

EM_SCROLLCARET(&HB7=183),0,0 把可见范围移至光标处

EM_LINEFROMCHAR(&HC9=201),偏移值,0 获取指定位置(或:-1,0 表示光标位置)所在的行号

EM_LINEINDEX(&HBB=187),行号,0 获取指定行(或:-1,0 表示光标所在行)首字符在文本中的位置(以字节数表示)

EM_LINELENGTH(&hC1=193),偏移值,0 获取指定位置所在行(或:-1,0 表示光标所在行)的文本长度(以字节数表示)

EM_POSFROMCHARPOINT,结构地址,偏移值 取得指定字符位置的行列号,偏移值是字符相对于文本头部的偏移。

EM_LINESCROLL(&HB6=182),列数,行数指定行数的文本水平滚动,每次滚动N列

EM_EXGETSEL (&H434 = 1076)

EM_EXSETSEL(&H437=1079),0,结构 RichEdit控件设置文本选定范围,参阅 EM_SETSEL 消息,结构是指 CHARRANGE 结构

EM_PASTESPECIAL(&H440=1088),2(1),1 RichEdit控件粘贴剪贴板中的位图(或文本)

EM_FINDTEXT(&H738=1080) RichEdit控件正文搜索操作

EM_FINDTEXTEX(&H44F=1103) 同上

EM_SETTEXTEX(&H461=1121) RichEdit控件正文替换/插入操作

EM_SETTARGETDEVICE, GetDC(RichText.hWnd), RichText.Width / 15)设置 RichTextBox 自动换行,后续代码是:RichText.RightMargin = iif(RichText.RightMargin = 0,1,0)

EM_SETTARGETDEVICE, 0, 1 设置 RichTextBox 不自动换行

EM_POSFROMCHAR(&HD6或&H426) 判断指定字符在编辑控件的位置(用于NT3.51)

EM_SCROLL(&HB5=181),*,0 文本垂直滚动。第三个参数*控制滚动方向:SB_LINEDOWN(1)向下滚动一行,SB_LINEUP(0)向上滚动一行,SB_PAGEDOWN (3)向下滚动一页,SB_PAGEUP(2)向上滚动一页。

EM_REPLACESEL(&HC2=194),1(0),字符串用指定字符串替换编辑控件中的当前选定内容,如果第三个参数wParam为1,则本次操作允许撤消,0禁止撤消。字符串可用传值方式,也可用传址方式(例:SendMessage Text1.hwnd, EM_REPLACESEL, 0, Text2.Text '这是传值方式)

EM_SETSEL(&HB1=177),起点,终点设置编辑控件中文本选定内容范围(或设置光标位置),该范围被反相显示,用于为复制、替换、粘贴、剪切、删除等编辑功能指定范围,光标将被移至指定的终点后面。还可使用指定相同起点和终点来移动光标而不是选定范围。当指定的起点等于0和终点等于-1时,文本全部被选中,此法常用在清空编辑控件。当指定的起点等于-2和终点等于-1时,全文均不选,光标移至文本未端,此法常用在文本未端追加内容。注意:当控件没有输入焦点时,本操作将会失败,一般在执行本操作前都应调用SetFocus先取得输入焦点。

EM_UNDO(&HC7=199),0,0 撤消前一次编辑操作,当重复发送本消息,控件将在撤消和恢复中来回切换

EM_SETCHARFORMAT(&H444) 改变选定文本的颜色

EM_SETHANDLE(&HBC=188),缓冲区指针,0 为编辑控件指定新的文本缓冲区。此操作仅适用对话框创建带DS_LOCALEDIT风格的控件。

EM_SETLIMITTEXT,长度(字节),0 设置编辑控件中的文本最大长度(不得用于NT3.51)

EM_SETMARGINS(&HD3=211) 设置编辑控件的左、右边距(不得用于NT3.51)

EM_SETMODIFY(&HB9=185),1(0),0 设置或清除一个编辑控件的修改标志

EM_SETPASSWORDCHAR(&HCC=204),字符,0 指定控件用来显示密码的字符,缺省为"*"。当第三个参数wParam为0时,本操作将清除控件的ES_PASSWORD风格,并按实际字符显示。

EM_SETREADONLY(&HCF=207),1(0),0 决定是否将编辑控件设为只读,同时决定控件的ES_READONLY风格

EM_SETRECT(&HB3=179),0(或RECT),结构地址为一个编辑控件设置格式化矩形

EM_SETRECTNP(&HB4=180),0(或RECT),结构地址为一个编辑控件设置格式化矩形,只是控件此时不会重画

EN_CHANGE(&H300=768) 编辑控件的内容发生改变。与EN_UPDATE不同,该消息是在编辑框显示的正文被刷新后才发出的。

EN_ERRSPACE(&H500=1280) 任何时候只要由于内存不足以完成一项编辑操作

EN_HSCROLL(&H601=1537) 用户单击了编辑控件的水平滚动条。注意:这条消息是在控件更新显示之前发送出去的。

EN_VSCROLL(&H602=1538) 用户单击了编辑控件的垂直滚动条。注意:这条消息是在控件更新显示之前发送出去的。

EN_KILLFOCUS(&H200=512) 编辑控件失去了输入焦点

EN_SETFOCUS(&H100=256) 编辑控件获得了输入焦点

EN_UPDATE(&H400=1024) 控件准备显示改变了的正文时发送该消息。它与EN_CHANGE通知消息相似,只是它发生于更新文本显示出来之前。

EN_MAXTEXT(&H501=1281) 用户输人的文字数超出由EM_LIMITTEXT消息规定的界限,或超出由VB Maxlength属性规定的界限,就会发送这条消息。此外,倘若不允许自动进行水平滚动,同时插入点要超出控件的宽度;或者不允许自动垂直滚动,同时插入点要超出控件的高度,那么也会触发这条消息。在没有 ES_AUTOHSCROLL或ES_AUTOVSCROLL的编辑框中,当正文超出了编辑框的边框时也会发出该消息。

编辑风格消息:

ES_MULTILINE  指定编辑控件能否进行多行文本编辑,若多行编辑器不指定ES_AUTOHSCROLL风格,则会自动换行,用户每按一次Enter,在当前光标处输入一个回车换行符(0Dh,0Ah),文本增加一行。若不指定ES_AUTOVSCROLL,则多行编辑器会在窗口中正文装满时发出警告声响。

ES_LEFT 文本显示居左

ES_CENTER 文本显示居中

ES_RIGHT 文本显示居右

ES_LOWERCASE 把用户输入的字母统统转换成小写字母

ES_UPPERCASE 把用户输入的字母统统转换成大写字母

ES_OEMCONVERT 把输入的文本从ANSI码转换成OEM码,然后又转换成ANSI码,目的是保证函数AnsiToOem的正确调用。这在编辑框中包含文件名时是很有用的。

ES_AUTOHSCROLL(自动增加水平滚动条)当用户在行尾键入一个字符时,正文将自动向右滚动10个字符,当用户按回车键时,正文总是滚向左边。

ES_AUTOVSCROLL  当用户在最后一个可见行按回车键时,正文向上滚动一页。

ES_NUMBER  只接收数码输入,其它字符输入一律无效。

ES_NOHIDESEL(&H100=256) 当编辑框失去输入焦点时,选中的文本将隐藏,正文中的选择保持不变。缺省时正文中的选择将失效,当获得输入焦点后才又显示出来。

ES_READONLY 将编辑框设置成只读的

ES_PASSWORD(&H20=32) 使所有键入的字符都用"*"来显示。

ES_WANTRETURN 使多行编辑器接收回车键输入并换行。如果不指定该风格,按回车键会选择缺省的命令按钮,这往往会导致对话框的关闭。

列表框操作:

LB_FINDSTRING(&H18F=399),-1,ByVal 字串查找列表项的字符串,返回值=字符串所在的列表项的索引。-1表示从第0行开始查找,如果改为一个有效的列表项索引值,将从该行开始查找。

LB_ITEMFROMPOINT(&H1A9=425) 获取光标所在的列表项的索引

LB_SETHORIZONTALEXTENT(&H194=404),长度,0 设置列表框的横向滚动条以及滚动长度,长度为象素值

组合框操作:

CB_SHOWDROPDOWN(&H14F),1(0),0 打开(关闭)组合框的列表

TVM_SETBKCOLOR(&H1100+29=4381) 设置扩展树型列表控件的背景色(TVM开头的常数)

常用窗口消息:

WM_GETFONT(&H31=49) 得到当前控件绘制文本的字体(的句柄)

WM_GETTEXT(&HD=13),变量长度,变量取得窗体的标题,变量须预先赋空字串(chr(0)),变量长度=Len(变量)

WM_SETTEXT(&HC=12),0,ByVal "字串" 设置窗体的标题

WM_NCLBUTTONDOWN(&HA1=161),2,0 在非客户区,即边框及标题栏上(假如定义的是一个组件,则非客户区包括Form等)按下鼠标左键;

WM_LBUTTONDOWN(&H201=513),2,0 在客户区,也就是除边框及标题栏以外按下鼠标左键

WM_VSCROLL(&H115=277),&H10000*p+SB_THUMBPOSITION(&H4),0 同步滚动文本,p是位置改变量

WM_PAINT

WM_USER (&H400 = 1024)

WM_CUT(&H300=768),0,0 剪切

WM_COPY(&H301=769)),0,0 复制

WM_PASTE(&H302=770)),0,0 粘贴

WM_CLEAR(&H303=771)),0,0 删除

WM_UNDO(&H304=772)),0,0 撤消

按纽消息:

BM_SETSTYLE(&HF4) 设置按纽样式

BS_RADIOBUTTON(&H4) 收音机旋纽式的按纽,是 BM_SETSTYLE 使用的参数

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值