很遗憾没有收到 投轻松解决票的朋友的答案。 VBA的TextBox 没有句柄,几乎无法用API来操作。主要用MouseMove事件来控制 通常的做法是对鼠标的位置进行判断,一般采取8+1 判断法 即 4边4角 + 中间。 然后进行相应的动作。 从代码判断的复杂性而言 中间的代码最容易其次是下边、右边和 右下角。 再复杂一点的是 上边、左边 和 右上角、左下角,最复杂的是左上角 要同时改变4 个值 。 代码运行时 只进行一种操作来改变控件状态。 8+1的判断方法不仅代码量大,而且很难扩展。 这期的答题者大都是采用的 8+1 判断法。 只有彭希仁有效采用4+1判断法,即 4边 + 中间。 这种方法运行时,进行 1或 2种操作,来改变控件状态。 这就把复杂的问题简单化了,在编写代码时只用考虑 左中右 三种状态。 因为左和上 右和下 的代码一致,直接复制,只要x 改 y ,left、width 改top、height就行了 而 中 和 右 的 代码都是最简单的,有点难度的只有左边的代码了,在8+1方法里这只算中等。 彭希仁答案给我很好的启发:这是我根据4+1方法编写的代码,仅仅需要一个MouseMove事件 出于代码可读性考虑,采用条状的 if语句,作用类同语句写在一行 Private Sub Text2_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Static xX As Single, yY As Single, 上 As Boolean, 下 As Boolean, 左 As Boolean, 右 As Boolean, 中 As Boolean With Text2 ' 标准移动,一般的程序都是这种效果,实现基本功能最洗练的代码 .ZOrder: If CheckBox1.value = 0 And .MousePointer > 0 Then .MousePointer = 0 If Button = 0 And CheckBox1 Then CheckBox1.SetFocus: xX! = X: yY! = Y 上 = Y <= 5: 下 = .Height - Y <= 5 左 = X <= 5: 右 = .Width - X <= 5 If 上 And 下 Then 上 = False If 左 And 右 Then 左 = False 中 = Not (上 Or 右 Or 左 Or 下) If 中 Then .MousePointer = 15 If (左 Or 右) Then .MousePointer = 9 If (上 Or 下) Then .MousePointer = 7 If (左 And 上) Or (右 And 下) Then .MousePointer = 8 If (左 And 下) Or (右 And 上) Then .MousePointer = 6 ElseIf Button = 1 And CheckBox1 Then If 中 Then .Move .Left + X - xX!, .Top + Y - yY! If 上 And .Height - Y + yY! >= 1 Then .Move , .Top + Y - yY!, , .Height - Y + yY! If 左 And .Width - X + xX! >= 1 Then .Move .Left + X - xX!, , .Width - X + xX! If 下 And .Height + Y - yY! >= 1 Then .Height = .Height + Y - yY!: yY! = Y If 右 And .Width + X - xX! >= 1 Then .Width = .Width + X - xX!: xX! = X End If End With End Sub If CheckBox1.value = 0 And .MousePointer > 0 Then .MousePointer = 0 在没有勾选复选框时 恢复默认光标 “I” 型, 鼠标按下前 记录参照点 xx,yy, 5 种状态值以及设置MousePointer属性, CheckBox1.SetFocus这句所起的作用是让鼠标正常显示。 也可以用 .visible = false: .visible=true 来达到相同效果,这是VBA的缺陷,VB中不用多此一举。 鼠标按下 根据 上下左右中 分别执行相关语句(1 或2 句)改变控件形态。 4+1的好处还在于容易扩展。如果要实现翻转拖动,在end if前 增加以下4句判断即可实现 实现翻转效果: If 上 And Y > .Height Then 上 = Not 上: 下 = Not 下: yY = Y: .Top = .Top + .Height If 下 And Y < 0 Then 上 = Not 上: 下 = Not 下: yY = Y: .Top = .Top + Y: .Height = -Y If 左 And X > .Width Then 左 = Not 左: 右 = Not 右: xX = X: .Left = .Left + .Width If 右 And X < 0 Then 左 = Not 左: 右 = Not 右: xX = X: .Left = .Left + X: .Width = -X 如果采用8+1方法,想要实现翻转拖动,工作量将会以几何级数递增。 根据这个方法可以容易地编写更加友好的界面,就像调整sheeet表中的控件一样,限制控件的移动范围。 无论如何快速拖动,控件始终不会超出窗体范围,并且不会出现鼠标与控件脱节的情况。 这就要考虑到各个边界值及最小值的问题,以及鼠标移出移入窗体 控件的反应, 要在窗体内实现控件边框紧跟鼠标效果,细节方面考虑比较多。用纯粹的VBA代码, 以实现完美效果。 具体代码请参考附件的 Text4的代码 “媲美 office系列产品的调整控件效果”。 注:office中鼠标按下时无法改变鼠标的可视形态,所以在翻转代码里用的是 “小十字线” 指针而不是“斜箭头” 参考 http://club.excelhome.net/viewthread.php?tid=339584&px=0 附件:
|