Edit显示代码行号
关键点
使用这个类然后关联Edit的变量为 LineNumberEdit类型的
实现过程
#if !defined(AFX_LINENUMBEREDIT_H__CAB7A465_709C_42B8_80D0_2B0AF6D25AD4__INCLUDED_) #define AFX_LINENUMBEREDIT_H__CAB7A465_709C_42B8_80D0_2B0AF6D25AD4__INCLUDED_ / // CLineNumberStatic window class CLineNumberStatic : public CStatic { // Construction/destruction public: CLineNumberStatic(); virtual ~ CLineNumberStatic(); // Operations public: void SetFgColor( COLORREF col, BOOL redraw ); void SetBgColor( COLORREF col, BOOL redraw ); void SetTopAndBottom( int topline, int bottomline ); void SetTopMargin( int topmargin ); void SetLineNumberFormat( CString format ); protected: afx_msg BOOL OnEraseBkgnd( CDC* pDC); afx_msg void OnPaint(); afx_msg void OnLButtonDown( UINT nFlags, CPoint point ); DECLARE_MESSAGE_MAP() private: // Attributes COLORREF m_fgcol; COLORREF m_bgcol; CString m_format; int m_topmargin; // Current top margin int m_topline; // Current top line number int m_bottomline; // Current bottom line number }; / // CLineNumberEdit window class CLineNumberEdit : public CEdit { // Construction/destruction public: CLineNumberEdit(); virtual ~ CLineNumberEdit(); // Operations public: void SetMarginForegroundColor( COLORREF col, BOOL redraw = TRUE, BOOL bEnabled = TRUE ); void SetMarginBackgroundColor( COLORREF col, BOOL redraw = TRUE, BOOL bEnabled = TRUE ); void SetLineNumberFormat( CString format ); void SetLineNumberRange( UINT nMin, UINT nMax = 0 ); void UseSystemColours( BOOL bUseEnabled = TRUE, BOOL bUseDisabled = TRUE ); protected: virtual void PreSubclassWindow(); virtual afx_msg void OnEnable( BOOL bEnable ); virtual afx_msg void OnSysColorChange(); virtual afx_msg void OnChange(); virtual afx_msg void OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); virtual afx_msg void OnVscroll(); virtual afx_msg void OnSize( UINT nType, int cx, int cy); virtual afx_msg LRESULT OnSetFont( WPARAM wParam, LPARAM lParam); // Maps to WM_SETFONT virtual afx_msg LRESULT OnSetText( WPARAM wParam, LPARAM lParam); // Maps to WM_SETTEXT virtual afx_msg LRESULT OnLineScroll( WPARAM wParam, LPARAM lParam); // Maps to EM_LINESCROLL virtual afx_msg LRESULT OnSelectLine( WPARAM wParam, LPARAM lParam); DECLARE_MESSAGE_MAP() private: void Prepare(); int CalcLineNumberWidth(); void UpdateTopAndBottom(); // Method to set window colour only void SetWindowColour( BOOL bEnable = TRUE ); // Attributes BOOL m_bUseEnabledSystemColours; COLORREF m_EnabledFgCol; COLORREF m_EnabledBgCol; BOOL m_bUseDisabledSystemColours; COLORREF m_DisabledFgCol; COLORREF m_DisabledBgCol; CLineNumberStatic m_line; CSize m_zero; int m_maxval; CString m_format; int m_LineDelta; // Introduced to provide an offset to the first line number }; #endif // !defined(AFX_LINENUMBEREDIT_H__CAB7A465_709C_42B8_80D0_2B0AF6D25AD4__INCLUDED_) #include "stdafx.h" #include "LineNumberEdit.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // Registered message to allow selection of complete // lines by clicking the line number UINT urm_SELECTLINE = ::RegisterWindowMessage( "_LINE_NUMBER_EDIT_SELECTLINE_" ); / // CLineNumberEdit CLineNumberEdit::CLineNumberEdit() /* ============================================================ Function : CLineNumberEdit::CLineNumberEdit Description : constructor Return : void Parameters : none Usage : ============================================================*/ { m_hWnd = NULL; m_line. m_hWnd = NULL; m_zero. cx = 0; m_zero. cy = 0; m_format = _T( "%05i" ); m_LineDelta = 0; // Could default m_maxval to 99,999, but may cause problems // if m_format is changed and m_maxval is not... m_maxval = 0; // Setting up so by defult the original hard-coded colour // scheme is used when enabled and the system colours are // used when disabled. m_bUseEnabledSystemColours = FALSE; m_bUseDisabledSystemColours = TRUE; m_EnabledFgCol = RGB( 0, 0, 0 ); m_EnabledBgCol = RGB( 255, 255, 248 ); m_DisabledFgCol = GetSysColor( COLOR_GRAYTEXT ); m_DisabledBgCol = GetSysColor( COLOR_3DFACE ); SetWindowColour(); } CLineNumberEdit::~CLineNumberEdit() { } BEGIN_MESSAGE_MAP(CLineNumberEdit, CEdit) ON_CONTROL_REFLECT( EN_CHANGE, OnChange) ON_WM_VSCROLL() ON_CONTROL_REFLECT( EN_VSCROLL, OnVscroll) ON_MESSAGE( WM_SETFONT, OnSetFont) ON_WM_SIZE() ON_MESSAGE( WM_SETTEXT, OnSetText) ON_WM_SYSCOLORCHANGE() ON_WM_ENABLE() ON_MESSAGE( EM_LINESCROLL, OnLineScroll) ON_REGISTERED_MESSAGE( urm_SELECTLINE, OnSelectLine) END_MESSAGE_MAP() void CLineNumberEdit:: PreSubclassWindow() { // Unfortunately, we can't change to ES_MULTILINE // during run-time. ASSERT( GetStyle() & ES_MULTILINE ); // Creating the line number control SetLineNumberFormat( m_format ); } / // CLineNumberEdit message handlers void CLineNumberEdit:: OnSysColorChange() { CEdit:: OnSysColorChange(); // update the CStatic with the new colours SetWindowColour( IsWindowEnabled() ); } LRESULT CLineNumberEdit::OnSetText( WPARAM wParam, LPARAM lParam ) { // Default processing LRESULT retval = DefWindowProc( WM_SETTEXT, wParam, lParam ); UpdateTopAndBottom(); return retval; } void CLineNumberEdit:: OnChange() { UpdateTopAndBottom(); } void CLineNumberEdit:: OnVscroll() { UpdateTopAndBottom(); } void CLineNumberEdit:: OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { CEdit:: OnVScroll( nSBCode, nPos, pScrollBar ); UpdateTopAndBottom(); } LRESULT CLineNumberEdit::OnLineScroll( WPARAM wParam, LPARAM lParam ) { LRESULT retval = DefWindowProc( EM_LINESCROLL, wParam, lParam ); UpdateTopAndBottom(); return retval; } /* ============================================================ Function : CLineNumberEdit::OnSetFont Description : Mapped to WM_SETFONT. We must recalculate the line number control size as well. Return : LRESULT - Always 0 Parameters : WPARAM wParam - From Windows LPARAM lParam - From Windows Usage : Called from Windows ============================================================*/ LRESULT CLineNumberEdit::OnSetFont( WPARAM wParam, LPARAM lParam ) { DefWindowProc( WM_SETFONT, wParam, lParam ); // We resize the line-number // field Prepare(); return 0; } /* ============================================================ Function : CLineNumberEdit::OnSize Description : Handles WM_SIZE. Recalculates the line number control size as well. Return : void Parameters : UINT nType - From Windows int cx - From Windows int cy - From Windows Usage : Called from Windows ============================================================*/ void CLineNumberEdit:: OnSize( UINT nType, int cx, int cy ) { CEdit:: OnSize( nType, cx, cy ); // If we have the line-number // control, it must be resized // as well. if( m_line. m_hWnd ) Prepare(); } /* ============================================================ Function : CLineNumberEdit::OnEnable Description : Handles WM_ENABLE. Calls to set colours. Return : void Parameters : BOOL bEnable - From Windows Usage : Called from Windows. ============================================================*/ void CLineNumberEdit:: OnEnable( BOOL bEnable ) { CEdit:: OnEnable( bEnable ); SetWindowColour( bEnable ); } /* ============================================================ Function : CLineNumberEdit::OnSelectLine Description : Handler for the urm_SELECTLINE registered message. Will select the line in wParam. Return : LRESULT - Not used Parameters : WPARAM wParam - The line to select LPARAM lParam - Not used Usage : Called from MFC. Use SendMessage( urm_SELECTLINE, line ) from code. ============================================================*/ LRESULT CLineNumberEdit::OnSelectLine(WPARAM wParam, LPARAM /*lParam*/ ) { // Calc start and end position of the line int lineno = wParam + GetScrollPos( SB_VERT ); int start = LineIndex( lineno ); int end = LineIndex( lineno + 1 ); SetSel( start, end - 1 ); return 0; } /* ============================================================ Function : CLineNumberEdit::SetWindowColour Description : Handles changing window colours. Return : void Parameters : BOOL bEnable - flag if set enabled/disabled colours Usage : Called to change colours in the edit box. ============================================================*/ void CLineNumberEdit:: SetWindowColour( BOOL bEnable /*= TRUE*/ ) { if ( m_bUseEnabledSystemColours) { // re-query the system colours in case they have changed. m_EnabledFgCol = GetSysColor( COLOR_WINDOWTEXT ); m_EnabledBgCol = GetSysColor( COLOR_WINDOW ); } if ( m_bUseDisabledSystemColours) { // re-query the system colours in case they have changed. m_DisabledFgCol = GetSysColor( COLOR_GRAYTEXT ); m_DisabledBgCol = GetSysColor( COLOR_3DFACE ); } // change the colour based on bEnable if ( bEnable) { m_line. SetFgColor( m_EnabledFgCol, TRUE ); m_line. SetBgColor( m_EnabledBgCol, TRUE ); } else { m_line. SetFgColor( m_DisabledFgCol, TRUE ); m_line. SetBgColor( m_DisabledBgCol, TRUE ); } } /* ============================================================ Function : CLineNumberEdit::UseSystemColours Description : Sets the Use*SystemColours flags. Return : void Parameters : BOOL bEnabled - flag if to use enabled system colours BOOL bDisabled - flag if to use disabled system colours Usage : Called to change colours in the edit box ============================================================*/ void CLineNumberEdit:: UseSystemColours( BOOL bUseEnabled /*= TRUE*/, BOOL bUseDisabled /*= TRUE*/ ) { m_bUseEnabledSystemColours = bUseEnabled; m_bUseDisabledSystemColours = bUseDisabled; BOOL bEnable = TRUE; if (:: IsWindow( m_hWnd)) bEnable = IsWindowEnabled(); SetWindowColour( bEnable ); } / // CLineNumberEdit private implementation /* ============================================================ Function : CLineNumberEdit::Prepare Description : Setting the edit rect for the control and either create or move the line number control. Also sets the top- and bottom line numbers. Return : void Parameters : none Usage : Must be called to (re)establish the edit rect, must also be called as soon as the control changes size. ============================================================*/ void CLineNumberEdit:: Prepare() { // Calc sizes int width = CalcLineNumberWidth(); CRect rect; GetClientRect( & rect ); CRect rectEdit( rect ); rect. right = width; rectEdit. left = rect. right + 1; // Setting the edit rect and // creating or moving child control SetRect( & rectEdit ); if( m_line. m_hWnd ) m_line. MoveWindow( 0, 0, width, rect. Height() ); else m_line. Create( NULL, WS_CHILD | WS_VISIBLE | SS_NOTIFY, rect, this, 1 ); GetRect( & rectEdit ); // Update line number control data m_line. SetTopMargin( rectEdit. top ); UpdateTopAndBottom(); } /* ============================================================ Function : CLineNumberEdit::CalcLineNumberWidth Description : Calculates the desired width of the line number control, using the current format string and the max number of chars allowed (pessimistic - assumes one character per line). Return : int - The width in pixels Parameters : none Usage : Called as soon as the format string is changed. ============================================================*/ int CLineNumberEdit:: CalcLineNumberWidth() { CClientDC dc( this ); // If a new font is set during runtime, // we must explicitly select the font into // the CClientDC to measure it. CFont* font = GetFont(); CFont* oldFont = dc. SelectObject( font ); m_zero= dc. GetTextExtent( _T( "0" ) ); CString format; // GetLimitText returns the number of bytes the edit box may contain, // not the max number of lines... //... which is the max number of lines, given one character per d:o :-) int maxval = GetLimitText(); if ( m_maxval > 0) maxval = m_maxval + m_LineDelta; format. Format( m_format, maxval ); CSize fmt = dc. GetTextExtent( format ); dc. SelectObject( oldFont ); // Calculate the size of the line- // number field. We add a 5 pixel margin // to the max size of the format string return fmt. cx + 5; } /* ============================================================ Function : CLineNumberEdit::UpdateTopAndBottom Description : Updates the top- and bottom line number for the line number control. Return : void Parameters : none Usage : Should be called as soon as the contents of the control is changed. ============================================================*/ void CLineNumberEdit:: UpdateTopAndBottom() { CRect rect; GetClientRect( & rect ); int maxline = GetLineCount() + m_LineDelta; // Height for individual lines int lineheight = m_zero. cy; // Calculate the number of lines to draw int topline = GetFirstVisibleLine() + m_LineDelta; if( ( topline + ( rect. Height() / lineheight ) ) < maxline ) maxline = topline + ( rect. Height() / lineheight ); if ( m_maxval > 0 && maxline > m_maxval + m_LineDelta ) maxline = m_maxval + m_LineDelta; m_line. SetTopAndBottom( topline, maxline ); } / // CLineNumberEdit public implementation /* ============================================================ Function : CLineNumberEdit::SetMarginForegroundColor Description : Sets the text color for the number margin. Return : void Parameters : COLORREF col - The new text color BOOL redraw - TRUE if the control should be redrawn (default) Usage : Call to set a new text color for the line number margin. The control will be redrawn if it exists. ============================================================*/ void CLineNumberEdit:: SetMarginForegroundColor( COLORREF col, BOOL redraw, BOOL bEnabled /*= TRUE*/ ) { m_line. SetFgColor( col, redraw ); if ( bEnabled) { m_bUseEnabledSystemColours = FALSE; m_EnabledFgCol = col; } else { m_bUseDisabledSystemColours = FALSE; m_DisabledFgCol = col; } } /* ============================================================ Function : CLineNumberEdit::SetMarginBackgroundColor Description : Sets the background color for the number margin. Return : void Parameters : COLORREF col - The new background color BOOL redraw - TRUE if the control should be redrawn (default) Usage : Call to set a new background color for the line number margin. The control will be redrawn if it exists. ============================================================*/ void CLineNumberEdit:: SetMarginBackgroundColor( COLORREF col, BOOL redraw, BOOL bEnabled /*= TRUE*/ ) { m_line. SetBgColor( col, redraw ); if ( bEnabled) { m_bUseEnabledSystemColours = FALSE; m_EnabledBgCol = col; } else { m_bUseDisabledSystemColours = FALSE; m_DisabledBgCol = col; } } /* ============================================================ Function : CLineNumberEdit::SetLineNumberFormat Description : Changes the way line numbers are presented on screen. Return : void Parameters : CString format - The new format string Usage : Call with a format string using the same format as CString::Format. It should contain one and only one numeric type. ============================================================*/ void CLineNumberEdit:: SetLineNumberFormat( CString format ) { m_format = format; m_line. SetLineNumberFormat( format ); if( m_hWnd ) Prepare(); } /* ============================================================ Function : CLineNumberEdit::SetLineNumberRange Description : Changes the default min and max line numbers. Return : void Parameters : int nMin - changes the line offset int nMax - changes the max line number Usage : Call to set up the min and max line numbers. ============================================================*/ void CLineNumberEdit:: SetLineNumberRange( UINT nMin, UINT nMax /*= 0*/ ) { m_LineDelta = ( int ) nMin; m_maxval = ( int ) nMax; } / // CLineNumberStatic CLineNumberStatic::CLineNumberStatic() { m_bgcol = RGB( 255, 255, 248 ); m_fgcol = RGB( 0, 0, 0 ); m_format = _T( "%05i" ); m_topline = 0; m_bottomline = 0; } CLineNumberStatic::~CLineNumberStatic() { } BEGIN_MESSAGE_MAP(CLineNumberStatic, CStatic) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() / // CLineNumberStatic message handlers /* ============================================================ Function : CLineNumberStatic::OnPaint Description : Handler for WM_PAINT. Return : void Parameters : none Usage : Called from Windows. ============================================================*/ void CLineNumberStatic:: OnPaint() { CPaintDC dcPaint( this ); CRect rect; GetClientRect( & rect ); // We double buffer the drawing - // preparing the memory CDC CDC dc; dc. CreateCompatibleDC( & dcPaint ); int saved = dc. SaveDC(); // Create GDI and select objects CBitmap bmp; CPen pen; bmp. CreateCompatibleBitmap( & dcPaint, rect. Width(), rect. Height() ); pen. CreatePen( PS_SOLID, 1, m_fgcol ); dc. SelectObject( & bmp ); dc. SelectObject( & pen ); // Painting the background dc. FillSolidRect( & rect, m_bgcol ); dc. MoveTo( rect. right - 1, 0 ); dc. LineTo( rect. right - 1, rect. bottom ); // Setting other attributes dc. SetTextColor( m_fgcol ); dc. SetBkColor( m_bgcol ); dc. SelectObject( GetParent()-> GetFont() ); // Output the line numbers if( m_bottomline ) { int lineheight = dc. GetTextExtent( _T( "0" ) ). cy; for( int t = m_topline ; t < m_bottomline ; t++ ) { CString output; output. Format( m_format, t ); int topposition = m_topmargin + lineheight * ( t - m_topline ); dc. TextOut( 2, topposition, output ); } } dcPaint. BitBlt( 0, 0, rect. right, rect. bottom, & dc, 0, 0, SRCCOPY ); dc. RestoreDC( saved ); } /* ============================================================ Function : CLineNumberStatic::OnEraseBkgnd Description : Mapped to WM_ERASEBKGND. Handled to avoid flicker, as we redraw the complete control in OnPaint Return : BOOL - Always TRUE Parameters : CDC* - From Windows Usage : Called from Windows. ============================================================*/ BOOL CLineNumberStatic::OnEraseBkgnd( CDC* ) { return TRUE; } /* ============================================================ Function : CLineNumberStatic::OnLButtonDown Description : Called when the control is clicked. Will send the urm_SELECTLINE registered message to the parent to select the line clicked on. Return : void Parameters : UINT nFlags - Not used CPoint point - Position of cursor Usage : Called from Windows. ============================================================*/ void CLineNumberStatic:: OnLButtonDown( UINT nFlags, CPoint point ) { // Find the line clicked on CClientDC dc( this ); dc. SelectObject( GetParent()-> GetFont() ); int lineheight = dc. GetTextExtent( _T( "0" ) ). cy; int lineno = ( int ) ( ( double ) point. y / ( double ) lineheight ); // Select this line in the edit control GetParent()-> SendMessage( urm_SELECTLINE, lineno ); CStatic:: OnLButtonDown( nFlags, point ); } / // CLineNumberStatic public implementation /* ============================================================ Function : CLineNumberStatic::SetBgColor Description : This function sets the panel background color Return : void Parameters : COLORREF col - New background color BOOL redraw - TRUE if the control should be redrawn (default) Usage : Called from the parent. ============================================================*/ void CLineNumberStatic:: SetBgColor( COLORREF col, BOOL redraw ) { m_bgcol = col; if( m_hWnd && redraw ) RedrawWindow(); } /* ============================================================ Function : CLineNumberStatic::SetFgColor Description : This function sets the panel foreground color Return : void Parameters : COLORREF col - New text color BOOL redraw - TRUE if the control should be redrawn (default) Usage : Called from the parent. ============================================================*/ void CLineNumberStatic:: SetFgColor( COLORREF col, BOOL redraw ) { m_fgcol = col; if( m_hWnd && redraw ) RedrawWindow(); } /* ============================================================ Function : CLineNumberStatic::SetTopAndBottom Description : Sets the top- and bottom line and redraw the control (if it exists) Return : void Parameters : int topline - The top line number int bottomline - The bottom line number Usage : Called when the top and bottom line is changed in the parent. ============================================================*/ void CLineNumberStatic:: SetTopAndBottom( int topline, int bottomline ) { m_topline = topline; m_bottomline = bottomline; if( m_hWnd ) RedrawWindow(); } /* ============================================================ Function : CLineNumberStatic::SetTopMargin Description : Sets the top margin for painting. Return : void Parameters : int topmargin - The top margin to set Usage : Will be called with the value of GetRect from the parent. ============================================================*/ void CLineNumberStatic:: SetTopMargin( int topmargin ) { m_topmargin = topmargin; } /* ============================================================ Function : CLineNumberStatic::SetLineNumberFormat Description : Sets the format string of the control Return : void Parameters : CString format - Format string to use Usage : Called from the parent when the format string is changed. ============================================================*/ void CLineNumberStatic:: SetLineNumberFormat( CString format ) { m_format = format; if( m_hWnd ) RedrawWindow(); } |
图
备注
1个类文件
LineNumberEdit.cpp
LineNumberEdit.h
出现了2个类
CLineNumberEdit
CLineNumberStatic
相关链接
相关链接 相关链接
附件列表