?

解决方案 »

  1.   

    利用子类处理技术限制窗体的大小
     
    ' * * * * * * * * * * 警告 * * * * * * * * * * * * *
    ' 对以下代码进行修改将有可能导致不可预料的后果,甚至能使您的VB崩溃!
    ' 在VB IDE环境中运行本程序之前请先保存您的修改
    ' 不要使用断点调试模式,这将导致VB崩溃!
    ' * * * * * * * * * * 注意 * * * * * * * * * * * * *
    模块:
    Option ExplicitPublic OldWindowProc As Long
    Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    '从指定的窗口结构中取得信息
    '参数/类型 说明
    'hwnd(long): 欲为其获取信息的窗口的句柄
    'nIndex(long): 欲取回的信息,可以是下述任何一个常数
    'GWL_EXSTYLE:扩展窗口样式
    'GWL_STYLE:窗口样式
    'GWL_WNDPROC:该窗口的窗口函数的地址
    'GWL_HINSTANCE:拥有窗口的实例的句柄
    'GWL_HWNDPARENT:该窗口之父的句柄.不要用 SetWindowWord 来改变这个值
    'GWL_ID:对话框中一个子窗口的标识符
    'GWL_USERDATA:含义由应用程序规定
    '对话框亦可指定下列常数
    'DWL_DLGPROC:这个窗口的对话框函数地址
    'DWL_MSGRESULT:在对话框函数中处理的一条消息返回的值
    'DWL_USER:含义由应用程序规定
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    '在窗体结构中为指定的窗口设置信息
    '参数/类型 说明
    'hwnd(long) 欲为其获取信息的窗口的句柄
    'nIndex(long) 参考GetWindowLong函数
    'dwNewLong(long) 由nIndex指定的窗口信息的新值
    Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)
    '这就是在VisualBasic中处理指针的"短柄斧"--CopyMemory.你可能在API文档中找不到它,但它确实存在,并且功能异常强大
    '参数/类型 说明
    'pDest 你想写入字节到其中的任何变量的ByRef参数(地址)
    'pSource 要从其中进行复制的ByRef变量
    'ByteLen 要复制的字节数
    Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    '把控制权传回给原来的窗口过程
    Public Const WM_GETMINMAXINFO = &H24
    Type POINTAPI
      x As Long
      y As Long
    End Type
    ' This is the structure that is passed by reference(ByRef)(ie an address) to your message handler(消息侦听器)
    ' The key items in this structure are ptMinTrackSize and ptMaxTrackSize
    Type MINMAXINFO
      ptReserved As POINTAPI
      ptMaxSize As POINTAPI
      ptMaxPosition As POINTAPI
      ptMinTrackSize As POINTAPI
      ptMaxTrackSize As POINTAPI
    End Type
    Public Function SubClass1_WndMessage(ByVal hwnd As Long, ByVal Msg As Long, ByVal wp As Long, ByVal lp As Long) As Long
    ' Watch for the pertinent message to come in
      If Msg = WM_GETMINMAXINFO Then
        Dim MinMax As MINMAXINFO
    '  This is necessary because the structure was passed by its address and there
    '  is currently no intrinsic way to use an address in Visual Basic
        CopyMemory MinMax, ByVal lp, Len(MinMax)
    ' This is where you set the values of the MinX,MinY,MaxX, and MaxY
    ' The values placed in the structure must be in pixels. The values
    ' normally used in Visual Basic are in twips. The conversion is as follows:
    '  pixels = twips\twipsperpixel
        MinMax.ptMinTrackSize.x = 3975 \ Screen.TwipsPerPixelX
        MinMax.ptMinTrackSize.y = 1740 \ Screen.TwipsPerPixelY
        MinMax.ptMaxTrackSize.x = Screen.Width \ Screen.TwipsPerPixelX \ 2
        MinMax.ptMaxTrackSize.y = 3480 \ Screen.TwipsPerPixelY
    ' Here we copy the datastructure back up to the address passed in the parameters
    ' because Windows will look there for the information.
        CopyMemory ByVal lp, MinMax, Len(MinMax)
    ' This message tells Windows that the message was handled successfully
        SubClass1_WndMessage = 1
        Exit Function
      End If
    ' Here, we forward all irrelevant messages on to the default message handler.
      SubClass1_WndMessage = CallWindowProc(OldWindowProc, hwnd, Msg, wp, lp)
    End Function
      

  2.   

    我的意思是要在:left:100
    top:100
    widht:800
    height:200的区域内显示,楼上的代码,就我肤浅的理解好象是,left=0,top=0......
    问题就在这,我不知道怎样用代码指定left,top,height等的值,并且要在点击最大化时触发?
      

  3.   

    '模块代码
    Option Explicit
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
    Public 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)
    Public Const GWL_winsize = (-4)
    Public Const WM_GETMINMAXINFO = &H24
    Type POINTAPI
        x As Long
        y As Long
    End Type
    Type MINMAXINFO
        ptReserved As POINTAPI
        ptMaxSize As POINTAPI
        ptMaxPosition As POINTAPI
        ptMinTrackSize As POINTAPI
        ptMaxTrackSize As POINTAPI
    End Type
    Public Prewinsize As LongPublic Function winsize(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Dim lwd As Long, hwd As Long
        Dim maxwin As MINMAXINFO
        If Msg = WM_GETMINMAXINFO Then
            CopyMemory maxwin, ByVal lParam, Len(maxwin)
            maxwin.ptMaxTrackSize.x = 800 '设定最大Resize的宽度
            maxwin.ptMaxTrackSize.y = 200 '设定最大Resize的高度
            CopyMemory ByVal lParam, maxwin, Len(maxwin)
            winsize = 1
            Exit Function
        End If
        winsize = CallWindowProc(Prewinsize, hwnd, Msg, wParam, lParam)
     End Function'窗体代码
    Private Sub Command1_Click()
        Dim ret As Long
        '记录初始窗体状态
        Prewinsize = GetWindowLong(Me.hwnd, GWL_winsize)
        ret = SetWindowLong(Me.hwnd, GWL_winsize, AddressOf winsize)
        Me.Left = 100
        Me.Top = 100
    End Sub
      

  4.   

    找到了更好的办法
    Private Declare Function MoveWindow Lib "user32.dll" ( _
         ByVal hwnd As Long, _
         ByVal x As Long, _
         ByVal y As Long, _
         ByVal nWidth As Long, _
         ByVal nHeight As Long, _
         ByVal bRepaint As Long) As LongPrivate Sub Form_Resize()
        If Me.WindowState = 2 Then
            MoveWindow Me.hwnd, 100, 150, 200, 250, True
        End If
    End Sub