⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gradient.bas

📁 金算盘软件代码
💻 BAS
📖 第 1 页 / 共 2 页
字号:
      'We don't let this happen in the WM_NCPAINT message,
      'which is called more often than NCACTIVATE.
      GradientCallback = CallWindowProc(OldGradProc, hwnd, wMsg, wParam, lParam)
      'Create memory DC to draw the titlebar in.
      tmpDC = GetWindowDC(GradhWnd)
      DrawDC = CreateCompatibleDC(tmpDC)
      NewBMP = CreateCompatibleBitmap(tmpDC, rcWnd.Right - rcWnd.Left, 50)
      OldBMP = SelectObject(DrawDC, NewBMP)
      With rcWnd
         hRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
         SelectClipRgn tmpDC, hRgn
         OffsetClipRgn tmpDC, -.Left, -.Top
      End With
      'Find out what color the titlebar needs
      'to be...
      If wParam And GetParent(GradhWnd) = 0 Then
         DrawGradient 0, GetSysColor(COLOR_ACTIVECAPTION)
      ElseIf wParam = GradhWnd And GetParent(GradhWnd) <> 0 Then
         DrawGradient 0, GetSysColor(COLOR_INACTIVECAPTION)
      ElseIf SendMessage(GetParent(GradhWnd), WM_MDIGETACTIVE, 0, 0) = GradhWnd Then
         DrawGradient 0, GetSysColor(COLOR_ACTIVECAPTION)
      Else
         DrawGradient 0, GetSysColor(COLOR_INACTIVECAPTION)
      End If
      'Cleanup
      SelectObject DrawDC, OldBMP
      DeleteObject NewBMP
      DeleteDC DrawDC
      OffsetClipRgn tmpDC, rcWnd.Left, rcWnd.Top
      GetClipRgn tmpDC, hRgn
      ReleaseDC GradhWnd, tmpDC
      DeleteObject hRgn
      tmpDC = 0
      Exit Function

   Case WM_NCPAINT
      'Basically same as above.
      GetWindowRect GradhWnd, rcWnd
      tmpDC = GetWindowDC(GradhWnd)
      DrawDC = CreateCompatibleDC(tmpDC)
      NewBMP = CreateCompatibleBitmap(tmpDC, rcWnd.Right - rcWnd.Left, 50)
      OldBMP = SelectObject(DrawDC, NewBMP)
      With rcWnd
         hRgn = CreateRectRgn(.Left, .Top, .Right, .Bottom)
         SelectClipRgn tmpDC, hRgn
         OffsetClipRgn tmpDC, -.Left, -.Top
      End With
      'Get the color to paint the caption with.
      If GetActiveWindow() = GradhWnd Then
         DrawGradient 0, GetSysColor(COLOR_ACTIVECAPTION)
      ElseIf SendMessage(GetParent(GradhWnd), WM_MDIGETACTIVE, 0, 0) = GradhWnd Then
         DrawGradient 0, GetSysColor(COLOR_ACTIVECAPTION)
      Else
         DrawGradient 0, GetSysColor(COLOR_INACTIVECAPTION)
      End If
      'Cleanup
      SelectObject DrawDC, OldBMP
      DeleteObject NewBMP
      DeleteDC DrawDC
      OffsetClipRgn tmpDC, rcWnd.Left, rcWnd.Top
      GetClipRgn tmpDC, hRgn
      'Call the old proc. This will only
      'draw the titlebar's min/max/close buttons
      'because we told it not to do the rest (this
      'eliminates flicker.
      GradientCallback = CallWindowProc(OldGradProc, hwnd, WM_NCPAINT, hRgn, lParam)
      ReleaseDC GradhWnd, tmpDC
      DeleteObject hRgn
      tmpDC = 0
      Exit Function
   Case WM_SIZE
      'Whoa, we need to paint the caption.
      If hwnd = GradhWnd Then SendMessage GradhWnd, WM_NCPAINT, 0, 0
   End Select

   GradientCallback = CallWindowProc(OldGradProc, hwnd, wMsg, wParam, lParam)
   
End Function

Public Sub GradientForm(frm As Form)

   If OldGradProc <> 0 Then Exit Sub

   GradhWnd = frm.hwnd
   GradIcon = frm.Icon
   OldGradProc = SetWindowLong(frm.hwnd, GWL_WNDPROC, AddressOf GradientCallback)
   GradientGetCapsFont

End Sub

Public Sub GradientReleaseForm()

   If OldGradProc = 0 Or GradhWnd = 0 Then Exit Sub

   SetWindowLong GradhWnd, GWL_WNDPROC, OldGradProc
   OldGradProc = 0
   GradhWnd = 0

End Sub

Private Function DrawGradient(ByVal Color1 As Long, ByVal Color2 As Long) As Long

   Dim i As Integer
   Dim DestWidth As Long, DestHeight As Long
   Dim StartPnt As Integer, EndPnt As Integer
   Dim PixelStep As Long, XBorder As Long
   Dim WndRect As RECT
   Dim OldFont As Long
   Dim fText As String
   
   On Error Resume Next
   
   GetWindowRect GradhWnd, WndRect
   With WndRect
      DestWidth = .Right - .Left
   End With

   'Get height of caption bar
   DestHeight = GetSystemMetrics(SM_CYCAPTION)
   'Get the text of the form's caption
   fText = Space$(255)
   Call GetWindowText(GradhWnd, fText, 255)
   fText = Trim$(fText)
   'Get the width of the border
   XBorder = GetSystemMetrics(SM_CXFRAME)
   'The width of the area we need to paint:
   DestWidth = DestWidth - (XBorder * 2) - (GetSystemMetrics(SM_CXSMSIZE) * 3) + 6
   'Where the painting begins:
   StartPnt = XBorder
   'Where the painting ends:
   EndPnt = XBorder + DestWidth - 4
   
   'How many steps do we need to
   'paint the titlebar?
   PixelStep = DestWidth \ 8
   ReDim Colors(PixelStep) As Long
   'Create gradient colors in the array
   GradateColors Colors(), Color1, Color2
   
   Dim rct As RECT
   Dim hBr As Long
   
   With rct
      .Top = XBorder
      .Left = XBorder
      .Right = XBorder + (DestWidth \ PixelStep)
      .Bottom = XBorder + DestHeight - 1
      For i = 0 To PixelStep - 1
         'Paint the titlebar in increments, increasing
         'the color index with each iteration.
         hBr = CreateSolidBrush(Colors(i))
         FillRect DrawDC, rct, hBr
         'Cleanup
         DeleteObject hBr
         'Prepare for the next iteration
         OffsetRect rct, (DestWidth \ PixelStep), 0
         If i = PixelStep - 2 Then .Right = EndPnt
      Next
      If GradIcon <> 0 Then 'Paint the icon
         'Move the caption text's start point over
         'to make room for the icon
         .Left = XBorder + GetSystemMetrics(SM_CXSMSIZE) + 2
         DrawIconEx DrawDC, XBorder + 1, XBorder + 1, GradIcon, GetSystemMetrics(SM_CXSMSIZE) - 2, GetSystemMetrics(SM_CYSMSIZE) - 2, ByVal 0&, ByVal 0&, 2
      Else
         'No icon
         .Left = XBorder
      End If
      'If getting the caption font failed, use the font
      'from the gradient caption form.
      If CaptionFont.lfHeight = 0 And tmpGradFont = 0 Then
         tmpGradFont = SendMessage(GradhWnd, WM_GETFONT, 0, 0)
      ElseIf tmpGradFont = 0 Then
         tmpGradFont = CreateFontIndirect(CaptionFont)
      End If
      OldFont = SelectObject(DrawDC, tmpGradFont)
      'This is like setting FontTransparent on a Form to True:
      SetBkMode DrawDC, 1
      'Use a white caption, since the background is black
      'on the left side
      SetTextColor DrawDC, RGB(255, 255, 255)
      .Left = .Left + 2
      .Right = .Right - 10
      'Draw the caption text
      DrawText DrawDC, fText, Len(fText) - 1, rct, DT_SINGLELINE Or DT_END_ELLIPSIS Or DT_VCENTER
      'Cleanup
      SelectObject DrawDC, OldFont
      DeleteObject tmpGradFont
      tmpGradFont = 0
      
      .Left = XBorder
      .Right = .Right + 12
      If tmpDC <> 0 Then
         'Blit our work from the memory DC to the form's
         'window DC to finish the job.
          BitBlt tmpDC, .Left, .Top, .Right - .Left - 10, .Bottom - .Top, DrawDC, .Left, .Top, vbSrcCopy
         'Tell windows that we already painted most of
         'the titlebar.
         ExcludeClipRect tmpDC, XBorder, XBorder, .Right - .Left - 8, .Bottom - .Top + 4
      End If

   End With

End Function

Private Sub GradateColors(Colors() As Long, ByVal Color1 As Long, ByVal Color2 As Long)

   'Alright, I admit -- this routine was
   'taken from a VBPJ issue a few months back.

   Dim i As Integer
   Dim dblR As Double, dblG As Double, dblB As Double
   Dim addR As Double, addG As Double, addB As Double
   Dim bckR As Double, bckG As Double, bckB As Double
   
   dblR = CDbl(Color1 And &HFF)
   dblG = CDbl(Color1 And &HFF00&) / 255
   dblB = CDbl(Color1 And &HFF0000) / &HFF00&
   bckR = CDbl(Color2 And &HFF&)
   bckG = CDbl(Color2 And &HFF00&) / 255
   bckB = CDbl(Color2 And &HFF0000) / &HFF00&
   
   addR = (bckR - dblR) / UBound(Colors)
   addG = (bckG - dblG) / UBound(Colors)
   addB = (bckB - dblB) / UBound(Colors)
   
   For i = 0 To UBound(Colors)
      dblR = dblR + addR
      dblG = dblG + addG
      dblB = dblB + addB
      If dblR > 255 Then dblR = 255
      If dblG > 255 Then dblG = 255
      If dblB > 255 Then dblB = 255
      If dblR < 0 Then dblR = 0
      If dblG < 0 Then dblG = 0
      If dblG < 0 Then dblB = 0
      Colors(i) = RGB(dblR, dblG, dblB)
   Next

End Sub

Public Sub GradientGetCapsFont()

   'Tries to retrieve the Windows caption font
   'in the current Appearance scheme. Doesn't
   'seem to work all the time, so if anyone knows
   'why I'd appreciate being told.
   
   Dim NCM As NONCLIENTMETRICS
   Dim lfNew As LOGFONT
   
   NCM.cbSize = Len(NCM)
   Call SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, NCM, 0)
   
   If NCM.iCaptionHeight = 0 Then
      CaptionFont.lfHeight = 0
   Else
      CaptionFont = NCM.lfCaptionFont
   End If

End Sub

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -