Ian Branch 127 Posted December 13, 2019 (edited) Hi Team, D10.3.3, Win 10. I am experimenting with closing an external App programaticaly. I have the following code.. procedure TForm10.Button2Click(Sender: TObject); var hnd: HWND; begin // hnd := FindWindow(nil, PChar('MyTestApp')); // if hnd = 0 then MessageDlg('MyTestApp is apperently not running.', mtInformation, [mbOK], 0) else MessageDlg('MyTestApp is apperently running.', mtInformation, [mbOK], 0); // end; Even though MyTestApp is clearly running, the FindWindow doesn't seem to find it. Should this work? Is there something I have missed? Is this a known issue/bug? Is there an alternative? Related - What actual Application property is the application name in the FindWindow(nil, PChar('AppName')); ? Regards & TIA, Ian Edited December 13, 2019 by Ian Branch clarification in text Share this post Link to post
David Heffernan 2345 Posted December 13, 2019 This would suggest that there is no to level window whose text is MyTestApp Share this post Link to post
Vincent Parrett 750 Posted December 13, 2019 On windows 10, this may be a permissions issue. Applications that were launched elevated are not visible to applications that are not elevated. Share this post Link to post
timfrost 78 Posted December 13, 2019 For FindWindow you need the name of the main window, not the application. Often this would begin with a T, but could be anything you have set it to. Look in the main form source for Tform1=class(Tform) and try 'Tform1' in the FindWindow call. Share this post Link to post
Lars Fosdal 1792 Posted December 13, 2019 Are you trying to prevent running the same app twice? https://lonewolfonline.net/prevent-multiple-instances-delphi-application-running/ https://stackoverflow.com/questions/8688078/preventing-multiple-instances-but-also-handle-the-command-line-parameters As mentioned above, FindWindow need window class names or window titles. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa Unless you want to enumerate processes to find the main window(s), calling taskkill could be an alternative. https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill Share this post Link to post
Ian Branch 127 Posted December 13, 2019 Hi Guys, Thank you for your inputs. The picture is that I have a head application that runs one or more function specific applications using the shellexecute functionality. That all works fine. The individual apps can be run as a standalone app. As it stands, each individual App has to be closed. What I would like to do is when the head app is closed it automatically closes any apps that are open. Even if the subordinate apps were run from outside the head app. Perhaps to complicate matters, the main form of each subordinate app is defined as follows. type TMainForm = class(TForm) .... ... I tried.. FindWindow(nil, PChar('TMainForm')); but that didn't work. 😞 Regards, Ian Share this post Link to post
Ian Branch 127 Posted December 13, 2019 Hi Team, Accidentally got it sorted. I should have had.. FindWindow(PChar('TMainForm'), nil); And this works. However I would rather use the Application's name rather than having to go into each of the apps and change their class definition. So, I still don't understand exactly what goes into FindWindow(nil, PChar('MyApp')); for 'MyApp'. Regards & TIA, Ian Share this post Link to post
David Heffernan 2345 Posted December 13, 2019 (edited) Read the documentation. It's the text of the window. Documentation is always the first port of call. Don't guess. You talk about the name of the application. Well, an application name isn't something well defined in programing terms. There may be conventions that the executable file has a name that matches what you think of the application name. But nothing enforces that. You need to decide on the right way to identify your process. If you try to kill windows with the class name TMainForm then there will be collateral damage. You'll kill my program's main window! So, try to work out how to robustly identify your process. Edited December 13, 2019 by David Heffernan Share this post Link to post
Ian Branch 127 Posted December 13, 2019 Hi David, I am clearly having a mental block on this subject. Starting to feel like a dunce. 😞 Which documentation are you referring to? When I did F1 on FindWindow in Delphi it took me to "FMX.Platform.Win.FindWindow". Singularly unhelpful. I don't understand what you mean by "It's the text of the window.". 😞 Regards, Ian Share this post Link to post
Ian Branch 127 Posted December 13, 2019 Ah Ha! It's the Main Window/Form Title. Sorted. Hmm. Not an issue in my case but what happens if the Form/Window doesn't have a Caption? Regards & Thanks for your input Guys. Ian Share this post Link to post
David Heffernan 2345 Posted December 13, 2019 It not the caption. Its the window text. By default the system uses that text as the caption, but it is possible to have windows with no caption, that do have window text. Share this post Link to post
Ian Branch 127 Posted December 13, 2019 And I was that close.... OK. I guess my question of what/where is the Windows Text still applies? Share this post Link to post
David Heffernan 2345 Posted December 13, 2019 Window text is simple an attribute owned by the window. Programs can do what they want with it. Top level windows typically display it in the caption. Edit controls display it as the text to be edited. Share this post Link to post
FredS 138 Posted December 13, 2019 3 hours ago, Ian Branch said: FindWindow(PChar('TMainForm'), nil); You're banking on no other form using 'TMainForm' as a class name on the system? I'd use Process Info instead, quick search gave me this: https://stackoverflow.com/questions/2616279/how-can-i-get-other-processes-information-with-delphi Share this post Link to post
Fr0sT.Brutal 900 Posted December 16, 2019 Processes are the right way here. Listing all running processes, you can check their parent process and thus easily find all of them being spawned by your process. Of course you can traverse all the call chain to find processes being spawned by processes being spawned by processes being spawned by your process 🙂 Share this post Link to post
Ian Branch 127 Posted December 16, 2019 All done. Killed the Process. Thanks to all. Ian Share this post Link to post