2015-05-14 63 views
1

我有一個任務來控制在Delphi中編寫的應用程序是否可以啓動。Delphi PostMessage找到lpWindowName?

我沒有編寫我需要控制的應用程序,此時無法編譯或更改它的代碼,所以我讓其他控制檯應用程序在後臺工作,根據OS中的條件啓動和結束此應用程序。

我用PostMessage關閉了這個應用程序,但我不明白如何找到我需要關閉的應用程序的WindowName

我該怎麼做?我有應用程序的源代碼。我使用"TApplication"作爲類名。這是安全的在Windows中使用?

+0

主窗口名稱(標題)是唯一的嗎? – MBo

回答

1

爲了找到你正在尋找你需要知道兩個參數,你會被髮送給FindWindow功能

1.窗口類名

對於大多數應用程序的應用程序的正確的窗口句柄向主窗體窗口句柄發送WM_CLOSE消息將終止應用程序。

也可以使用應用程序窗口句柄,但僅適用於以2007年之前的Delphi版本編寫的應用程序,或者應用程序的Application.MainFormOnTaskbar屬性設置爲false。

注:Application.MainFormOnTaskbar在Delphi 2007

介紹了主要形式的窗口類名稱將是主要形式的類名(例如'TForm1')和應用程序處理窗口類名是'TApplication'

2。窗口名稱(標題)

該值取決於您是否將消息發送到應用程序窗口或主窗體窗口。

對於應用程序,這將是Application.Title值或如果沒有明確設置程序名稱將被使用。

program MyApplication; 

... 

begin 
    Application.Initialize; 
    Application.Title := 'My Application Title'; 
... 

如果使用主窗體窗口值將主窗體Caption屬性。

所以一般來講一些如下的組合會給你正確的結果(當然,實際的類名和窗口標題必須合併)

var h: HWND; 

    h := FindWindow('TApplication', 'MyApplication'); 
    h := FindWindow('TApplication', 'My Application Title'); 
    h := FindWindow('TForm1', 'Form1'); 

雖然上述規則將是普遍有效的,它是可能的應用程序以動態方式設置這些值,在這種情況下,您將不得不使用EnumWindows而不是Findwindow

如果window class name & window name組合唯一地定義了您打算關閉的應用程序,則以這種方式關閉應用程序是完全安全的。如果系統中有多個滿足之前條件的應用程序,則最終可能會關閉錯誤的應用程序,並且找到正確的應用程序可能會更復雜,或者應用程序生命週期必須以另一種方式進行控制。

+0

雖然這*一般*適用於很多Delphi應用程序,但它不適用於每個Delphi應用程序。例如,如果一個應用程序動態設置Application.Title,那麼您將無法對該名稱進行硬編碼,因此您必須在運行時尋找它,例如使用'EnumWindows()'。如果一個應用程序使用'Application.MainFormOnTaskbar = True'(大多數現代的Delphi應用程序都是這樣做的),你甚至不應該與TApplication窗口進行交互,而必須與MainForm窗口交互,其類名可能在多個應用程序中是唯一的,也可能不是唯一的 –

+0

@RemyLebeau我正在使用自定義解決方案來處理不包含'TApplication'的應用程序之間的消息,所以我完全沒有意識到MainFromOnTaskBar會改變應用程序響應外部消息的方式。我的代碼適用於兩者。我可以做研究(實際上,我已經做了一些),併發布了更完整的解決方案,但是如果您發佈自己的,更詳細的答案也許是最好的。 –

+0

'MainFormOnTaskbar'做了很多事情(比它應該多),但主要是它指定了'TApplication'窗口或'TApplication.MainForm'窗口是否代表Windows本身的應用程序。但它不會改變窗口消息的接收方式。您仍然可以將消息發送到「TApplication」窗口,但取決於特定的消息,這可能不是發送到的窗口。 –