Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to activate window? 4

Status
Not open for further replies.

Mandy_crw

Programmer
Jul 23, 2020
585
PH
Hi everyone... my project is finish and already done two executable files... these two executable file were put in the shell:startup so that both application would automatically open everytime computer starts... both files open perfectly... my problem is, the second application is active instead of the other one which has a textbox that waits for an input... My question is, how can i make that window that has a text box to be active and not the other window? Thanks in advance Everyone...
 
Hello, Mandy. Good to hear that you are making such good progress.

Place the following code in the Init of the form that you want to activate:

Code:
DECLARE INTEGER SetForegroundWindow IN WIN32API INTEGER
SetForegroundWindow(thisform.HWnd)
CLEAR DLLS "SetForegroundWindow"

I think that should do what you want.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
If you put something into that Autostart folder there is no guaranteed order and priority. What becomes active last will become the foreground process and its foreground window becomes the focussed window of the whole desktop session.

We've had a lengthy disccussion about all this in an older thread. You can't control this within a single exe that wants to be the foreground process, because if any process could make itself the foreground process which no other process could override that would mean a security hole, because one viral GUI app could hinder you to use your windows OS and anything other than it.

So you can only gain partial control about this, and the best would be to have both EXEs as one, instead. What is the reason to have two executables?

Chriss
 
Mike Lewis,

yes, that API call makes one window of the current process the foreground window. If a second EXE in the Autostart becomes visible later, it will still override this, you can't force one EXE to be foreground forever, just for thee moment.

So in case of two executables, the one that should be background would have to know which hwnd should be foreground and, just in case it becomes the active process as last of both of them, it should set the foreground window to that other process. That will not protect against a third EXE becomeing the foregrpund window.

But before I'd go this route to at least resolve the issue between your own to EXEs, why do you actually need two EXEs? If one should be a background process for the foreground process, there are several reasons it should not simple start in parallel, buut be started by the foreground (GUI) EXE anyway, because you'd want to be the owner of that background process and be able to controll it, communicate with it, etc.

Chriss
 
Hi Chriss... i got a timer in the second exe, that executes in an interval time, the first exe is to accept all input for the second exe to process... i separated it because when it was only one exe, it has to wait for a second or two seconds of a time (maybe because it processes data first) before the first exe can continue to accept another data for process... so i deparated it... Thanks Chriss

Mike... I already have that one in my init... but still i have to click the first window for it to accept input from the user... Thanks Mike...
 
Mandy, are you saying that, even though the relevant form is now at the front, the textbox does not have focus? If so, calling the textbox's SetFocus should solve that (you would do this in form's Init, after the call to SetForegroundWindow().)

Or have I misunderstood what you are asking?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mandy_crw said:
separated it because when it was only one exe, it has to wait for a second or two seconds of a time (maybe because it processes data first) before the first exe can continue to accept another data for process...

Well, that is okay, but still the way you do this is wrong, the main GUI exe should start its background processing EXE and not Windows Autostart folder, which gives ou no guaranteed order of ecxecution. But mainly, because you want to know about your second EXE, it's processID, for example, to address it.

What's the processing that takes so long that you want to go this complicated route, especially for the beginner you are, and do things in two processes? One more typical way would be to start a second EXE just to process something and quit, so just use a secondary EXE for each processing step, not one EXE that starts with the PC and runs in parallel all the time. It's much easier to pass in the data the second EXE should process in the main.prg LPARAMETERS than to establish an interprocess communication, even if you choose a simple one.

In short, since your idea didn't turn out to be that great, better than to try and fix this is to rethink it to something much simpler.

Now, if you're saying: "But it's only this one small problem", please think back how often you thought so and just didn't yet know what can of worms you just opened.

How do you even pass over data? And how do you pass back a result? Or signal finishing? Or do you think this will be easy once you got the focussed window thing right?

Chriss
 
Hi Mandy,

You could automatically start the first executable and start the second executable from there.
In other words, executable ONE uses “run” or a “shellexec” command to run executable TWO.

This will give you the right starting order.

Regards, Gerrit
 
Rule of thumb: If something takes longer than 3 seconds indicate progress to the user with a progress bar.

That says nothing about when to do something in a background process, but you can also take it for saying any shorter period is not yet worth caring for.
Also, I'm pretty sure the 2 seconds your code needs can be cut down. It would be wirth more asking about improving that thn trying to cover up by doing that in asepaate process and not even knowing how to get a window as foreground window.

By the way, in thread184-1817657 you already used SetForegroundWindow and it didnt work. And in that thread, if you reread everythinng carefully, I told you why. SetForegroundWindow can make a window the foregroudwindow, but that's not making it a permanent foreground window. If another process is still stating and becomes the new active process with foreground window, then it's worth nothing you set your window to be fooreround window as that's overridden.

And you can't solve that sufficiently, even if you make use of a delay before using SetForegroundWindow. The easiest way is your background process last step before its own READ EVENTS will be to start the UI EXE. But even in that scenario you only solved the foreground window state and nothing else yet. I said the foreground process should start the background process, for a good reason. But it will take a long article to show you why and how.

Chriss
 
Here's the essence.

Lesson 1 or Realization 1:
There is no such thing as a VFP background process in terms of what background process means from the point of view of the Windows OS.

First of all, notice the foreground process in Windows is defined by having the foreground window, and you can influence that momentarily by the SetForegroundWindow API call, and you can also find out what it is by GetForegroundWindow. That's not all to it, but if you google for how to find out the foregroundprocess, the base line is to use GetForegroundWindow followed by GetWindowThreadProcessId or GetProcessHandleFromHwnd. Which means the foregroundwindow is easy to determine first and is already the essential information for the currently active process.

This is the main.prg of an EXE I just did, to check that fact:
Code:
Declare Integer GetForegroundWindow in Win32API

Text To lcMessage NoShow Textmerge
   Foreground hWnd: <<GetForegroundWindow()>>
   _Screen hWnd: <<_screen.HWnd>>
   _VFP hWnd: <<_vfp.hWnd>>
EndText 

MessageBox(lcMessage)
On top of that, there is a config.fpw with SCREEN=OFF, which you know from several earlier threads.

And this is the output:
backgroundprocess_utxzzu.png


Running it several times, the hWnd windows handle differ by number, but one thing always remains the same: This VFP.exe, though it has no visible screen form, still becomes the foreground process with the foreground window, namely the never visible _vfp system variable that also is a window with a hWnd handle.

Notice several things, here: SCREEN=OFF does not mean there is no screen, it just is not made visible. _VFP and _SCREEN are two of many system variables available in any VFP process. They always exist. And they are windows, by the OS meaning of windows, with a HWnd. That's the basis of many things like the Windows OS messaging system that is based on hWnd handles.

In conjunction with the knowledge that the last started EXE becomes the foreground process it means it takes the status of the previous foregroudwindow away from the previous foreground process. You can't stop that from happening. Also if VFP would be able to build console applications, they have the console window, also a window with a hWnd. There are background processes, real background processes, but that needs more than a process without a (visible) UI.

For what you need this realization does not mean you can't implement your idea of a background process, which only needs the feature to be without a UI and a separate process that can really run code in parallel, even on a separate core of the CPU. But you need to be aware that starting your "background process" it changes the foregroundwindow. And you have to wait for that to happen to then eventually reclaim that stauts by SetForeGroundWindow to your own main form hwnd. It does not work well to do the SetForegroundWindow as soon as possible and be done with it. Always keep in mind, this is just momentarily and no process controls this status forever or can become the permanent foreground window.

Chriss
 
I'll continue with further Lessons/Realizations later. For now I just have one main question aside from those I already asked:

Do you want your application to be the only application that runs when a computer starts? There is a term for this, that's a kiosk system, and there are both hardware and software solutions to define a kiosk system, but that's a totally separate topic. But it might still be what you're after, too and don't even know exists. Here's a starter about that topic for Windows 10/11:
That has not the aspect of separating UI from a background parallel process, it has the aspect to automatically start with the system and be the only application running, like an ATM machine or a check-in terminal at an airport and many other such systems.


Chriss
 
I thought you'd react, but maybe I have to wait til Monday.

Anway, your answer to my first post was:
Mandy said:
i separated it because when it was only one exe, it has to wait for a second or two seconds of a time (maybe because it processes data first) before the first exe can continue to accept another data for process.

I can't believe you only vagely know what takes long. You're doing some code with the input. You can measure how long this needs by doing coverage profiling. I already showed you that. Would you please post that code? Because all in all it will be much simpler to optimize it than to run it separately. The question even is whether it can be done by a separate process. If this code works on workareas of your first exe, those are not seen by the second exe. In the second EXE you don't have everything at hand that your first EXE sees. So this is not a universal solution for doing things in parallel. You are not only starting in a new general datasession in a second EXE, you can't switch datasession to one of the datasessions the first EXE has. Seperate processes mean separation of all things.

It's not a solution Foxpro developers use all the time to solve parallel execution and to be able to stay responsive for further input. You don't understand the overall complexity of this and the limits of what a second process can do or can't.

Chriss
 
Mandy,

are you with me/us? I want you to undertand what you're trying is quite fruitless. Because if you don't even know what code or behavior in your one EXE takes long, what do you want to move to a second EXE. It becomes very useless to show you in which way to start two exes so the first one stays in the foregound, if you don't even know what to make the second EXE do. Then you have a mechanism but still no solution. I want to help you, I really want to solve your problem. But I can't, if I know nothing about it.

Okay, I hope the first lesson has been clear: Every VFP EXE you start will take the foregroundwindow state, even if it starts no form, it will go to the _VFP system variable, which indeed also is a form. It doesn't matter that this is invisble, this also means if the background EXE starts as second process, it will take the foregroundstate from the foregound EXE. And what's most importat: It doesn't matter that your foregrround EXE had used SetForegroundWindow, this is not a function to tell the OS this should be the permanent foreground window unless you say otherwise. The OS will switch this, the user can switch this. Otherwise there could be all kind of malware that takes Windows as hostage as it does not allow the user to pick what window he wants to use. This is not what the OS will allow.


From this information you could learn that starting the foreground EXE as second exe would work. Well, if two processes start at almost the same time, their loading and initialization process can take slightly different times and you sometimes end up with a frontend in focus and sometimes not.

Lesson 2 / Realization 2:

Mandy, so how do you get the foreground state to the foreground EXE, if you can't be sure how Windows starts what is in the autostartfolder and how it turns out, depending on a gazillion other things all starting when the computer starts? How can you gain full control of what happens? You have to start one EXE from the other, so there is a definite starting order. And I already told above
myself said:
the main GUI exe should start its background processing EXE and not Windows Autostart folder, which gives you no guaranteed order of ecxecution

Why not the other way around? Well, becuase if you start the second non GUI EXE first, let it start the other EXE with the forms, then the UI becomes the child process of the background process. And that's bad, because of what I already showed you:

SetForegroundWindow said:
The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The process is being debugged.
The foreground process is not a Modern Application or the Start Screen.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.

Not only SetForegroundWindow has such privilidge restrictions. You want your main process to be the one that starts the background, even though then the background EXE is started last and removes the foreground state. But now you have it in your hands to forward the Hwnd to the background EXE and make it the first task to do for it, to set the foreground back to the first EXE. That's how you solve this.

first EXE main.prg:
Code:
* initializations...
*...
*...
*... whatever code you need to start with

Local lnHwnd, lcHwnd
Declare Integer GetForegroundWindow In Win32API
lnHwnd = GetForegroundWindow()
lcHwnd = Transform(lnHwnd)
RUN /N second.EXE &lcHwnd
Read events

second EXE main.prg:

Code:
LPARAMETERS tcForegroundHwnd

If pcount()<1
   quit
Endif

Local lnHwnd
lnHwnd = Val(tcForegroundHwnd)
DECLARE INTEGER SetForegroundWindow IN WIN32API INTEGER
SetForegroundWindow(lnHWnd)
*...
*...
This at the start of the second EXE makes your first exe the foreground again.

There's still no guarantee at the starrt of a computer, no other application will also start and get the foreground state, you're really lamenting about a thing that may need a click from the user anyway, when there are further windows starting on the desktop. Even if your own two EXEs play their role with each other. On Windows, your application is never alone. So, it's actually a detail solution that will not really bring you forward a decent step towards untangling what would really help to improve the responsiveness of the first EXE - without a second EXE.

Mandy, I beg you please don't continue even if that solves your problem, you still have to think about how to communicate between these processes, and how to ensure if the first EXE is quit by the user, the second EXE also quits to not leave endless running background processes, just because you still only have two processes, but have in no way connected them to each other.

Mandy, in your old thread I gave you code for a COM server. That is not started as a normal EXE, that is started by CREATEOBJECT() with a comserver class name. And that is indeed one way you get a new process that doesn't even cause this problem at all. And you have a reference to that background process, and you can program any method you want iside it. You already have a solution, Mandy, you just disregarded it.

Chriss
 
Hey Everyone,

With all due respect, I have to say that this thread ranks in the top ten of all the absurd threads I have ever read.

Chris, you are a smart guy - but dude, you sure know how to get into the weeds on things. Please learn how to be concise - you cannot expect people to get into the weeds with you.

And Mandy. Without your um, well um questions, this board would have to shut down. Is this the only way (or place) you are learning VFP? Are you being paid to ask questions here?
 
TIP: You can have two EXEs communicate with each other using the WM_COPYDATA message
 
Hi Vernspace,

I do this on purpose, because you don't get a memorable lesson, if you just would give a solution, as is often demanded, not only by you.

You know, I could also say do this:

1. start the second.EXE with autostart, and in it do this main.prg:
Code:
RUN /N first.EXE
Read Events

This works, too. It concisely, precisly and explicitly only solves the foreground problem.

This is not what I want, and I will never answer in such ways. I also get an impression of memebers, who post more regularly or by looking into their post history, so I adapt my answer to that impression.

You're making a concise remark about how to establish interprocess communication. But then there's much more to that, too and it's yet not even a good birdview descpription, you make use of SendMessage and BindEvent to use the Windows message queue and then in dtail see WM_COPYDATA is away to bring over a chunk of bytes, which could be anything and thus it's a universal communication possibility.

But then you still overlook the solution I already gave using a COM Server for the background process. Create a VFP COM Server and a) you have no foreground state change, b) you have a reference to the background process, c) you can pass object references to it, which it then can use. And I bet Mandy needs that, if the background process should, for example, care for an animation on the input control, while the input control is responding to the next input already.

Every ingredient for that was already on the table in thread184-1817657 and this thread also is that absurd because even after I pointed to it so many times, there's still no understanding of it, obviously.

Chriss
 
For what it's worth, I wrote an application a few years ago where the main EXE launches a second EXE to run in the background. I used a DBF to pass information between the two, and it worked very well - better than I had expected. I'm not saying it's the best solution (it could be that a method that uses WM_COPYDATA would be better), but it was fine for my needs.

And it might well have been better to use a COM server rather than the second EXE. I tried the two EXE approach as a bit of an experiment, and when I saw how well it worked, I didn't pursue any other methods.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike Lewis

We use two separate exe and the second one is started with ShellExecute from the first one, which creates a separate thread.



If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Hi everyone… sorry for not answering immediately… to vernpace, i am not being paid to ask here, those question that i have asked were relevant to my project… and all you suggestions are taken noted well…

To Mike and Chriss.. i am so thankful that you you give me answers always…

I have been working with the foreground problem, and while reading all your answers, i was overwhelmed by the info, so i need to read well to understand it well.. im really sorry…
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top