標準 MessageBox/MessageDlg 無法使用自訂圖示。Windows API MessageBoxIndirect 支援 MB_USERICON 載入資源圖示,但參數結構 TMsgBoxParams 複雜。本文提供封裝函數 MessageEx 簡化呼叫。
Source\RTL\Win\Windows.pas。MessageBoxIndirect 宣告 (三處),將回傳型別 BOOL 改為 Integer。Lib\Windows.dcu,將修改後的 Windows.pas 複製到 Lib 目錄 (或專案目錄) 重新編譯。
function MessageEx(lText, lCaption: PChar; lStyle: DWORD; lIcon: PChar): Integer;
var Msg: TMsgBoxParams;
begin
FillChar(Msg, SizeOf(Msg), 0);
Msg.cbSize := SizeOf(Msg);
Msg.hwndOwner := Application.Handle;
Msg.hInstance := HInstance;
Msg.lpszText := lText;
Msg.lpszCaption := lCaption;
Msg.dwStyle := lStyle;
Msg.lpszIcon := lIcon; // 資源圖示名稱,或 nil
Msg.dwContextHelpId := 1;
Msg.lpfnMsgBoxCallback := nil;
Msg.dwLanguageId := LANG_NEUTRAL;
Result := MessageBoxIndirect(Msg);
end;
// 專案引入資源檔 {$R MyRes.res},資源中有圖示 MYICON
MessageEx('自訂圖示訊息', '標題', MB_OK or MB_USERICON, 'MYICON');
// 不使用自訂圖示
MessageEx('一般訊息', '標題', MB_OK or MB_ICONINFORMATION, nil);
MessageEx 放入獨立單元 (如 MsgEx.pas) 置於 Library Path,專案只需 uses MsgEx 即可使用。Windows.pas,可自行宣告 external 'user32.dll' name 'MessageBoxIndirectA' 並定義 TMsgBoxParams 記錄。