textrot.bas
来自「多种图表的绘制及其运用」· BAS 代码 · 共 210 行
BAS
210 行
Attribute VB_Name = "basTextRot"
Option Explicit
' ***************************************************
' * Text Rotation Module *
' * *
' * Created by: Rocky Clark (Kath-Rock Software) *
' * *
' * This module may be used and distributed, as *
' * is, in your code, as long as these credits and *
' * the code itself remain unchanged. *
' * *
' ***************************************************
Public uDisplayDescript As Boolean 'Display description when selectable
'API Constants:
Private Const LF_FACESIZE As Long = 32&
Private Const SYSTEM_FONT As Long = 13&
Private Const ANTIALIASED_QUALITY = 4
'Type Structures:
Private Type PointAPI
X As Long
Y As Long
End Type
Private Type SizeStruct
Width As Long
Height As Long
End Type
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName(LF_FACESIZE) As Byte
End Type
'API Declarations:
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long
Private Declare Function GetTextExtentPoint32 Lib "gdi32" Alias "GetTextExtentPoint32A" (ByVal hDC As Long, ByVal lpsz As String, ByVal cbString As Long, lpSize As SizeStruct) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Public Function PrintRotText(ByVal hDC As Long, ByVal Text As String, ByVal CenterX As Long, ByVal CenterY As Long, ByVal RotDegrees As Single) As Boolean
' ***************************************************
' * PrintRotText *
' * *
' * Created by: Rocky Clark (Kath-Rock Software) *
' * *
' * Print text on an object centered on CenterX, *
' * CenterY and rotated by RotDegrees. *
' * *
' * This procedure may be used and distributed, as *
' * is, in your code, as long as these credits and *
' * the code itself remain unchanged. *
' * *
' ***************************************************
' *************** I M P O R T A N T ***************
' This procedure only works for vector fonts, such
' as True Type fonts like Times New Roman. Raster
' fonts, such as MS Sans Serif or System will not
' rotate and may produce unpredictable results.
' **************************************************
'Parameters:
'
'hDC = Device context where printing will occur.
' This may be any object with an hDC (Form,
' PictureBox, UserControl, etc.)
'
'Text = Text string to be printed.
'
'CenterX, CenterY = Center point of text in pixels.
'
'RotDegrees = Rotation amount in degrees (0.0 to 359.9999999)
' (counter-clockwise; zero = horizontal (no rotation)).
Dim bOkSoFar As Boolean 'Flag to continue.
Dim hFontOld As Long 'Handle to original font.
Dim hFontNew As Long 'Handle to new font.
Dim lfFont As LOGFONT 'LOGFONT structure for new font.
Dim ptOrigin As PointAPI 'Point of origin for drawing text.
Dim ptCenter As PointAPI 'Center point of text.
Dim szText As SizeStruct 'Width and Height of text.
'Get the current LOGFONT structure from the device.
'To accomplish this, first select a stock font into the
'device, which will return a handle to it's current font.
hFontOld = SelectObject(hDC, GetStockObject(SYSTEM_FONT))
'If successful getting the font from the device...
If hFontOld <> 0 Then
'Now get the LOGFONT structure from the font.
bOkSoFar = (GetObjectAPI(hFontOld, Len(lfFont), lfFont) <> 0)
'Put the original font back into the device.
Call SelectObject(hDC, hFontOld)
'Reset for use later
hFontOld = 0
End If
'Continue only if successful getting the LOGFONT structure.
If bOkSoFar Then
'Change the escapement and orientation of the font.
lfFont.lfEscapement = RotDegrees * 10
lfFont.lfOrientation = lfFont.lfEscapement
lfFont.lfQuality = ANTIALIASED_QUALITY
'Now create a font object from the LOGFONT structure.
hFontNew = CreateFontIndirect(lfFont)
'If font creation was successful...
If hFontNew <> 0 Then
'Select the new font into the device.
hFontOld = SelectObject(hDC, hFontNew)
'If successful selecting the new font into the device...
If hFontOld <> 0 Then
'Get the size of the text in logical units (pixels).
bOkSoFar = (GetTextExtentPoint32(hDC, Text, Len(Text), szText) <> 0)
'If successful getting the size of the text...
If bOkSoFar Then
'Calculate the point of origin for the text
'as it would be if the text was horizontal.
With ptOrigin
.X = CenterX - (szText.Width / 2)
.Y = CenterY - (szText.Height / 2)
End With
'Convert CenterX, CenterY to a point structure
'(needed for call to RotatePoint).
With ptCenter
.X = CenterX
.Y = CenterY
End With
'Rotate the point of origin to match
'the desired rotation (RotDegrees).
Call RotatePoint(ptCenter, ptOrigin, RotDegrees)
'Now Print the rotated text and return success/failure.
PrintRotText = (TextOut(hDC, ptOrigin.X, _
ptOrigin.Y, Text, Len(Text)) <> 0)
End If
'Put the original font back into the device.
hFontNew = SelectObject(hDC, hFontOld)
End If
'Clean up memory by deleting the created font.
Call DeleteObject(hFontNew)
End If
End If
End Function
Private Sub RotatePoint(ptAxis As PointAPI, ptRotate As PointAPI, fDegrees As Single)
' ***************************************************
' * RotatePoint *
' * *
' * Created by: Rocky Clark (Kath-Rock Software) *
' * *
' * Rotate ptRotate around ptAxis, fDegrees from *
' * its current position. *
' * *
' * This procedure may be used and distributed, as *
' * is, in your code, as long as these credits and *
' * the code itself remain unchanged. *
' * *
' ***************************************************
Dim fDX As Single 'Delta X
Dim fDY As Single 'Delta Y
Dim fRads As Single 'Radians
Const dPi As Double = 3.14159265358979 'Pi
'Convert degrees to radians.
fRads = fDegrees * (dPi / 180#)
'Calculate the deltas from the center point.
fDX = ptRotate.X - ptAxis.X
fDY = ptRotate.Y - ptAxis.Y
'Rotate the point.
ptRotate.X = ptAxis.X + ((fDX * Cos(fRads)) + (fDY * Sin(fRads)))
ptRotate.Y = ptAxis.Y + -((fDX * Sin(fRads)) - (fDY * Cos(fRads)))
End Sub
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?