我想通过使用SetWindowLong覆盖winmobile任务栏的窗口过程(以捕获和阻止按下的按钮)。我创建了一个类,其中一个方法用于覆盖,另一个用于恢复窗口过程。 MessageReceived方法是我用来替换任务栏窗口过程的方法。我的类看起来方式如下:P /在托管代码(紧凑框架)中调用SetWindowLong和CallWindowProc
class ButtonBlocker
{
public delegate IntPtr WindowProc(IntPtr hwnd, uint uMsg, IntPtr wParam, IntPtr lParam);
public static WindowProc newWindowDeleg;
private static IntPtr oldWindowProc;
[DllImport("coredll.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("coredll.dll")]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("coredll.dll")]
static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
private static IntPtr MessageReceived(IntPtr hwnd, uint uMsg, IntPtr wParam, IntPtr lParam)
{
Debug.WriteLine("Message received");
return CallWindowProc(oldWindowProc, hwnd, uMsg, wParam, lParam);
}
public static void OverrideWindowProc()
{
newWindowDeleg = MessageReceived;
IntPtr taskBarHandle = FindWindow("HHTaskBar", null);
int newWndProc = Marshal.GetFunctionPointerForDelegate(newWindowDeleg).ToInt32();
int result = SetWindowLong(taskBarHandle, -4, newWndProc);
oldWindowProc = (IntPtr)result;
if (result == 0)
{
MessageBox.Show("Failed to SetWindowLong");
}
}
public static void RestoreWindowProc()
{
IntPtr taskBarHandle = FindWindow("HHTaskBar", null);
int result = SetWindowLong(taskBarHandle, -4, oldWindowProc.ToInt32());
}
}
在移动仿真器的行为是下面的 - 之后我按下一个按钮,“收到消息”显示在调试输出,但该程序崩溃,并提供送向微软提交崩溃报告。 visual studio调试器挂起并且不会对停止命令做出反应。只有在仿真器复位后才会解冻。 问题似乎是在MessageReceived方法结束时的CallWindowProc。很可能,旧的windowproc地址存在一些问题。 如果我试图在OverrideWindowProc代码之后立即执行RestoreWindowProc代码(没有消息被我的函数拦截),那么应用程序退出并且调试器不会冻结。 任何想法如何让这个工作,将不胜感激。
我正在使用Visual Studio 2008 SP1。该项目面向.NET Framework v3.5,Windows Mobile 6 Professional。
事实上,如果我使用我的应用程序窗口句柄而不是任务栏,代码将很好地工作。唯一让我无法理解的是,为什么GreenButton应用程序能够工作,因为它不注入dll,并且实际上在它自己的exe文件中定义了两个函数。它是用本地代码编写的,但根据你的解释,这不应该起作用。有什么想法吗? 这里是网站:http://www.supware.net/GreenButton/ 这里是链接到源代码: http://www.supware.net/GreenButton/GreenButton-source.zip The有趣的部分是在GreenButton.cpp文件中。 – Yakimych 2010-01-21 10:17:23