返回列表 发帖

[讨论]关于用VB创建不规则窗体

以下是在网上搜到的资料: 偶以前在书上也见过,但只能用画方啊圆的来组合,感觉不太爽! 偶还见过一种方法,是导入一幅图片,通过扫描某种图片里面没有的像素色,然后留下的部分就是图像。但偶忘记API函数了,请达人指教!
普通的窗体都是方方的,使用API函数可以做出一些奇怪的形状。比如,窗体是圆角矩形,在中间挖一个椭圆形的洞。 先要理解一个重要的概念:区域。区域是描述设备场景中某一块的GDI对象,每个区域都有一个句柄。一个区域可以是矩形,也可以是复杂的多边形,甚至是几个区域组织在一起。窗体默认的区域就是我们看到的矩形,当然它并非一定要用这个默认的区域 现在开始,首先在窗体上做一个圆角矩形区域,这是窗体的大致轮廓。在圆角矩形里再确定一个椭圆形的区域,然后把这两个区域组织成一个区域,并设置窗体的区域为这个组织出来的区域。 CreateRoundRectRgn函数用于创建一个圆角矩形区域;CreateEllipticRgn用于创建一个椭圆区域;CombineRgn函数用于将两个区域组合为一个新区域;SetWindowRgn函数允许您改变窗口的区域。使用其他的函数还可以做出其他更奇怪的窗体。 源代码如下: Option Explicit '; API 函数声明 Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long 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 CombineRgn Lib "gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode 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 Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long ';常数声明 Private Const RGN_DIFF = 4 '; 目标区域被设置为两个区域不相交的部分 ';模块级变量声明 Private OutRgn As Long '; 外边的圆角矩形区域 Private InRgn As Long '; 里边的椭圆区域 Private MyRgn As Long '; 圆角区域剪切掉椭圆区域后的区域,也是窗体最终的形状 Private Sub Form_Click() If OutRgn <> 0 And InRgn <> 0 And MyRgn <> 0 Then Exit Sub Dim w As Long, h As Long w = ScaleX(Form1.Width, vbTwips, vbPixels) h = ScaleY(Form1.Height, vbTwips, vbPixels) MyRgn = CreateRectRgn(0, 0, 0, 0) OutRgn = CreateRoundRectRgn(30, 30, w - 30, h - 30, 100, 100) InRgn = CreateEllipticRgn(100, 100, w - 100, h - 100) Call CombineRgn(MyRgn, OutRgn, InRgn, RGN_DIFF) Call SetWindowRgn(Form1.hWnd, MyRgn, True) Form1.BackColor = QBColor(4) End Sub Private Sub Form_DblClick() Unload Form1 End Sub Private Sub Form_Load() OutRgn = 0 InRgn = 0 MyRgn = 0 Form1.Width = 7800 Form1.Height = 6000 End Sub Private Sub Form_Unload(Cancel As Integer) If MyRgn <> 0 Then DeleteObject MyRgn If OutRgn <> 0 Then DeleteObject OutRgn If InRgn <> 0 Then DeleteObject InRgn End Sub 这个程序运行后,在窗体上单击,窗体就会变形,双击窗体程序结束。要注意的是,在卸载窗体时,用DeleteObject函数删除已定义的区域。

[讨论]关于用VB创建不规则窗体

唉,偶只能玩VB这种玩具了。。。。。。。
.Net计划学习中。不过不知道排到哪个时间去了!

TOP

[讨论]关于用VB创建不规则窗体

VB像玩具语言似的,从某种角度看,也确实是这样的;
不过VB.NET确实是和C&#35;同样强大的.NET开发语言。有些人说它更强大。

TOP

[讨论]关于用VB创建不规则窗体

API在MS VS里面来说应该是通用的吧,兄弟能不能给个C++下的解决方案呢?

TOP

[讨论]关于用VB创建不规则窗体

偶不会VB,所以看不懂你的贴子。我一开始学的就是VB.net。
就像我没学C语言,但一开始就学C++一样。
其实VB和VB.net相差很大,基本上就不是同一个编程语言了。VB许多功能还是由API函数来完成的,VB.net已经不存在API函数了,除非你自己把它的命名空间导进去。VB.net集成的强大功能,许多事件都非常完善。用半个小时写的程序,换用C++,说不定要折腾一天时间。

TOP

[讨论]关于用VB创建不规则窗体

偶用以下代码实现了部分功能,但还有问题。
就是当我用屏幕热拷贝截图的时候,窗体的真实颜色就出来了,体现不出透明的效果!
制作半透明窗体和形状不规则的窗体
函数SetLayeredWindowAttributes
  使用这个函数,可以轻松的实现半透明窗体。按照微软的要求,透明窗体窗体在创建时应使用WS_EX_LAYERED参数(用CreateWindowEx),或者在创建后设置该参数(用SetWindowLong),我选用后者。全部函数、常量声明如下:
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
   其中hwnd是透明窗体的句柄,crKey为颜色值,bAlpha是透明度,取值范围是[0,255],dwFlags是透明方式,可以取两个值:当取值为LWA_ALPHA时,crKey参数无效,bAlpha参数有效;当取值为LWA_COLORKEY时,bAlpha参数有效而窗体中的所有颜色为crKey的地方将变为透明--这个功能很有用:我们不必再为建立不规则形状的窗体而调用一大堆区域分析、创建、合并函数了,只需指定透明处的颜色值即可,哈哈哈哈!请看具体代码。
Private Const WS_EX_LAYERED = &H80000
Private Const GWL_EXSTYLE = (-20)
Private Const LWA_ALPHA = &H2
Private Const LWA_COLORKEY = &H1
代码一:一个半透明窗体
Private Sub Form_Load()
  Dim rtn As Long
  rtn = GetWindowLong(hwnd, GWL_EXSTYLE)
  rtn = rtn Or WS_EX_LAYERED
  SetWindowLong hwnd, GWL_EXSTYLE, rtn
  SetLayeredWindowAttributes hwnd, 0, 200, LWA_ALPHA
End Sub
代码二:形状不规则的窗体
Private Sub Form_Load()
  Dim rtn As Long
  BorderStyler=0
  rtn = GetWindowLong(hwnd, GWL_EXSTYLE)
  rtn = rtn Or WS_EX_LAYERED
  SetWindowLong hwnd, GWL_EXSTYLE, rtn
  SetLayeredWindowAttributes hwnd, &HFF0000, 0, LWA_COLORKEY ';将扣去窗口中的蓝色
End Sub

TOP

返回列表 回复 发帖