用过 ActiveSkin 的朋友应该都知道,它在处理异形窗口的时候,速度是非常快的!
而我们在处理异形窗口的时候,不外乎以下两种方法:
1、用逐点扫描的方法寻找图片中的关键色来建立的异形窗口;
2、用 UserControl 的 MaskColor,MaskPicture 方法先形成异形窗体,然后用 GetWindowRgn 取得它的 hRgn,最后用 SetWindowRgn 来设置窗体的形状。这两种种方法在处理不能改变大小的窗体时还行,但是要做成类似 Windows Media Player 9.0 那种能改变大小的异形窗体就不行了。
我想请问的是,有什么办法能快速实现异形窗体呢?

解决方案 »

  1.   

    给你个过程:
    Public Function MakeRegion(picSkin As Form) As Long
        Dim X As Long, Y As Long, StartLineX As Long
        Dim FullRegion As Long, LineRegion As Long
        Dim TransparentColor As Long
        Dim InFirstRegion As Boolean
        Dim InLine As Boolean
        Dim hdc As Long
        Dim PicWidth As Long
        Dim PicHeight As Long
        hdc = picSkin.hdc
        PicWidth = picSkin.ScaleWidth
        PicHeight = picSkin.ScaleHeight
        InFirstRegion = True: InLine = False
        X = Y = StartLineX = 0
        TransparentColor = RGB(255, 0, 255)
        For Y = 0 To PicHeight - 1
            For X = 0 To PicWidth - 1
                If GetPixel(hdc, X, Y) = TransparentColor Or X = PicWidth Then
                    If InLine Then
                        InLine = False
                        LineRegion = CreateRectRgn(StartLineX, Y, X, Y + 1)
                    
                        If InFirstRegion Then
                            FullRegion = LineRegion
                            InFirstRegion = False
                        Else
                            CombineRgn FullRegion, FullRegion, LineRegion, RGN_OR
                            DeleteObject LineRegion
                        End If
                    End If
                Else
                    If Not InLine Then
                        InLine = True
                        StartLineX = X
                    End If
                End If
            Next
        Next
        MakeRegion = FullRegion
    End Function
    在这个过程中,使用粉红色(RGB(255,0,255))作为透明色。在窗体上打印出图片,然后用这个将透明部分去掉~最后用
    SetWindowRgn hWnd, MakeRegion(Me), True
    来重画窗体~
    另注:每行应至少有一个透明点,否则视为透明行,切记~
      

  2.   

    SetWindowRgn 是个API函数,具体声明去VB的APIViewer里面找吧~
      

  3.   

    里面还有几个API函数分别是:
    GetPixel
    CreateRectRgn
    CombineRgn
    DeleteObject
    具体声明自己找~就在APIViewer里~
      

  4.   

    当然用createRectgn来实现了,多数也是用它实现的,你所说的逐行扫描,
    和MaskPicture却是很不常用的两种。
    从没感觉自己写的异行窗口比activeskin慢,用它是因为它封装了很多其他控件,
    不仅仅是窗口。
      

  5.   

    能改变大小的异形窗口实现实际上也并不困难
    拖动边框的操作是可以通过响应 WM_NCHIT 消息的消息过程返回值来控制边界的放大缩小的
    大小改变后会产生 WM_SIZE 消息,你通过响应大小变化然后重新计算并 SetWindowRgn 并绘制就可以了
      

  6.   

    GetPixel?????用这个当然慢。至于楼主说的:1、用逐点扫描的方法寻找图片中的关键色来建立的异形窗口;更是完全不适合用在这里。试试GetBitmapBits之类吧
      

  7.   

    还有一种方法
    用.RGN 文件每次启动的时候都要去 逐点扫描 太慢了  所以把扫描结果保存成.rgn文件
    这样的话 每次启动的时候直接读取 
    速度快了N倍
      

  8.   

    对于固定大小的窗体来讲,“书林”说的.rgn文件是很好的选择。
    但楼主要是想设置可改变大小的窗体,.rgn文件似乎派不上用场了。在对图片进行扫描来建立区域时, 采纳lsftest() 的建议,用GetBitmapBits之类的函数将图像数据存入数组,而不要在每次循环中使用GetPixel,这样速度会有提升。
      

  9.   

    http://club.5ivb.net/dispbbs.asp?boardID=123&replyID=24751&ID=37267&skin=1把图片生成 rgn
    http://club.5ivb.net/UploadFile/200410217591byUID16686.zip读取rgn文件生成窗体 (vc版)
    http://club.5ivb.net/UploadFile/200410218659byUID16686.zip读取rgn文件生成窗体 (vb版)
    http://club.5ivb.net/UploadFile/200410218936byUID16686.rar
     songyaowu 说这种方法适应 固定大小的窗体
    其实是不一定的我曾写过保存用N个RGN文件在 RES文件里面 
    动态读取
    实现桌面精灵的效果 
      

  10.   

    用 GetBitmapBits 的方法,就是在每一次窗体大小改变后都要重新计算过一次,照样很慢。
    如果谁认为这样快的话可以亲自去试试看,下面的链接中有现成的代码,只需要生成不规则窗体了。
    谢谢 书林跋涉 提供的读取 RGN 文件的办法,但这只适合于固定大小的窗体。麻烦大家下载这个源码看看:
    www.zjjtour.com/tms/windows media player.rar
      

  11.   

    ft 谁说 RGN文件只适合固定大小的窗体了……可以读取N次 每次用不同的大小
    桌面精灵就可以这样实现……
      

  12.   

    www.zjjtour.com/tms/windows media player.rar
    ===================
    链接无效
      

  13.   

    回:书林跋涉
    你说的桌面精灵是可以很容易实现,可以做N多连续动作的图片的RGN,然后一个一个的读取。
    但是我所问的问题是一个可以改变大小的异形窗体,难道这样也只能把每一个大小图片的 RGN 都存在 资源文件里面??
      

  14.   

    地址在这里,那个错了
    http://club.5ivb.net/UploadFile/200571815547byUID43364.rar
      

  15.   

    To  liuning623哦,理解你的意思了
    可惜我还是不是很理解那个XFORM结构
    按那个结构的定义 应该是可以扩大倍数的
    这样的话就可以改变大小了……