![]() |
#2
sam_jiang2022-11-16 22:31
|
最近终于想起来了,分享给大家。今天百度了一下,这个方法叫冒泡事件。。。
想必大家都有用过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编辑过]