Execfile
Blitz3D Forums/Blitz3D Programming/Execfile
| ||
Is it possible to close a window(process) that i startet with Execfile? Thanks, soli |
| ||
AFAIK, only if you wrote it yourself to be able to do so. Although using the Windows API, you may be able to? Don't know if this is any help: Example found on http://www.digitaloptics.net/technical/vpascal/winapi.htm As a practical example, consider how to shut down V++ from a module (there's no built-in function to do this). You can shut down by using SendMessage to send the main V++ window a Windows wm_Close message. In order to send the message, you first need to declare another API function, FindWindow, which you use to determine the handle of the main V++ window. The technique is illustrated in the sample module Close.v which you can download. |
| ||
Yes, Execfile's no good for this. You must use an API lib to run the program, Find the hWnd, then use SendMessage(hWnd, WM_CLOSE,0,0). |
| ||
If you mean end a program by "close a window" then John is right. If it's only a DOS-Box that remains on screen when the Programm ended then you may call the Dos Program with the "/c" flag to make sure it will close after execution, eg:ExecFile "command /c ping.exe 127.0.0.1 >testping.txt" |
| ||
Sorry, i didn't get it to work All i want to do is starting a helpfile, and prevent the user from opening dozens of times. ;own window for testing Graphics 600,400,16,2 AppTitle "mywindow" Global handlewinhlp% ;the app that i wanted to execute If FileType("c:/windows/winhlp32.exe")=1 Then helpprogramm$="winhlp32" If FileType("c:/windows/winhlp.exe")=1 Then helpprogramm$="winhlp" ;my rules-file mydir$="d:/eigene dateien/blitz/games/as-solitaire/" helpfile$=mydir$+"soli.hlp" ;only importand for my-file tmpas=23 ; pointer for testing parameter$=" -I SHM_contents" number$=Right$("0000"+Str$(tmpas),4) ;here i start the app ExecFile (helpprogramm$+" "+parameter$+number$+" "+helpfile$) ;only for testing, i wait until the app has startet properly Delay 1000 ;i get a handle, everything is fine. handlewinhlp%=api_FindWindow(0,"AS-Solitaire Spielregeln") DebugLog handlewinhlp% ;i wait until i want to close the help-window WaitKey() ; i get an "Memory Access Violation" :-(((( api_SendMessage(handlewinhlp%,WM_CLOSE,0,0) ; wait to end While Not KeyHit(1) Wend End Maybe i need OpenProcess or CreateProcess, but i don't know enought about WinApi to do so. Is there anybody who could help me, please? soli |
| ||
Check the kernel userlibs or other windows system dlls |
| ||
OpenProcess would work, if you know how to create the crazy thing that you need to pass to it :S I don't. It does return a handle to the process though, so ending it would be easy. |
| ||
Looking through my old Windows 'C' I see the method I have used in the past is:int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { if(!hPrevInstance) { // create the window } In other words when a window is created Windows sends a value hPrevInstance which indicates a previous instance, and then the logic below prevents opening another one of the same. Not trying to be baffling here, but this is how it is done in strict 'C'. I think helpfiles are another thing altogether though, and I think you would have to communicate/interact with WIndows Help runner to achieve this, though I'm afraid I haven't done any work along these lines since Blitz came along so my knowledge is probably hopelessly out of date. I'd suggest you go to the Microsoft Knowledge Base website, no matter which language you are trying to code this in. |
| ||
All i want to do is starting a helpfile, and prevent the user from opening dozens of times. Check soja's post in the following thread for a method of doing that. It uses the 'CreateMutexA' function from the kernel32.dll WinAPI, so you need to create a userlib decls file (included in the post). The code works fine in BlitzPlus, but it should work ok with Blitz3D too (remember to remove the 'Notify' function references). http://www.blitzmax.com/Community/posts.php?topic=28740 "My Program Instance" is the name of the program (in the title bar) which you want to detect. Use it to detect whether the program is already open, then you can decide whether to call ExecFile or not based on the result. |
| ||
Sadly the method described in the thread does not work:CreateMutex(0,1,"My Help File") If GetLastError() = ERROR_ALREADY_EXISTS Then result = 0 Else result = 1 EndIf If result = 1 ExecFile("help\help.chm") EndIf result = 1 is always the case, so Execfile is always called. Can anyone else clarify this? |
| ||
Just tried it and it does work ok, but it only seems to work when another instance of the Blitz3D program is running. Try this code and run it twice, the first will display 'Nope' and the second will display 'Yep'. Graphics 640,480,0,2 AppTitle "hello" Const ERROR_ALREADY_EXISTS=183 CreateMutex(0,1,"hello") If GetLastError()=ERROR_ALREADY_EXISTS Text 0,0,"Yep" Else Text 0,0,"Nope" End If WaitKey() But when I tried to detect notepad for example, it didn't seem to detect it was running for some reason :/ [edit] It appears the program title in CreateMutex(0,1,"ProgramTitle") doesn't work in Blitz3D like it does in BlitzPlus, but it still detects another Blitz3D program running regardless of the program title used. In this case it won't be of any use unfortunately. It would only be useful for detecting whether any other Blitz3D program is running. |
| ||
The point is that solitaire (and I) are trying to run a helpfile once only from our app, not run our app only once. Any futher ideas? |
| ||
Yes I know, the idea was to detect CreateMutex(0,1,"WhateverYourHelpFileIsCalled") and use ExecFile accordingly. I'm guessing it must be possible with some other Win API functions, but I've no idea which ones. |
| ||
If you give up, you could use one of Windows' built in help file apps, which probably prevents repeated opening automatically. |
| ||
@John Blackledge Not exactly, to run the app only once could be done like this. Graphics 600,400,16,2 AppTitle "mywindow" Global handlewinhlp% Global apptitlename$="Rechner" Global appname$="c:/windows/calc.exe" ; to show that it only run once While Not KeyHit(1) handlewinhlp%=api_FindWindow(0,apptitlename$) If handlewinhlp%=0 ExecFile (appname$) ;wait until the app is open Delay 1000 EndIf Wend End But what i need, for example is. open Rules-Klondike and then open Rules-Freecell in the same window, or close the first window, and open a new one. |
| ||
Ok I modified your code for English, then ran it...Graphics 600,400,16,2 AppTitle "mywindow" Global handlewinhlp% Global apptitlename$="Calculator" Global appname$="calc.exe" ; to show that it only run once While Not KeyHit(1) handlewinhlp%=api_FindWindow(0,apptitlename$) If handlewinhlp%=0 ExecFile (appname$) ;wait until the app is open Delay 1000 EndIf Wend End and get So what was your point again? |
| ||
The user32.decls must look like this: .lib "user32.dll" api_FindWindow% (lpClassName%, lpWindowName$) : "FindWindowA" The "%" in lpClassName% is the important thing. |
| ||
Can I just take a moment to go AARRGGHH! Yes, you're right. It was down to the definition. My old def was api_FindWindow%(lpClassName$,lpWindowName$):"FindWindowA" Yours works perfectly and _finally_ I have the control I need over runniing a help file. Many thanks! Now, how many other definitions do I have which are wrong, but which I thought simply didn't work? |