容器控件拦截容器内控件的方法
记得上次发帖求助grid控件的gridhittest事件无法获得正确结果,后来有兄弟用bindevent的方法解决了。但我总记得有简单的方法来传递控件事件给容器控件的,以前在网上有看到过,当时一直没想起来。最近终于想起来了,分享给大家。今天百度了一下,这个方法叫冒泡事件。。。
想必大家都有用过container,pageframe,commandgroup,grid等容器控件,当点击容器内控件时,首先接收消息的是容器内的最内层的控件,而容器是接收不到的。就像上次我的gridhittest,在grid上点击事件被传递给cell,或者header了,导致gridhittest无法正常工作。而我们编程的过程中,肯定有希望让容器控件来接收用户的鼠标或键盘事件,而不是容器里的控件。举个例子,一个form上有很多控件,用户需要用鼠标动态调整控件的大小,而这些控件是联动的,这就很麻烦,因为要涉及到mousemove事件,当鼠标移动到控件上时,触发的是控件的mousemove事件,移走就触发form的mousemove事件了。。。
最近在写一个prg的文件管理程序,终于实现了!废话不多说,上代码吧。。。
程序代码:
PUBLIC oform1 oform1=NEWOBJECT("form1") oform1.Show RETURN ************************************************** *-- Form: form1 (d:\documents\visual foxpro 项目\bubbledevent.scx) *-- ParentClass: form *-- BaseClass: form *-- Time Stamp: 11/16/22 09:52:11 PM * DEFINE CLASS form1 AS form Height = 750 Width = 1057 DoCreate = .T. AutoCenter = .T. Caption = "Form1" WindowState = 0 Name = "Form1" ADD OBJECT olecontrol1 AS olecontrol WITH ; Top = 35, ; Left = 1, ; Height = 24, ; Width = 280, ; Anchor = 0, ;&&当form调整大小时,控件也随之调整 Name = "Olecontrol1" ADD OBJECT olecontrol3 AS olecontrol WITH ; Top = 61, ; Left = 1, ; Height = 688, ; Width = 280, ; Anchor = (64+2+1), ;&&当form调整大小时,控件也随之调整 Name = "Olecontrol3" ADD OBJECT edit1 AS editbox WITH ; Anchor = (64+8+2+1), ; &&当form调整大小时,控件也随之调整 Height = 714, ; Left = 284, ; Top = 35, ; Width = 771, ; Name = "Edit1" ADD OBJECT commandgroup1 AS commandgroup WITH ; ButtonCount = 6, ; Value = 1, ; Height = 30, ; Left = 1, ; Top = 2, ; Width = 154, ; Name = "Commandgroup1", ; Command1.Top = 2, ; Command1.Left = 3, ; Command1.Height = 25, ; Command1.Width = 25, ; Command1.Picture = "graphics\bitmaps\offctlbr\small\color\new.bmp", ; Command1.Caption = "", ; Command1.StatusBarText = "新建一个文件!", ; Command1.Alignment = 2, ; Command1.Name = "Command1", ; Command2.Top = 2, ; Command2.Left = 28, ; Command2.Height = 25, ; Command2.Width = 25, ; Command2.Picture = "graphics\bitmaps\offctlbr\small\color\open.bmp", ; Command2.Caption = "", ; Command2.StatusBarText = "打开一个文件!", ; Command2.Alignment = 2, ; Command2.Name = "Command2", ; Command3.Top = 2, ; Command3.Left = 53, ; Command3.Height = 25, ; Command3.Width = 25, ; Command3.Picture = "graphics\bitmaps\offctlbr\small\color\save.bmp", ; Command3.Caption = "", ; Command3.StatusBarText = "保存文件", ; Command3.Alignment = 2, ; Command3.Name = "Command3", ; Command4.Top = 2, ; Command4.Left = 78, ; Command4.Height = 25, ; Command4.Width = 25, ; Command4.Picture = "graphics\bitmaps\offctlbr\small\color\copy.bmp", ; Command4.Caption = "", ; Command4.StatusBarText = "复制选择的文字", ; Command4.Alignment = 2, ; Command4.Name = "Command4", ; Command5.Top = 2, ; Command5.Left = 103, ; Command5.Height = 25, ; Command5.Width = 25, ; Command5.Picture = "graphics\bitmaps\offctlbr\small\color\print.bmp", ; Command5.Caption = "", ; Command5.StatusBarText = "打印", ; Command5.Alignment = 2, ; Command5.Name = "Command5", ; Command6.Top = 2, ; Command6.Left = 128, ; Command6.Height = 25, ; Command6.Width = 25, ; Command6.Picture = "graphics\bitmaps\tlbr_w95\delete.bmp", ; Command6.Caption = "", ; Command6.StatusBarText = "删除当前文件", ; Command6.Name = "Command6" ADD OBJECT line1 AS line WITH ; Anchor = 10, ; Height = 0, ; Left = 1, ; Top = 32, ; Width = 1054, ; Name = "Line1" ADD OBJECT line2 AS line WITH ; Anchor = 10, ; Height = 0, ; Left = 1, ; Top = 33, ; Width = 1054, ; BorderColor = RGB(255,255,255), ; Name = "Line2" PROCEDURE Resize this.olecontrol1.Width=this.olecontrol3.Width ENDPROC PROCEDURE MouseMove &&当鼠标移动至2个控件之间,鼠标指针变成可调整边界的形状,进而动态调整控件的边界 LPARAMETERS nButton, nShift, nXCoord, nYCoord IF nxcoord<this.edit1.Left+3 AND nxcoord>this.olecontrol3.Left+this.olecontrol3.Width-3 this.MousePointer= 9 *!* IF nbutton=1 AND this.MousePointer=9 *!* this.olecontrol3.Width=nxcoord-this.olecontrol3.left *!* this.olecontrol1.Width=this.olecontrol3.width *!* x=this.edit1.left *!* this.edit1.Left=this.olecontrol3.left+this.olecontrol3.width+3 *!* this.edit1.Width=this.edit1.Width+x-nxcoord-3 *!* ENDIF *!* ELSE *!* this.MousePointer= 0 &&不能加这句,否则边框只能向右移,不能左移 ENDIF IF this.MousePointer=9 AND nbutton=1 &&这两个条件顺序不一样居然效果不一样,我也是醉了。 this.olecontrol3.Width=nxcoord-this.olecontrol3.left this.olecontrol1.Width=this.olecontrol3.width x=this.edit1.left nwidth=this.edit1.width this.edit1.Left=this.olecontrol3.left+this.olecontrol3.width+3 this.edit1.Width=nwidth+x-nxcoord-3 ENDIF ENDPROC PROCEDURE olecontrol1.Refresh *** ActiveX 控件方法程序 *** ENDPROC PROCEDURE olecontrol1.Change *** ActiveX 控件事件 *** ENDPROC PROCEDURE olecontrol1.Init ENDPROC PROCEDURE olecontrol1.GetFirstVisible *** ActiveX 控件方法程序 *** ENDPROC PROCEDURE olecontrol3.MouseMove *** ActiveX 控件事件 *** LPARAMETERS button, shift, x, y thisform.MouseMove(button,shift,x,y) &&向容器传递mousemove事件,冒泡。如果容器控件中还有控件,那么继续冒泡 ENDPROC PROCEDURE olecontrol3.DblClick *** ActiveX 控件事件 *** ENDPROC PROCEDURE olecontrol3.Init this.Nodes.Add(,,"Root","我的电脑",,) DECLARE integer GetLogicalDriveStrings IN WIN32API integer,string@ cstr=REPLICATE(CHR(0),40) n=getlogicaldrivestrings(40,@cstr) FOR i=1 TO n STEP 4 this.nodes.Add(1,4,,SUBSTR(cstr,i,2),,) ENDFOR this.Nodes.Item(1).Expanded=.t. ENDPROC PROCEDURE olecontrol3.HitTest *** ActiveX 控件方法程序 *** LPARAMETERS x, y ENDPROC PROCEDURE edit1.MouseMove LPARAMETERS nButton, nShift, nXCoord, nYCoord thisform.MouseMove(nbutton,nshift,nxcoord,nycoord) &&向容器传递mousemove事件,冒泡。如果容器控件中还有控件,那么继续冒泡 ENDPROC ENDDEFINE * *-- EndDefine: form1 **************************************************
现在就可以动态调整edit控件的大小,以及treeview控件的大小了,所有控件都会随之调整大小。同理如果是grid控件,那么把cell,以及header的事件传递column,再把column的事件传递给grid,如果grid在container里面,或者pageframe里面,那么继续一级一级上传,直到传递给表单,然后我们在表单的事件中统一处理。
如果你们觉得这个方法有用,点个赞吧。。。
[此贴子已经被作者于2022-11-16 22:13编辑过]