Discussion:
CEditView and linie numbers
(too old to reply)
Laurs
2008-12-12 09:39:00 UTC
Permalink
My apllication should display line numbers in a MDI applications Text windows
view. Each line should have its own line number, like:
00001 Some text
00002 Next line with text
00003 Another ....

Wordwrap is not on
Any hint?
AliR (VC++ MVP)
2008-12-12 15:43:04 UTC
Permalink
You will have to write a custom control to that, which means you will have
to write your own edit control from scratch.

See if this helps:
http://www.learnstar.com/AliR/HexView.zip

I wrote this sample while I was helping someone on here a couple of years
ago. All of the logic of the hex editor is in the HexViewView.cpp class.

AliR.
Post by Laurs
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
Joseph M. Newcomer
2008-12-13 19:16:48 UTC
Permalink
There are three approaches:

(a) write your own edit control
(b) create your control borderless. Put a borderless control next to it, in which you put
the line numbers. Keep the two controls "in sync" as you scroll the edit control (it
isn't impossible, but is tedious)
(c) use rich edit, make the line numbers protected, keep them updated as you add or remove
lines (really tedious, as it turns out, but I've been told it is comparable to (b))
joe
Post by Laurs
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Laurs
2008-12-15 14:13:10 UTC
Permalink
Hi
Thanks. I see both proposals as possible, but have ended with a more lazy
version. I just write the line number and caracter position (L,P) in a Pane
in my CStatusBar.
Only one thing is missing. When I move the caret(text cursor) with the
keyboard or mouse I get no event.
How can I get a notification for that in in my messagehandler:
BEGIN_MESSAGE_MAP(MICVIWTXT, GICVED)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
END_MESSAGE_MAP()
None of these
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_KEYDOWN()
gives me any help.
Best regards
Laurs
Post by Joseph M. Newcomer
(a) write your own edit control
(b) create your control borderless. Put a borderless control next to it, in which you put
the line numbers. Keep the two controls "in sync" as you scroll the edit control (it
isn't impossible, but is tedious)
(c) use rich edit, make the line numbers protected, keep them updated as you add or remove
lines (really tedious, as it turns out, but I've been told it is comparable to (b))
joe
Post by Laurs
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Laurs
2008-12-15 15:57:02 UTC
Permalink
Hi
I found it on GodeGuru, so no panic

ON_UPDATE_COMMAND_UI(ID_INDICATOR_CURPOS, OnUpdateCurPosIndicator)

void CMainFrame::OnUpdateCurPosIndicator(CCmdUI *pCmdUI)
{
CString strCurPos;
int nLineNum, nColNum;
int nSelStart, nSelEnd;

// you're going to have to get a pointer
// to the edit control in the view
m_wndEditCtrl->GetSel(nSelStart, nSelEnd);
nLineNum = m_wndEditCtrl->LineFromChar(nSelStart);
nColNum = nSelStart - m_wndEditCtrl->LineIndex(nLineNum);
strCurPos.Format(ID_INDICATOR_CURPOS,
nLineNum+1,
nColNum+1);

m_wndStatusBar.SetPaneText(
m_wndStatusBar.CommandToIndex(ID_INDICATOR_CURPOS),
strCurPos);
}
Post by Laurs
Hi
Thanks. I see both proposals as possible, but have ended with a more lazy
version. I just write the line number and caracter position (L,P) in a Pane
in my CStatusBar.
Only one thing is missing. When I move the caret(text cursor) with the
keyboard or mouse I get no event.
BEGIN_MESSAGE_MAP(MICVIWTXT, GICVED)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
END_MESSAGE_MAP()
None of these
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_KEYDOWN()
gives me any help.
Best regards
Laurs
Post by Joseph M. Newcomer
(a) write your own edit control
(b) create your control borderless. Put a borderless control next to it, in which you put
the line numbers. Keep the two controls "in sync" as you scroll the edit control (it
isn't impossible, but is tedious)
(c) use rich edit, make the line numbers protected, keep them updated as you add or remove
lines (really tedious, as it turns out, but I've been told it is comparable to (b))
joe
Post by Laurs
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2008-12-15 16:11:30 UTC
Permalink
Yes, this is a problem; an edit control gives no notification of selection change. THe
way I handled this was that I subclassed CEdit, and handle keyboard and mouse
notifications, track the current selection, and force an update of the position
information if the selection changes. This is a bit of a pain, and today, I would use a
rich edit control, use SetEventMask to allow EN_SELCHANGE notifications, and handle the
EN_SELCHANGE notification to force the update.
joe
Post by Laurs
Hi
Thanks. I see both proposals as possible, but have ended with a more lazy
version. I just write the line number and caracter position (L,P) in a Pane
in my CStatusBar.
Only one thing is missing. When I move the caret(text cursor) with the
keyboard or mouse I get no event.
BEGIN_MESSAGE_MAP(MICVIWTXT, GICVED)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
END_MESSAGE_MAP()
None of these
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_KEYDOWN()
gives me any help.
Best regards
Laurs
Post by Joseph M. Newcomer
(a) write your own edit control
(b) create your control borderless. Put a borderless control next to it, in which you put
the line numbers. Keep the two controls "in sync" as you scroll the edit control (it
isn't impossible, but is tedious)
(c) use rich edit, make the line numbers protected, keep them updated as you add or remove
lines (really tedious, as it turns out, but I've been told it is comparable to (b))
joe
Post by Laurs
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
unknown
2010-03-04 04:17:21 UTC
Permalink
step 1 :-----

SendMessage( hRichEdit, EM_SETMARGINS, EC_LEFTMARGIN, 70 );

step 2 :------

case WM_COMMAND:
switch( HIWORD(wParam) ){
case EN_UPDATE:
hRichEdit = FindWindowEx( hwnd, NULL, "RichEdit20A", NULL );
hdc = GetDC( hRichEdit );
makeLineNumber( hRichEdit, hdc );
ReleaseDC( hRichEdit, hdc );
break;
}
break;


step 3:----
void makeLineNumber( HWND hRichEdit, HDC hdc ){

/*get height of rich edit*/
RECT richEditRect;
SendMessage( hRichEdit, EM_GETRECT, 0 , (LPARAM)&richEditRect );
int iRectHeight = richEditRect.bottom - richEditRect.top;

/*get height of font being used*/
TEXTMETRIC tm;
GetTextMetrics( hdc, &tm );

/*use height of font and height of rich edit control to get the maximum number of lines
the edit control can hold, increase by one for additional line (necessary because rich
edit has smooth scrolling and shows partial line*/
int iMaxNumberOfLines = (iRectHeight/tm.tmHeight) + 1;

/*get first visible line*/
int iFirstVisibleLine = SendMessage( hRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0 );

/*create integers to temporarily hold the line number/char*/
int iLineChar = 0;
int iLineNumber = 0;

/*loop cannot run more than the max number of lines in the edit control*/
for( int c = 0; c <= iMaxNumberOfLines; c++ ){
/*return value is the character index of the line specified in the wParam parameter,
or it is ?1 if the specified line number is greater than the number of lines in the
edit control. */
iLineChar = SendMessage( hRichEdit, EM_LINEINDEX, (iFirstVisibleLine + c ), 0 );

/*break if last line of edit control is reached*/
if( iLineChar == -1 )
break;

/*otherwise output line number*/
else{
iLineNumber = SendMessage( hRichEdit, EM_LINEFROMCHAR, (WPARAM)iLineChar, 0 );
std::stringstream strLineIndex;
strLineIndex << (iLineNumber + 1);

POINTL pl;
SendMessage( hRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, (LPARAM)iLineChar );

RECT tmpRect;
tmpRect.right = 55; //right border is 55 (rich edit control left border is 70 so there is a gap of 15)
tmpRect.left = 0; //left border is flush with edge of window
tmpRect.bottom = richEditRect.bottom; //bottom is same as rich edit controls bottom
tmpRect.top = pl.y; //top is the y position of the characters in that line number

DrawText( hdc, strLineIndex.str().c_str(), strlen( strLineIndex.str().c_str() ), &tmpRect, DT_RIGHT );
}
}

}



Laur wrote:

CEditView and linie numbers
12-Dec-08

My apllication should display line numbers in a MDI applications Text windows
view. Each line should have its own line number, like
00001 Some tex
00002 Next line with tex
00003 Another ...

Wordwrap is not on
Any hint?

Previous Posts In This Thread:

On Friday, December 12, 2008 4:39 AM
Laur wrote:

CEditView and linie numbers
My apllication should display line numbers in a MDI applications Text windows
view. Each line should have its own line number, like
00001 Some tex
00002 Next line with tex
00003 Another ...

Wordwrap is not on
Any hint?

On Friday, December 12, 2008 10:43 AM
AliR \(VC++ MVP\) wrote:

You will have to write a custom control to that, which means you will have to
You will have to write a custom control to that, which means you will have
to write your own edit control from scratch

See if this helps
http://www.learnstar.com/AliR/HexView.zi

I wrote this sample while I was helping someone on here a couple of years
ago. All of the logic of the hex editor is in the HexViewView.cpp class

AliR

"Laurs" <***@discussions.microsoft.com> wrote in message news:81AC5C46-A075-48B0-A486-***@microsoft.com...

On Saturday, December 13, 2008 2:16 PM
Joseph M. Newcomer wrote:

Re: CEditView and linie numbers
There are three approaches

(a) write your own edit control
(b) create your control borderless. Put a borderless control next to it, in which you put
the line numbers. Keep the two controls "in sync" as you scroll the edit control (it
isn't impossible, but is tedious)
(c) use rich edit, make the line numbers protected, keep them updated as you add or remove
lines (really tedious, as it turns out, but I've been told it is comparable to (b))
joe

On Fri, 12 Dec 2008 01:39:00 -0800, Laurs <***@discussions.microsoft.com> wrote:

Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

On Monday, December 15, 2008 9:13 AM
Laur wrote:

HiThanks.
Hi
Thanks. I see both proposals as possible, but have ended with a more lazy
version. I just write the line number and caracter position (L,P) in a Pane
in my CStatusBar.
Only one thing is missing. When I move the caret(text cursor) with the
keyboard or mouse I get no event.
How can I get a notification for that in in my messagehandler:
BEGIN_MESSAGE_MAP(MICVIWTXT, GICVED)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
END_MESSAGE_MAP()
None of these
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_KEYDOWN()
gives me any help.
Best regards
Laurs


"Joseph M. Newcomer" wrote:

On Monday, December 15, 2008 10:57 AM
Laur wrote:

HiI found it on GodeGuru, so no panicON_UPDATE_COMMAND_UI(ID_INDICATOR_CURPOS,
Hi
I found it on GodeGuru, so no panic

ON_UPDATE_COMMAND_UI(ID_INDICATOR_CURPOS, OnUpdateCurPosIndicator)

void CMainFrame::OnUpdateCurPosIndicator(CCmdUI *pCmdUI)
{
CString strCurPos;
int nLineNum, nColNum;
int nSelStart, nSelEnd;

// you're going to have to get a pointer
// to the edit control in the view
m_wndEditCtrl->GetSel(nSelStart, nSelEnd);
nLineNum = m_wndEditCtrl->LineFromChar(nSelStart);
nColNum = nSelStart - m_wndEditCtrl->LineIndex(nLineNum);
strCurPos.Format(ID_INDICATOR_CURPOS,
nLineNum+1,
nColNum+1);

m_wndStatusBar.SetPaneText(
m_wndStatusBar.CommandToIndex(ID_INDICATOR_CURPOS),
strCurPos);
}


"Laurs" wrote:

On Monday, December 15, 2008 11:11 AM
Joseph M. Newcomer wrote:

Yes, this is a problem; an edit control gives no notification of selection
Yes, this is a problem; an edit control gives no notification of selection change. THe
way I handled this was that I subclassed CEdit, and handle keyboard and mouse
notifications, track the current selection, and force an update of the position
information if the selection changes. This is a bit of a pain, and today, I would use a
rich edit control, use SetEventMask to allow EN_SELCHANGE notifications, and handle the
EN_SELCHANGE notification to force the update.
joe

On Mon, 15 Dec 2008 06:13:10 -0800, Laurs <***@discussions.microsoft.com> wrote:

Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


Submitted via EggHeadCafe - Software Developer Portal of Choice
What's New for Developers in SharePoint 2010 Object Model?
http://www.eggheadcafe.com/tutorials/aspnet/84e8403e-a25c-49b7-a0d8-3e2773fa29b5/whats-new-for-developers.aspx
Joseph M. Newcomer
2010-03-04 05:16:21 UTC
Permalink
See below...
Post by unknown
step 1 :-----
SendMessage( hRichEdit, EM_SETMARGINS, EC_LEFTMARGIN, 70 );
*****
Not sure how you arrived at the magical number "70". I certainly would not trust this
number to be meaningful except on your current display, with your current display driver
and your current display card, with your current default font and your current screen
resolution. If you want to put line numbers out, you need to do something like
GetTextExtent32 on a string of digits (e.g., _T("000000")) to find out how wide they are
RIGHT NOW in THIS SYSTEM, and use that width (plus perhaps some fudge factors, such as
adding some spaces around it)
****
Post by unknown
step 2 :------
switch( HIWORD(wParam) ){
hRichEdit = FindWindowEx( hwnd, NULL, "RichEdit20A", NULL );
****
This is almost certainly the WRONG way to find the control. You should know the control
ID and do GetDlgItem to get it. If you were to have two controls, this would fail
completely. Since you created the control, you know its ID.
****
Post by unknown
hdc = GetDC( hRichEdit );
makeLineNumber( hRichEdit, hdc );
ReleaseDC( hRichEdit, hdc );
break;
}
break;
step 3:----
void makeLineNumber( HWND hRichEdit, HDC hdc ){
/*get height of rich edit*/
RECT richEditRect;
SendMessage( hRichEdit, EM_GETRECT, 0 , (LPARAM)&richEditRect );
int iRectHeight = richEditRect.bottom - richEditRect.top;
/*get height of font being used*/
TEXTMETRIC tm;
GetTextMetrics( hdc, &tm );
****
This assumes that all your text is in the same-height font. Rich edit does not require
this. I'd be inclined to compute the point from a line index, which will take into
account line wrap, different font heights, etc.
****
Post by unknown
/*use height of font and height of rich edit control to get the maximum number of lines
the edit control can hold, increase by one for additional line (necessary because rich
edit has smooth scrolling and shows partial line*/
int iMaxNumberOfLines = (iRectHeight/tm.tmHeight) + 1;
/*get first visible line*/
int iFirstVisibleLine = SendMessage( hRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0 );
/*create integers to temporarily hold the line number/char*/
int iLineChar = 0;
int iLineNumber = 0;
/*loop cannot run more than the max number of lines in the edit control*/
for( int c = 0; c <= iMaxNumberOfLines; c++ ){
/*return value is the character index of the line specified in the wParam parameter,
or it is ?1 if the specified line number is greater than the number of lines in the
edit control. */
iLineChar = SendMessage( hRichEdit, EM_LINEINDEX, (iFirstVisibleLine + c ), 0 );
****
SendMessage is such a clumsy and essentially obsolete way to do this that I find the code
nearly unreadable. Use the macros in windowsx.h whenever possible; the code is easier to
write, and much easier to maintain!
****
Post by unknown
/*break if last line of edit control is reached*/
if( iLineChar == -1 )
break;
/*otherwise output line number*/
else{
iLineNumber = SendMessage( hRichEdit, EM_LINEFROMCHAR, (WPARAM)iLineChar, 0 );
std::stringstream strLineIndex;
strLineIndex << (iLineNumber + 1);
POINTL pl;
SendMessage( hRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, (LPARAM)iLineChar );
RECT tmpRect;
tmpRect.right = 55; //right border is 55 (rich edit control left border is 70 so there is a gap of 15)
*****
Again, numbers like this are essentially gibberish, and might as well be chosen by using
rand() for all the good they do. ALWAYS ask how wide something is in the current screen
resolution, with the current default font size, etc. by using values based either on
GetWindowRect, GetClientRect, and GetTextExtent types of computations. And whatever else
you need to make sure that such constants are never, ever wired into your code.
****
Post by unknown
tmpRect.left = 0; //left border is flush with edge of window
tmpRect.bottom = richEditRect.bottom; //bottom is same as rich edit controls bottom
tmpRect.top = pl.y; //top is the y position of the characters in that line number
DrawText( hdc, strLineIndex.str().c_str(), strlen( strLineIndex.str().c_str() ), &tmpRect, DT_RIGHT );
}
}
}
CEditView and linie numbers
12-Dec-08
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
On Friday, December 12, 2008 4:39 AM
CEditView and linie numbers
My apllication should display line numbers in a MDI applications Text windows
00001 Some text
00002 Next line with text
00003 Another ....
Wordwrap is not on
Any hint?
On Friday, December 12, 2008 10:43 AM
You will have to write a custom control to that, which means you will have to
You will have to write a custom control to that, which means you will have
to write your own edit control from scratch.
http://www.learnstar.com/AliR/HexView.zip
I wrote this sample while I was helping someone on here a couple of years
ago. All of the logic of the hex editor is in the HexViewView.cpp class.
AliR.
On Saturday, December 13, 2008 2:16 PM
Re: CEditView and linie numbers
(a) write your own edit control
(b) create your control borderless. Put a borderless control next to it, in which you put
the line numbers. Keep the two controls "in sync" as you scroll the edit control (it
isn't impossible, but is tedious)
(c) use rich edit, make the line numbers protected, keep them updated as you add or remove
lines (really tedious, as it turns out, but I've been told it is comparable to (b))
joe
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
On Monday, December 15, 2008 9:13 AM
HiThanks.
Hi
Thanks. I see both proposals as possible, but have ended with a more lazy
version. I just write the line number and caracter position (L,P) in a Pane
in my CStatusBar.
Only one thing is missing. When I move the caret(text cursor) with the
keyboard or mouse I get no event.
BEGIN_MESSAGE_MAP(MICVIWTXT, GICVED)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
END_MESSAGE_MAP()
None of these
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_KEYDOWN()
gives me any help.
Best regards
Laurs
On Monday, December 15, 2008 10:57 AM
HiI found it on GodeGuru, so no panicON_UPDATE_COMMAND_UI(ID_INDICATOR_CURPOS,
Hi
I found it on GodeGuru, so no panic
ON_UPDATE_COMMAND_UI(ID_INDICATOR_CURPOS, OnUpdateCurPosIndicator)
void CMainFrame::OnUpdateCurPosIndicator(CCmdUI *pCmdUI)
{
CString strCurPos;
int nLineNum, nColNum;
int nSelStart, nSelEnd;
// you're going to have to get a pointer
// to the edit control in the view
m_wndEditCtrl->GetSel(nSelStart, nSelEnd);
nLineNum = m_wndEditCtrl->LineFromChar(nSelStart);
nColNum = nSelStart - m_wndEditCtrl->LineIndex(nLineNum);
strCurPos.Format(ID_INDICATOR_CURPOS,
nLineNum+1,
nColNum+1);
m_wndStatusBar.SetPaneText(
m_wndStatusBar.CommandToIndex(ID_INDICATOR_CURPOS),
strCurPos);
}
On Monday, December 15, 2008 11:11 AM
Yes, this is a problem; an edit control gives no notification of selection
Yes, this is a problem; an edit control gives no notification of selection change. THe
way I handled this was that I subclassed CEdit, and handle keyboard and mouse
notifications, track the current selection, and force an update of the position
information if the selection changes. This is a bit of a pain, and today, I would use a
rich edit control, use SetEventMask to allow EN_SELCHANGE notifications, and handle the
EN_SELCHANGE notification to force the update.
joe
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Submitted via EggHeadCafe - Software Developer Portal of Choice
What's New for Developers in SharePoint 2010 Object Model?
http://www.eggheadcafe.com/tutorials/aspnet/84e8403e-a25c-49b7-a0d8-3e2773fa29b5/whats-new-for-developers.aspx
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Loading...