2010-05-13 84 views
12

我的应用程序启动另一个外部应用程序。使用c删除外部应用程序的标题栏#

我想在启动后删除这个外部应用程序的标题栏。

这是否可行,如果是的话,将如何做?

根据我使用的工作代码如下

//Finds a window by class name 
[DllImport("USER32.DLL")] 
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

//Sets a window to be a child window of another window 
[DllImport("USER32.DLL")] 
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

//Sets window attributes 
[DllImport("USER32.DLL")] 
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 

//Gets window attributes 
[DllImport("USER32.DLL")] 
public static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] 
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); 


//assorted constants needed 
public static int GWL_STYLE = -16; 
public static int WS_CHILD = 0x40000000; //child window 
public static int WS_BORDER = 0x00800000; //window with border 
public static int WS_DLGFRAME = 0x00400000; //window with double border but no title 
public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar 

public void WindowsReStyle() 
{ 
    Process[] Procs = Process.GetProcesses(); 
    foreach (Process proc in Procs) 
    { 
     if (proc.ProcessName.StartsWith("notepad")) 
     { 
      IntPtr pFoundWindow = proc.MainWindowHandle; 
      int style = GetWindowLong(pFoundWindow, GWL_STYLE); 
      SetWindowLong(pFoundWindow, GWL_STYLE, (style & ~WS_CAPTION)); 
     } 
    } 
} 
+0

'公共静态INT WS_CAPTION = WS_BORDER | WS_DLGFRAME;'不正确,因为WS_DLGFRAME不是标题的一部分。参考:http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx – 2014-12-10 15:23:08

回答

9

无需注入任何东西,你可以修改窗口样式位如使用API​​,例如这适用于记事本,但是YMMV取决于你玩的应用程序。

alt text http://img297.imageshack.us/img297/8580/40498359.png

//Get current style 
lCurStyle = GetWindowLong(hwnd, GWL_STYLE) 

//remove titlebar elements 
lCurStyle = lCurStyle And Not WS_CAPTION 
lCurStyle = lCurStyle And Not WS_SYSMENU 
lCurStyle = lCurStyle And Not WS_THICKFRAME 
lCurStyle = lCurStyle And Not WS_MINIMIZE 
lCurStyle = lCurStyle And Not WS_MAXIMIZEBOX 

//apply new style 
SetWindowLong hwnd, GWL_STYLE, lCurStyle 

//reapply a 3d border 
lCurStyle = GetWindowLong(hwnd, GWL_EXSTYLE) 

SetWindowLong hwnd, GWL_EXSTYLE, lCurStyle Or WS_EX_DLGMODALFRAME 

//redraw 
SetWindowPos hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_FRAMECHANGED 
+0

可以更详细的代码。谢谢。 – Anuya 2010-05-14 02:19:00

+0

当然; http://stackoverflow.com/questions/2832828/how-to-remove-the-menubar-of-an-application-using-windows-api;) – 2010-05-14 09:55:24

+0

imageshack网址似乎是“死”? – 2017-04-26 11:18:12

2

一般的意见,你不能这样做,除非有在应用程序正在启动(例如直接支持,如果它需要一个命令行开关来删除标题栏)。

您只能控制ProcessStartInfo类中已有的东西(即打开一个新窗口,开始最小化/最大化等等)。

+0

是否有任何其他方式来隐藏该第三方应用程序的标题栏?它只有一种形式,我需要删除它。 – Anuya 2010-05-13 09:20:32

+0

@karthik - 仅当它已经支持此功能。这不是你可以直接控制的东西。 – Oded 2010-05-13 09:38:54

1

这与以前提出的问题非常相似,我很肯定答案是你不能这样做。 (或者,如果可以的话,你需要挖掘到Windows API,它可以是具有挑战性的,这取决于你的经验。)

How to add button to other apps window title bar (XP/Vista)

+1

这是不正确的。你可以做到这一点,这里列出的解决方案确实有效。 – 2013-12-05 21:47:10

2

好,亚历克斯从来没有与代码阐述,以及至少它不是一个插件的即插即用解决方案,但仍这主要归功于他......这除非您使用“SetParent”将它放入某种容器(例如表单或面板)中,否则就是一种错误。只是认为我会分享结果。

的Visual Basic:

Option Strict On 
Public Class Form1 
    Const WS_BORDER As Integer = 8388608 
    Const WS_DLGFRAME As Integer = 4194304 
    Const WS_CAPTION As Integer = WS_BORDER Or WS_DLGFRAME 
    Const WS_SYSMENU As Integer = 524288 
    Const WS_THICKFRAME As Integer = 262144 
    Const WS_MINIMIZE As Integer = 536870912 
    Const WS_MAXIMIZEBOX As Integer = 65536 
    Const GWL_STYLE As Integer = -16& 
    Const GWL_EXSTYLE As Integer = -20& 
    Const WS_EX_DLGMODALFRAME As Integer = &H1L 
    Const SWP_NOMOVE As Integer = &H2 
    Const SWP_NOSIZE As Integer = &H1 
    Const SWP_FRAMECHANGED As Integer = &H20 
    Const MF_BYPOSITION As UInteger = &H400 
    Const MF_REMOVE As UInteger = &H1000 
    Declare Auto Function GetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer 
    Declare Auto Function SetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer 
    Declare Auto Function SetWindowPos Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean 
    Public Sub MakeExternalWindowBorderless(ByVal MainWindowHandle As IntPtr) 
     Dim Style As Integer 
     Style = GetWindowLong(MainWindowHandle, GWL_STYLE) 
     Style = Style And Not WS_CAPTION 
     Style = Style And Not WS_SYSMENU 
     Style = Style And Not WS_THICKFRAME 
     Style = Style And Not WS_MINIMIZE 
     Style = Style And Not WS_MAXIMIZEBOX 
     SetWindowLong(MainWindowHandle, GWL_STYLE, Style) 
     Style = GetWindowLong(MainWindowHandle, GWL_EXSTYLE) 
     SetWindowLong(MainWindowHandle, GWL_EXSTYLE, Style Or WS_EX_DLGMODALFRAME) 
     SetWindowPos(MainWindowHandle, New IntPtr(0), 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_FRAMECHANGED) 
    End Sub 
End Class 

升C(C#)

using System.Runtime.InteropServices; 
public class Form1 
{ 
    const int WS_BORDER = 8388608; 
    const int WS_DLGFRAME = 4194304; 
    const int WS_CAPTION = WS_BORDER | WS_DLGFRAME; 
    const int WS_SYSMENU = 524288; 
    const int WS_THICKFRAME = 262144; 
    const int WS_MINIMIZE = 536870912; 
    const int WS_MAXIMIZEBOX = 65536; 
    const int GWL_STYLE = -16L; 
    const int GWL_EXSTYLE = -20L; 
    const int WS_EX_DLGMODALFRAME = 0x1L; 
    const int SWP_NOMOVE = 0x2; 
    const int SWP_NOSIZE = 0x1; 
    const int SWP_FRAMECHANGED = 0x20; 
    const uint MF_BYPOSITION = 0x400; 
    const uint MF_REMOVE = 0x1000; 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 
    public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); 
    public void MakeExternalWindowBorderless(IntPtr MainWindowHandle) 
    { 
     int Style = 0; 
     Style = GetWindowLong(MainWindowHandle, GWL_STYLE); 
     Style = Style & !WS_CAPTION; 
     Style = Style & !WS_SYSMENU; 
     Style = Style & !WS_THICKFRAME; 
     Style = Style & !WS_MINIMIZE; 
     Style = Style & !WS_MAXIMIZEBOX; 
     SetWindowLong(MainWindowHandle, GWL_STYLE, Style); 
     Style = GetWindowLong(MainWindowHandle, GWL_EXSTYLE); 
     SetWindowLong(MainWindowHandle, GWL_EXSTYLE, Style | WS_EX_DLGMODALFRAME); 
     SetWindowPos(MainWindowHandle, new IntPtr(0), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); 
    } 
} 

再次感谢你亚历克斯

+1

嗨,感谢您的代码,它纠正了C#部分中的一些错误后对我的工作。样式&!WS_CAPTION不起作用。你需要编写Style&〜WS_CAPTION。 – 2014-04-29 07:23:32

5
Process[] processes = Process.GetProcessesByName("notepad"); 
IntPtr windowHandle = processes[0].MainWindowHandle; 

const int GWL_STYLE = (-16); 
const UInt32 WS_VISIBLE = 0x10000000; 
SetWindowLong(windowHandle, GWL_STYLE, (WS_VISIBLE));`