【发布时间】:2018-12-30 16:32:20
【问题描述】:
我正在尝试单击并拖动 TCanvas 并将背景颜色更改为 clHighlight,因为我向下拖动并将其更改回 clWhite 如果我要反转拖动方向。如果您单击正在阅读的文本并向下或向上拖动,几乎会发生什么,无论如何都是相同的想法。我已经从 link 中收集到了我能做的事情。
自从我第一次发布此代码以来,我已经对下面的代码进行了广泛的编辑,下面的代码现在完成了我打算做的事情,只是如果你不以均匀的速度拖动,选择中的文本可能会变得混乱,这是不可接受的。如果你真的快速上下移动鼠标,它肯定会搞砸。如果你移动鼠标 以稳定的速度运行良好,这让我担心可能无法解决这个问题。如果有人有任何建议,我会继续关注。我还遇到了几个“资源不足”错误,不确定是怎么回事,我正在释放位图,我知道没有涉及其他资源。
下面的代码是在一个 MouseMove 事件中。srect 是在 TImage 的 Canvas 中被选中的矩形。 drect 是翻译成 0,0 的同一个 srect。 bm1 包含使用 CopyRect 从 TImage 的画布复制的选定矩形。 bm2 包含 bm1,其中 clWhite(背景)使用 BrushCopy 更改为 clHighlight(或相反)。然后使用 BitBlt 将 bm2 复制回原始 TImage 的选定矩形。
// vp is derived from TImage
if (Y > sel_data->_last_y)
{
TRect srect = Rect(sel_data->_rect.Left,sel_data->_last_y,sel_data->_rect.Right, Y);
TRect drect = Rect(sel_data->_rect.Left,0,sel_data->_rect.Right, sel_data->_rect.Height() - 1);
Graphics::TBitmap* bm1 = new Graphics::TBitmap;
bm1->Width = srect.Width();
bm1->Height = srect.Height();
Graphics::TBitmap* bm2 = new Graphics::TBitmap;
bm2->Width = srect.Width();
bm2->Height = srect.Height();
bm1->Canvas->CopyRect(drect, vp->Canvas, srect);
bm2->Canvas->Brush->Color = clHighlight;
bm2->Canvas->BrushCopy(drect, bm1, drect, clWindow);
BitBlt(vp->Canvas->Handle, srect.Left, srect.Top, srect.Width(), srect.Height(),
bm2->Canvas->Handle, 0, 0, SRCCOPY);
vp->Refresh();
delete bm1;
delete bm2;
}
else if (Y < sel_data->_last_y)
{
TRect srect = Rect(sel_data->_rect.Left, Y,sel_data->_rect.Right, sel_data->_last_y);
TRect drect = Rect(sel_data->_rect.Left,0,sel_data->_rect.Right, sel_data->_rect.Height() - 1);
Graphics::TBitmap* bm1 = new Graphics::TBitmap;
bm1->Width = srect.Width();
bm1->Height = srect.Height();
Graphics::TBitmap* bm2 = new Graphics::TBitmap;
bm2->Width = srect.Width();
bm2->Height = srect.Height();
bm1->Canvas->CopyRect(drect, vp->Canvas, srect);
bm2->Canvas->Brush->Color = clWhite;
bm2->Canvas->BrushCopy(drect, bm1, drect, clHighlight);
int w = srect.Width();
int h = srect.Height();
BitBlt(vp->Canvas->Handle, srect.Left, srect.Top, w, h, bm2->Canvas->Handle, 0, 0, SRCCOPY);
vp->Refresh();
delete bm1;
delete bm2;
}
sel_data->_last_y = Y;
}
【问题讨论】:
-
您的意思是在备忘录或 Richedit 中选择文本,还是因为您提到
TCanvas,您想“选择”图形区域(像素) -
这将是图形区域(像素),我需要将 clWindow 颜色更改为 clHighlight 并可能返回到 clWindow。
-
所以你需要
property ScanLine[Row: Integer]: Pointer read GetScanLine; -
实际修改图像(或图像的副本)的像素感觉很重。也许您可以考虑另一种方法:用半透明表单覆盖图像/表单,您可以在其上用鼠标绘制选择矩形,并可选择用另一种透明阴影/颜色填充它。类似于 Windows 截图工具。
标签: delphi canvas graphics c++builder vcl