需要给整个应用程序的所有Form的显示进行拦截,然后动态修改显示窗体的样式和标题,请问怎样实现?
用AddMessageFilter()好像找不到对应的消息,就算找到了如果得到正在显示的窗体的实例?
用AddMessageFilter()好像找不到对应的消息,就算找到了如果得到正在显示的窗体的实例?
解决方案 »
- Datagridview 显示存储过程创建的表
- 我在codeproject中看到一段代码关于使用RAS拨VPN的,但需要先将VPN设置好,并保存密码才能拨号,有哪位大虾能帮我改改这段代码
- 关于gridview模版列的问题
- 关于Random().NextBytes()在内存的编码(分不够可再加)
- 发第三个贴接着问。不信没人会
- 如何用sqldmo执行命令获取SQL数据
- 怎样读出单元格开头的'号(Excel中)
- 菜!B/S程序做好后怎么样让客户端可访问
- C#中如何取得计算机名?
- sqlDataAdapter.Fill()发生异常!大家帮帮忙!~~~
- 请大家帮我看一个调试的问题
- 怎样把unicode转换成字符,反之亦然
Form2 frm=new Form2(); //这里已经实例化
frm.Show(); //**********执行到这里的时候进行拦截
整个应用程序中有几百个Form,如果每个都加上比较冗余,而且有部分Form在一些没有代码的DLL中,所以需要进行拦截.
就只能用API修改~~~~
到网上去找找,例子很多
,在MyForm里面重写OnLoad方法,然后所有自己写的Form都去继承这个MyForm
用哪个API,能提供一点线索吗?
皮肤控件不需要你有基类,只需要你在Main()方法中增加一行初始化皮肤控件的语句就可以了.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Xml;
using System.Runtime.InteropServices;
namespace WindowsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
HookMsg.Install();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
HookMsg.Install();
} private void button1_Click(object sender, EventArgs e)
{
Form frm = new Form();
frm.Text = "新建窗口!";
frm.Show();
}
}
public class HookMsg
{ private const int WH_CBT = 0x5;
private const int IDC_OK = 0x1;
private const int IDC_Text = 0xFFFF;
[DllImport("user32.dll")]
protected static extern IntPtr SetWindowsHookEx(int code, HookProc func, IntPtr hInstance, int threadID);
[DllImport("user32.dll")]
protected static extern int UnhookWindowsHookEx(IntPtr hhook);
[DllImport("user32.dll")]
protected static extern int CallNextHookEx(IntPtr hhook, int code, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern int GetWindowText(IntPtr hwnd, [Out]StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")]
protected static extern int GetClassName(IntPtr hwnd, [Out]StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")]
protected static extern int SetWindowText(IntPtr hWnd, string lpString); [DllImport("user32.dll")]
protected static extern IntPtr GetDlgItem(IntPtr hwnd, int id);
[DllImport("User32")]
protected static extern int SetDlgItemText(IntPtr hDlg, int nIDDlgItem, string lpString);
[DllImport("user32.dll")]
protected static extern int GetDlgItemText(IntPtr hDlg, int nIDDlgItem, [Out] StringBuilder lpString, int nMaxCount); [DllImport("user32.dll", EntryPoint = "MessageBox")]
protected static extern int _MessageBox(IntPtr hwnd, string text, string caption,
int options); [DllImport("user32.dll")]
protected static extern IntPtr GetActiveWindow(); [DllImport("user32.dll")]
protected static extern void DestroyWindow(IntPtr hwnd);
private static System.IntPtr m_hhook; public delegate int HookProc(int code, IntPtr wParam, IntPtr lParam); protected static HookProc m_filterFunc; static HookMsg()
{
if (m_filterFunc == null)
m_filterFunc = new HookProc(CoreHookProc);
} public static void Install()
{ m_hhook = SetWindowsHookEx(WH_CBT, m_filterFunc, IntPtr.Zero, AppDomain.GetCurrentThreadId());
} public static void Uninstall()
{
UnhookWindowsHookEx(m_hhook);
} //CallBack
protected static int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code == 5)
{
StringBuilder sb = new StringBuilder();
sb.Capacity = 255;
//Title
GetWindowText(wParam, sb, 255);
string strTitle = "jinjazz看到了:" + sb.ToString();
SetWindowText(wParam, strTitle);
}
return 0;
}
}
}
非常感谢!感觉成功了99%,还有两个小问题:
protected static int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code == 5)
{
//【问题1】:这里如何只被调用一次,感觉窗体每刷新一次,这里调用一次 ***
StringBuilder sb = new StringBuilder();
sb.Capacity = 255;
//Title
GetWindowText(wParam, sb, 255);
string strTitle = "jinjazz看到了:" + sb.ToString();
SetWindowText(wParam, strTitle); //【问题2】:如何通过wParam得到对应窗体的实例?
Form frm = XXX(wParam);
frm.其它属性 = Value;
}
return 0;
}
问题2,如果都是.net的可以用系统函数
//CallBack static System.Collections.Generic.List<IntPtr> listForms = new List<IntPtr>();
protected static int CoreHookProc(int code, IntPtr wParam, IntPtr lParam)
{
if (code == 5)
{
//问题1
if (listForms.Contains(wParam))
{
return 0;
}
else
{
listForms.Add(wParam);
}
StringBuilder sb = new StringBuilder();
sb.Capacity = 255;
//Title
GetWindowText(wParam, sb, 255);
string strTitle = "jinjazz看到了:" + sb.ToString();
SetWindowText(wParam, strTitle); //问题2
try
{
Form frm = Form.FromHandle(wParam) as Form;
frm.Size = new Size(100, 100);
}
catch { }
}
return 0;
}
http://blog.csdn.net/jinjazz/archive/2007/11/21/1896625.aspx这段代码是我为一个大型成品系统写多语言版本时用的一个插件,只需要在主窗体里面载入这个翻译插件,然后设置挂钩,配合资源文件来翻译成品系统的所有ui控件,在Form.FromHandle得到窗体实例后,可以递归遍历其中的所有已知控件。
问题一,自己设置一个标志位,问题二使用Control.FromHandle感谢大家的关注!
感谢jinjazz的代码!!
刚才没看见你上面的回复,我search了一下,用Control.FromHandle 可以实现.thanks!