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

Delphi 多線程程式設計(4):CreateThread 傳遞參數技巧與 LoWord/HiWord 壓縮座標

     編輯:Delphi

前言

CreateThread 第四個參數 lpParameter: Pointer 可傳遞任意 32 位元資料給入口函數。本文示範兩種傳遞滑鼠座標的寫法:指標傳遞結構體與整數壓縮高/低字組,後者技巧源自 Windows 訊息機制(lParam)。

方法一:傳遞 TPoint 指標(需全域變數)

var
  pt: TPoint;  { 必須為全域,避免區域變數生命週期結束 }

function MyThreadFun(p: Pointer): Integer; stdcall;
var
  i: Integer;
  pt2: TPoint;
begin
  pt2 := PPoint(p)^;  { 解參考取得座標快照 }
  for i := 0 to 1000000 do
  begin
    with Form1.Canvas do
    begin
      Lock;
      TextOut(pt2.X, pt2.Y, IntToStr(i));
      Unlock;
    end;
  end;
  Result := 0;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ID: DWORD;
begin
  pt := Point(X, Y);
  CreateThread(nil, 0, @MyThreadFun, @pt, 0, ID);
end;

缺點:需全域變數暫存座標,若連續快速點擊,前一筆座標可能被覆蓋導致競態條件。

方法二:整數壓縮 X/Y(無全域變數,無競態)

利用 MakeLong/LoWord/HiWord 將 X、Y 壓縮為單一 32 位元整數,再轉型為 Pointer 傳遞:

function MyThreadFun(p: Pointer): Integer; stdcall;
var
  i: Integer;
  x, y: Word;
begin
  x := LoWord(Integer(p));
  y := HiWord(Integer(p));
  { 等價寫法:
  x := Integer(p) and $FFFF;
  y := Integer(p) shr 16;
  }
  for i := 0 to 1000000 do
  begin
    with Form1.Canvas do
    begin
      Lock;
      TextOut(x, y, IntToStr(i));
      Unlock;
    end;
  end;
  Result := 0;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ID: DWORD;
  num: Integer;
begin
  num := MakeLong(X, Y);        { 或 Y shl 16 + X }
  CreateThread(nil, 0, @MyThreadFun, Pointer(num), 0, ID);
end;

執行畫面

滑鼠點擊建立執行緒繪圖

技巧總結與延伸

  • MakeLong/LoWord/HiWord 定義於 Windows.pas,實際為巨集/內建函式,零成本。
  • 同樣原理適用於 PostMessage、SendMessage 的 lParam、wParam 參數打包。
  • 若需傳遞超過 32 位元資料,請配置記憶體區塊(GetMem/AllocMem),傳遞指標,執行緒結束前 FreeMem。
  • 同步問題:範例中 Lock/Unlock 僅保護 Canvas,計數器 i 仍在等待時遞增,真實專案應使用 Critical Section、Event、Mutex 等同步物件(下一篇主題)。

結語

整數壓縮傳遞參數是 Windows 系統程式設計的經典慣用語,掌握後可簡化執行緒參數傳遞、視窗訊息打包與回呼資料結構設計,提升程式碼緊湊度與執行效率。

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