用一般方法创建的控件形状都为方形的,即使把它设置为透明 如何创建像Line一样的控件(控件的形状不规则),使点到控件以外的地方时,不触发事件分不够再加

解决方案 »

  1.   

    不明白你想要什么。干脆添加line控件不就可以了????
    你是不是想做一个空心的按钮或者不规则形状控件之类????网上很多例子。
      

  2.   

    回复人: LicStar(利星) ( ) 信誉:100  2004-07-11 18:05:00  得分: 0  
     
     
       我想做一个曲线控件 回复人: kmzs(.:RNPA:.山水岿濛) ( ) 信誉:105  2004-07-11 20:22:00  得分: 0  
     
     
       曾经见过椭圆按钮空间,不知道是不是VB做得
    ===================================================
    相对来说,“椭圆 ”其实也是有规则的,所以实现起来并不难方法可参考:
    http://vbworld.sxnw.gov.cn/articles/api/tvb54.html。
    文章里介绍的是怎么做一些特殊形状的窗体,如果想做特殊形状的控件,只要把窗体的句柄改为控件的句柄就基本可以了。
    而更进一步的,是实现真正的完全不规则窗体,代码可参考:
    http://www.moon-soft.com/download/other/j011.zip
    而再更进一步的,是在2000、xp下制作半透明的异形窗体。代码上google找找吧应该有的
     
      
     
      
     
      

  3.   

    而再更进一步的,是在2000、xp下制作半透明的异形窗体
    ===============================================WS_EX_LAYERED 不能被用在子窗口上。
      

  4.   

    而更进一步的,是实现真正的完全不规则窗体,代码可参考:
    http://www.moon-soft.com/download/other/j011.zip
      

  5.   

    真正的不规则窗体来了,大家看看我的代码哦,不灵别给分
    在你的窗体上放一个PICTUREBOX控件,再放一个COMMDIALOG控件,将窗体和PICTUREBOX的SCALEMODE属性设为PIXEL,然后将下面的代码贴进去就可以了
    Option ExplicitPrivate Type Position
       X As Long
       Y As Long
    End TypeDim MoveFrom As Position
    Dim Dot(100000) As Position
    Dim OldWindow(3) As Position   'Put the original size of form
    Dim DotNumber As Long          'The number of Dots in the Poly line
    Dim DXY(7) As Position         'The offset x,y if each deriction
    Dim Direction As Long
    Dim BKCOLOR As Long            'The BASE-Color, it must be defferent to the color of the edge
    Const GrayDeff As Long = 150   'The defference of Color-Gray between the BASE-Color and the EDGE-Color
    Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As Any, 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 Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Private Sub Command1_Click()
    End SubPrivate Sub Form_Load()
    BKCOLOR = Me.BackColor
    DXY(0).X = 0
    DXY(0).Y = -1
    DXY(1).X = 1
    DXY(1).Y = -1
    DXY(2).X = 1
    DXY(2).Y = 0
    DXY(3).X = 1
    DXY(3).Y = 1
    DXY(4).X = 0
    DXY(4).Y = 1
    DXY(5).X = -1
    DXY(5).Y = 1
    DXY(6).X = -1
    DXY(6).Y = 0
    DXY(7).X = -1
    DXY(7).Y = -1
    With Me
       OldWindow(0).X = .ScaleLeft
       OldWindow(0).Y = .ScaleTop
       OldWindow(1).X = .ScaleLeft + .ScaleWidth
       OldWindow(1).Y = .ScaleTop
       OldWindow(2).X = .ScaleLeft + .ScaleWidth
       OldWindow(2).Y = .ScaleTop + .ScaleHeight
       OldWindow(3).X = .ScaleLeft
       OldWindow(3).Y = .ScaleTop + .ScaleHeight
    End With
    End SubPrivate Function FirstDot(ByVal X As Long, ByVal Y As Long) As Boolean
    Dim X1 As Long
    Dim Y1 As Long
    Dim Wid As Long
    Dim Hei As Long
    Dim Col As Long
    On Error Resume Next
    With Picture1
       BKCOLOR = .Point(X, Y)
       Wid = .Width - 1
       Hei = .Height - 1
       For X1 = X To Wid   '扫描第一个点的位置,注意:这里是先从上到下,再从左到右,所以开始Direction的初始值是4
          For Y1 = Y To Hei
             Col = .Point(X1, Y1)
             If GetDeff(Col, BKCOLOR) > GrayDeff Then
                Dot(0).X = X1          '第一个点的DotNumber总是0
                Dot(0).Y = Y1          '所以直接写0而不写DotNumber了
                GoTo Find
             Else
                BKCOLOR = Col
             End If
          Next
       Next
    Find:
       DotNumber = 1
       Direction = 4
    End With
    End FunctionPrivate Sub SeekEdge()
    Dim DX As Long
    Dim DY As Long
    Dim I As Long
    Dim L As Long
    Dim LastDirection As Long
    Dim Col As Long
    LastDirection = 0
    L = 0
    Do
       Direction = (Direction + 4) Mod 8   '在开始下以点的查找前,必须先把探测方向转180度
       For I = 0 To 7
          Direction = (Direction + 1) Mod 8
          Dot(DotNumber).X = Dot(L).X + DXY(Direction).X
          Dot(DotNumber).Y = Dot(L).Y + DXY(Direction).Y
          If GetDeff(Picture1.Point(Dot(DotNumber).X, Dot(DotNumber).Y), BKCOLOR) > GrayDeff Then Exit For
       Next
       If Direction <> LastDirection Then   '同方向点判断和压缩
          L = DotNumber
          DotNumber = L + 1
          LastDirection = Direction
       Else
          Dot(L).X = Dot(DotNumber).X
          Dot(L).Y = Dot(DotNumber).Y
          'DotNumber = L
       End If
    Loop Until Dot(DotNumber).X = Dot(0).X And Dot(DotNumber).Y = Dot(0).Y Or DotNumber > 99999
    End SubPrivate Sub PolyWindow(ByVal Restore As Boolean)
    Dim HRgn As Long          'HWND of Region
    If Restore Then
       HRgn = CreatePolygonRgn(OldWindow(0), 4, 1)
       Picture1.Cls
    Else
       HRgn = CreatePolygonRgn(Dot(0), DotNumber, 1)
       MsgBox "Dot Number:" & DotNumber
    End If
    SetWindowRgn Me.hWnd, HRgn, True
    DeleteObject HRgn
    End SubPrivate Sub PolyLine()
    Dim I As Long
    Picture1.DrawMode = 7
    Picture1.DrawWidth = 1
    Picture1.AutoRedraw = True
    For I = 1 To DotNumber
       Picture1.Line (Dot(I - 1).X, Dot(I - 1).Y)-(Dot(I).X, Dot(I).Y)
    Next
    Picture1.DrawMode = 13
    Picture1.DrawWidth = 2
    Picture1.Refresh
    End SubPrivate Function GetDeff(ByVal Col As Long, ByVal BKCol As Long) As Long
    GetDeff = Abs((Col Mod 256) - (BKCol Mod 256))
    GetDeff = GetDeff + Abs((Col \ 256 Mod 256) - (BKCol \ 256 Mod 256))
    GetDeff = GetDeff + Abs((Col \ 65536) - (BKCol \ 65536))
    End FunctionPrivate Sub Picture1_DblClick()
    FirstDot MoveFrom.X, MoveFrom.Y
    SeekEdge
    'PolyLine
    PolyWindow DotNumber < 3
    End SubPrivate Sub Picture1_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim A As String
    If KeyCode = 13 Then
       CommonDialog1.ShowOpen
       A = CommonDialog1.FileName
       If Trim(A) <> "" Then
          Picture1.Picture = LoadPicture(A)
          With Me
             .Width = Picture1.Width / 1024 * 1440 * 12 '* 0.715
             .Height = Picture1.Height / 768 * 1440 * 9 '* 0.715
             OldWindow(0).X = .ScaleLeft
             OldWindow(0).Y = .ScaleTop
             OldWindow(1).X = .ScaleLeft + .ScaleWidth
             OldWindow(1).Y = .ScaleTop
             OldWindow(2).X = .ScaleLeft + .ScaleWidth
             OldWindow(2).Y = .ScaleTop + .ScaleHeight
             OldWindow(3).X = .ScaleLeft
             OldWindow(3).Y = .ScaleTop + .ScaleHeight
          End With
       End If
    End If
    PolyWindow True
    End SubPrivate Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    MoveFrom.X = X
    MoveFrom.Y = Y
    End SubPrivate Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim Col As Long
    Col = Picture1.Point(X, Y)
    Picture1.ToolTipText = X & ":" & Y & " >>" & GetDeff(Col, 0)
    End SubPrivate Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim MoveTo As Position
    If Button = 1 Then
       With Me
          MoveTo.X = .Left + (X - MoveFrom.X) / 1024 * 1440 * 12 * 0.715  '15寸显示器宽为12寸,因为实际尺寸不到15寸所以要比实际少点
          MoveTo.Y = .Top + (Y - MoveFrom.Y) / 768 * 1440 * 9 * 0.715     '15寸显示器宽为9寸
          .Move MoveTo.X, MoveTo.Y
          'MsgBox .Left & "  " & .Top
       End With
    End If
    If Button = 2 Then
       Picture1.Line (MoveFrom.X, MoveFrom.Y)-(X, Y)
    End If
    End Sub'说明一下,这个程序有几个地方我偷懒了,一是移动无界面窗体的办法,因为我懒得查API就自己写了个土办法,可能显示器不是15寸的朋友在移动的时候会有点偏差。二是PictureBox控件中加载的图片不要太花哨,对比度要大一些,否则可能会裁下来很小很小的一个窗体,甚至小到你这个窗体只有1个像素,到时候找不到你的窗体可别怪我哦。对啦,差点忘了,鼠标双击图片的不同部位可以得到不同的裁剪效果。对着图片按着鼠标右键拖放,可以画一条直线,对着图片按键盘可以加载其他图片。
    这个程序我使用了行程压缩的方法,所以比一般算法得到的不规则窗体的关键点少很多,可以加快执行的速度,但是因为我使用的边界探测算法不好,所以有的时候会因为找不到边界点造成死循环(建议大家用卡通画之类边界明显的图片来试会得到非常好的效果),这不,我这里已经死循环了,要是有哪位高手可以给个好点的边界探测的算法,将不胜感激!对了,贴在这里或发信息给我都行!