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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to put my app be on top, and active...? 5

Status
Not open for further replies.

Mandy_crw

Programmer
Jul 23, 2020
578
PH
I have this codes in my app, with the intention of letting my app be at the foreground and active while cursor is blinking waiting for user input... the cursor is blinking but i still have to click the textbox so that i could input.... I also have alwaysontop set to .t. Please help me solve... Thanks and God bless

code...
go_Form.Visible = .T.
go_Form.Show(2)

code...
code...


Procedure Init()

thisform.pgfnames.activepage = 5

_screen.Visible = .f.
_screen.borderstyle = 2

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

thisform.pgfnames.activepage = 5

WITH thisform.pgfnames.page5
.text1.setfocus()
ENDWITH

code ....
code...

endproc
 
Good news,

If you aiim for using a separate VFP built EXE as background process, without or even with a form diplaysing, here's the solution to that not taking away the foreground process and foeground form state of the app using this background process. Here's just the main.prg of a project you compile as an EXE, say background.exe:

Code:
* Compile as EXE and use as OLE public COM server
* Direct start of the EXE will do nothing and end immediately.

Define Class Process as Session Olepublic

   Procedure Init()
       Public goApp
       goApp = This
       
       This.AddProperty("Self",JustFname(_vfp.ServerName))
       
       This.Main()
       * usually here goes a READ EVENTS, but
       * it's not possible to read events here, as we need to 
       * return to the session starting and using this OLEpublic 
       * COM server class, so we let a timer call read events 
       * after we returned:
       CreateAnyonymousPublicObject('AsyncCommand',['goApp.Readevents()'])
   EndProc
   
   Procedure Main()
       * just for example:
       * -------------------------------------------------------------
       * -------------------------------------------------------------
       * +++ ATTENTION +++
       *
       * "Batteries not included". This is just an example,
       * Code of backgroundmain.scx is not included.
       *
       * +++ ATTENTION +++
       * -------------------------------------------------------------
       * -------------------------------------------------------------
       Do Form backgroundmain.scx
       * Requirements of backgroundmain.scx are:
       * -non-modal form
       * -top level form.
       *
       * An in-screen form is possible but is in-screen of a new _Screen,
       * which can be shown by _Screen.visble = .T. 
       * Just notice this form is not part of the forms of the calling 
       * application, the COM server is its own new process!
       *
       * DON'T INCLUDE READ EVENTS here!
       * don't include read events or any code after it.
       * There's the ReadEvents() method and the Destroy() for that.
       * The Init() will care to both return from Init() and yet run 
       * the read events of the new OLE process
   EndProc 
   
   Procedure ReadEvents()
       Read Events
   EndProc 
   
   Procedure Quit()
       Release This
   EndProc  
   
   Procedure Destroy()
       Clear Events
       Quit
   EndProc 
EndDefine

Define Class AsyncCommand as Timer
    Interval = 1
    cCommand = ''
    
    Procedure Init(tcCommand)
        This.cCommand = tcCommand
    Endproc
    
    Procedure Timer()
       Local lcCommand
       lcCommand = This.cCommand
       
       This.Enabled = .F.
       * self release:
       Release This
       * This will still execute as last line of code
       * of this timer method, as the release just hits 
       * when nothing remains on the callstack, i.e.
       * after the current method ends:
       &lcCommand
    EndProc
EndDefine

Procedure CreateAnyonymousPublicObject(tcClass, tcParams)
    _Screen.AddObject(Sys(2015), tcClass, &tcParams)
EndProc

See comments, you need to add a backgroundmain.scx or change the Main() method to whatever else. Just note: If that takes long in itself, it won't be good. The Init needs to end and return quick or else it will not feel like it's doing what it mainly should do in the background. The Junction is done by the timer, that does it's command - calling the ReadEvents method, after Main returned to Init() and Init() returns to the CreateObject call.

When this code is saved as the main.prg of a new background.pjx and is compiled as EXE with administrative elevation of the VFP9.exe you don't just get background.exe but also background.tlb and background.vbr, as it's a COM server.

Usage of this is not by Shellexecute or run, but - giving the name of the exe is background.exe and the class is named Process, create it by CREATEOBJECT("Background.Process").

For sake of testing just do an empty top level non-modal backgroundmain.scx form and you'll see the Background.Process will start and show (as long as what stores the object reference doesn't release). While the ReadEvents() method keeps the form and the COM object from ending, too, releasing the object you create by CREATEOBJECT("Background.Process") causes the Destroy() and thus the CLEAR EVENTS and QUIT. You may now do more with the form code, you can also add something to the ReadEvents method before the READ EVENTS line or instead of it. It will be executed really in parallel to who- or whatever creates this object and when the ReadEvents method ends by calling This.Quit() instead of doing READ EVENTS it would also work as a shoot off process that, for example sends a list of mails and then ends.

It's surely not beginner material and if you found this thread to start a form behind another simply in z-order, there are much easier ways without a separate EXE, this is not intended for you.

I'm still looking into starting any other EXE and keeping foreground process state, as this just solves the case the background process is your own VPF creation. It's also not easy to understand and extend.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top