none
标准按钮何在 RRS feed

  • 问题

  • 就是中文环境自动显示“确定”“取消”,英文环境自动变为“OK”“Cancel”的按钮。

    MessageBox 常用 MessageBoxButton ,但我想在自定义对话框中使用。


    箪食瓢饮随遇安,不求栋梁求参天。
    2011年7月15日 21:58

答案

  • 我已经用这样的方法解决了,只是比较绕,现在的问题是不知道有没有更简洁的 C# 方法。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication1 {
      class Program {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
        [DllImport("kernel32")]
        static extern IntPtr LoadLibrary(string lpFileName);
    
        private const uint OK_CAPTION = 800;
        private const uint CANCEL_CAPTION = 801;
    
        static void Main(string[] args)
        {
          StringBuilder sb = new StringBuilder(256);
    
          IntPtr user32 = LoadLibrary(Environment.SystemDirectory + "\\User32.dll");
    
          LoadString(user32, OK_CAPTION, sb, sb.Capacity);
          string ok = sb.ToString();
    
          LoadString(user32, CANCEL_CAPTION, sb, sb.Capacity);
          string cancel = sb.ToString();
    
          Console.WriteLine("{0} {1}", ok, cancel);
        }
      }
    }
    
    可以看到,在中文系统上,输出为“确定  取消”。


    箪食瓢饮随遇安,不求栋梁求参天。
    • 已标记为答案 Cookie Luo 2011年7月27日 1:25
    2011年7月21日 6:33

全部回复

  • 就是中文环境自动显示“确定”“取消”,英文环境自动变为“OK”“Cancel”的按钮。

    MessageBox 常用 MessageBoxButton ,但我想在自定义对话框中使用。


    箪食瓢饮随遇安,不求栋梁求参天。

    如果是我,我将会使用Resource(资源文件)进行按钮以及其它相关的文字“本地化处理”。
    具体您可以参考这篇文章:
    http://msdn.microsoft.com/zh-cn/library/y99d1cd3(v=VS.80).aspx
    如果你有其它意见或私下交流,请直接发送maledong_work@foxmail.com;或者讨论(Talk)
    If you do not have QQ, please open the page and download it and click the image to talk or leave message for me.
    下载MSDN桌面工具(Vista,Win7)
    下载Technet桌面小工具(Vista,Win7)
    慈善点击,点击此处
    2011年7月16日 4:54
    版主
  • 若该对话框是直接在项目中用的,大可一起随程序其它部分本地化。问题在于该对话框是作为库而写的,而我也见过有些全英文软件的这种按钮是中文的,明显是系统提供的。估计 Win32 API 应该有提供,但我不懂。

    箪食瓢饮随遇安,不求栋梁求参天。
    2011年7月16日 5:27
  • dear

    System.Windows.Forms.MessageBox 是实作Win32AIP的MessageBox,所以不建议使用它来处理对话视窗,並沒有處理文化特性,當然要處理也可以,你得多費點心神處裡Win32API

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern int MessageBox(int h, string m, string c, int type);
    private void button2_Click(object sender, EventArgs e)
    {
      MessageBox(0, "API Message Box", "API Demo", 0);
    }

    建议自已弄一个对话视窗的Form以便实现多国语言,有很多種方式可以達到多國語言,比用Win32API方便呀,在一个Form上画两个按钮应该不难吧!?

    1.利用文畫特性

    http://www.dotblogs.com.tw/yc421206/archive/2011/02/21/21482.aspx

    2.利用序列化

    http://www.dotblogs.com.tw/yc421206/archive/2011/02/20/21469.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年7月16日 6:22
  • .NET 也提供了 MessageBox 包装,但那只是一个消息框,我的是对话框,有编辑框、组合框等,一个完整的表单,但没标签,编辑框是用图片作提示的,所以不存在本地化问题。但两个按钮例外,得要是文字。
    箪食瓢饮随遇安,不求栋梁求参天。
    2011年7月16日 6:30
  • 楼主:)

    我和MVP都是这样认为的:你是可以用一个普通的Form取而代之API中繁琐复杂的窗体按钮什么的,然后拖拽两个Button,使用序列化工具对文字序列化。

    把普通窗体当成MessageBox使用,只需调用ShowDialog()方法即可。


    如果你有其它意见或私下交流,请直接发送maledong_work@foxmail.com;或者讨论(Talk)
    If you do not have QQ, please open the page and download it and click the image to talk or leave message for me.
    下载MSDN桌面工具(Vista,Win7)
    下载Technet桌面小工具(Vista,Win7)
    慈善点击,点击此处
    2011年7月16日 6:33
    版主
  • .NET 也提供了 MessageBox 包装,但那只是一个消息框,我的是对话框,有编辑框、组合框等,一个完整的表单,但没标签,编辑框是用图片作提示的,所以不存在本地化问题。但两个按钮例外,得要是文字。
    箪食瓢饮随遇安,不求栋梁求参天。

    Dear

    你的对话框是客制化的,更确定.NET没有提供,小的愚昧,贸然请问你是如何包装??是继承MessageBox??

     

    就是中文环境自动显示“确定”“取消”,英文环境自动变为“OK”“Cancel”的按钮。

    MessageBox 常用 MessageBoxButton ,但我想在自定义对话框中使用。


    箪食瓢饮随遇安,不求栋梁求参天。

    Dear

    这就是多国语言...你要丢值给MessageBox才会帮你处理,可没有系统会帮你翻译噢
    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年7月16日 6:58
  • 我没处理 MessageBox ,我用的就是 Form ,愿望很简单,就是希望两个按钮标题由本地系统提供。

    我看到过英文软件用的中文按钮,但绝不是消息框,而是它自己的对话框,别的都是英文,唯独这样的按钮是本地化的。

    所以我相信肯定是有途径的。


    箪食瓢饮随遇安,不求栋梁求参天。
    2011年7月16日 8:23
  • dear

    只要处理那"两个按钮"的多国语言即可,语言切换机制就是判断计算机的语系

    下段代码在我帖给你的连结里就有,我想你应该可以看仔细点
    System.Threading.Thread.CurrentThread.CurrentUICulture


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年7月16日 8:48
  • class Program {
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
    [DllImport("kernel32")]
    static extern IntPtr LoadLibrary(string lpFileName);
    
    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;
    
    static void Main(string[] args) {
        StringBuilder sb = new StringBuilder(256);
    
        IntPtr user32 = LoadLibrary(Environment.SystemDirectory + "\\User32.dll");
    
        LoadString(user32, OK_CAPTION, sb, sb.Capacity);
        string ok = sb.ToString();
    
        LoadString(user32, CANCEL_CAPTION, sb, sb.Capacity);
        string cancel = sb.ToString();
    
        LoadString(user32, ABORT_CAPTION, sb, sb.Capacity);
        string abort = sb.ToString();
    
        LoadString(user32, RETRY_CAPTION, sb, sb.Capacity);
        string retry = sb.ToString();
    
        LoadString(user32, IGNORE_CAPTION, sb, sb.Capacity);
        string ignore = sb.ToString();
    
        LoadString(user32, YES_CAPTION, sb, sb.Capacity);
        string yes = sb.ToString();
    
        LoadString(user32, NO_CAPTION, sb, sb.Capacity);
        string no = sb.ToString();
    
        LoadString(user32, CLOSE_CAPTION, sb, sb.Capacity);
        string close = sb.ToString();
    
        LoadString(user32, HELP_CAPTION, sb, sb.Capacity);
        string help = sb.ToString();
    
        LoadString(user32, TRYAGAIN_CAPTION, sb, sb.Capacity);
        string tryAgain = sb.ToString();
    
        LoadString(user32, CONTINUE_CAPTION, sb, sb.Capacity);
        string cont = sb.ToString();
    
    }
    
    



    箪食瓢饮随遇安,不求栋梁求参天。
    2011年7月19日 23:33
  • dear

    完全看不懂你的问题,到底是用Win32API处理还是用控件?若你要让你的问题能够早点解决应该描述清楚点

     


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年7月20日 2:03
  • 就是希望两个按钮标题能随系统语言而变,与本地系统统一,但不是自己搞本地化。

    上面的方法,思维很直接,但做法有点绕,

    看 wxWidgets 文档,虽然我没用过,但 wx/stockitem.h 提供的 wxGetStockLabel() 应该也可以从系统获取本地化标题, MFC 也不清楚, C# 则是没找到有这样功能的预定义类。


    箪食瓢饮随遇安,不求栋梁求参天。
    2011年7月20日 7:31
  • 默认就是在不同的操作系统下显示不同的语言的文字。

    我刚才测试了下,把以前在中文vs2005的做的一个小软件拿出来在英文操作系统(上班用的操作系统)下试了下,显示的是Yes/No。 并非是以前的是/否。


    Cookie Luo[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    2011年7月21日 2:22
  •  

    你那是 MessageBox ,但我的不是 MessageBox ,而是自定义的对话框,有组合框,有编辑框等等,是一个有特殊用途能接受用户输入的对话框,而不是一个简单的消息框。

    鉴于上次有贴发图失败,这次就用文本略做说明


    // ------------------------------------
    // | (图标)             X|
    // ------------------------------------
    // | (苹果图标).           |
    // | [____________ComboBox________[v] |
    // | (梨子图标).           |
    // | [____________ComboBox________[v] |
    // | (香蕉图标).           |
    // | [____________TextBox___________] |
    // |                 |
    // |          [确定] [取消] |
    // ------------------------------------

    怎么不是等宽字体?

    2011年7月21日 6:02
  • 楼主,你的意思是——使用自定义的WinForm+Windows API的语言实时动态变化按钮?

    我还是建议你使用C#内置的Local本地化功能。把这两个联合起来做不是很容易的。


    如果你有其它意见或私下交流,请直接发送maledong_work@foxmail.com;或者讨论(Talk)
    If you do not have QQ, please open the page and download it and click the image to talk or leave message for me.
    下载MSDN桌面工具(Vista,Win7)
    下载Technet桌面小工具(Vista,Win7)
    慈善点击,点击此处
    2011年7月21日 6:06
    版主
  • 我已经用这样的方法解决了,只是比较绕,现在的问题是不知道有没有更简洁的 C# 方法。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication1 {
      class Program {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
        [DllImport("kernel32")]
        static extern IntPtr LoadLibrary(string lpFileName);
    
        private const uint OK_CAPTION = 800;
        private const uint CANCEL_CAPTION = 801;
    
        static void Main(string[] args)
        {
          StringBuilder sb = new StringBuilder(256);
    
          IntPtr user32 = LoadLibrary(Environment.SystemDirectory + "\\User32.dll");
    
          LoadString(user32, OK_CAPTION, sb, sb.Capacity);
          string ok = sb.ToString();
    
          LoadString(user32, CANCEL_CAPTION, sb, sb.Capacity);
          string cancel = sb.ToString();
    
          Console.WriteLine("{0} {1}", ok, cancel);
        }
      }
    }
    
    可以看到,在中文系统上,输出为“确定  取消”。


    箪食瓢饮随遇安,不求栋梁求参天。
    • 已标记为答案 Cookie Luo 2011年7月27日 1:25
    2011年7月21日 6:33
  • 你好

    我觉得你的方法不错。.net好像没有封装对应的类来解决这种问题。如果要说有的话,也就是本地化了,但是如果只是为了确定,取消等等很少的文字去做本地化的话,太麻烦了点。

    所以我觉得你这样调用系统api去实现是可行的。我测试了下代码,在我的电脑上运行结果是:Ok Cancle。


    Cookie Luo[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年7月21日 6:44
  • dear

    這是MS針對某些字串的本地化,但對我而言彈性太小,倘若今天客戶覺得字型太小,又得改Code,操作Win32API很麻煩,除非沒有更好的選擇我才會用它,所以我會比較傾向使用多國語系的方式來處理,這也是微軟建議的方法,我想沒有人願意回到造輪子的時代,什麼事都自己來,讓我們更專心的開發商業流程把工作更快速的完成才是我們要的~

    http://msdn.microsoft.com/zh-cn/library/y99d1cd3%28VS.80%29.aspx

    但這僅是我的想法,實際上還是得根據您的需求而定。


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年7月21日 8:54
  • 楼主,您的这个方式是非常好的。.NET 没有提供基于类似 C++ 对话框体系的东西,因此对于一些 C++ 中的特殊控件以及文本,比如 IDOK, IDM_CLOSE 等,都没有直接的支持。

    最好的方法就是用 LoadString。


    Mark Zhou
    2011年7月26日 7:33