问题仍然由定制MessageBox引发。
定制MessageBox,虽加入自定义些东西,但仍然希望,最大限度接近系统原生框。碰到的问题,就是其钮文本。
即如MessageBox.Show()之MessageBoxButtons(c#)或MessageBox()之MB_OKCANCEL之类。
遍找网络,功夫不负有心人,终于找到!
一、GetModuleHandle、LoadString与user32.dll
所用到的资源,存在于user32.dll中,其编号以8开头,定义其常量为:
c#:
[DllImport("kernel32")] static extern IntPtr GetModuleHandle(string lpFileName); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax); private const uint OK_CAPTION = 800; private const uint CANCEL_CAPTION = 801; private const uint ABORT_CAPTION = 802; private const uint RETRY_CAPTION = 803; private const uint IGNORE_CAPTION = 804; private const uint YES_CAPTION = 805; private const uint NO_CAPTION = 806; private const uint CLOSE_CAPTION = 807; private const uint HELP_CAPTION = 808; private const uint TRYAGAIN_CAPTION = 809; private const uint CONTINUE_CAPTION = 810;
Delphi:
const OK_CAPTION = 800; CANCEL_CAPTION = 801; ABORT_CAPTION = 802; RETRY_CAPTION = 803; IGNORE_CAPTION = 804; YES_CAPTION = 805; NO_CAPTION = 806; CLOSE_CAPTION = 807; HELP_CAPTION = 808; TRYAGAIN_CAPTION = 809; CONTINUE_CAPTION = 810;
二、获取
根据以上资源,写获取函数为:
c#:
private string LoadWindowsStr(string libraryName, uint ident, string defaultText = "") { IntPtr ptr = GetModuleHandle(libraryName); if (ptr == IntPtr.Zero) return defaultText; var sb = new StringBuilder(256); int len = LoadString(ptr, ident, sb, sb.Capacity); if (len == 0) return defaultText; return sb.ToString(); } private void Form1_Load(object sender, EventArgs e) { string s = string.Empty; for (uint i = OK_CAPTION; i <= CONTINUE_CAPTION; i++) s += LoadWindowsStr("user32.dll", i, string.Empty) + "\r\n"; textBox2.Text = s; }
Delphi:
function LoadWindowsStr(const LibraryName: String; const AIdent: Integer; const ADefaultText: String = ''): String; var hLibrary: THandle; iSize: Integer; begin hLibrary := GetModuleHandle(PChar(LibraryName)); if (hLibrary <> 0) then begin SetLength(Result, MAX_PATH); iSize := LoadString(hLibrary, AIdent, PChar(Result), MAX_PATH); if (iSize > 0) then SetLength(Result, iSize) else Result := ADefaultText; end else Result := ADefaultText; end; procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin Memo1.Clear; for i := OK_CAPTION to CONTINUE_CAPTION do Memo1.Lines.Append(LoadWindowsStr('user32.dll', i)); end;
三、效果:
验证获取字串如下,以中、日、英为例:
确定 取消 中止(&A) 重试(&R) 忽略(&I) 是(&Y) 否(&N) 关闭(&C) 帮助 重试(&T) 继续(&C)
OK キャンセル 中止(&A) 再試行(&R) 無視(&I) はい(&Y) いいえ(&N) 閉じる(&C) ヘルプ 再実行(&T) 続行(&C)
OK Cancel &Abort &Retry &Ignore &Yes &No &Close Help &Try Again &Continue
OK,问题解决。
参考资料:
c# - c # - Sì / No valore del sistema - CoreDump.one
c# - How do I get MessageBox button caption? - Stack Overflow