在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
用SendMessage向控件发送消息 在编程中,有时需要控件以特殊的风格显示,而这种要求又无法通过设置控件属性实现。例如,读取客户列表并显示在下拉框供用户选择,如果下拉框宽度太窄,则不能全部显示;如果将宽度定得太宽,界面又有不紧凑之感。因此希望能在运行期动态地确定下拉框显示区域的宽度,这种要求如果不用SendMessage函数就很难实现。 解决办法是,在读数据库时计算字符串的显示宽度,用显示宽度的最大值确定下拉框显示区域的宽度。再用SendMessage函数向下拉框发送CB_SETDROPPEDWIDTH消息和宽度值,下拉框根据消息中传来的信息,就可以进行正确显示。 部分源程序代码如下: i:=0; //计数 MaxWidth:=0; Query1.SQL.Clear; Query1.SQL.Add(‘select Company from Customer’); Query1.Open; //读客户列表到下拉框 while not Query1.Eof do begin ComboBox1.Items.add(Query1.FieldByName (‘Company’).AsString); Width:=ComboBox1.Font.Size * Length (ComboBox1.Items[i]); if Width>MaxWidth then MaxWidth:=Width; //找出最大值 Query1.Next; i:=i+1; end; Query1.Close; ComboBox1.Text:=ComboBox1.Items[0]; //发送消息以确定显示区域的宽度 SendMessage(ComboBox1.Handle, CB_SETDROPPEDWIDTH,MaxWidth,0); 利用SendMessage函数还可以实现一些有趣的效果,例如在按钮的Click事件中加入如下语句: SendMessage(Button.Handle,BM_SETSTYLE, BS_RADIOBUTTON,1); 运行后点击按钮,就可以把按钮变成一个收音机按钮。 控件接收SendMessage消息 上面讨论了用SendMessage向控件发送消息的过程。但凡事有利就有弊,用SendMessage发送的消息在处理上存在着一定困难。因为该消息不经过消息队列,所以无法用OnMessage方式来指定对消息的响应,甚至用HookMainWindow也不行,因为消息直接发送到控件,绕过了主窗体。要对这种类型的消息作出响应,需要重载控件的WndProc方法。 例如,对于一个列表框,滚动条的滚动消息就是用SendMessage方式发送的,因此该消息不在TlistBox的事件列表中。下面是处理控件响应该滚动消息的具体步骤。 1.首先从TlistBox继承一个TmyListBox类,并重载WndProc方法。在程序中加入下列定义: type TMyListBox=class(TListBox) private procedure WndProc(var Msg: TMessage); override; //重载WndProc,处理发送到控件的消息 public end; 其中WndProc方法指定控件对消息的响应,输入参数是TMessage类型,该数据类型是一个记录,包含了消息代码和消息的参数,消息参数可以用Longint或Word方式获得。 2.对滚动事件做出响应,在WndProc方法中加入如下处理代码: if (Msg.Msg=WM_VSCROLL) and (Msg.WParamLo=SB_ENDSCROLL) then begin //获得鼠标位置对应的列 ItemIndex:=ItemAtPos(Point,true); Form1.Edit1.Text:=inttostr(ItemIndex); inherited; end else inherited; 当程序接收到WM_VSCROLL消息,且WParamLo参数为SB_ENDSCROLL时,表示竖直滚动条停止滚动,就可以用ItemAtPos方法确定与鼠标位置对应的ItemIndex。ItemAtPos方法的Point参数是一个TPoint类型的变量,用来保存鼠标的位置。 3.定义方法ListBoxMouseMove,在鼠标移动时,将当前位置保存在Point中: procedure TForm1.ListBoxMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); begin Point.X:=X; Point.Y:=Y; end; 4.在运行期创建和初始化列表框,并指定列表框的MouseMove事件对应上一步定义的ListBoxMouseMove方法。在主窗体的Create事件中输入下面的代码:begin Point.X:=0; Point.Y:=0; //创建自定义列表框 List:=TMyListBox.Create(Form1); List.Parent:=Form1; List.Left:=5; List.Top:=30; List.Width:=150; List.Height:=200; for i:=0 to 300 do begin List.Items.Add(inttostr(i)); //初始化 end; //指定处理MouseMove事件的方法 List.OnMouseMove := ListBoxMouseMove; end; |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论