我发现做透明控件与做不透明控件在很多地方有不同之处,而且处理这些不同之处相当困难。我把这些问题做了个总结,希望大家帮忙讨论、解决!
问题一:Caption
如果要实现透明控件类似于Label的Caption,我现在有两个方案,但是这两个方案都有点问题:
方案1:Print "Caption"
Private Sub UserControl_Paint()
UserControl.Cls
Print "Caption"
End Sub
为了实现Usercontrol的透明,则必须对以下属性做设置(缺一不可):
Usercontrol.BackStyle=0
UserControl.ClipBehavior = 0
Usercontrol.Windowless=True
好,问题出来一大堆...具体的请看问题二、问题三、问题四!
方案2:在UserControl中直接放Label:
为了实现Usercontrol的透明,必须将Usercontrol和Label都设置为BackStyle="0"
问题:多数字体显示不全。如字体="宋规五"、字体="楷规五",除非字体是粗体,且字号较大,则不怎么看不出字体不全。
?????:不知道还有没有其它办法可以实现透明的Caption?问题二:BackStyle
当BackStyle=0(透明)时,UserControl不响应MouseDown、MouseUp、MouseClick事件,只是HitTest事件;同时MousePointer、MouseIcon属性无效。为什么MousePointer、MouseIcon无效?而Label都有这些属性和事件呀?
?????:如何判断透明控件的MouseDown、MouseUp、MouseClick事件?如何给透明控件添加MouseIcon、MousePoiont属性?问题三:Windowless
如果Windowless=True,则Usercontrol的hwnd=0,这就导致:
1、很多API都用不成;
比如,通常判断鼠标在控件上的“移进”(MouseOver),“移出”(MouseOut),都用Setcapture。这下,就只能通过timer控件和GetCursorPos来完成了,比用Setcapture多用了一个Timer,不爽!
2、在设计时,控件不可以“点选”
在设计时,无法通过点击来选择该控件,只能"框选"或通过在"属性"下拉列表中进行选择。
?????:Windowless=True时,如何实现“点选”?问题四:AutoRedraw
当Usercontrol.BackStyle=0 And UserControl.ClipBehavior = 0 And Usercontrol.Windowless=True时,无法设置AutoRedraw=True。
?????:但是我又需要用到AutoRedraw=True,如需要用存储在内存中的图象进行重绘,怎么办?
问题一:Caption
如果要实现透明控件类似于Label的Caption,我现在有两个方案,但是这两个方案都有点问题:
方案1:Print "Caption"
Private Sub UserControl_Paint()
UserControl.Cls
Print "Caption"
End Sub
为了实现Usercontrol的透明,则必须对以下属性做设置(缺一不可):
Usercontrol.BackStyle=0
UserControl.ClipBehavior = 0
Usercontrol.Windowless=True
好,问题出来一大堆...具体的请看问题二、问题三、问题四!
方案2:在UserControl中直接放Label:
为了实现Usercontrol的透明,必须将Usercontrol和Label都设置为BackStyle="0"
问题:多数字体显示不全。如字体="宋规五"、字体="楷规五",除非字体是粗体,且字号较大,则不怎么看不出字体不全。
?????:不知道还有没有其它办法可以实现透明的Caption?问题二:BackStyle
当BackStyle=0(透明)时,UserControl不响应MouseDown、MouseUp、MouseClick事件,只是HitTest事件;同时MousePointer、MouseIcon属性无效。为什么MousePointer、MouseIcon无效?而Label都有这些属性和事件呀?
?????:如何判断透明控件的MouseDown、MouseUp、MouseClick事件?如何给透明控件添加MouseIcon、MousePoiont属性?问题三:Windowless
如果Windowless=True,则Usercontrol的hwnd=0,这就导致:
1、很多API都用不成;
比如,通常判断鼠标在控件上的“移进”(MouseOver),“移出”(MouseOut),都用Setcapture。这下,就只能通过timer控件和GetCursorPos来完成了,比用Setcapture多用了一个Timer,不爽!
2、在设计时,控件不可以“点选”
在设计时,无法通过点击来选择该控件,只能"框选"或通过在"属性"下拉列表中进行选择。
?????:Windowless=True时,如何实现“点选”?问题四:AutoRedraw
当Usercontrol.BackStyle=0 And UserControl.ClipBehavior = 0 And Usercontrol.Windowless=True时,无法设置AutoRedraw=True。
?????:但是我又需要用到AutoRedraw=True,如需要用存储在内存中的图象进行重绘,怎么办?
不过我问一下:
Usercontrol.Windowless=True 一定要设么?
我不设,也可以实现透明也?
如果Usercontrol.Windowless=True ,用Print "Caption"方法就打印不出来"标题"
如Label、Image就是透明控件
yefanqiu(叶帆):
如果Usercontrol.Windowless=False ,用Print "Caption"方法就打印不出来"标题",不知道你试的结果有没有显示“标题”?
windowless=true 就没有窗口了, 用container的dc.
或者用一个不可见的picturebox.
"用container的dc."如何用?"不可见的picturebox"如何不可见,能讲详细点吗?
我需要控件即透明有能打印标题.在线等待!
我需要控件既透明又能打印标题.在线等待!
Private Sub UserControl_Paint()
UserControl.Cls
Print "Caption"
End Sub
在控件透明时,无论怎样,也不会显示标题。与Usercontrol.Windowless无关呀?
对以下属性做设置:
Usercontrol.BackStyle=0
UserControl.ClipBehavior = 0
Usercontrol.Windowless=True
'在usercontrol中
Private Sub UserControl_Paint()
UserControl.Cls
Print "Caption"
End Sub
不知道还有没有其它方法既透明又能显示标题,就象Label一样.
Private Sub UserControl_Paint()
UserControl.CurrentX = 0
UserControl.CurrentY = 0
Print "标题"
End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
If Ambient.UserMode = False Then
UserControl.BackStyle = 1 ‘设计时不透明
Else
UserControl.BackStyle = 0 ’运行时透明
End If
End Sub
这个方法,勉强可以解决“点选”的问题。但是如果给控件添加一个backStyle的属性,在设计时使用该控件,设置该控件的该属性就有点别扭了。
那么,问题二、问题四呢?
Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As _
Long, lpRect As RECT) As LongPrivate Declare Function GetClientRect Lib "user32" (ByVal hWnd As _
Long, lpRect As RECT) As LongPrivate Declare Function CombineRgn Lib "gdi32" (ByVal hDestRgn As _
Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal _
nCombineMode As Long) As LongPrivate Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, _
ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As LongPrivate Declare Function ScreenToClient Lib "user32" (ByVal hWnd As _
Long, lpPoint As POINTAPI) As LongPrivate Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As _
Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As LongConst RGN_AND = 1
Const RGN_COPY = 5
Const RGN_DIFF = 4
Const RGN_OR = 2
Const RGN_XOR = 3Private Type POINTAPI
x As Long
Y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
Public Sub MakeTransparent(mHwnd As Long)
Dim rctClient As RECT, rctFrame As RECT
Dim hClient As Long, hFrame As Long
'获得窗口矩形区域
GetWindowRect mHwnd, rctFrame
GetClientRect mHwnd, rctClient
'将窗口矩形坐标转换为屏幕坐标
Dim lpTL As POINTAPI, lpBR As POINTAPI
lpTL.x = rctFrame.Left
lpTL.Y = rctFrame.Top
lpBR.x = rctFrame.Right
lpBR.Y = rctFrame.Bottom
ScreenToClient mHwnd, lpTL
ScreenToClient mHwnd, lpBR
rctFrame.Left = lpTL.x
rctFrame.Top = lpTL.Y
rctFrame.Right = lpBR.x
rctFrame.Bottom = lpBR.Y
rctClient.Left = Abs(rctFrame.Left)
rctClient.Top = Abs(rctFrame.Top)
rctClient.Right = rctClient.Right + Abs(rctFrame.Left)
rctClient.Bottom = rctClient.Bottom + Abs(rctFrame.Top)
rctFrame.Right = rctFrame.Right + Abs(rctFrame.Left)
rctFrame.Bottom = rctFrame.Bottom + Abs(rctFrame.Top)
rctFrame.Top = 0
rctFrame.Left = 0
hClient = CreateRectRgn(rctClient.Left, rctClient.Top, rctClient.Right, rctClient.Bottom)
hFrame = CreateRectRgn(rctFrame.Left, rctFrame.Top, rctFrame.Right, rctFrame.Bottom)
CombineRgn hFrame, hClient, hFrame, RGN_XOR
SetWindowRgn mHwnd, hFrame, True
End Sub
Private Sub UserControl_Initialize()
MakeTransparent pic.hWnd
MakeTransparent UserControl.hWnd
End Sub'可问题也解决不了