Code Bye

自制文本编辑器,文本选中时的高亮显示

win32编程实现文本编辑器,不使用任何控件,本人完成,现在当鼠标左键按下,并且移动时,选中所经过的文本字符,并让这些字符高亮显示,例如系统自带的NotePad一样,现在是鼠标移动的起始位置和终止位置本人都能正确的得到,关键就是本人该怎么重绘这个区域之间的字符?分不多了,请大家帮帮,谢谢!
解决方案

15

// this four variable mean the select area
int selectAreaX1 = 0;
int selectAreaY1 = 0;
int selectAreaX2 = 0;
int selectAreaY2 = 0;
void DrawSelectArea(HDC hDC, RECT rect)                  // color the select area
{
    HBRUSH hBrush;
    hBrush = CreateSolidBrush(RGB(255,255,0));
    SetDCBrushColor(hDC,RGB(255, 255, 0));
    RECT rectSelect;
    SIZE size1, size2;
    GetTextExtentPoint(hDC, data[selectAreaY2], selectAreaX2, &size2);
    GetTextExtentPoint(hDC, data[selectAreaY1], selectAreaX1, &size1);
    // calculate the select rect area and Fill it.
    if (selectAreaY1 < selectAreaY2)
    {
        rectSelect.bottom = 16 * (selectAreaY2 + 1);
        rectSelect.left = 0;
        rectSelect.right = size2.cx + 40;
        rectSelect.top = 16 * selectAreaY2;
        FillRect(hDC, &rectSelect, hBrush);
        rectSelect.bottom = 16 * (selectAreaY2);
        rectSelect.left = 0;
        rectSelect.right = rect.right;
        rectSelect.top = 16 * (selectAreaY1 + 1);
        FillRect(hDC, &rectSelect, hBrush);
        rectSelect.bottom = 16 * (selectAreaY1 + 1);
        rectSelect.left = size1.cx + 40;
        rectSelect.right = rect.right;
        rectSelect.top = 16 * (selectAreaY1);
        FillRect(hDC, &rectSelect, hBrush);
    }
    if (selectAreaY1 > selectAreaY2)                                  
    {
        rectSelect.bottom = 16 * (selectAreaY1+1);
        rectSelect.left = 0; 
        rectSelect.right = size1.cx + 40;
        rectSelect.top = 16 * selectAreaY1;
        FillRect(hDC, &rectSelect, hBrush);
        rectSelect.bottom = 16 * (selectAreaY1);
        rectSelect.left = 0;
        rectSelect.right = rect.right;
        rectSelect.top = 16 * (selectAreaY2+1);
        FillRect(hDC, &rectSelect, hBrush);
        rectSelect.bottom = 16 * (selectAreaY2+1);
        rectSelect.left = size2.cx + 40;
        rectSelect.right = rect.right;
        rectSelect.top = 16 * (selectAreaY2);
        FillRect(hDC, &rectSelect, hBrush);
    }
    
    if (selectAreaY1 == selectAreaY2)
    {
        if (selectAreaX1 > selectAreaX2)
        {
            rectSelect.bottom = 16 * (selectAreaY1+1);
            rectSelect.left = size2.cx + 40;
            rectSelect.right = size1.cx + 40;
            rectSelect.top = 16 * (selectAreaY1);
            FillRect(hDC, &rectSelect, hBrush);
        }
        if (selectAreaX1 < selectAreaX2)
        {
            rectSelect.bottom = 16 * (selectAreaY1+1);
            rectSelect.left = size1.cx + 40;
            rectSelect.right = size2.cx + 40;
            rectSelect.top = 16 * (selectAreaY1);
            FillRect(hDC, &rectSelect, hBrush);
        }
    }
    DeleteObject(hBrush);
}

不知道是不是你想要的..这个好像选中区域中的空白部分也会被重绘,

5

参考Notepad++源代码。

5

1. 在鼠标按下和移动是记录选择区域, 可以以[选中标志][起始行、列]、[终止行、列]的方式保存
原因是向上选中和向下选中时,选中起始不同, 所以最好保存一下向上选中时的 [起始行、列]和向下选中时的[起始行、列]
2. 描画时, 确认数据能否和选择区域有交叉, 假如有交叉, 给交叉的部分画个实体矩形, 然后显示文字。

15

描画矩形
一行选中情况  ***********<*************>,”<>”内为选中字符串
int iPos = 0;
int iTemp = 0;
CRect Rect;
pDC ->SetBkMode(TRANSPARENT);
// normal  没选中字体也能设置背景色
iPos = point.x;
iTemp = DrawSelInfo.iStPos - DrawData.iStPos;
Rect = CRect(iPos, point.y,  iPos + iTemp * TextInfo.iWidth, point.y + TextInfo.iLineWidth);
pDC ->FillRect(Rect, pBGBrush);
// select
iPos += iTemp * TextInfo.iWidth;
Rect = CRect(iPos, point.y,  iPos + (strText.GetLength() - iTemp) * TextInfo.iWidth, point.y + TextInfo.iLineWidth);
pDC ->FillRect(Rect, &m_SelectBrush);
pDC ->TextOut(point.x, point.y, strText);

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明自制文本编辑器,文本选中时的高亮显示