RT,这个消息框不是我弹出的,弹出的消息内容是一串英文,客户看不懂,所有想改变下里的内容,
我用了系统API函数来抓它的句柄,抓是抓出来了,可改变里的内容就改变不了,只能改变MessageBox的标题。求解??
 
   [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        [DllImport("user32.dll ", EntryPoint = "SendMessageA")]
        private static extern int SendMessage(int hwnd, int wMsg, IntPtr wParam, string lParam);
      
        public void alter()
        {
            int WM_SETTEXT = 0x000C;
            string lpszParentWindow = "Error";
            int ParenthWnd = (int)FindWindow(null, lpszParentWindow);
            if (ParenthWnd != null)
            {
                 SendMessage(ParenthWnd , WM_SETTEXT , IntPtr.Zero, "要修改的内容");
            }
        }

解决方案 »

  1.   

    我觉得,这句本来就是只起到修改窗口标题的作用
    SendMessage(ParenthWnd , WM_SETTEXT , IntPtr.Zero, "要修改的内容");因为你只抓到了对话框的句柄
      

  2.   

    但是窗口的内容是  static类型的,所以我得不到它的句柄
      

  3.   

    没经历过winapi编程的阶段,不知道我的理解对不对。
    除非你知道那个消息框内的数据的构造,否则无法按要求修改里面的内容,你甚至不知道你要修改的那个message是什么,也许就是个图片。
    首先确定message的容器是什么,尝试抓取这个容器的句柄,然后自定一个一样的容器(装了你改了的message),替换掉原来的。
    一个窗体里面的每个组件应该都有其句柄并且可抓取,用截图软件的时候它就能够分析出一个窗体内的不同部分(比如工具栏、滚动条)。
      

  4.   

    MessageBoxW int (HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
      

  5.   


            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        [DllImport("user32.dll ", EntryPoint = "SendMessageA")]
            private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, string lParam);        [DllImport("user32.dll ", EntryPoint = "SendMessageW")]
            private static extern int SendMessageW(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);        [DllImport("user32.dll ", EntryPoint = "GetWindow")]
            private static extern IntPtr GetWindow(IntPtr hwnd, int cmd);        public static void alter()
            {
                int WM_SETTEXT = 0x000C;
                int WM_GETTEXT = 0x000D;
                int GW_HWNDFIRST = 0;
                int GW_HWNDNEXT = 2;
                int GW_CHILD = 5;
                string lpszParentWindow = "Error";
                IntPtr ParenthWnd = FindWindow(null, lpszParentWindow);
                IntPtr control = IntPtr.Zero;
                if (ParenthWnd != IntPtr.Zero)
                {
                    control = GetWindow(ParenthWnd, GW_CHILD);
                    
                    string w = string.Empty;
                    int maxLength = 100;
                    IntPtr buffer;                buffer = Marshal.AllocHGlobal((maxLength + 1) * 2);
                    SendMessageW(control, WM_GETTEXT, maxLength, buffer);
                    w = Marshal.PtrToStringUni(buffer);
                    Marshal.FreeHGlobal(buffer);                while (w != "原来的内容")
                    {
                        control = GetWindow(control, GW_HWNDNEXT);                    buffer = Marshal.AllocHGlobal((maxLength + 1) * 2);
                        SendMessageW(control, WM_GETTEXT, maxLength, buffer);
                        w = Marshal.PtrToStringUni(buffer);
                        Marshal.FreeHGlobal(buffer);
                    }                SendMessage(control, WM_SETTEXT, IntPtr.Zero, "要修改的内容");
                }
            }
      

  6.   

    7楼估计能实现你要的效果。先从技术实现的角度说说你的代码不能工作的原因。sendmessage发送的实际只是2个int型数据,字符串也只发送了地址。这个地址是在你自己的进程空间中的地址。你把这个地址发送给目标进程,他会按这个地址在自己的进程控件里找字符串。那得位置有什么信息,完全是不确定的,自然不行了。就相当于,邻居问你接锤子,你把锤子放进柜子的第二个抽屉里,然后写张纸条“锤子在第二个抽屉”扔给邻居。邻居按你的提示,在自己家的抽屉里找锤子,显然是找不到的。
    另外你这个解决问题很不彻底。你能保证那个程序只弹这一条错误提示吗?其他提示也被你替换成这段文本了。
      

  7.   

    这个好像先得用spy++获取句柄吧 得到句柄了以后用sendmessage 去改消息。
      

  8.   

    因为每弹出一个窗口、弹出一个消息框就好比我们人的身份证号码一样`都有唯一的一个标识,像8#那个例子一样 锤子在第二个抽屉 但是不知道是谁家的抽屉 哪个屋子的抽屉spy++得到这个句柄正是指定了这一个条件。
      

  9.   

    lz可以换个思路,静态修改程序文件。一般如果控件用 VC 写的,那么这些都放在字符串资源里面。如果是 .NET、VB、Delphi 写的就更好修改了。事实上那么多汉化软件,都是这么做出来的。要是按照lz的思路,那麻烦死了。
      

  10.   

    8楼说的,是不准确的。SendMessage不等同于函数调用,字符串的内容,是会被Windows内部复制到目标进程的地址空间里面的。楼主已经说他能够用此方法更改了消息框的标题了。况且据我估计,楼主是因为调用了别人的DLL,而这个DLL可能是英文的,所以他想把错误消息用中文翻译一下。如果是DLL的话,就更不存在地址空间的问题了。楼主的方法之所以不奏效的原因,是WM_SETTEXT消息针对窗口句柄的话,只是修改标题,而不是修改里面显示的内容,如果我们能取到显示内容的控件的子窗口句柄,给那个句柄直接发消息就可以。然而,MessageBox的显示内容并不是在一个控件子窗口里面,(当你尝试用SPY++捕捉的时候,抓不到),
    估计它是在窗口初始化的时候,直接画出来的文字。如果是调用别人DLL的话,也许可以这样做:
    在进程内创建消息钩子,把每个对话框的WM_INITDIALOG接管一下。