home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / VBGUI_-_A_19412410172005.psc / Library / clsAnchor.cls next >
Text File  |  2005-10-18  |  14KB  |  322 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "CAnchor"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = True
  14. Option Explicit
  15.  
  16. Implements ISubclass
  17.  
  18. Private Const WM_WINDOWPOSCHANGED As Long = &H47
  19. Private Const WM_DESTROY As Long = &H2
  20. Private Const WM_NCDESTROY As Long = &H82
  21.  
  22. Private Const SPI_GETNONCLIENTMETRICS As Long = 41
  23.  
  24. Private Const LF_FACESIZE As Long = 32
  25.  
  26. Private Type RECT
  27.     Left As Long
  28.     Top As Long
  29.     Right As Long
  30.     Bottom As Long
  31. End Type
  32.  
  33. Private Type LOGFONT
  34.     lfHeight As Long
  35.     lfWidth As Long
  36.     lfEscapement As Long
  37.     lfOrientation As Long
  38.     lfWeight As Long
  39.     lfItalic As Byte
  40.     lfUnderline As Byte
  41.     lfStrikeOut As Byte
  42.     lfCharSet As Byte
  43.     lfOutPrecision As Byte
  44.     lfClipPrecision As Byte
  45.     lfQuality As Byte
  46.     lfPitchAndFamily As Byte
  47.     lfFaceName(1 To LF_FACESIZE) As Byte
  48. End Type
  49.  
  50. Private Type NONCLIENTMETRICS
  51.     cbSize As Long
  52.     iBorderWidth As Long
  53.     iScrollWidth As Long
  54.     iScrollHeight As Long
  55.     iCaptionWidth As Long
  56.     iCaptionHeight As Long
  57.     lfCaptionFont As LOGFONT
  58.     iSMCaptionWidth As Long
  59.     iSMCaptionHeight As Long
  60.     lfSMCaptionFont As LOGFONT
  61.     iMenuWidth As Long
  62.     iMenuHeight As Long
  63.     lfMenuFont As LOGFONT
  64.     lfStatusFont As LOGFONT
  65.     lfMessageFont As LOGFONT
  66. End Type
  67.  
  68. Private Declare Function GetClientRect Lib "user32.dll" (ByVal hwnd As Long, ByRef lpRect As RECT) As Long
  69. Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, ByRef lpRect As RECT) As Long
  70. Private Declare Function SetRect Lib "user32.dll" (ByRef lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
  71. Private Declare Function GetProp Lib "user32.dll" Alias "GetPropA" (ByVal hwnd As Long, ByVal lpString As String) As Long
  72. Private Declare Function SetProp Lib "user32.dll" Alias "SetPropA" (ByVal hwnd As Long, ByVal lpString As String, ByVal hData As Long) As Long
  73. Private Declare Function RemoveProp Lib "user32.dll" Alias "RemovePropA" (ByVal hwnd As Long, ByVal lpString As String) As Long
  74. Private Declare Function SetWindowPos Lib "user32.dll" (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 Long
  75. Private Declare Function SystemParametersInfo Lib "user32.dll" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
  76. Private Declare Function GetParent Lib "user32.dll" (ByVal hwnd As Long) As Long
  77.  
  78. Dim mColCtls As Collection
  79. Dim AttachedHwnd As Long
  80.  
  81. Public Enum eAnchorTypes
  82.     eLeft = 1
  83.     eTop = 2
  84.     eRight = 4
  85.     eBottom = 8
  86.     eAll = 15
  87.     eNone = 0
  88. End Enum
  89.  
  90. Private Sub Class_Initialize()
  91.     '-- Initialise the collection
  92.     Set mColCtls = New Collection
  93. End Sub
  94.  
  95. Private Sub Class_Terminate()
  96.     '-- Make sure we unsubclass
  97.     DetachWind
  98.     '-- Destroy the collection
  99.     Set mColCtls = Nothing
  100. End Sub
  101.  
  102. Private Function ISubclass_WndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, bHandled As Boolean) As Long
  103.     Select Case uMsg
  104.         Case WM_WINDOWPOSCHANGED
  105.             '-- The window position has changed
  106.             If mColCtls.Count > 0 Then
  107.                 '-- Make sure we don't bother to loop if there's nothing to loop through
  108.                 Dim i As Long
  109.                 Dim relRect As RECT
  110.                 Dim WndRect As RECT
  111.                 Dim CtlRect As RECT
  112.                 Dim AnchorType As eAnchorTypes
  113.                 Dim Left As Long, Top As Long, width As Long, height As Long
  114.                 
  115.                 GetClientRect hwnd, WndRect
  116.                 
  117.                 For i = 1 To mColCtls.Count
  118.                     '-- Retrieve the control's anchor type
  119.                     AnchorType = GetProp(mColCtls(i), "AnchorType")
  120.                     '-- Get its original rect relative to the parent
  121.                     relRect = GetRectFromWndProperties(mColCtls(i))
  122.                     '-- Get its new rect
  123.                     GetWindowRect mColCtls(i), CtlRect
  124.                     
  125.                     '-- Initialise our vars
  126.                     Left = relRect.Left
  127.                     Top = relRect.Top
  128.                     width = CtlRect.Right - CtlRect.Left
  129.                     height = CtlRect.Bottom - CtlRect.Top
  130.                     
  131.                     '-- If it's anchored right
  132.                     If (AnchorType And eAnchorTypes.eRight) = eAnchorTypes.eRight Then
  133.                         '-- If it's also anchored left
  134.                         If (AnchorType And eAnchorTypes.eLeft) = eAnchorTypes.eLeft Then
  135.                             '-- Adjust the width
  136.                             width = (WndRect.Right - WndRect.Left) - (relRect.Right + relRect.Left)
  137.                         Else
  138.                             '-- Otherwise just adjust the left position
  139.                             Left = ((WndRect.Right - WndRect.Left) - relRect.Right) - (CtlRect.Right - CtlRect.Left)
  140.                         End If
  141.                     End If
  142.                     
  143.                     '-- If it's anchored to the bottom
  144.                     If (AnchorType And eAnchorTypes.eBottom) = eAnchorTypes.eBottom Then
  145.                         '-- If it's also anchored to the top
  146.                         If (AnchorType And eAnchorTypes.eTop) = eAnchorTypes.eTop Then
  147.                             '-- Adjust the height
  148.                             height = (WndRect.Bottom - WndRect.Top) - (relRect.Bottom + relRect.Top)
  149.                         Else
  150.                             '-- Otherwise we just need to adjust its top position
  151.                             Top = ((WndRect.Bottom - WndRect.Top) - relRect.Bottom) - (CtlRect.Bottom - CtlRect.Top)
  152.                         End If
  153.                     End If
  154.                     
  155.                     '-- Change the window's position
  156.                     SetWindowPos mColCtls(i), 0, Left, Top, width, height, 0
  157.                     
  158.                     '-- Get the pointer to the label object, if there is one
  159.                     Dim pLabel As Long
  160.                     pLabel = GetProp(mColCtls(i), "pLabel")
  161.                     If pLabel <> 0 Then
  162.                         '-- If we have a pointer
  163.                         Dim mLabel As Label
  164.                         
  165.                         '-- Get a Label object from the pointer
  166.                         CopyMemory mLabel, pLabel, 4&
  167.                         
  168.                         '-- Get the alignment data
  169.                         Dim Align As AlignmentConstants, Side As AlignConstants
  170.                         Align = GetProp(mColCtls(i), "LabelAlign")
  171.                         Side = GetProp(mColCtls(i), "LabelSide")
  172.                         
  173.                         '-- Move the label to the correct place
  174.                         Select Case Align
  175.                             Case vbLeftJustify
  176.                                 Select Case Side
  177.                                     Case vbAlignLeft
  178.                                         mLabel.Left = (Left * Screen.TwipsPerPixelX) - mLabel.width
  179.                                         mLabel.Top = Top * Screen.TwipsPerPixelY
  180.                                     Case vbAlignRight
  181.                                         mLabel.Left = ((Left + width) * Screen.TwipsPerPixelX) - mLabel.width
  182.                                         mLabel.Top = Top * Screen.TwipsPerPixelY
  183.                                     Case vbAlignTop
  184.                                         mLabel.Left = Left * Screen.TwipsPerPixelX
  185.                                         mLabel.Top = (Top * Screen.TwipsPerPixelY) - mLabel.height
  186.                                     Case vbAlignBottom
  187.                                         mLabel.Left = Left * Screen.TwipsPerPixelX
  188.                                         mLabel.Top = (Top + height) * Screen.TwipsPerPixelY
  189.                                 End Select
  190.                             Case vbRightJustify
  191.                                 Select Case Side
  192.                                     Case vbAlignLeft
  193.                                         mLabel.Left = (Left * Screen.TwipsPerPixelX) - mLabel.width
  194.                                         mLabel.Top = (Top + height) * Screen.TwipsPerPixelY - mLabel.height
  195.                                     Case vbAlignRight
  196.                                         mLabel.Left = (Left + width) * Screen.TwipsPerPixelX
  197.                                         mLabel.Top = (Top + height) * Screen.TwipsPerPixelY
  198.                                     Case vbAlignTop
  199.                                         mLabel.Left = (Left + width) * Screen.TwipsPerPixelX - mLabel.width
  200.                                         mLabel.Top = (Top * Screen.TwipsPerPixelY) - mLabel.height
  201.                                     Case vbAlignBottom
  202.                                         mLabel.Left = (Left + width) * Screen.TwipsPerPixelX - mLabel.width
  203.                                         mLabel.Top = (Top + height) * Screen.TwipsPerPixelY
  204.                                 End Select
  205.                             Case vbCenter
  206.                                 Select Case Side
  207.                                     Case vbAlignLeft
  208.                                         mLabel.Left = (Left * Screen.TwipsPerPixelX) - mLabel.width
  209.                                         mLabel.Top = (Top + height \ 2) * Screen.TwipsPerPixelY - mLabel.height \ 2
  210.                                     Case vbAlignRight
  211.                                         mLabel.Left = (Left + width) * Screen.TwipsPerPixelX
  212.                                         mLabel.Top = (Top + height \ 2) * Screen.TwipsPerPixelY - mLabel.height \ 2
  213.                                     Case vbAlignTop
  214.                                         mLabel.Left = (Left + width \ 2) * Screen.TwipsPerPixelX - mLabel.width \ 2
  215.                                         mLabel.Top = Top * Screen.TwipsPerPixelY - mLabel.height
  216.                                     Case vbAlignBottom
  217.                                         mLabel.Left = (Left + width \ 2) * Screen.TwipsPerPixelX - mLabel.width \ 2
  218.                                         mLabel.Top = (Top + height) * Screen.TwipsPerPixelY
  219.                                 End Select
  220.                         End Select
  221.                         
  222.                         '-- Clean up
  223.                         ZeroMemory mLabel, 4&
  224.                     End If
  225.                 Next i
  226.             End If
  227.         
  228.         Case WM_DESTROY, WM_NCDESTROY
  229.             '-- Make sure we unsubclass
  230.             DetachWind
  231.     End Select
  232. End Function
  233.  
  234. Public Sub AttachWind(ByVal hwnd As Long)
  235.     '-- Make sure we're not trying to subclass something
  236.     '   when we're already Attached to another window
  237.     If AttachedHwnd = 0 Then
  238.         '-- Subclass the window
  239.         modSubclass.SubWnd hwnd, Me, modSubclass.NewCSubclass(hwnd), "CAnchor"
  240.         '-- Store its handle for later use
  241.         AttachedHwnd = hwnd
  242.     End If
  243. End Sub
  244.  
  245. Public Sub DetachWind()
  246.     If Not AttachedHwnd = 0 Then
  247.         '-- Remove the handler
  248.         modSubclass.GetCSubclass(AttachedHwnd).RemoveHandler "CAnchor"
  249.         
  250.         '-- Reset our handle variable
  251.         AttachedHwnd = 0
  252.     End If
  253. End Sub
  254.  
  255. Public Sub AddCtlLabel(ByVal hwnd As Long, c As Object, ByVal Align As AlignmentConstants, ByVal Side As AlignConstants)
  256.     SetProp hwnd, "pLabel", ObjPtr(c)
  257.     SetProp hwnd, "LabelAlign", Align
  258.     SetProp hwnd, "LabelSide", Side
  259. End Sub
  260.  
  261. Public Sub RemoveCtlLabel(ByVal hwnd As Long)
  262.     RemoveProp hwnd, "pLabel"
  263. End Sub
  264.  
  265. Public Sub AddCtl(ByVal hwnd As Long, ByVal AnchorType As eAnchorTypes)
  266.     '-- Set the control's anchor type and add it to the collection
  267.     SetCtlAnchorType hwnd, AnchorType
  268.     mColCtls.Add hwnd, "m" & hwnd
  269. End Sub
  270.  
  271. Public Sub RemoveCtl(ByVal hwnd As Long)
  272.     '-- Remove the window's properties and remove the control from the collection
  273.     RemoveProp hwnd, "AnchorType"
  274.     RemoveProp hwnd, "relrectLeft"
  275.     RemoveProp hwnd, "relrectTop"
  276.     RemoveProp hwnd, "relrectRight"
  277.     RemoveProp hwnd, "relrectBottom"
  278.     
  279.     mColCtls.Remove "m" & hwnd
  280. End Sub
  281.  
  282. Public Sub SetCtlAnchorType(ByVal hwnd As Long, ByVal AnchorType As eAnchorTypes)
  283.     '-- Set the anchor type and relative rect position
  284.     SetProp hwnd, "AnchorType", AnchorType
  285.     SetRectAsWndProperties hwnd, GetWindRelPos(hwnd, AttachedHwnd)
  286. End Sub
  287.  
  288. Public Function GetCtlAnchorType(ByVal hwnd As Long) As eAnchorTypes
  289.     '-- Retrieve the anchor type
  290.     GetCtlAnchorType = GetProp(hwnd, "AnchorType")
  291. End Function
  292.  
  293. Public Sub RefreshStoredCtlPositions()
  294.     If mColCtls.Count > 0 Then
  295.         Dim i As Long
  296.         
  297.         For i = 1 To mColCtls.Count
  298.             SetRectAsWndProperties mColCtls(i), GetWindRelPos(mColCtls(i), AttachedHwnd)
  299.         Next i
  300.     End If
  301. End Sub
  302.  
  303. Private Sub SetRectAsWndProperties(ByVal hwnd As Long, r As RECT)
  304.     SetProp hwnd, "relrectLeft", r.Left
  305.     SetProp hwnd, "relrectTop", r.Top
  306.     SetProp hwnd, "relrectRight", r.Right
  307.     SetProp hwnd, "relrectBottom", r.Bottom
  308. End Sub
  309.  
  310. Private Function GetRectFromWndProperties(ByVal hwnd As Long) As RECT
  311.     Dim r As RECT
  312.     SetRect _
  313.         r, _
  314.         GetProp(hwnd, "relrectLeft"), _
  315.         GetProp(hwnd, "relrectTop"), _
  316.         GetProp(hwnd, "relrectRight"), _
  317.         GetProp(hwnd, "relrectBottom")
  318.     GetRectFromWndProperties = r
  319. End Function
  320.  
  321.  
  322.