2009-06-19 84 views
4

有没有什么办法可以重新命名已启动的应用程序的窗口标题栏?即如果我启动了Notepad.exe,我可以将其标题栏从“无标题 - 记事本”重命名为“新记事本名称”。C# - 我如何重命名我开始的进程窗口?

+0

你的意思,而它的运行? – Sev 2009-06-19 07:58:32

+0

是的......尽管如果我在启动过程之前可以指定标题栏,那也是可以接受的。 – GenericTypeTea 2009-06-19 07:59:16

+0

一般来说,除非应用程序支持该功能。许多人不知道。记事本包括当前在其标题栏中打开的文件的名称,并且不支持标题的任何其他更改。另一方面,CMD.EXE具有内置的命令TITLE,可以控制控制台窗口的标题。 – RBerteig 2009-06-19 08:02:03

回答

13

可以以P做/调用:

[DllImport("user32.dll")] 
static extern int SetWindowText(IntPtr hWnd, string text); 



private void StartMyNotepad() 
{ 
    Process p = Process.Start("notepad.exe"); 
    Thread.Sleep(100); // <-- ugly hack 
    SetWindowText(p.MainWindowHandle, "My Notepad"); 
} 

的代码示例中的丑陋的黑客攻击的背景是,它好像您在启动过程后,立即打电话函数SetWindowText,标题不会改变。也许消息在记事本的消息队列中过早结束,以便记事本以后再次设置标题。

另请注意,这是一个非常短暂的变化;如果用户选择文件 - >新建(或做任何其他事情,将导致记事本更新窗口标题),原标题将回来...

-3

编号

这将要求目标应用程序允许窗口标题根本被修改。许多程序使用它们的标题来显示有用的信息(例如在记事本中打开的文件的名称,或者在Firefox中打开的HTML文档的<TITLE>)。

我知道的一种情况是,让用户设置标题文本的几个限制是在控制台窗口中运行CMD.EXE。 CMD支持TITLE内置命令,该命令根据参数设置窗口标题。但是如果不在特定的控制台窗口中注入按键,通常不推荐使用第二个窗口。

编辑:

由于想法是浮动的那SetWindowText()会为你做到这一点,让我澄清。

该API函数确实会更改顶级窗口的标题栏。事实上,像记事本这样的应用程序可能会在它认为标题已经改变的时候设置自己的标题。

我声称这是而不是的一个解决方案的原因是记事本确实在它想要的时候改变标题。支持对其标题进行任意更改的应用程序会有某种机制记住标题已更改,而不是任意恢复其首选标题字符串。

+0

SetWindowText是解决这个问题的方法。它完全符合我的要求,因此不能否认它是解决问题的办法。无论如何,我其实并没有要求它是永久的,但正如我在其他评论中发布的那样,有一个简单的解决方法可以保持它永久不变。 – GenericTypeTea 2009-06-19 10:33:55

4

其实,我自己排序它,它完美的作品。不管怎么说,还是要谢谢你。

[DllImport("user32.dll")] 
static extern SetWindowText(IntPtr hWnd, string windowName); 

IntPtr handle = p.MainWindowHandle; 
SetWindowText(handle, "This is my new title"); 
4

你不能在C#中做到这一点,但你可以做它使用低级别的API。 注入进程中的线程,请致电SetWindowText()

2

正如@FredrikMörk认为的,问题是需要等待窗口可以接收消息来设置其标题。等待100毫秒会破坏程序的内部消息循环,这只是一个解决方法。 要接收消息,窗口必须有一个用于引用该窗口的句柄,因此您可以简单地等待窗口的句柄,该句柄在启动时应该是IntPtr.Zero(空句柄)。

下面是一个这种方法的例子:使用Application.DoEvents()程序将继续接收和处理系统消息

Process p = Process.Start("notepad.exe"); 
while (p.MainWindowHandle == IntPtr.Zero) 
    Application.DoEvents(); 
SetWindowText(p.MainWindowHandle, "My Notepad"); 

,所以不会挡住(也不崩溃),尽管它不是异步的。

你也可以认为通过用SpinWait.SpinUntil调用替换while声明以避免内存泄漏(这样,你需要导入System.Threading):

Process p = Process.Start("notepad.exe"); 
SpinWait.SpinUntil(delegate 
    { 
     return p.MainWindowHandle != IntPtr.Zero; 
    }); 
SetWindowText(p.MainWindowHandle, "My Notepad");