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

在 C++Builder 中打造可調整大小與拖曳的 Edit 控件

     編輯:VC 教學

前言

標準的 TEdit 控件預設不支援使用者透過滑鼠拖曳邊框來調整大小,也不支援在表單上自由拖曳移動位置。本文將示範如何透過 Windows API 修改視窗樣式,為 TEdit 增加「調整大小邊框」與「標題列拖曳移動」兩項實用功能,讓單行編輯框擁有類似視窗的互動體驗。

核心原理

  • WS_SIZEBOX 樣式:賦予控件可調整大小的邊框(即視窗右下角的縮放控制點)。
  • WM_NCLBUTTONDOWN + HTCAPTION:模擬使用者點擊視窗標題列,讓系統誤以為正在拖曳視窗標題,從而觸發移動邏輯。
  • ReleaseCapture():釋放滑鼠捕獲,確保拖曳操作順暢啟動。

完整實作程式碼

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    // 1. 取得 Edit1 目前的視窗樣式
    DWORD dwStyle = ::GetWindowLong(Edit1->Handle, GWL_STYLE);
    // 2. 加入 WS_SIZEBOX,使其擁有可調整大小的邊框
    ::SetWindowLong(Edit1->Handle, GWL_STYLE, dwStyle | WS_SIZEBOX);

    // 3. 強制重繪視窗,修正客戶區尺寸,確保邊框可被正確拖曳
    ::MoveWindow(Edit1->Handle,
                 Edit1->Left, Edit1->Top,
                 Edit1->Width, Edit1->Height + 1,
                 true);
}
//---------------------------------------------------------------------------

// 當滑鼠在 Edit1 上按下時,若游標為箭頭則啟動拖曳
void __fastcall TForm1::Edit1MouseDown(TObject *Sender,
    TMouseButton Button, TShiftState Shift, int X, int Y)
{
    if (Edit1->Cursor == crArrow)
    {
        ::ReleaseCapture();                          // 釋放滑鼠捕獲
        // 送出「非客戶區左鍵按下」訊息,參數 HTCAPTION 表示點擊標題列
        ::SendMessage(Edit1->Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
    }
}
//---------------------------------------------------------------------------

// 滑鼠移動時保持箭頭游標,提示使用者可拖曳
void __fastcall TForm1::Edit1MouseMove(TObject *Sender,
    TShiftState Shift, int X, int Y)
{
    Edit1->Cursor = crArrow;
}
//---------------------------------------------------------------------------

關鍵細節解析

為什麼要呼叫 MoveWindow?

加入 WS_SIZEBOX 後,視窗邊框會變粗以容納調整控制點,但控件的客戶區大小不會自動更新。呼叫 MoveWindow 並將高度加 1 像素,強制視窗重新計算非客戶區與客戶區的佈局,使邊框能正確回應滑鼠拖曳。

拖曳機制的巧思

WM_NCLBUTTONDOWN 配合 HTCAPTION 是 Windows 內建的視窗移動觸發機制。我們在 OnMouseDown 事件中手動發送此訊息,欺騙系統以為使用者正在拖曳標題列,從而無需撰寫複雜的座標計算與 SetWindowPos 迴圈即可實現平滑拖曳。

應用場景與延伸

  • 適用於需由使用者自訂大小與位置的輸入區塊(如動態表單設計器、報表編輯器)。
  • 同樣技巧可套用至 TMemo、TRichEdit 等其他視窗化控件。
  • 若需限制最小/最大尺寸,可在 OnResize 或 OnCanResize 事件中加入邏輯判斷。

常見問題排查

現象可能原因解決方案
邊框出現但無法拖曳調整未呼叫 MoveWindow 更新佈局確保建構子中呼叫 MoveWindow 並將高度 +1
拖曳移動時畫面閃爍未釋放滑鼠捕獲在 SendMessage 前務必呼叫 ReleaseCapture()
游標不變為箭頭OnMouseMove 未設定 Cursor在 OnMouseMove 中指派 Edit1->Cursor = crArrow

掌握這項技巧,能讓你的 C++Builder 應用程式擁有更靈活、更專業的使用者介面互動體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved