还有这个函数GetCaretPos Public Declare Function GetCaretPos Lib "user32" (lpPoint As POINTAPI) As Long Type POINTAPI X As Long Y As Long End Type Public POINTAPI As POINTAPI
IViewObjectEx::GetRect Returns a rectangle describing a requested drawing aspect.HRESULT GetRect( DWORD dwAspect, //Requested drawing aspect LPRECTL pRect //Pointer to the rectangle ); Parameters dwAspect [in] Drawing aspect requested. pRect [out] Pointer to the rectangle describing the requested drawing aspect. Return Values S_OK The rectangle was successfully returned. DV_E_DVASPECT The method does not support the specified aspect. Either the object does not support the aspect requested or the aspect is not rectangular. Res This method returns a rectangle describing the specified drawing aspect. The returned rectangle is in HIMETRIC units, relative to the object's origin. The rectangle returned depends on the drawing aspect as follows: DVASPECT_CONTENT Objects should return the bounding rectangle of the whole object. The top-left corner is at the object's origin and the size is equal to the extent returned by IViewObject2::GetExtent. DVASPECT_OPAQUE Objects with a rectangular opaque region should return that rectangle. Others should fail and return error code DV_E_DVASPECT. If a rectangle is returned, it is guaranteed to be completely obscured by calling IViewObject::Draw for that aspect. The container should use that rectangle to clip out the object's opaque parts before drawing any object behind it during the back to front pass. If this method fails on an object with a non-rectangular opaque region, the container should draw the entire object in the back to front part using the DVASPECT_CONTENT aspect. DVASPECT_TRANSPARENT Objects should return the rectangle covering all transparent or irregular parts. If the object does not have any transparent or irregular parts, it may return DV_E_ASPECT. A container may use this rectangle to determine whether there are other objects overlapping the transparent parts of a given object.
//但到了Rich Edit 2.0才支持PARAFORMAT2,允许用户取得/设置行间距 原来PARAFORMAT没有行间距设置功能尽信书则不如无书,你测试一下不就知道了:)Option Explicit Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Const WM_USER& = &H400 Private Const EM_GETPARAFORMAT = (WM_USER + 61) Private Const EM_SETPARAFORMAT = (WM_USER + 71) Private Const MAX_TAB_STOPS = 32& Private Const PFM_LINESPACING = &H100& Private Type PARAFORMAT2 cbSize As Integer wPad1 As Integer dwMask As Long wNumbering As Integer wEffects As Integer dxStartIndent As Long dxRightIndent As Long dxOffset As Long wAlignment As Integer cTabCount As Integer lTabStops(0 To MAX_TAB_STOPS - 1) As Long ' PARAFORMAT2 dySpaceBefore As Long dySpaceAfter As Long dyLineSpacing As Long sStyle As Integer bLineSpacingRule As Byte bOutlineLevel As Byte wShadingWeight As Integer wShadingStyle As Integer wNumberingStart As Integer wNumberingStyle As Integer wNumberingTab As Integer wBorderSpace As Integer wBorderWidth As Integer wBorders As Integer End TypePrivate Sub Command1_Click() Dim PF2 As PARAFORMAT2 With PF2 .cbSize = LenB(PF2) .dwMask = PFM_LINESPACING .bLineSpacingRule = 4 .dyLineSpacing = 100 * Screen.TwipsPerPixelY End With Dim i As Long i = SendMessage(RichTextBox1.hwnd, EM_SETPARAFORMAT, 0, PF2) End Sub
//但到了Rich Edit 2.0才支持PARAFORMAT2,允许用户取得/设置行间距 原来PARAFORMAT没有行间距设置功能尽信书则不如无书,你测试一下不就知道了:)Option Explicit Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Const WM_USER& = &H400 Private Const EM_GETPARAFORMAT = (WM_USER + 61) Private Const EM_SETPARAFORMAT = (WM_USER + 71) Private Const MAX_TAB_STOPS = 32& Private Const PFM_LINESPACING = &H100& Private Type PARAFORMAT2 cbSize As Integer wPad1 As Integer dwMask As Long wNumbering As Integer wEffects As Integer dxStartIndent As Long dxRightIndent As Long dxOffset As Long wAlignment As Integer cTabCount As Integer lTabStops(0 To MAX_TAB_STOPS - 1) As Long ' PARAFORMAT2 dySpaceBefore As Long dySpaceAfter As Long dyLineSpacing As Long sStyle As Integer bLineSpacingRule As Byte bOutlineLevel As Byte wShadingWeight As Integer wShadingStyle As Integer wNumberingStart As Integer wNumberingStyle As Integer wNumberingTab As Integer wBorderSpace As Integer wBorderWidth As Integer wBorders As Integer End TypePrivate Sub Command1_Click() Dim PF2 As PARAFORMAT2 With PF2 .cbSize = LenB(PF2) .dwMask = PFM_LINESPACING .bLineSpacingRule = 4 .dyLineSpacing = 100 * Screen.TwipsPerPixelY End With Dim i As Long i = SendMessage(RichTextBox1.hwnd, EM_SETPARAFORMAT, 0, PF2) End Sub
Selection.GetPoint cprGPLeft + cprGPStart + cprGPTop, x, Y_T
lHeight = Y_B - Y_T '此处的lHeight即表示本行的行高不过在VB中还不能很好的实现TOM模型,在Word中可以用。
另外获取的高度有时不准确(比如该行的当前位置不在屏幕范围中)其他高手们有没有更好的办法呢?
Public Declare Function GetCaretPos Lib "user32" (lpPoint As POINTAPI) As Long Type POINTAPI
X As Long
Y As Long
End Type Public POINTAPI As POINTAPI
Returns a rectangle describing a requested drawing aspect.HRESULT GetRect(
DWORD dwAspect, //Requested drawing aspect
LPRECTL pRect //Pointer to the rectangle
);
Parameters
dwAspect
[in] Drawing aspect requested.
pRect
[out] Pointer to the rectangle describing the requested drawing aspect.
Return Values
S_OK
The rectangle was successfully returned.
DV_E_DVASPECT
The method does not support the specified aspect. Either the object does not support the aspect requested or the aspect is not rectangular.
Res
This method returns a rectangle describing the specified drawing aspect. The returned rectangle is in HIMETRIC units, relative to the object's origin. The rectangle returned depends on the drawing aspect as follows: DVASPECT_CONTENT
Objects should return the bounding rectangle of the whole object. The top-left corner is at the object's origin and the size is equal to the extent returned by IViewObject2::GetExtent.
DVASPECT_OPAQUE
Objects with a rectangular opaque region should return that rectangle. Others should fail and return error code DV_E_DVASPECT.
If a rectangle is returned, it is guaranteed to be completely obscured by calling IViewObject::Draw for that aspect. The container should use that rectangle to clip out the object's opaque parts before drawing any object behind it during the back to front pass. If this method fails on an object with a non-rectangular opaque region, the container should draw the entire object in the back to front part using the DVASPECT_CONTENT aspect. DVASPECT_TRANSPARENT
Objects should return the rectangle covering all transparent or irregular parts. If the object does not have any transparent or irregular parts, it may return DV_E_ASPECT. A container may use this rectangle to determine whether there are other objects overlapping the transparent parts of a given object.
发送EM_EXGETSEL消息可以得到当前选择的字符位置
发送EM_LINEFROMCHAR消息可以得到字符位置所处行号
发送EM_LINEINDEX消息可以知道某行第一个字符的字符位置所以我们可以这样做:
发送EM_EXGETSEL消息得到当前光标所处字符位置
发送EM_LINEFROMCHAR消息得到当前行行号
发送EM_LINEINDEX消息可得到当前行及下一行的字符位置
发送EM_POSFROMCHAR消息可以得到当前行及下一行的坐标位置
再将两个坐标相减,就可得到行高这其实就是happywqw(键盘跳蚤)提出来的方法
只不过他用的是TOM
而我这是直接发送RichTextBox消息行高是包括行间距的
注意看选择文本时的反色区域
行高是指字符高度+行间距
所以不需要减行间距(何况你还需要算上图片高度)
如果需要减行间距的话,就用senmemessage发送 EM_GETPARAFORMAT消息
只有Rich Edit 2.0+才支持PARAFORMAT2,支持行间距
只有Rich Edit 2.0+才支持PARAFORMAT2,支持行间距
说是这么说,但经过测试,RichTextBox还是支持行间距的
但到了Rich Edit 2.0才支持PARAFORMAT2,允许用户取得/设置行间距
原来PARAFORMAT没有行间距设置功能
原来PARAFORMAT没有行间距设置功能尽信书则不如无书,你测试一下不就知道了:)Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_USER& = &H400
Private Const EM_GETPARAFORMAT = (WM_USER + 61)
Private Const EM_SETPARAFORMAT = (WM_USER + 71)
Private Const MAX_TAB_STOPS = 32&
Private Const PFM_LINESPACING = &H100&
Private Type PARAFORMAT2
cbSize As Integer
wPad1 As Integer
dwMask As Long
wNumbering As Integer
wEffects As Integer
dxStartIndent As Long
dxRightIndent As Long
dxOffset As Long
wAlignment As Integer
cTabCount As Integer
lTabStops(0 To MAX_TAB_STOPS - 1) As Long
' PARAFORMAT2
dySpaceBefore As Long
dySpaceAfter As Long
dyLineSpacing As Long
sStyle As Integer
bLineSpacingRule As Byte
bOutlineLevel As Byte
wShadingWeight As Integer
wShadingStyle As Integer
wNumberingStart As Integer
wNumberingStyle As Integer
wNumberingTab As Integer
wBorderSpace As Integer
wBorderWidth As Integer
wBorders As Integer
End TypePrivate Sub Command1_Click()
Dim PF2 As PARAFORMAT2
With PF2
.cbSize = LenB(PF2)
.dwMask = PFM_LINESPACING
.bLineSpacingRule = 4
.dyLineSpacing = 100 * Screen.TwipsPerPixelY
End With
Dim i As Long
i = SendMessage(RichTextBox1.hwnd, EM_SETPARAFORMAT, 0, PF2)
End Sub
原来PARAFORMAT没有行间距设置功能尽信书则不如无书,你测试一下不就知道了:)Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_USER& = &H400
Private Const EM_GETPARAFORMAT = (WM_USER + 61)
Private Const EM_SETPARAFORMAT = (WM_USER + 71)
Private Const MAX_TAB_STOPS = 32&
Private Const PFM_LINESPACING = &H100&
Private Type PARAFORMAT2
cbSize As Integer
wPad1 As Integer
dwMask As Long
wNumbering As Integer
wEffects As Integer
dxStartIndent As Long
dxRightIndent As Long
dxOffset As Long
wAlignment As Integer
cTabCount As Integer
lTabStops(0 To MAX_TAB_STOPS - 1) As Long
' PARAFORMAT2
dySpaceBefore As Long
dySpaceAfter As Long
dyLineSpacing As Long
sStyle As Integer
bLineSpacingRule As Byte
bOutlineLevel As Byte
wShadingWeight As Integer
wShadingStyle As Integer
wNumberingStart As Integer
wNumberingStyle As Integer
wNumberingTab As Integer
wBorderSpace As Integer
wBorderWidth As Integer
wBorders As Integer
End TypePrivate Sub Command1_Click()
Dim PF2 As PARAFORMAT2
With PF2
.cbSize = LenB(PF2)
.dwMask = PFM_LINESPACING
.bLineSpacingRule = 4
.dyLineSpacing = 100 * Screen.TwipsPerPixelY
End With
Dim i As Long
i = SendMessage(RichTextBox1.hwnd, EM_SETPARAFORMAT, 0, PF2)
End Sub
Rich Edit SDK 中文参考:
http://www.cnpopsoft.com/blog/article.asp?id=3