home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / Animated__201018812006.psc / Reflection.bas < prev    next >
BASIC Source File  |  2006-08-01  |  18KB  |  549 lines

  1. Attribute VB_Name = "Reflection"
  2. Option Explicit
  3.  
  4. ' Declares...
  5. Private Type SAFEARRAYBOUND
  6.     cElements As Long
  7.     lLbound As Long
  8. End Type
  9. Private Type SAFEARRAY2D
  10.     cDims As Integer
  11.     fFeatures As Integer
  12.     cbElements As Long
  13.     cLocks As Long
  14.     pvData As Long
  15.     Bounds(0 To 1) As SAFEARRAYBOUND
  16. End Type
  17. Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long
  18.  
  19. Private Type RGBQUAD
  20.     rgbBlue As Byte
  21.     rgbGreen As Byte
  22.     rgbRed As Byte
  23.     rgbReserved As Byte
  24. End Type
  25. Private Type BITMAPINFOHEADER '40 bytes
  26.     biSize As Long
  27.     biWidth As Long
  28.     biHeight As Long
  29.     biPlanes As Integer
  30.     biBitCount As Integer
  31.     biCompression As Long
  32.     biSizeImage As Long
  33.     biXPelsPerMeter As Long
  34.     biYPelsPerMeter As Long
  35.     biClrUsed As Long
  36.     biClrImportant As Long
  37. End Type
  38. Private Type BITMAPINFO
  39.     bmiHeader As BITMAPINFOHEADER
  40.     ' Note no palette entry here, not needed
  41. End Type
  42.  
  43. Private Const BI_RGB = 0&
  44. Private Const BI_RLE4 = 2&
  45. Private Const BI_RLE8 = 1&
  46. Private Const DIB_RGB_COLORS = 0 '  color table in RGBs
  47.  
  48. Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
  49. Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
  50. Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
  51. Private Declare Function GetDesktopWindow Lib "user32" () As Long
  52. Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
  53. Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
  54. Private Declare Function GetCurrentObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal uObjectType As Long) As Long
  55. Private Const OBJ_BITMAP As Long = 7
  56.  
  57. Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
  58. Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
  59.  
  60. Private Declare Function SetTimer Lib "user32.dll" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
  61. Private Declare Function KillTimer Lib "user32.dll" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
  62.  
  63. Private Declare Function timeGetTime Lib "winmm.dll" () As Long
  64.  
  65. Private Declare Function UpdateLayeredWindow Lib "user32" ( _
  66.     ByVal hwnd As Long, _
  67.     ByVal hdcDst As Long, _
  68.     pptDst As Any, _
  69.     psize As Any, _
  70.     ByVal hdcSrc As Long, _
  71.     pptSrc As Any, _
  72.     ByVal crKey As Long, _
  73.     pblend As BLENDFUNCTION, _
  74.     ByVal dwFlags As Long) As Long
  75.  
  76. ' Note - this is not the declare in the API viewer - modify lplpVoid to be
  77. ' Byref so we get the pointer back:
  78. Private Declare Function CreateDIBSection Lib "gdi32" _
  79.     (ByVal hdc As Long, _
  80.     pBitmapInfo As BITMAPINFO, _
  81.     ByVal un As Long, _
  82.     lplpVoid As Long, _
  83.     ByVal handle As Long, _
  84.     ByVal dw As Long) As Long
  85.     
  86. Private Type SIZEAPI
  87.    cx As Long
  88.    cy As Long
  89. End Type
  90.  
  91. Private Type POINTAPI
  92.    x As Long
  93.    y As Long
  94. End Type
  95.  
  96. Private Type RECT
  97.    Left As Long
  98.    Top As Long
  99.    Right As Long
  100.    Bottom As Long
  101. End Type
  102.  
  103. Private Type BLENDFUNCTION
  104.    BlendOp As Byte
  105.    BlendFlags As Byte
  106.    SourceConstantAlpha As Byte
  107.    AlphaFormat As Byte
  108. End Type
  109.  
  110. Private Const AC_SRC_OVER As Long = &H0&
  111. Private Const ULW_COLORKEY As Long = &H1&
  112. Private Const ULW_ALPHA As Long = &H2&
  113. Private Const ULW_OPAQUE As Long = &H4&
  114. Private Const AC_SRC_ALPHA = &H1
  115.  
  116.  
  117. Private Const WS_EX_TOPMOST As Long = &H8&
  118. Private Const WS_EX_TRANSPARENT  As Long = &H20&
  119. Private Const WS_EX_TOOLWINDOW As Long = &H80&
  120. Private Const WS_EX_LAYERED As Long = &H80000
  121. Private Const WS_POPUP = &H80000000
  122. Private Const WS_VISIBLE = &H10000000
  123. Private Const WS_DISABLED As Long = &H8000000
  124.  
  125. Private Const WM_DESTROY = &H2
  126. Private Const WM_SIZE = &H5
  127. Private Const WM_SIZING = &H214
  128. Private Const WM_MOVING = &H216&
  129. Private Const WM_ENTERSIZEMOVE = &H231&
  130. Private Const WM_EXITSIZEMOVE = &H232&
  131. Private Const WM_MOVE As Long = &H3
  132.  
  133. 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
  134. Private Const SWP_ASYNCWINDOWPOS As Long = &H4000
  135. Private Const SWP_DEFERERASE As Long = &H2000
  136. Private Const SWP_FRAMECHANGED As Long = &H20
  137. Private Const SWP_DRAWFRAME As Long = SWP_FRAMECHANGED
  138. Private Const SWP_HIDEWINDOW As Long = &H80
  139. Private Const SWP_NOACTIVATE As Long = &H10
  140. Private Const SWP_NOCOPYBITS As Long = &H100
  141. Private Const SWP_NOMOVE As Long = &H2
  142. Private Const SWP_NOOWNERZORDER As Long = &H200
  143. Private Const SWP_NOREDRAW As Long = &H8
  144. Private Const SWP_NOREPOSITION As Long = SWP_NOOWNERZORDER
  145. Private Const SWP_NOSENDCHANGING As Long = &H400
  146. Private Const SWP_NOSIZE As Long = &H1
  147. Private Const SWP_NOZORDER As Long = &H4
  148. Private Const SWP_SHOWWINDOW As Long = &H40
  149.  
  150. Private Declare Function GetDIBits Lib "gdi32.dll" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, ByRef lpBits As Any, ByRef lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
  151. Private Declare Function GetWindowDC Lib "user32.dll" (ByVal hwnd As Long) As Long
  152. Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hdc As Long) As Long
  153.  
  154.  
  155. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
  156.     lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
  157.  
  158. Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  159. Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
  160. Private Const GWL_EXSTYLE As Long = -20
  161. Private Const GWL_WNDPROC As Long = -4
  162.  
  163. Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
  164. Private Declare Function IsWindow Lib "user32.dll" (ByVal hwnd As Long) As Long
  165.  
  166. Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
  167. Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
  168. Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  169.  
  170. Private Declare Sub OutputDebugString Lib "kernel32.dll" Alias "OutputDebugStringA" (ByVal lpOutputString As String)
  171. Private Declare Function Ellipse Lib "gdi32.dll" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
  172.  
  173. Private hWndAttach As Long
  174. Private hWndReflection As Long
  175. Private pFnOldWindowProc As Long
  176. Private iTimerID As Long
  177. Private bDying As Boolean
  178.  
  179. Const WAVE_SIZE As Long = 20 ' Amplitude
  180. Const WAVE_GAP As Long = 5 ' Extra space to try and stop truncation
  181. Const WAVE_FREQ As Long = 4
  182. Private OffsetLookup(0 To 256) As Long
  183.  
  184. ' Graphic objects
  185. Private hDib As Long
  186. Private hBmpOld As Long
  187. Private hdc As Long
  188. Private hDD As Long
  189. Private lPtr As Long
  190. Private bi As BITMAPINFO
  191.  
  192. Public Sub Attach(ByVal hwnd As Long)
  193.     If hWndAttach <> 0 Then
  194.         Err.Raise vbObjectError, "Reflection::Attach()", "Only one window supported in this version"
  195.         Exit Sub
  196.     End If
  197.     If IsWindow(hwnd) = 0 Then
  198.         Err.Raise vbObjectError, "Reflection::Attach()", "Not a valid window"
  199.         Exit Sub
  200.     End If
  201.     hWndAttach = hwnd
  202.     
  203.     ' Build lookup tables
  204.     Dim i As Long
  205.     Dim two_pi As Double
  206.     two_pi = Atn(1) * 8#
  207.     For i = 0 To 256
  208.         OffsetLookup(i) = Round((2 * WAVE_SIZE - WAVE_GAP) * Sin(CDbl(WAVE_FREQ) * two_pi * CDbl(i) / 256#))
  209.     Next
  210.     
  211.     
  212.     ' Get window info
  213.     
  214.     Dim rc As RECT, cy As Long
  215.     GetWindowRect hWndAttach, rc
  216.     cy = rc.Bottom - rc.Top
  217.     rc.Top = rc.Top + cy
  218.     rc.Bottom = rc.Top + cy
  219.     
  220.     ' Create reflection window
  221.     
  222.     hWndReflection = CreateWindowEx(WS_EX_LAYERED Or WS_EX_TRANSPARENT Or WS_EX_TOOLWINDOW, _
  223.                                     "STATIC", "Reflection", WS_POPUP Or WS_VISIBLE Or WS_DISABLED, _
  224.                                     rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, _
  225.                                     0, 0, App.hInstance, ByVal 0&)
  226.                                     
  227.     If hWndReflection = 0 Then
  228.         hWndAttach = 0
  229.         Err.Raise vbObjectError, "Reflection::Create()", "Could not create window"
  230.         Exit Sub
  231.     End If
  232.     
  233.     ' Subclass the parent window
  234.     pFnOldWindowProc = SetWindowLong(hWndAttach, GWL_WNDPROC, AddressOf AttachedWindow_WindowProc)
  235.     
  236.     ' Set a tiemr
  237.     iTimerID = SetTimer(0, 0, 50, AddressOf TimerProc)
  238.     
  239.     bDying = False
  240.     
  241. End Sub
  242.  
  243. Public Sub Detach()
  244.     bDying = True
  245.     
  246.     ODS "Detach()..."
  247.     If hWndAttach = 0 Then Exit Sub
  248.     
  249.     ' Kill timer
  250.     KillTimer 0, iTimerID
  251.     
  252.     ' Unsubclass
  253.     ODS "Unsubclassing..."
  254.     SetWindowLong hWndAttach, GWL_WNDPROC, pFnOldWindowProc
  255.     
  256.     ' Destroy our reflection window
  257.     ODS "Destroying our window..."
  258.     If hWndReflection <> 0 Then
  259.         If IsWindow(hWndReflection) Then
  260.             SetWindowLong hWndReflection, GWL_EXSTYLE, GetWindowLong(hWndReflection, GWL_EXSTYLE) And Not (WS_EX_LAYERED)
  261.             DestroyWindow hWndReflection
  262.         End If
  263.         hWndReflection = 0
  264.     End If
  265.     
  266.     ' Delete graphic objects
  267.     ODS "Deleting graphics..."
  268.     ClearUp
  269.     
  270.     hWndAttach = 0
  271.     ODS "Done"
  272. End Sub
  273.  
  274. Private Function CreateDIB( _
  275.         ByVal hDCRef As Long, _
  276.         ByVal w As Long, _
  277.         ByVal h As Long, _
  278.         ByRef hDib As Long _
  279.     ) As Boolean
  280.     With bi.bmiHeader
  281.         .biSize = Len(bi.bmiHeader)
  282.         .biWidth = w
  283.         .biHeight = h
  284.         .biPlanes = 1
  285.         .biBitCount = 32
  286.         .biCompression = BI_RGB
  287.         '.biSizeImage = BytesPerScanLine * .biHeight
  288.         .biSizeImage = 4& * .biHeight * .biHeight
  289.     End With
  290.     hDib = CreateDIBSection( _
  291.             hDCRef, _
  292.             bi, _
  293.             DIB_RGB_COLORS, _
  294.             lPtr, _
  295.             0, 0)
  296.     CreateDIB = (hDib <> 0)
  297. End Function
  298.  
  299. Private Function Create( _
  300.         ByVal w As Long, _
  301.         ByVal h As Long _
  302.     ) As Boolean
  303.     
  304.    ' Don't bother creating if it's the same size as what we already have
  305.    ' This could be further optimized to keep larger bitmaps and not
  306.    ' re-create smaller ones.
  307.    If w = bi.bmiHeader.biWidth And h = bi.bmiHeader.biHeight Then
  308.         Create = True
  309.         Exit Function
  310.    End If
  311.     
  312.    ClearUp
  313.    hdc = CreateCompatibleDC(0)
  314.    If (hdc <> 0) Then
  315.        If (CreateDIB(hdc, w, h, hDib)) Then
  316.            hBmpOld = SelectObject(hdc, hDib)
  317.            Create = True
  318.        Else
  319.            DeleteObject hdc
  320.            hdc = 0
  321.        End If
  322.    End If
  323. End Function
  324. Private Sub ClearUp()
  325.     If (hdc <> 0) Then
  326.         If (hDib <> 0) Then
  327.             SelectObject hdc, hBmpOld
  328.             DeleteObject hDib
  329.         End If
  330.         DeleteObject hdc
  331.     End If
  332.     hdc = 0: hDib = 0: hBmpOld = 0: lPtr = 0
  333. End Sub
  334.  
  335. Private Function AttachedWindow_WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  336.     If bDying = False Then
  337.     Static bInSizeMove As Boolean
  338.     Dim rc As RECT
  339.     Select Case uMsg
  340.     Case WM_MOVING
  341.         ' Retrieve the rectangle
  342.         'CopyMemory rc, ByVal lParam, Len(rc)
  343.         GetWindowRect hwnd, rc
  344.         Reposition rc
  345.     Case WM_SIZING
  346.         ' Retrieve the rectangle
  347.         'CopyMemory rc, ByVal lParam, Len(rc)
  348.         GetWindowRect hwnd, rc
  349.         Reposition rc
  350.     Case WM_SIZE, WM_MOVE
  351.         If Not bInSizeMove Then
  352.             GetWindowRect hwnd, rc
  353.             Reposition rc
  354.         End If
  355.     Case WM_ENTERSIZEMOVE
  356.         bInSizeMove = True
  357.     Case WM_EXITSIZEMOVE
  358.         bInSizeMove = False
  359.     Case WM_DESTROY
  360.         rc.Left = pFnOldWindowProc
  361.         Detach
  362.         AttachedWindow_WindowProc = CallWindowProc(rc.Left, hwnd, uMsg, wParam, lParam)
  363.         Exit Function
  364.     End Select
  365.     End If
  366.     AttachedWindow_WindowProc = CallWindowProc(pFnOldWindowProc, hwnd, uMsg, wParam, lParam)
  367.     
  368. End Function
  369.  
  370. Private Function Reposition(rc As RECT)
  371.     If bDying Then Exit Function
  372.     
  373.     Dim cy As Long
  374.     cy = rc.Bottom - rc.Top
  375.     rc.Top = rc.Top + cy
  376.     
  377.     If cy > 128 * 2 Then
  378.         rc.Bottom = rc.Top + 128
  379.     Else
  380.         rc.Bottom = rc.Top + cy \ 2
  381.     End If
  382.             
  383.     rc.Left = rc.Left - WAVE_SIZE
  384.     rc.Right = rc.Right + WAVE_SIZE
  385.     
  386.     SetWindowPos hWndReflection, 0, rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top, SWP_NOOWNERZORDER Or SWP_NOACTIVATE
  387.     
  388.     Create rc.Right - rc.Left, rc.Bottom - rc.Top
  389.     Redraw
  390. End Function
  391.  
  392. Public Function Redraw()
  393.     If bDying Then Exit Function
  394.     
  395.     Dim rc As RECT
  396.     Dim si As SIZEAPI
  397.     GetWindowRect hWndReflection, rc
  398.     si.cx = rc.Right - rc.Left
  399.     si.cy = rc.Bottom - rc.Top
  400.     Dim bf As BLENDFUNCTION
  401.     bf.BlendOp = AC_SRC_OVER
  402.     bf.BlendFlags = 0
  403.     bf.AlphaFormat = AC_SRC_ALPHA
  404.     bf.SourceConstantAlpha = 192    ' Not fully opaque at any point
  405.     Dim pt As POINTAPI
  406.     pt.x = 0
  407.     pt.y = 0
  408.     
  409.     Create rc.Right - rc.Left, rc.Bottom - rc.Top
  410.     Render
  411.     
  412.     UpdateLayeredWindow hWndReflection, ByVal 0&, ByVal 0&, si, hdc, pt, 0, bf, ULW_ALPHA
  413. End Function
  414.  
  415. Private Function Render()
  416.     Static LastRenderTime As Long
  417.     Dim ThisRenderTime As Long
  418.     
  419.     ThisRenderTime = timeGetTime
  420.     
  421.     If bDying Then Exit Function
  422.     
  423.     Dim SrcBits() As Byte
  424.     Dim DstBits() As Byte
  425.     Dim x As Long, y As Long
  426.     Dim tSA As SAFEARRAY2D
  427.  
  428.     With tSA
  429.         .cbElements = 1
  430.         .cDims = 2
  431.         .Bounds(0).lLbound = 0
  432.         .Bounds(0).cElements = bi.bmiHeader.biHeight
  433.         .Bounds(1).lLbound = 0
  434.         .Bounds(1).cElements = bi.bmiHeader.biWidth * 4 ' Bytes per scanline
  435.         .pvData = lPtr
  436.     End With
  437.     CopyMemory ByVal VarPtrArray(DstBits()), VarPtr(tSA), 4
  438.     
  439.     
  440.     GetWindowBits hWndAttach, SrcBits()
  441.     'Dim rc As RECT
  442.     'GetWindowRect hWndAttach, rc
  443.     'ReDim WinBits(0 To ((rc.Right - rc.Left) * 4) - 1, 0 To (rc.Bottom - rc.Top) - 1)
  444.     
  445.     
  446.     Dim SrcX As Long, SrcY As Long
  447.     'SrcY = UBound(SrcBits, 2)
  448.     SrcY = 2
  449.     
  450.     Dim alpha As Long, alpha_delta As Long
  451.     alpha_delta = Int(255# / CDbl(bi.bmiHeader.biHeight) + 0.5)
  452.     alpha = 0
  453.     
  454.     Dim phase As Double
  455.     phase = CDbl(ThisRenderTime Mod 1000) * 0.001
  456.     phase = phase * 3.1415927 * 2#
  457.     
  458.     Dim phase2 As Long
  459.     phase2 = (ThisRenderTime Mod 1000)
  460.     phase2 = phase2 \ 16
  461.     
  462.     Dim pos As Double
  463.     Dim pos2 As Long
  464.  
  465.     For y = bi.bmiHeader.biHeight - 1 To 0 Step -1
  466.         pos2 = y * 255 \ bi.bmiHeader.biHeight
  467.         alpha = pos2
  468.         For x = 0 To bi.bmiHeader.biWidth * 4 - 1 Step 4
  469.             'alpha = 127
  470.             
  471.             SrcX = x \ 4
  472.             SrcX = SrcX - WAVE_SIZE + ((255 - pos2) * OffsetLookup(((y + phase2)) Mod 256)) \ 255
  473.             SrcX = SrcX * 4
  474.             
  475.             If SrcX < 0 Or SrcX > UBound(SrcBits, 1) Then
  476.                 DstBits(x + 3, y) = 0   ' Alpha
  477.                 DstBits(x + 2, y) = 0
  478.                 DstBits(x + 1, y) = 0
  479.                 DstBits(x + 0, y) = 0
  480.             Else
  481.                 DstBits(x + 3, y) = alpha   ' Alpha
  482.                 DstBits(x + 2, y) = (SrcBits(SrcX + 2, SrcY) * alpha) \ 255
  483.                 DstBits(x + 1, y) = (SrcBits(SrcX + 1, SrcY) * alpha) \ 255
  484.                 DstBits(x + 0, y) = (SrcBits(SrcX + 0, SrcY) * alpha) \ 255
  485.             End If
  486.         Next
  487.         SrcY = SrcY + 1
  488.         alpha = alpha + alpha_delta
  489.     Next
  490.  
  491.     CopyMemory ByVal VarPtrArray(DstBits()), 0&, 4
  492.     
  493.     LastRenderTime = ThisRenderTime
  494. End Function
  495.  
  496. Private Function GetWindowBits(ByVal hwnd As Long, ByRef WinBits() As Byte)
  497.     Dim rc As RECT
  498.     Dim hWinDC As Long
  499.     Dim hWinBmp As Long
  500.     Dim hWinOldBmp As Long
  501.     Dim tSA As SAFEARRAY2D
  502.     Dim biWin As BITMAPINFO
  503.         
  504.     ' Get dimensions
  505.     GetWindowRect hwnd, rc
  506.     
  507.     ' Fill in bitmap structure
  508.     With biWin.bmiHeader
  509.         .biSize = Len(bi.bmiHeader)
  510.         .biWidth = rc.Right - rc.Left
  511.         .biHeight = rc.Bottom - rc.Top
  512.         .biPlanes = 1
  513.         .biBitCount = 32
  514.         .biCompression = BI_RGB
  515.         .biSizeImage = 4& * .biHeight * .biHeight
  516.     End With
  517.     
  518.     ReDim WinBits(0 To ((rc.Right - rc.Left) * 4) - 1, 0 To (rc.Bottom - rc.Top) - 1)
  519.  
  520. Dim ret As Long
  521. Dim hTempDC As Long
  522.     
  523.     hWinDC = GetWindowDC(hwnd)
  524.     hTempDC = CreateCompatibleDC(0)
  525.     hWinBmp = CreateCompatibleBitmap(hWinDC, biWin.bmiHeader.biWidth, biWin.bmiHeader.biHeight)
  526.     hWinOldBmp = SelectObject(hTempDC, hWinBmp)
  527.     BitBlt hTempDC, 0, 0, biWin.bmiHeader.biWidth, biWin.bmiHeader.biHeight, hWinDC, 0, 0, vbSrcCopy
  528.     SelectObject hTempDC, hWinOldBmp
  529.     '
  530.     ret = GetDIBits(hWinDC, hWinBmp, 0, rc.Bottom - rc.Top, WinBits(0, 0), biWin, DIB_RGB_COLORS)
  531.     '
  532.     ReleaseDC hwnd, hWinDC
  533.     DeleteDC hTempDC
  534.     DeleteObject hWinBmp
  535.     
  536. End Function
  537.  
  538. Public Function ODS(ParamArray s())
  539.     OutputDebugString Join(s, ", ") & vbCrLf
  540. End Function
  541.  
  542. Private Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
  543.     If bDying Then Exit Sub
  544.     Dim rc As RECT
  545.     GetWindowRect hWndAttach, rc
  546.     Reposition rc
  547. End Sub
  548.  
  549.