C++[转]动态改变MessageBox的按钮文本的语言

本文转自:
http://whatsthematrix.spaces.live.com/blog/cns!52A6BFE11C08D828!158.entry

 

因而设置CultureUIInfo不能改变MessageBox的按钮的文件语言,因为这么些文件是依照你所装之操作系统的语言决定的:你伪装的英文操作系统,

那固然是”Yes””No”;你伪装的国语操作系统,那么就是是“是”“否”。

于是对于可以更改语言版的应用程序,就会面碰到英文版应用程序下的MessageBox的按钮显示“是”“否”(闽南语操作系统);中文版应用程序下之

MessageBox的按钮呈现”Yes””No”。傻呼呼。

相思达到目标,依旧得的,只是于费心,要无拣手段。要动用win-API函数,以及Hook技术
下是自身参考着C++代码写的C#代码
一如既往、首先讲明Hook的品种
   public enum HookType
        {
            Keyboard = 2,//键盘操作

            CBT = 5,//窗口操作

            Mouse = 7, //鼠标操作
        };

二、声明API函数
        [DllImport(“kernel32.dll”)]
        static extern int GetCurrentThreadId();//拿到时之线程ID

        [DllImport(“user32.dll”)]
        static extern int GetDlgItem(IntPtr hDlg, int
nIDDlgItem);//得到Dialog窗口的子项

        [DllImport(“user32”, EntryPoint = “SetDlgItemText”)]
        static extern int SetDlgItemTextA(IntPtr hDlg, int nIDDlgItem,
string lpString);//设置Dialog窗口子项的文本

        [DllImport(“user32.dll”)]
        static extern void UnhookWindowsHookEx(IntPtr handle);//解掉挂钩

        [DllImport(“user32.dll”)]
        static extern IntPtr SetWindowsHookEx(int idHook,
[MarshalAs(UnmanagedType.FunctionPtr)]C++, HookProc lpfn, IntPtr

hInstance, int threadID);//设置挂钩

        [DllImport(“user32.dll”)]
        static extern IntPtr CallNextHookEx(IntPtr handle, int code,
IntPtr wparam, IntPtr lparam);//举办下一个联络,假如有些话

其三、定义有变量
        static IntPtr _nextHookPtr;
        static HookProc myProc = new HookProc(MyHookProc);//must be
global, or it will be Collected by GC, then no callback

func can be used for the Hook
 delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);

季、自定义HookProck逻辑,这是无与伦比首要的局部,咋样威胁人质,怎样敲诈人质,怎么着释放人质
   static IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)
          {
            IntPtr hChildWnd;// msgbox is “child”

            // notification that a window is about to be activated
            // window handle is wParam
            if (code == 5)//HCBT_ACTIVATE = 5
            {
                // set window handles of messagebox
                hChildWnd = wparam;
                //to get the text of yes button

                int result;

                if (GetDlgItem(hChildWnd, 6) != 0)//IDYES = 6
                {
                    result = SetDlgItemTextA(hChildWnd, 6,
Properties.Resources.YES);//在Project.Resources里从定义文本
                }
                if (GetDlgItem(hChildWnd, 7) != 0)//IDNO = 7
                {
                    result = SetDlgItemTextA(hChildWnd, 7,
Properties.Resources.NO);
                }
            }
            else
            {
                CallNextHookEx(_nextHookPtr, code, wparam, lparam);//
otherwise, continue with any possible chained hooks
            }

            //return (IntPtr)1; //直接再次来到了,该新闻就是处理了了
            return IntPtr.Zero;//再次来到,让后边的程序处理该新闻

        }
五、提供被外部调用的Hook方法,如以Form_Load时SetHook,Form_Closing时UnHook.
  public static void SetHook()
        {
            if (_nextHookPtr != IntPtr.Zero)//Hooked already
            {
                return;
            }

            _nextHookPtr = SetWindowsHookEx((int)HookType.CBT, myProc,
IntPtr.Zero, GetCurrentThreadId());

        }

        public static void UnHook()
        {
            if (_nextHookPtr != IntPtr.Zero)
            {
                UnhookWindowsHookEx(_nextHookPtr);

                _nextHookPtr = IntPtr.Zero;
            }
        }

地点的代码可以在一个独文件要APIHelper.cs,供User使用。
指标达到了,看代码就了解,这样不仅可让button的文件可以因语言改变,文本的情节为得打定义。
事实评释抢劫的拿走是诱人的,不过风险资产为是甚高之,
1.对此挂钩Hook技术,我们还不是好通晓,比如什么死后SetHook(),什么时UnHook()就是值得考虑的一个题目,你呢得以以次启动就

SetHook,也堪当进展某项操作后虽SetHook,但是毫无疑问毫无忘记了UnHook,否则你的Hook会造成你出人意料的限量的震慑。
2.回调函数要咬定音讯号,所有的Form在Activate的早晚依然code =
5,不过我们只有当弹出MessageBox的时光装Button的公文。所以若自己

曹以启动程序的时段便SetHook(),必然会吃每趟音讯处理多运动了几段代码,尽管眼睛不能识别那个差异,然而确不必要。

万一SetHook和UnHook的老本不愈,大家得考虑以MessageBox.Show()的地点开展联系和解钩。若是这样,那么只要您的次序中散布着

MessageBox.show(),你就哭吧;TMS真是行,把MessageBox.Show()的效用还抽取到了一个大局静态类里面,我只要反之全局方法就是足以了。

足见抽取共用逻辑依然要命关键之!

敲定:就为大家的主次傻傻的,傻傻要较傻B强得几近。
      至少大家领略了,这一个题目出化解方案。