實現類似瀏覽器中鍵拖曳捲動的效果:按住滑鼠右鍵在 TRichEdit 上拖曳即可上下捲動內容,釋放右鍵恢復預設右鍵選單。
OnMouseDown:偵測右鍵按下,記錄初始座標,設定捕捉滑鼠,改變游標為手型。OnMouseMove:若右鍵按下中,比較當前 Y 座標與記錄座標,差距超過閾值(8 像素)則發送 EM_SCROLL 訊息捲動一行,更新記錄座標。OnMouseUp:釋放滑鼠捕捉,恢復游標,若有捲動動作則隱藏右鍵選單,否則顯示預設右鍵選單。
void __fastcall TMainForm::RichEditMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) {
if (RightButtonFlag) {
if (RightY > (Y + 8)) { // 向上拖曳 -> 向下捲動
RightY = Y;
SendMessage(RichEdit->Handle, EM_SCROLL, SB_LINEDOWN, 0);
} else if (RightY < (Y - 8)) { // 向下拖曳 -> 向上捲動
RightY = Y;
SendMessage(RichEdit->Handle, EM_SCROLL, SB_LINEUP, 0);
}
RichEditDragFlag = true;
}
}
void __fastcall TMainForm::RichEditMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
if (Button == mbRight) {
RightButtonFlag = true;
Screen->Cursor = crHandPoint;
RightX = X;
RightY = Y;
SetCapture(RichEdit->Handle);
} else {
RightButtonFlag = false;
}
}
void __fastcall TMainForm::RichEditMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
if (RightButtonFlag)
ReleaseCapture();
if (RichEditDragFlag) {
RightButtonFlag = false;
RichEditDragFlag = false;
Screen->Cursor = crDefault;
RichEdit->PopupMenu = NULL; // 隱藏右鍵選單
} else {
RichEdit->PopupMenu = RichEditPopupMenu; // 顯示預設選單
}
}
bool RightButtonFlag; // 右鍵是否按下
bool RichEditDragFlag; // 是否發生捲動拖曳
int RightX, RightY; // 記錄按下時座標
OnCreate 中初始化旗標為 false。TRichEdit 設定 OnMouseDown、OnMouseMove、OnMouseUp 事件。TPopupMenu 元件 RichEditPopupMenu 作為預設右鍵選單。按住右鍵上下拖曳即可平滑捲動長文件,釋放右鍵若無捲動則彈出編輯選單(複製/貼上等),體驗直觀自然。