gpt4 book ai didi

c# - 删除和恢复窗口边框

转载 作者:可可西里 更新时间:2023-11-01 09:35:13 24 4
gpt4 key购买 nike

我想在 C# 中删除另一个进程的窗口边框;我使用 RemoveMenu 删除边框。它几乎可以工作,但我还有 2 个问题:

  • 我需要移除边框两次,第一次菜单栏还在存在。
  • 我无法恢复菜单的

这是我已经写的:

public void RemoveBorders(IntPtr WindowHandle, bool Remove)
{
IntPtr MenuHandle = GetMenu(WindowHandle);

if (Remove)
{
int count = GetMenuItemCount(MenuHandle);
for (int i = 0; i < count; i++)
RemoveMenu(MenuHandle, 0, (0x40 | 0x10));
}
else
{
SetMenu(WindowHandle,MenuHandle);
}

int WindowStyle = GetWindowLong(WindowHandle, -16);

//Redraw
DrawMenuBar(WindowHandle);
SetWindowLong(WindowHandle, -16, (WindowStyle & ~0x00080000));
SetWindowLong(WindowHandle, -16, (WindowStyle & ~0x00800000 | 0x00400000));
}

有人可以告诉我我做错了什么吗?我已经尝试保存 MenuHandle 并稍后恢复它,但这不起作用。

最佳答案

  • I can't restore the menu's

这是因为您的 MenuHandle 是本地变量。

当对方法 RemoveBorders 的第一次调用结束时,垃圾收集器会删除 MenuHandle 并释放内存。

第二次调用 RemoveBorders 时,MenuHandle 重新创建为新的本地 变量,并重新分配给窗口菜单的当前状态 - 一个没有菜单项的菜单.

结果:

MenuHandle 不保存窗口菜单的先前状态,这解释了为什么不能恢复窗口菜单。

我的建议是让 MenuHandle 成为全局变量,并在 RemoveBorders 方法定义之外定义它。

您可以将其定义为私有(private)、 protected 或公共(public)字段,还可以为其定义另一个属性,但这是可选的,不是必需的。如果此属性更适合您,您也可以将其定义为静态。

下面是 MenuHandle 定义的一些例子:

private IntPtr MenuHandle;
//or
IntPtr MenuHandle; //Defined outside of RemoveBorders, which is defined below this line, to show that MenuHandle is not local variable.
public void RemoveBorders(IntPtr WindowHandle, bool Remove)
//or
protected IntPtr MenuHandle;
//or
public IntPtr MenuHandle
//or
private static IntPtr MenuHandle
//or
static IntPtr MenuHandle
//etc...

你必须移动这条线:

IntPtr MenuHandle = GetMenu(WindowHandle);

内部:

if (Remove)

在调用 GetMenuItemCount 函数之前。

您还必须修改该行,至少删除 IntPtr,以声明 MenuHandle 不是 local 变量,并引用 MenuHandle < strong>field,它是在 RemoveBorders 方法之外定义的。IntelliSense 仍会将其识别为字段,并且不会提醒您未定义的错误。

如果 MenuHandle 是不是 static,那么您也可以添加this。删除 MenuHandle 之前的 IntPtr 关键字后(换句话说,您可以将 IntPtr 替换为 this.),以记住 MenuHandle 不是 < strong>local 变量,因此垃圾收集器不会在 RemoveBorders 完成作业时删除它。

当您启动程序时,MenuHandle 将被分配给 IntPtr.Zero 作为默认值。当您第一次调用 RemoveBorders 时,MenuHandle 的值将设置为 if (Remove) 中 GetMenu 函数的返回值。

当 RemoveBorders 第一次 完成时,MenuHandle 不会被删除,并保存窗口菜单的先前状态,在所有项目被删除之前。

因此,当您第二次调用 RemoveBorders 以恢复菜单时,执行程序将到达 if (Remove) 代码并立即跳转到 else 代码,因为 remove = false,并且在那里你调用 SetMenu 函数,当你给它 previous 窗口菜单的状态时,因为 first 调用删除边框。这样您就可以最终恢复窗口的菜单。

我仍然不明白为什么你需要删除边框两次,第一次菜单栏仍然存在。我也想帮你解决这个问题,但是没有办法。在这种情况下,您的代码是正确的。抱歉,但我希望其他人可以为您解决这个问题,并为您提供解决方案。

关于c# - 删除和恢复窗口边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10337680/

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