瑞星软件的助手狮子用Microsoft Agent Character Editor来做,微软的主页上有,设置一个颜色作为透明色就行了
Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, _ ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, _ ByVal hRgn As Long, ByVal bRedraw As Boolean) As LongPrivate Sub Form_Load() Show 'The form! SetWindowRgn hWnd, CreateEllipticRgn(0, 0, 300, 200), True End Sub上述代码可以创建一个椭圆形状的窗口。
用api: Public Declare Function CreatePolygonRgn Lib "gdi32" Alias "CreatePolygonRgn" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As LongPublic Declare Function SetWindowRgn Lib "user32" Alias "SetWindowRgn" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
一个T型窗口 Option ExplicitPrivate Type POINTAPI X As Long Y As Long End Type Dim XY() As POINTAPIPrivate Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long Private Sub cmdT_Click() Dim hRgn As Long Dim lRes As Long ReDim XY(7) As POINTAPI 'T shape has 8 points ' ' Points must be in order like connecting the dots. Start at the origin ' and following from point to point. You don't need to specify the origin ' point as the last entry. ' With Me XY(0).X = 0 XY(0).Y = 0 XY(1).X = .ScaleWidth XY(1).Y = 0 XY(2).X = .ScaleWidth XY(2).Y = .ScaleHeight / 2 XY(3).X = .ScaleWidth - (.ScaleWidth / 3) XY(3).Y = .ScaleHeight / 2 XY(4).X = .ScaleWidth - (.ScaleWidth / 3) XY(4).Y = .ScaleHeight XY(5).X = .ScaleWidth / 3 XY(5).Y = .ScaleHeight XY(6).X = .ScaleWidth / 3 XY(6).Y = .ScaleHeight / 2 XY(7).X = 0 XY(7).Y = .ScaleHeight / 2 End WithhRgn = CreatePolygonRgn(XY(0), 8, 2) lRes = SetWindowRgn(Me.hWnd, hRgn, True) End SubPrivate Sub cmdQuit_Click() Unload Me End SubPrivate Sub Form_Load() Me.ScaleMode = vbPixels End Sub
希望有更多的答案。up! 谢 谢 谢 谢 up有分
这个问题我感兴趣,暂时我只会使窗体变为XP风格的,可能也不算规则的. uo
'下面是我写的一个函数,其中用到的API可以在浏览器中查到 '作用是,将一幅图片(文件,或者资源)按照一个屏蔽色挖掉(缺省是0,0) '图片大的话有点慢Public Function ReDrawFormRegion(ByVal frmMe As Form, ByVal MyResource As REDRAW_RES_TYPE, ByVal varImage As Variant, Optional ByVal lngBackColor As Long = -1, Optional ByVal bReturnRegion As Boolean = False) As Long '重画窗体区域,可以使用屏蔽色来重新绘制窗体的区域 'frmMe传递欲重新绘制的窗体, 'bResource为True的时候是使用资源的字符串,为False的时候使用图像文件的路径 'varImage用来定义去掉屏蔽色的图像,可以使用资源或者文件 'lngBackColor传递屏蔽颜色,可以使用Point从窗体上取色 'bReturnRegion是否返回区域句柄,False为不返回,如果返回但是不设置窗体区域, '注意:如果返回区域句柄需要在适当的时候调用DeleteObject删除句柄指向的资源
'检查参数varImage '如果是文件检查文件是否存在 Select Case MyResource Case 0 '文件 If Dir(varImage) = "" Then Call Err.Raise(vbObjectError + 1600, "ReDrawFormRegion", "找不到文件" & CStr(varImage) & "!")
Case 1 '资源 '如果是资源检查是使用编号还是字符串,如果是编号就转换格式 If varImage <> "" Then If IsNumeric(varImage) Then varImage = CLng(varImage) Else Call Err.Raise(vbObjectError + 1601, "ReDrawFormRegion", "图片资源不可以使用空字符串标识!") End If
End Select
'定义窗体绘图的尺度为像素 frmMe.ScaleMode = vbPixels
'定义范围,用来获得窗体范围大小 Dim FormRect As RECT '获得窗体大小 Call GetWindowRect(frmMe.hwnd, FormRect)
'定义并创建一个DC,用来读取窗体上的颜色 Dim lngMyFormDC As Long lngMyFormDC = CreateCompatibleDC(frmMe.hdc) '将窗体的图像选进这个DC Dim lngMyFormBMP As Long
'打开资源并检查错误 On Error GoTo OpenResErrLabel '资源分为文件和资源文件两种 Select Case MyResource Case 0 '文件类型 '如果图片是来自文件 lngMyFormBMP = SelectObject(lngMyFormDC, LoadPicture(CStr(varImage)))
Case 1 '资源类型 '如果图片来自程序本身的资源 lngMyFormBMP = SelectObject(lngMyFormDC, LoadResPicture(varImage, vbResBitmap))
End Select On Error GoTo 0
'如果lngBackColor=-1那么就取左上角的坐标为屏蔽色 If lngBackColor = -1 Then lngBackColor = GetPixel(lngMyFormDC, 0, 0)
'定义两个区域 '定义整个窗体大小的区域,用来最后和窗体背景区域做XOR操作去掉背景 Dim lngFormRegion As Long '定义背景区域,用来描绘出来背景色lngBackColor覆盖的背景区 Dim lngBackgroundRegion As Long
'纵行扫描区域,检查DC中的颜色值 '定义对比的颜色值 Dim lngPixelColor As Long '定义拼装背景用的点区域 Dim lngPointRegion As Long '定义扫描时的X和Y的值 Dim x As Long Dim y As Long
'定义扫描线起始点X1,从X1到非屏蔽色止,一条线段一条线段的扫描 Dim X1 As Long X1 = -1
For y = 0 To FormRect.Bottom - FormRect.Top '按行扫描 For x = 0 To FormRect.Right - FormRect.Left '对每一个像素点进行对比 DoEvents '取得这一个点的颜色 lngPixelColor = GetPixel(lngMyFormDC, x, y)
'对比这个颜色和背景屏蔽色是否相同,并且是否不是左或者上边界 If lngPixelColor = lngBackColor Then '相同就将它加入到背景区域lngBackgroundRegion中 '创建这一点的区域,如果是左边界或者上边界左特殊处理 If x = 0 Or y = 0 Then X1 = 0 Else If X1 = -1 Then X1 = x + 1 End If Else '颜色值不同的时候,检查X1的值,如果不是-1就绘图 If X1 <> -1 Then '创建区域 lngPointRegion = CreateRectRgn(X1, IIf(y = 0, 0, y + 1), x + 2, y + 2)
中的
http://www.applevb.com/sourcecode/winrgn.zip
ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, _
ByVal hRgn As Long, ByVal bRedraw As Boolean) As LongPrivate Sub Form_Load()
Show 'The form!
SetWindowRgn hWnd, CreateEllipticRgn(0, 0, 300, 200), True
End Sub上述代码可以创建一个椭圆形状的窗口。
Public Declare Function CreatePolygonRgn Lib "gdi32" Alias "CreatePolygonRgn" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As LongPublic Declare Function SetWindowRgn Lib "user32" Alias "SetWindowRgn" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Option ExplicitPrivate Type POINTAPI
X As Long
Y As Long
End Type
Dim XY() As POINTAPIPrivate Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
Private Sub cmdT_Click()
Dim hRgn As Long
Dim lRes As Long
ReDim XY(7) As POINTAPI 'T shape has 8 points
'
' Points must be in order like connecting the dots. Start at the origin
' and following from point to point. You don't need to specify the origin
' point as the last entry.
'
With Me
XY(0).X = 0
XY(0).Y = 0
XY(1).X = .ScaleWidth
XY(1).Y = 0
XY(2).X = .ScaleWidth
XY(2).Y = .ScaleHeight / 2
XY(3).X = .ScaleWidth - (.ScaleWidth / 3)
XY(3).Y = .ScaleHeight / 2
XY(4).X = .ScaleWidth - (.ScaleWidth / 3)
XY(4).Y = .ScaleHeight
XY(5).X = .ScaleWidth / 3
XY(5).Y = .ScaleHeight
XY(6).X = .ScaleWidth / 3
XY(6).Y = .ScaleHeight / 2
XY(7).X = 0
XY(7).Y = .ScaleHeight / 2
End WithhRgn = CreatePolygonRgn(XY(0), 8, 2)
lRes = SetWindowRgn(Me.hWnd, hRgn, True)
End SubPrivate Sub cmdQuit_Click()
Unload Me
End SubPrivate Sub Form_Load()
Me.ScaleMode = vbPixels
End Sub
谢 谢 谢 谢
up有分
uo
'作用是,将一幅图片(文件,或者资源)按照一个屏蔽色挖掉(缺省是0,0)
'图片大的话有点慢Public Function ReDrawFormRegion(ByVal frmMe As Form, ByVal MyResource As REDRAW_RES_TYPE, ByVal varImage As Variant, Optional ByVal lngBackColor As Long = -1, Optional ByVal bReturnRegion As Boolean = False) As Long '重画窗体区域,可以使用屏蔽色来重新绘制窗体的区域
'frmMe传递欲重新绘制的窗体,
'bResource为True的时候是使用资源的字符串,为False的时候使用图像文件的路径
'varImage用来定义去掉屏蔽色的图像,可以使用资源或者文件
'lngBackColor传递屏蔽颜色,可以使用Point从窗体上取色
'bReturnRegion是否返回区域句柄,False为不返回,如果返回但是不设置窗体区域,
'注意:如果返回区域句柄需要在适当的时候调用DeleteObject删除句柄指向的资源
'检查参数varImage
'如果是文件检查文件是否存在
Select Case MyResource
Case 0 '文件
If Dir(varImage) = "" Then Call Err.Raise(vbObjectError + 1600, "ReDrawFormRegion", "找不到文件" & CStr(varImage) & "!")
Case 1 '资源
'如果是资源检查是使用编号还是字符串,如果是编号就转换格式
If varImage <> "" Then
If IsNumeric(varImage) Then varImage = CLng(varImage)
Else
Call Err.Raise(vbObjectError + 1601, "ReDrawFormRegion", "图片资源不可以使用空字符串标识!")
End If
End Select
'定义窗体绘图的尺度为像素
frmMe.ScaleMode = vbPixels
'定义范围,用来获得窗体范围大小
Dim FormRect As RECT
'获得窗体大小
Call GetWindowRect(frmMe.hwnd, FormRect)
'定义并创建一个DC,用来读取窗体上的颜色
Dim lngMyFormDC As Long
lngMyFormDC = CreateCompatibleDC(frmMe.hdc)
'将窗体的图像选进这个DC
Dim lngMyFormBMP As Long
'打开资源并检查错误
On Error GoTo OpenResErrLabel
'资源分为文件和资源文件两种
Select Case MyResource
Case 0 '文件类型
'如果图片是来自文件
lngMyFormBMP = SelectObject(lngMyFormDC, LoadPicture(CStr(varImage)))
Case 1 '资源类型
'如果图片来自程序本身的资源
lngMyFormBMP = SelectObject(lngMyFormDC, LoadResPicture(varImage, vbResBitmap))
End Select
On Error GoTo 0
'如果lngBackColor=-1那么就取左上角的坐标为屏蔽色
If lngBackColor = -1 Then lngBackColor = GetPixel(lngMyFormDC, 0, 0)
'定义两个区域
'定义整个窗体大小的区域,用来最后和窗体背景区域做XOR操作去掉背景
Dim lngFormRegion As Long
'定义背景区域,用来描绘出来背景色lngBackColor覆盖的背景区
Dim lngBackgroundRegion As Long
'初始化区域和窗体区域大小相同
With FormRect
lngFormRegion = CreateRectRgn(0, 0, .Right - .Left, .Bottom - .Top)
lngBackgroundRegion = CreateRectRgn(0, 0, .Right - .Left, .Bottom - .Top)
End With
'初始化背景区域为空区域,使用XOR合成区域
Call CombineRgn(lngBackgroundRegion, lngBackgroundRegion, lngBackgroundRegion, RGN_XOR)
'纵行扫描区域,检查DC中的颜色值
'定义对比的颜色值
Dim lngPixelColor As Long
'定义拼装背景用的点区域
Dim lngPointRegion As Long
'定义扫描时的X和Y的值
Dim x As Long
Dim y As Long
'定义扫描线起始点X1,从X1到非屏蔽色止,一条线段一条线段的扫描
Dim X1 As Long
X1 = -1
For y = 0 To FormRect.Bottom - FormRect.Top
'按行扫描
For x = 0 To FormRect.Right - FormRect.Left
'对每一个像素点进行对比
DoEvents
'取得这一个点的颜色
lngPixelColor = GetPixel(lngMyFormDC, x, y)
'对比这个颜色和背景屏蔽色是否相同,并且是否不是左或者上边界
If lngPixelColor = lngBackColor Then
'相同就将它加入到背景区域lngBackgroundRegion中
'创建这一点的区域,如果是左边界或者上边界左特殊处理
If x = 0 Or y = 0 Then
X1 = 0
Else
If X1 = -1 Then X1 = x + 1
End If
Else
'颜色值不同的时候,检查X1的值,如果不是-1就绘图
If X1 <> -1 Then
'创建区域
lngPointRegion = CreateRectRgn(X1, IIf(y = 0, 0, y + 1), x + 2, y + 2)
'用OR(并)合成区域
Call CombineRgn(lngBackgroundRegion, lngBackgroundRegion, lngPointRegion, RGN_OR)
'删除区域lngPointRegion
Call DeleteObject(lngPointRegion)
'设置X1=-1,停止记录
X1 = -1
End If
End If
Next x
'当一行扫描结束的时候,如果X1<>-1就绘图
If X1 <> -1 Then
'创建区域
lngPointRegion = CreateRectRgn(X1, y + 1, x + 2, y + 2)
'用OR(并)合成区域
Call CombineRgn(lngBackgroundRegion, lngBackgroundRegion, lngPointRegion, RGN_OR)
'删除区域lngPointRegion
Call DeleteObject(lngPointRegion)
'设置X1=-1,停止记录
X1 = -1
End If
Next y
'合成新的区域,将背景区域lngBackgroundRegion从区域lngFormRegion中去掉
Call CombineRgn(lngFormRegion, lngFormRegion, lngBackgroundRegion, RGN_XOR)
'删除已经无用的背景区域
Call DeleteObject(lngBackgroundRegion)
'设置函数返回值
ReDrawFormRegion = lngFormRegion
If Not bReturnRegion Then
'设置窗体新的区域并重绘
Call SetWindowRgn(frmMe.hwnd, lngFormRegion, True)
'删除创建的区域
Call DeleteObject(lngFormRegion)
End If
Exit Function
'错误处理
OpenResErrLabel:
Call Err.Raise(vbObjectError + 1602, "ReDrawFormRegion", "无法打开图片资源" & CStr(varImage) & "!")
End Function