Sometimes, I need to take action on only those lines visible within a
RichEdit control. The top line is easily retrieved using the GetFirstVisibleLine
message, whereas a combination of messages is required to get the bottom
line.
Primary Code:
The CharFromPos message is used to get the character at the bottom of
the client area of the RichEdit control. If there is no character there, then
CharFromPos returns the closest character - from which the LineFromChar
message can be used to get the bottom-most visible line#.
The great thing about CharFromPos is that it returns the nearest character,
even if that character is not directly under the specified position. So this
code works even when the last visible line in the control is not at the bottom
of the RichEdit control client area.
The code is provided below, and is also available in the
gbSnippets PowerBASIC source code library (snippet# gbs_00407).
You can get the entire library by downloading gbSnippets or you
can view individual snippets online.
gbSnippets home page: http://www.garybeene.com/sw/gbsnippets.htm
Online source code listings: http://www.garybeene.com/power/code/
If you've already installed gbSnippets, you can ensure that your local
library is synchronized with the latest snippets on the gbSnippets server
by using the "Actions/Synchronize with gbSnippets Server" menu.
Here's the basic code:
Compilable Example:
And here's a compilable example:
RichEdit control. The top line is easily retrieved using the GetFirstVisibleLine
message, whereas a combination of messages is required to get the bottom
line.
Primary Code:
The CharFromPos message is used to get the character at the bottom of
the client area of the RichEdit control. If there is no character there, then
CharFromPos returns the closest character - from which the LineFromChar
message can be used to get the bottom-most visible line#.
The great thing about CharFromPos is that it returns the nearest character,
even if that character is not directly under the specified position. So this
code works even when the last visible line in the control is not at the bottom
of the RichEdit control client area.
The code is provided below, and is also available in the
gbSnippets PowerBASIC source code library (snippet# gbs_00407).
You can get the entire library by downloading gbSnippets or you
can view individual snippets online.
gbSnippets home page: http://www.garybeene.com/sw/gbsnippets.htm
Online source code listings: http://www.garybeene.com/power/code/
If you've already installed gbSnippets, you can ensure that your local
library is synchronized with the latest snippets on the gbSnippets server
by using the "Actions/Synchronize with gbSnippets Server" menu.
Here's the basic code:
Code:
Sub GetTopBottomLines(iTopLine&, iBottomLine&) 'assumes hDlg, %IDC_RichEdit and hRichEdit Global variables Local P as Point, w as Long, h as Long Control Get Client hDlg, %IDC_RichEdit TO w,h P.x = w : P.y = h iTopLine& = SendMessage(hRichEdit, %EM_GetFirstVisibleLine,0,0) 'visible line# at top of control iBottomLine& = SendMessage(hRichEdit, %EM_CharFromPos, 0, VarPTR(P) ) iBottomLine& = SendMessage(hRichEdit, %EM_LineFromChar, iBottomLine&, 0) End Sub
And here's a compilable example:
Code:
'Compilable Example: #Compile Exe #Dim All #Include "Win32API.inc" #Include "RichEdit.inc" #Include "CommCtrl.inc" Global hDlg as DWord, hRichEdit as DWord %ID_RichEdit = 500 Function PBMain() As Long Local style&, buf$, i As Long For i = 0 To 40 : buf$ = buf$ + Str$(i) + "line" + $CrLf : Next i : buf$ = Trim$(buf$, $crlf) style& = %WS_Child Or %WS_Visible Or %ES_MultiLine Or %WS_VScroll Or %ES_AutoHScroll _ Or %WS_HScroll Or %ES_AutoVScroll Or %ES_WantReturn Or %ES_NoHideSel Or %WS_TabStop Dialog New Pixels, 0, "Test Code",300,300,200,150, %WS_OverlappedWindow To hDlg Control Add Button, hDlg, 100,"Push", 30,10,140,20 LoadLibrary("riched32.dll") : InitCommonControls Control Add "RichEdit", hDlg, %ID_RichEdit, buf$,20,40,160,100, style&, %WS_EX_ClientEdge Control Handle hDlg, %ID_RichEdit To hRichEdit Dialog Show Modal hDlg Call DlgProc End Function CallBack Function DlgProc() As Long Local iTopLine&, iBottomLine&, P as Point, w as Long, h as Long Select Case CB.Msg Case %WM_Command If CB.Ctl = 100 AND CB.Ctlmsg = %BN_Clicked Then GetTopBottomLines(iTopLine&, iBottomLine&) ? Str$(iTopLine&) + " : " + Str$(iBottomLine&) End If Case %WM_Size Dialog Get Client hDlg To w,h Control Set Size hDlg, %ID_RichEdit, w-40, h-60 End Select End Function Sub GetTopBottomLines(iTopLine&, iBottomLine&) 'assumes hDlg, %ID_RichEdit and hRichEdit Global variables Local P as Point, w as Long, h as Long Control Get Client hDlg, %ID_RichEdit TO w,h P.x = w : P.y = h iTopLine& = SendMessage(hRichEdit, %EM_GetFirstVisibleLine,0,0) 'visible line# at top of control iBottomLine& = SendMessage(hRichEdit, %EM_CharFromPos, 0, VarPTR(P) ) iBottomLine& = SendMessage(hRichEdit, %EM_LineFromChar, iBottomLine&, 0) End Sub 'gbs_00407