首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

StringGrid 右鍵選單複製貼上:極簡實作與座標陷阱解析

     編輯:關於C++

需求

在 TStringGrid 上右鍵彈出選單,複製當前儲存格文字到剪貼簿,或從剪貼簿貼上到目標儲存格。

核心難點:座標時機

OnMouseUp 觸發時取得的 X, Y 是相對 StringGrid 用戶區的座標。但彈出選單後使用者移動滑鼠點選選單項目,Mouse->CursorPos 已改變。必須在 OnMouseUp 即刻保存螢幕座標,供後續選單事件使用。

完整實作

#include 

TPoint g_ptSelect; // 全域/表單成員:保存右鍵彈出時的螢幕座標

//---------------------------------------------------------------------------
void __fastcall TForm1::StringGrid1MouseUp(TObject* Sender,
    TMouseButton Button, TShiftState Shift, int X, int Y) {

    if (Button != mbRight) return;

    int Col, Row;
    StringGrid1->MouseToCell(X, Y, Col, Row);
    if (Col < 1 || Row < 1) return; // 忽略標題列/欄

    StringGrid1->Col = Col;
    StringGrid1->Row = Row;

    g_ptSelect = Mouse->CursorPos; // 關鍵:保存螢幕座標
    PopupMenu1->Popup(Mouse->CursorPos.x, Mouse->CursorPos.y);
}

//---------------------------------------------------------------------------
void __fastcall TForm1::miCopyClick(TObject* Sender) {
    // 由保存的螢幕座標反推儲存格
    TPoint pt = StringGrid1->ScreenToClient(g_ptSelect);
    int Col, Row;
    StringGrid1->MouseToCell(pt.x, pt.y, Col, Row);

    Clipboard()->AsText = StringGrid1->Cells[Col][Row];
}

//---------------------------------------------------------------------------
void __fastcall TForm1::miPasteClick(TObject* Sender) {
    TPoint pt = StringGrid1->ScreenToClient(g_ptSelect);
    int Col, Row;
    StringGrid1->MouseToCell(pt.x, pt.y, Col, Row);

    StringGrid1->Cells[Col][Row] = Clipboard()->AsText;
}

關鍵 API 對照

方法用途
MouseToCell(X, Y, Col, Row)用戶區座標 → 儲存格索引
ScreenToClient(Point)螢幕座標 → 控制項用戶區座標
Mouse->CursorPos取得當前滑鼠螢幕座標
Clipboard()->AsText剪貼簿純文字讀寫

常見錯誤與避坑

  1. 直接在選單事件用 Mouse->CursorPos:座標已偏移,會貼到錯誤儲存格
  2. 未檢查 Col/Row >= 1:標題列/欄索引為 0,誤寫入會覆蓋標題
  3. 未包含 Clipbrd.hpp:連結錯誤 [Linker Error] Unresolved external 'Clipboard()'

擴充建議

  • 加入「剪下」:複製後清空儲存格
  • 支援多儲存格選取區塊複製/貼上(需維護選取範圍)
  • 右鍵選單動態啟用/停用:無選取時停用「複製」、「剪下」
  • 鍵盤快速鍵 Ctrl+C/V/X:在 OnKeyDown 處理
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved