我想在C#中删除另一个进程的窗口边框;我使用RemoveMenu删除边框。它几乎可以工作,但是我还有两个问题:
存在。
这是我已经写的:
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并在以后还原它,但这不起作用。
最佳答案
这是因为您的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是而不是 本地变量,并引用MenuHandle 字段,该字段是在RemoveBorders方法之外定义的。
IntelliSense仍会将其识别为字段,并且不会提醒您未定义的错误。
如果MenuHandle是而不是 静态,则还可以添加this
。在删除MenuHandle之前的IntPtr之后的关键字(换句话说,您可以将IntPtr
替换为this.
),以记住MenuHandle不再是 本地变量,而不是,因此Garbage Collector 将不再ojit_rorder删除它工作。
当您启动程序时,MenuHandle将被分配给IntPtr.Zero
作为默认值。当您在的第一个时间内调用RemoveBorders时,MenuHandle的值将设置为if (Remove)
中GetMenu函数的返回值。
当RemoveBorders在的第一个时间内完成时,不会删除MenuHandle,并且会在删除所有菜单项之前保存窗口菜单的先前状态。
因此,当您为了恢复菜单而在的第二个时间内调用RemoveBorders时,执行程序将到达if (Remove)
代码并立即跳转到else
代码,因为remove = false,然后在其中调用SetMenu函数,当您将自首次对RemoveBorders进行调用以来,窗口菜单的先前状态。
这样,您将最终能够恢复窗口的菜单。
我仍然不知道为什么您需要在第一次出现菜单栏时就删除边框两次。
我也想帮助您解决这个问题,但是不知道。
在这种情况下,您的代码是正确的。抱歉,但我希望其他人可以为您解决此问题,并也为您提供解决方案。
关于c# - 删除和还原窗口边框,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10337680/