gpt4 book ai didi

c# - P/Invoking SetWindowLong 和 CallWindowProc 在托管代码(紧凑框架)

转载 作者:行者123 更新时间:2023-12-04 06:59:28 26 4
gpt4 key购买 nike

我正在尝试使用 SetWindowLong 覆盖 winmobile 任务栏的窗口过程(以捕获和阻止按下的按钮)。我创建了一个类,其中一种方法用于覆盖,另一种方法用于恢复窗口过程。 MessageReceived 方法是我用来替换任务栏窗口过程的方法。我的类(class)看起来如下:

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());
}
}

移动模拟器中的行为如下 - 在我按下按钮后,调试输出中显示“收到消息”,但程序崩溃并提供向 Microsoft 发送崩溃报告。 Visual Studio 调试器挂起并且对停止命令没有反应。它仅在模拟器重置后解冻。
问题似乎出在 MessageReceived 方法末尾的 CallWindowProc 上。很可能,旧的 windowproc 地址存在一些问题。
如果我尝试在 OverrideWindowProc 代码之后立即执行 RestoreWindowProc 代码(我的函数没有截获任何消息),则应用程序正常退出并且调试器不会卡住。
任何有关如何使其工作的想法将不胜感激。

我正在使用 Visual Studio 2008 SP1。该项目面向 .NET 框架 v3.5、Windows Mobile 6 Professional。

最佳答案

您不能替换由另一个进程拥有的窗口的窗口过程。替换函数的地址只在你的进程中有效。它会在另一个过程中立即引发炸弹。您必须将 DLL 注入(inject)目标进程才能解决此问题。您不能注入(inject)以托管语言编写的 DLL,CLR 未初始化。

关于c# - P/Invoking SetWindowLong 和 CallWindowProc 在托管代码(紧凑框架),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2104667/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com