首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Delphi 控制捲軸三大 API 對比:Perform vs SendMessage vs PostMessage

     編輯:更多程式設計知識

前言

Delphi 透過發送視窗訊息控制元件捲軸 (如 `TDBGrid`),常用三種 API:`Perform`、`SendMessage`、`PostMessage`。本文詳細對比三者語法、同步/非同步特性、回傳值差異與適用場景。

核心代碼對比

1. Perform 方法 (VCL 封裝,推薦)


// 向下翻頁
DBGrid1.Perform(WM_VSCROLL, SB_PAGEDOWN, 0);
// 向上翻頁
DBGrid1.Perform(WM_VSCROLL, SB_PAGEUP, 0);
  • 優點:VCL 內建、自動處理視窗控制代碼、同步執行、程式碼簡潔。
  • 本質:內部呼叫 `SendMessage(Handle, ...)`。

2. SendMessage 函式 (同步阻塞)


SendMessage(DBGrid1.Handle, WM_VSCROLL, SB_PAGEDOWN, 0);
SendMessage(DBGrid1.Handle, WM_VSCROLL, SB_PAGEUP, 0);
  • 特性:同步阻塞,訊息處理完成才返回。
  • 回傳值:目標視窗程序的處理結果 (LRESULT)。
  • 適用:需確認捲軸已移動、需取得捲軸位置、跨進程控制。

3. PostMessage 函式 (非同步佇列)


PostMessage(DBGrid1.Handle, WM_VSCROLL, SB_PAGEDOWN, 0);
PostMessage(DBGrid1.Handle, WM_VSCROLL, SB_PAGEUP, 0);
  • 特性:非同步,將訊息放入佇列立即返回,不等待處理。
  • 回傳值:`BOOL`,表示訊息是否成功入佇列 (非處理結果)。
  • 適用:觸發後不需等待、避免 UI 凍結、大量訊息發送。

關鍵差異總結表

維度PerformSendMessagePostMessage
同步性同步同步 (阻塞)非同步 (非阻塞)
回傳值LRESULT (處理結果)LRESULT (處理結果)BOOL (入佇列成功與否)
視窗控制代碼自動取得 Self.Handle需手動傳 Handle需手動傳 Handle
執行緒安全僅主執行緒跨執行緒可用跨執行緒可用
常見用途VCL 內部控制、同步捲軸需結果確認、跨進程通知類、非阻塞觸發

常見捲軸訊息常數


WM_VSCROLL  = $0115;  // 垂直捲軸
WM_HSCROLL  = $0114;  // 水平捲軸

WPARAM 低字節命令碼:
SB_LINEUP       = 0;   // 向上一行
SB_LINEDOWN     = 1;   // 向下一行
SB_PAGEUP       = 2;   // 向上一頁
SB_PAGEDOWN     = 3;   // 向下一頁
SB_THUMBTRACK   = 5;   // 拖曳捲軸桿 (LOWORD(wParam) 為位置)
SB_TOP          = 6;   // 到頂端
SB_BOTTOM       = 7;   // 到底端
SB_THUMBPOSITION= 4;   // 定位 (舊版)

進階:精確捲動到指定行


// 計算目標位置並發送 SB_THUMBPOSITION
var
  ScrollInfo: TScrollInfo;
begin
  ScrollInfo.cbSize := SizeOf(TScrollInfo);
  ScrollInfo.fMask := SIF_RANGE or SIF_PAGE or SIF_POS;
  GetScrollInfo(DBGrid1.Handle, SB_VERT, ScrollInfo);
  
  // 目標行在可見範圍內
  ScrollInfo.nPos := TargetRow * RowHeight;
  ScrollInfo.fMask := SIF_POS;
  SetScrollInfo(DBGrid1.Handle, SB_VERT, ScrollInfo, True);
  
  // 觸發重繪
  PostMessage(DBGrid1.Handle, WM_VSCROLL, SB_THUMBPOSITION, ScrollInfo.nPos);
end;

選擇指南

  • 首選 Perform:VCL 元件內部控制、同步需求、程式碼可讀性最高。
  • 需跨進程/跨執行緒/需回傳值:用 SendMessage。
  • 大量觸發/非阻塞通知/避免 UI 凍結:用 PostMessage。
  • 切記:`PostMessage` 返回不代表捲軸已移動,若後續邏輯依賴捲軸位置,必須用 `SendMessage` 或 `Perform`。

結語

三大 API 各有分工:`Perform` 是 VCL 開發者的瑞士刀,`SendMessage` 是同步控制的基石,`PostMessage` 是非同步架構的基石。理解同步 vs 非同步、回傳值語意、執行緒語境三大核心差異,即能在捲軸控制、自訂訊息、跨進程通訊等場景精準選型。

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