带行号的EditView

实现步骤:


1、建立SDI或者MDI的MFC程序,View选择CEditView(这里假设工程名字为Stylepad)
 
2、在CEditView的继承类中追加
protected:
    void UpdateLineNumber();
    LRESULT OnIdle(WPARAM wp, LPARAM lCount);
    LONG cxCharWidth;
    LONG cyCharHeight;
 
3、响应 WM_VSCROLL 消息
void CStylepadView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    CEditView::OnVScroll(nSBCode, nPos, pScrollBar);
    this->UpdateLineNumber();
}

4、响应 WM_SIZE 消息
void CStylepadView::OnSize(UINT nType, int cx, int cy)
{
    CEditView::OnSize(nType, cx, cy);
    RECT rectWin;
    this->GetClientRect(&rectWin);
    SIZE size ;
    CClientDC dc(this);
    GetTextExtentPoint32W (dc.m_hDC, L"W", 1, &size) ;
    this->cxCharWidth  = size.cx;
    this->cyCharHeight = size.cy;
    rectWin.left = cxCharWidth * 4 + 3;
    this->GetEditCtrl().SetRect(&rectWin);
    this->Invalidate();
}

5、追加 #include <afxpriv.h>
然后再在 MESSAGE_MAP 中追加 ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdle)

结果为:
BEGIN_MESSAGE_MAP(CStylepadView, CEditView)
    ON_WM_VSCROLL()
    ON_WM_SIZE()
    ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdle)
END_MESSAGE_MAP()

实现:
LRESULT CStylepadView::OnIdle(WPARAM wp, LPARAM lCount)
{
    UpdateLineNumber();
    return 0;
}

6、最后就是如何输出行号

void CTestEditViewView::UpdateLineNumber()
{
    RECT rectWin;
    this->GetClientRect(&rectWin);
    UINT uViewWidth = cxCharWidth * 4;
    UINT uViewHeight = rectWin.bottom;
    // Count Visible Line
    int nViewLineMin = this->GetEditCtrl().GetFirstVisibleLine() + 1;
    int nViewLineMax = (uViewHeight / cyCharHeight) + nViewLineMin;
    // Get DC
    CClientDC dc(this);
    HDC hdcView = ::CreateCompatibleDC(dc.GetSafeHdc());
    HBITMAP hbmScaled = CreateCompatibleBitmap(dc.GetSafeHdc(), uViewWidth, uViewHeight);
    HGDIOBJ hbmOld = SelectObject(hdcView, (HGDIOBJ)hbmScaled);
    // Fill Rect
    RECT rectLine;
    rectLine.left = rectLine.top = 0;
    rectLine.bottom = uViewHeight;
    rectLine.right = uViewWidth;
    FillRect(hdcView, &rectLine, (HBRUSH) (COLOR_WINDOW + 1));
    // Draw the Number
    static TCHAR strNumber[7];
    wmemset(strNumber, 0, 7);
    int nLeft = uViewWidth - 3;
    int nBufferSize = 0;
    SetTextAlign(hdcView, TA_RIGHT);
    int nCurrentLine = this->GetEditCtrl().LineFromChar(-1) + 1;
    SetTextColor(hdcView, RGB(41,41,41));
    for (UINT i = 1; i <= uViewHeight ; i += cyCharHeight)
    {
        if(nCurrentLine == nViewLineMin)
        {
            SetTextAlign(hdcView, TA_LEFT);
            SetTextColor(hdcView, RGB(255,0,0));
            TextOutW(hdcView, 0, i, L"*", 1);
            SetTextColor(hdcView, RGB(41,41,41));
            SetTextAlign(hdcView, TA_RIGHT);
        }
        nBufferSize = ::wsprintfW(strNumber, L"%d", nViewLineMin++);
        TextOutW(hdcView, nLeft, i, strNumber, nBufferSize);
    }
    // Draw the Line
    // Initialize the pen's brush.
    LOGBRUSH lb;
    lb.lbStyle = BS_SOLID;
    lb.lbColor = RGB(255,0,0);
    lb.lbHatch = HS_CROSS;
    // Create a pen to darw line
    HPEN hPen = ExtCreatePen(PS_GEOMETRIC | PS_DASHDOTDOT, 1, &lb, 0, NULL);
    HGDIOBJ hOldPen = SelectObject(hdcView, (HGDIOBJ)hPen);
    MoveToEx(hdcView, uViewWidth - 1, 0, 0) ;
    LineTo(hdcView, uViewWidth - 1, uViewHeight);
    // Restore the old Pen
    SelectObject(hdcView, hOldPen);
    DeleteObject(hPen);
    // Draw the Image To Client View
    BitBlt(dc.GetSafeHdc(), 0, 0, uViewWidth, uViewHeight, hdcView, 0, 0, SRCCOPY);
    // Restore the old Bitmap
    SelectObject(hdcView, hbmOld);
    DeleteDC(hdcView);
    DeleteObject(hbmScaled);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值