控件随窗体大小而变化

 '当窗体大小改变时,如何动态的改变控件的大小是许多VB程序员头痛的  
  '事。有的人设置窗体Resizable但却不改变控件的大小;有的人则根据控件的  
  '绝对位置与窗口大小相加减的办法来重新定位控件与改变大小,这种办法比  
  '较繁琐,且不可重用;当然也有人则限定窗口干脆不让改变。  
  '下面给出一个一劳永逸的办法,源程序如下:  
   
  Private   FormOldWidth   As   Long  
  '原始宽度  
  Private   FormOldHeight   As   Long  
  '原始高度  
   
  '在调用ResizeForm前先调用本函数  
  Public   Sub   ResizeInit(FormName   As   Form)  
  Dim   Obj   As   Control  
  FormOldWidth   =   FormName.ScaleWidth  
  FormOldHeight   =   FormName.ScaleHeight  
  On   Error   Resume   Next  
  For   Each   Obj   In   FormName  
  Obj.Tag   =   Obj.Left   &   "   "   &   Obj.Top   &   "   "   &   Obj.Width   &   "   "   &   Obj.Height   &   "   "  
  Next   Obj  
  On   Error   GoTo   0  
  End   Sub  
   
  '按比例改变表单内各元件的大小,  
  '在调用ReSizeForm前先调用ReSizeInit函数  
  Public   Sub   ResizeForm(FormName   As   Form)  
  Dim   Pos(4)   As   Double  
  Dim   i   As   Long,   TempPos   As   Long,   StartPos   As   Long  
  Dim   Obj   As   Control  
  Dim   ScaleX   As   Double,   ScaleY   As   Double  
   
  ScaleX   =   FormName.ScaleWidth   /   FormOldWidth  
  '保存窗体宽度缩放比例  
  ScaleY   =   FormName.ScaleHeight   /   FormOldHeight  
  '保存窗体高度缩放比例  
  On   Error   Resume   Next  
  For   Each   Obj   In   FormName  
  StartPos   =   1  
  For   i   =   0   To   4  
  '读取控件的原始位置与大小  
   
  TempPos   =   InStr(StartPos,   Obj.Tag,   "   ",   vbTextCompare)  
  If   TempPos   >   0   Then  
  Pos(i)   =   Mid(Obj.Tag,   StartPos,   TempPos   -   StartPos)  
  StartPos   =   TempPos   +   1  
  Else  
  Pos(i)   =   0  
  End   If  
  '根据控件的原始位置及窗体改变大小  
  '的比例对控件重新定位与改变大小  
  Obj.Move   Pos(0)   *   ScaleX,   Pos(1)   *   ScaleY,   Pos(2)   *   ScaleX,   Pos(3)   *   ScaleY  
  Next   i  
  Next   Obj  
  On   Error   GoTo   0  
  End   Sub  
   
  Private   Sub   Form_Load()  
  Call   ResizeInit(Me)   '在装入时必须加入  
  End   Sub  
   
  Private   Sub   Form_Resize()  
    Call   ResizeForm(Me)   '控件随之改变  
  End   Sub  
   
  方法二  
   
    WINDOWS下的窗口一般都可以通过鼠标拖动来扩   大,有些时候我们需要控制窗口的比例不变,以防窗口比例失调时造成界面的不协调。要做   到这一点,可以利用API函数CallWindwosProc,当得到用户调整窗口的消息时,判断X或Y方   向上的比例是否和原来的比例一样,如果不一样,则调整为一样。下面是一个例子。    
  Private   Sub   Command1_Click()  
  UnloadMe  
  EndSub  
   
  Private   Sub   Form_Load()  
  OldWindowProc=SetWindowLong(hwnd,GWL_WNDPROC,AddressOf   NewWindowProc)  
  EndSub  
   
  模块中:    
   
  Public   OldWindowProc   As   Long  
  声明API函数如下:  
  Declare   Function   CallWindowProc   Lib"user32"Alias"CallWindowProcA"(ByVal   lpPrevWndFunc   As    
  Long,ByVal   hwnd   As   Long,ByValmsg   As   Long,ByVal   wParam   As   Long,lParam   As   WINDOWPOS)As   Long  
  Declare   Function   SetWindowLong   Lib   "user32"Alias"SetWindowLongA"   (alhwnd   As    
  Long,ByValnIndex   As   Long,ByVal   dwNewLong   As   Long)As   Long  
   
  Const   GWL_WNDPROC=-4  
  定义一个窗口位置数据类型  
  Type   WINDOWPOS  
  hwnd   As   Long  
  hWndInsertAfter   As   Long  
  x   As   Long  
  y   As   Long  
  cx   As   Long  
  cy   As   Long  
  flags   As   Long  
  End   Type  
  Const   WM_WINDOWPOSCHANGING=&H46  
  Const   WM_WINDOWPOSCHANGED=&H47  
  处理窗口变化的函数  
  PublicFunctionNewWindowProc(ByVal   hwnd   As   Long,ByVal   msg   As   Long,ByVal   wParam   As    
  Long,lParam   As   WINDOWPOS)As   Long  
  Static   done_before   As   Boolean  
  Static   aspect   As   Single  
  Dim   new_aspect   As   Single  
   
  If   msg=WM_WINDOWPOSCHANGING   Then  
  If   lParam.cy>0   Then  
  保存原来的比例  
  If   Notdone_before   Then  
  aspect=lParam.cx/lParam.cy  
  done_before=True  
  End   If  
   
  new_aspect=lParam.cx/lParam.cy  
  If   new_aspect>aspect   Then  
  lParam.cy=lParam.cx/aspect  
  Else  
  lParam.cx=aspect*lParam.cy  
  End   If  
  End   If  
  End   If  
   
  NewWindowProc=CallWindowProc  
  (OldWindowProc,hwnd,msg,wParam,lParam)  
   
  End   Function  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VB窗体控件大小窗体大小变化自動調整 有时窗体变化后,如改变分辨率后控件大小却不能随之改变。手工代码调整实在麻烦,下面的模块实现自动查找窗体控件并使其改变大小以适应窗体变化。 在Form的Resize事件中调用函数Resize_All就能实现控件自动调整大小,如: Private Sub Form_Resize() Dim H, i As Integer On Error Resume Next Resize_ALL Me 'Me是窗体名,Form1,Form2等等都可以 End Sub 在模块中添加以下代码: Public Type ctrObj Name As String Index As Long Parrent As String Top As Long Left As Long Height As Long Width As Long ScaleHeight As Long ScaleWidth As Long End Type Private FormRecord() As ctrObj Private ControlRecord() As ctrObj Private bRunning As Boolean Private MaxForm As Long Private MaxControl As Long Private Const WM_NCLBUTTONDOWN = &HA1 Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function ReleaseCapture Lib "USER32" () As Long Function ActualPos(plLeft As Long) As Long If plLeft < 0 Then ActualPos = plLeft + 75000 Else ActualPos = plLeft End If End Function Function FindForm(pfrmIn As Form) As Long Dim i As Long FindForm = -1 If MaxForm > 0 Then For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then FindForm = i Exit Function End If Next i End If End Function Function AddForm(pfrmIn As Form) As Long Dim FormControl As Control Dim i As Long ReDim Preserve FormRecord(MaxForm + 1) FormRecord(MaxForm).Name = pfrmIn.Name FormRecord(MaxForm).Top = pfrmIn.Top FormRecord(MaxForm).Left = pfrmIn.Left FormRecord(MaxForm).Height = pfrmIn.Height FormRecord(MaxForm).Width = pfrmIn.Width FormRecord(MaxForm).ScaleHeight = pfrmIn.ScaleHeight FormRecord(MaxForm).ScaleWidth = pfrmIn.ScaleWidth AddForm = MaxForm MaxForm = MaxForm + 1 For Each FormControl In pfrmIn i = FindControl(FormControl, pfrmIn.Name) If i < 0 Then i = AddControl(FormControl, pfrmIn.Name) End If Next FormControl End Function Function FindControl(inControl As Control, inName As String) As Long Dim i As Long FindControl = -1 For i = 0 To (MaxControl - 1) If ControlRecord(i).Parrent = inName Then If ControlRecord(i).Name = inControl.Name Then On Error Resume Next If ControlRecord(i).Index = inControl.Index Then FindControl = i Exit Function End If On Error GoTo 0 End If End If Next i End Function Function AddControl(inControl As Control, inName As String) As Long ReDim Preserve ControlRecord(MaxControl + 1) On Error Resume Next ControlRecord(MaxControl).Name = inControl.Name ControlRecord(MaxControl).Index = inControl.Index ControlRecord(MaxControl).Parrent = inName If TypeOf inControl Is Line Then ControlRecord(MaxControl).Top = inControl.Y1 ControlRecord(MaxControl).Left = ActualPos(inControl.X1) ControlRecord(MaxControl).Height = inControl.Y2 ControlRecord(MaxControl).Width = ActualPos(inControl.X2) Else ControlRecord(MaxControl).Top = inControl.Top ControlRecord(MaxControl).Left = ActualPos(inControl.Left) ControlRecord(MaxControl).Height = inControl.Height ControlRecord(MaxControl).Width = inControl.Width End If inControl.IntegralHeight = False On Error GoTo 0 AddControl = MaxControl MaxControl = MaxControl + 1 End Function Function PerWidth(pfrmIn As Form) As Long Dim i As Long i = FindForm(pfrmIn) If i < 0 Then i = AddForm(pfrmIn) End If PerWidth = (pfrmIn.ScaleWidth * 100) \ FormRecord(i).ScaleWidth End Function Function PerHeight(pfrmIn As Form) As Double Dim i As Long i = FindForm(pfrmIn) If i < 0 Then i = AddForm(pfrmIn) End If PerHeight = (pfrmIn.ScaleHeight * 100) \ FormRecord(i).ScaleHeight End Function Public Sub ResizeControl(inControl As Control, pfrmIn As Form) On Error Resume Next Dim i As Long Dim widthfactor As Single, heightfactor As Single Dim minFactor As Single Dim yRatio, xRatio, lTop, lLeft, lWidth, lHeight As Long yRatio = PerHeight(pfrmIn) xRatio = PerWidth(pfrmIn) i = FindControl(inControl, pfrmIn.Name) If inControl.Left < 0 Then lLeft = CLng(((ControlRecord(i).Left * xRatio) \ 100) - 75000) Else lLeft = CLng((ControlRecord(i).Left * xRatio) \ 100) End If lTop = CLng((ControlRecord(i).Top * yRatio) \ 100) lWidth = CLng((ControlRecord(i).Width * xRatio) \ 100) lHeight = CLng((ControlRecord(i).Height * yRatio) \ 100) If TypeOf inControl Is Line Then If inControl.X1 < 0 Then inControl.X1 = CLng(((ControlRecord(i).Left * xRatio) \ 100) - 75000) Else inControl.X1 = CLng((ControlRecord(i).Left * xRatio) \ 100) End If inControl.Y1 = CLng((ControlRecord(i).Top * yRatio) \ 100) If inControl.X2 < 0 Then inControl.X2 = CLng(((ControlRecord(i).Width * xRatio) \ 100) - 75000) Else inControl.X2 = CLng((ControlRecord(i).Width * xRatio) \ 100) End If inControl.Y2 = CLng((ControlRecord(i).Height * yRatio) \ 100) Else inControl.Move lLeft, lTop, lWidth, lHeight inControl.Move lLeft, lTop, lWidth inControl.Move lLeft, lTop End If End Sub Public Sub ResizeForm(pfrmIn As Form) Dim FormControl As Control Dim isVisible As Boolean Dim StartX, StartY, MaxX, MaxY As Long Dim bNew As Boolean If Not bRunning Then bRunning = True If FindForm(pfrmIn) < 0 Then bNew = True Else bNew = False End If If pfrmIn.Top < 30000 Then isVisible = pfrmIn.Visible On Error Resume Next If Not pfrmIn.MDIChild Then On Error GoTo 0 ' ' pfrmIn.Visible = False Else If bNew Then StartY = pfrmIn.Height StartX = pfrmIn.Width On Error Resume Next For Each FormControl In pfrmIn If FormControl.Left + FormControl.Width + 200 > MaxX Then MaxX = FormControl.Left + FormControl.Width + 200 End If If FormControl.Top + FormControl.Height + 500 > MaxY Then MaxY = FormControl.Top + FormControl.Height + 500 End If If FormControl.X1 + 200 > MaxX Then MaxX = FormControl.X1 + 200 End If If FormControl.Y1 + 500 > MaxY Then MaxY = FormControl.Y1 + 500 End If If FormControl.X2 + 200 > MaxX Then MaxX = FormControl.X2 + 200 End If If FormControl.Y2 + 500 > MaxY Then MaxY = FormControl.Y2 + 500 End If Next FormControl On Error GoTo 0 pfrmIn.Height = MaxY pfrmIn.Width = MaxX End If On Error GoTo 0 End If For Each FormControl In pfrmIn ResizeControl FormControl, pfrmIn Next FormControl On Error Resume Next If Not pfrmIn.MDIChild Then On Error GoTo 0 pfrmIn.Visible = isVisible Else If bNew Then pfrmIn.Height = StartY pfrmIn.Width = StartX For Each FormControl In pfrmIn ResizeControl FormControl, pfrmIn Next FormControl End If End If On Error GoTo 0 End If bRunning = False End If End Sub Public Sub SaveFormPosition(pfrmIn As Form) Dim i As Long If MaxForm > 0 Then For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then FormRecord(i).Top = pfrmIn.Top FormRecord(i).Left = pfrmIn.Left FormRecord(i).Height = pfrmIn.Height FormRecord(i).Width = pfrmIn.Width Exit Sub End If Next i AddForm (pfrmIn) End If End Sub Public Sub RestoreFormPosition(pfrmIn As Form) Dim i As Long If MaxForm > 0 Then For i = 0 To (MaxForm - 1) If FormRecord(i).Name = pfrmIn.Name Then If FormRecord(i).Top < 0 Then pfrmIn.WindowState = 2 ElseIf FormRecord(i).Top < 30000 Then pfrmIn.WindowState = 0 pfrmIn.Move FormRecord(i).Left, FormRecord(i).Top, FormRecord(i).Width, FormRecord(i).Height Else pfrmIn.WindowState = 1 End If Exit Sub End If Next i End If End Sub Public Sub Resize_ALL(Form_Name As Form) Dim OBJ As Object For Each OBJ In Form_Name ResizeControl OBJ, Form_Name Next OBJ End Sub Public Sub DragForm(frm As Form) On Local Error Resume Next Call ReleaseCapture Call SendMessage(frm.hwnd, WM_NCLBUTTONDOWN, 2, 0) End Sub

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值