打赏

问题仍然由定制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

Delphi tips

LoadString() 中 uID 的资料在哪

posted on 2018-12-10 19:18  楚人无衣  阅读(2325)  评论(0编辑  收藏  举报