因要保持窗体大小鼠标可调的状态,在设计时边框设为2(可调)
但在运行时,它总有一个难看的边框,
也带来了无法精确拷贝窗体内容的问题(因边框也有宽度)
请问,如何在窗体运行时去掉边框?最好还能动态恢复 :)
是否用SetWindowLong?具体如何做?

解决方案 »

  1.   

    用Me.ScaleHeight,Me.ScaleWidth
    Private Sub Form_Load()
        Debug.Print Me.Height
        Debug.Print Me.Width
        Debug.Print Me.ScaleHeight
        Debug.Print Me.ScaleWidth
    End Sub
      

  2.   

    其实此问题也可称为:保持窗体鼠标可调大小的前提下,不显示边框。一般情况下,有边框的话,系统自动完成鼠标调整窗体大小
    但现在不显示边框,仍希望由系统自动完成。自编代码(MouseMove)虽然也能做到,只是有没有更方便的通用办法,交给系统做?
      

  3.   

    //也带来了无法精确拷贝窗体内容的问题(因边框也有宽度)像2楼说的那样,拷贝.Scale高度宽度。//保持窗体鼠标可调大小的前提下,不显示边框。用SETWINDOWLONG,我记得有个BORDER的窗体样式。你把它去掉看看。
      

  4.   

    //但在运行时,它总有一个难看的边框,其实我还没搞清楚这个框是什么东西。只有在边框样式为NONE的时候,窗体的宽度高度才会=窗体的Scale高度宽度。你是想让窗体在NONE的样式时有标题栏和RESIZE?
      

  5.   

    系统加这个框就是为了能自动捕捉鼠标的调整边框的事件(类似自编代码MouseMove)
    现试过用SETWINDOWLONG把窗体的ReSize去掉,这样边框是没有了,但同时也丧失了系统自动鼠标的调整边框的功能,:( 俺认为这个功能很重要现在有没有办法,在运行时>>>不显示<<<(而不是去掉)边框,仍能让系统自动捕捉鼠标调整事件?之所以不用Scale高度,是因为想让窗体外框显示为指定大小(为了和此窗体背后的大背景精确配合),同时拷贝窗体内部,但正如楼上所说,只有在边框样式为NONE的时候,窗体的宽度高度才会=窗体的Scale高度宽度。
    但又没了自动调整边框的功能 :(5555555 真是一对矛盾啊
      

  6.   

    转来的Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
    (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPrivate Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
    (ByVal hwnd As Long, ByVal nIndex As Long) As LongPrivate Const GWL_STYLE = (-16)
    Private Const WS_CAPTION = &HC00000     ' WS_BORDER 或 WS_DLGFRAME
    Private Const WS_MAXIMIZEBOX = &H10000
    Private Const WS_MINIMIZEBOX = &H20000
    Private Const WS_SYSMENU = &H80000Private Declare Function SetWindowPos Lib "user32" _
    (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
    ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As LongPrivate Enum ESetWindowPosStyles
        SWP_SHOWWINDOW = &H40
        SWP_HIDEWINDOW = &H80
        SWP_FRAMECHANGED = &H20 ' The frame changed: send WM_NCCALCSIZE
        SWP_NOACTIVATE = &H10
        SWP_NOCOPYBITS = &H100
        SWP_NOMOVE = &H2
        SWP_NOOWNERZORDER = &H200 ' Don't do owner Z ordering
        SWP_NOREDRAW = &H8
        SWP_NOREPOSITION = SWP_NOOWNERZORDER
        SWP_NOSIZE = &H1
        SWP_NOZORDER = &H4
        SWP_DRAWFRAME = SWP_FRAMECHANGED
        HWND_NOTOPMOST = -2
    End EnumPrivate Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End TypePrivate Function ShowTitleBar(ByVal bState As Boolean)
    Dim lStyle As Long
    Dim tR As RECT    ' 获取窗口的位置:
        GetWindowRect Me.hwnd, tR    ' 调整标题栏是否可见:
        lStyle = GetWindowLong(Me.hwnd, GWL_STYLE)
        If (bState) Then
        Me.Caption = Me.Tag
        If Me.ControlBox Then
            lStyle = lStyle Or WS_SYSMENU
        End If
        If Me.MaxButton Then
            lStyle = lStyle Or WS_MAXIMIZEBOX
        End If
        If Me.MinButton Then
            lStyle = lStyle Or WS_MINIMIZEBOX
        End If
        If Me.Caption <> "" Then
            lStyle = lStyle Or WS_CAPTION
        End If
        Else
        Me.Tag = Me.Caption
        Me.Caption = ""
        lStyle = lStyle And Not WS_SYSMENU
        lStyle = lStyle And Not WS_MAXIMIZEBOX
        lStyle = lStyle And Not WS_MINIMIZEBOX
        lStyle = lStyle And Not WS_CAPTION
    End If
    SetWindowLong Me.hwnd, GWL_STYLE, lStyle' 重新设定窗口:
    SetWindowPos Me.hwnd, 0, tR.Left, tR.Top, tR.Right - tR.Left, tR.Bottom - tR.Top, SWP_NOREPOSITION Or SWP_NOZORDER Or SWP_FRAMECHANGED
    Me.Refresh' 你可能需要在Form_Resize中加一点代码,因为客户区的大小已经改变:
    'Form_ResizeEnd Function
        '为了试验一下代码,在窗体上放一个CheckBox,将它的Value属性设为1 (Checked)。然后写入以下代码:Private Sub Check1_Click()
        If (Check1.Value = Checked) Then
        ShowTitleBar True
        Else
        ShowTitleBar False
    End If
    End Sub
      

  7.   

    呵呵,这个不是运行时去窗体标题嘛,但不是>>>隐藏<<<边框
      

  8.   

    Dim PrevX As Long, PrevY As LongPrivate Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
        PrevX = X: PrevY = Y
    End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If Button = 1 Then
            If Me.MousePointer = 0 Then
                Me.Move Me.Left + X - PrevX, Me.Top + Y - PrevY
            End If
            X = IIf(X <= 1200, 1200, X): Y = IIf(Y <= 900, 900, Y)
            Select Case Me.MousePointer
                Case 7: Me.Height = Y
                Case 8: Me.Width = X: Me.Height = Y
                Case 9: Me.Width = X
            End Select
        End If
        If Y > Me.ScaleHeight - 120 Then
            Me.MousePointer = IIf(X > Me.ScaleWidth - 120, 8, 7)
        Else
            Me.MousePointer = IIf(X > Me.ScaleWidth - 120, 9, 0)
        End If
    End Sub
      

  9.   

    楼上兄弟,自编代码完成大小调整初看起来不错。
    但进一步想想,却发现很多问题:
    有没有注意到系统的自动捕捉边框调整事件,是不区分前台与后台窗体的?
    就是说哪怕自己的窗体并不是前台的,也能在边框处显示不同鼠标指针。
    虽然说可以用SetCapture捕捉全局鼠标位置,但还要考虑到本窗体是否已显示,是否在前台,是否处于当中(否则的话,在前台窗体的当中出现调整指针,会让用户莫名其妙)
    还有一个问题,你这里是定死边框宽度的,而系统的窗体边框宽度是个“全局样式”是可调的,并且对于不同的分辨率有不同的换算比,那
    还有一个问题,系统在左上角是一定位于边框才捕捉事件的,而右下角则不同。
    另外,由于自编代码用到了ScaleWidth,意为着用户无法更改使用内部坐标了。
    总总问题,都无法让自编代码实现完美的通用性。
    看来,还是系统自己在这方面做的最好,那我们为啥不交给它呢?(这样可以多考虑程序其它功能嘛)
    所以,我的想法是,能否欺骗系统,在不显示边框的情况下,让它仍以为有边框,当鼠标处于合理位置时,自动完成调整事件?
      

  10.   

    楼主不用把技术问题转移成审美观的问题。什么叫做“一个难看的边框”,没有它才真不方便呢。想知道边框大小:
    1. 用 GetSystemMetrics()取各部分大小
    2. 用 API 的 GetWindowRect 和 GetClientRect,然后用 ClientToScreen 把后一个结果转化为屏幕坐标,比较一下两个矩形就很清楚了。