调用外部应用程序 代码如下
 try
            {
                ProcessStartInfo p = null;
                Process Proc;
                p = new ProcessStartInfo("Setup.exe", "-update");
                p.WorkingDirectory = Path.GetTempPath() + "\\RavUp";//设置此外部程序所在windows目录
                  Proc = Process.Start(p);//调用外部程序
            }
            catch (Exception err) 
            { 
                MessageBox.Show("启动更新程序出错\n\r"+err.ToString(), "RavUp提示");
            }setup.exe 窗口有四个按钮 “上一步(p)”“下一步(n)”“完成(f)”“取消(c)”我想把“取消(C)”设成不可用状态(灰色)
请问各位大虾们怎么用api HOOK设置

解决方案 »

  1.   

    找到按钮的窗口句柄,然后调用EnableWindows函数。
    我自己先试一个,然后发一段代码上来。
      

  2.   

    楼上说的对,用FindWindow\FindWindowEx找按钮的句柄,然后EnableWindow
      

  3.   

    OK,我尝试成功了。
    定义一个函数:        [DllImport("User32.dll")]
            public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
    第一个参数是窗口句柄,第二个窗口是设置是窗口有效或者无效,传入false即可。问题在于如何取得窗口句柄,我在测试程序中是用spy++直接查找窗口句柄,在实际中你可以用:
         
            [DllImport("User32.dll")]
            public static extern int FindWindow(string strClassName, string strWindowName);    
            [DllImport("User32.dll")]
            public static extern int FindWindowEx(int hwndParent, int hwndChildAfter, string strClassName, string strWindowName);    
            [DllImport("User32.dll", SetLastError = true)]
            public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
    这两个函数的均是返回窗口句柄,比如:
    IntPtr k = (IntPtr)FindWindowEx("ClassName","WindowsName");
    第一种调用方法中第一个参数是窗口的类名,可以为空(null),第二个参数是窗口的标题栏名称。必须至少有一个有效。
      

  4.   

    对了,有一点我还没尝试。我是直接尝试对一个.NET程序的按钮发送了这个指令,这个按钮的确被禁止了(点击无效),但按钮的文本并没有变灰。我得再研究研究。
      

  5.   

    楼上说的对,用FindWindow\FindWindowEx找按钮的句柄,然后EnableWindow个人认为这是正解。不知道句柄是什么的在提问
      

  6.   

            [DllImport("User32.dll")]
            public static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);
           
            [DllImport("User32.dll")]
            public static extern int FindWindow(string lpClassName, string lpWindowName);
             [DllImport("User32.dll")]
            public static extern int EnableWindow(int hwnd, bool fEnable);        private void button1_Click(object sender, EventArgs e)
            {
                int h1 = 0, h2 = 0;
                bool bEnable = true;
                h1 = FindWindow(null, "任务栏和「开始」菜单属性");    //这要修改为窗口标题
                if (h1 != 0)
                {
                    h2 = FindWindowEx(h1, 0, null, "应用(&A)");    //这要修改为按钮文本
                    if (h2 != 0)
                    {
                        EnableWindow(h2, false);
                    }
                    else
                    {
                        MessageBox.Show("h2==0");
                    }
                }
                else
                {
                    MessageBox.Show("h1==0");
                }
            }
      

  7.   

    经过测试,确定了上面的问题:.NET开发的WinForm程序响应EnableWindows不会使窗口变灰,而用其它语言开发的则可以,我的notepad是可以的。另外需要提醒的一点是使用FindWindows可能找不到单个的窗口,需要通过spy++确定规律,比如由某种类型的窗口包含的子窗口之类的。
      

  8.   

    给另外一段代码,这段代码是用于查找右下角的系统托盘的窗口句柄的C#代码的,这种代码需要考虑不同操作系统中的这个托盘窗口的类型和隶属关系的不同而处理。        //取得系统托盘窗口的句柄
            private static int GetSysTrayWnd()
            {
                OSName osn = OS.GetVersion();
                int k = Windows.FindWindow("Shell_TrayWnd", null);
                k = Windows.FindWindowEx(k, 0, "TrayNotifyWnd", null);            if (osn == OSName.Win2000 || osn == OSName.WinXP || osn == OSName.Win2003)
                {                
                    if (osn == OSName.Win2000)
                    {
                        k = Windows.FindWindowEx(k, 0, "ToolbarWindow32", null);
                        return k;
                    }
                    else
                    {
                        k = Windows.FindWindowEx(k, 0, "SysPager", null);
                        k = Windows.FindWindowEx(k, 0, "ToolbarWindow32", null);
                        return k;
                    }
                }
                else
                {
                    return k;
                }
            }