Windows API 以 PChar (即 PAnsiChar) 為標準字串介面。Delphi 的 string (AnsiString/UnicodeString) 記憶體布局與之兼容,但正確的賦值、取值、記憶體管理模式至關重要,關係到穩定性與效能。
SetWindowText(Handle, '新標題'); // 編譯器自動生成 PChar 字面值
var
p: PChar;
begin
p := '新標題'; // 隱式轉換:字面值 → PChar
SetWindowText(Handle, p);
end;
var
str: string;
begin
str := '新標題';
SetWindowText(Handle, PChar(str)); // 取得內部緩衝區指標
end;
var
arr: array[0..255] of Char;
begin
arr := '新標題'; // 自動補 #0 結尾
SetWindowText(Handle, arr); // 陣列名即指標
end;
var
arr: array[0..254] of Char; // 預留 1 字元給 #0
begin
GetWindowText(Handle, arr, 255); // API 填充緩衝區
ShowMessage(arr); // 自動按 #0 截斷
end;
var
p: PChar;
begin
GetMem(p, 255); // 分配 255 位元組
try
GetWindowText(Handle, p, 255);
ShowMessage(p);
finally
FreeMem(p); // 必須手動釋放
end;
end;
var
hMem: HGLOBAL;
begin
hMem := GlobalAlloc(GMEM_FIXED, 255); // GMEM_FIXED = 0
try
GetWindowText(Handle, PChar(hMem), 255);
ShowMessage(PChar(hMem));
finally
GlobalFree(hMem);
end;
end;
var
str: string;
begin
SetLength(str, 255); // 1. 預分配緩衝區
GetWindowText(Handle, PChar(str), 255);
str := PChar(str); // 2. 利用 #0 截斷還原實際長度
ShowMessage(str);
end;
var
s: String[20];
begin
s := 'Hello';
// s 內存佈局:[Length:Byte][Chars...] 無 #0 結尾
// 傳給 API 會讀越界 → 嚴重錯誤
// 解決:轉為 PChar 或使用 ShortString 配合 StrPCopy
end;
| 場景 | 推薦方式 | 關鍵點 |
|---|---|---|
| 短字串、已知最大長度 | 靜態陣列 array[0..N] of Char | 棧上分配、無洩漏風險、速度最快 |
| 長度未知、可能很大 | string + SetLength + PChar | 自動管理、支援 Unicode、Delphi 2009+ 首選 |
| 跨 DLL/進程共享 | GlobalAlloc / Shared Memory | 需手動管理、效能較差 |
| 高頻調用、極致效能 | GetMem/FreeMem + PChar | 避免 string 參考計數開銷 |