Jump to content
Sign in to follow this  
the123punch

Locking window from losing focus

Recommended Posts

the123punch

Hi,

Is it possible to lock a window from losing focus until that window is closed??

The reason I need to do this is that I open an Oracle Forms window in which I enter data sequentially and in order for this to work I need to make sure the window or its subwindows never lose focus during the manipulation of data entry inside the Oracle Forms window.

Does anyone know how to do that?

Thanks.

the123punch

Share this post


Link to post
Share on other sites
the123punch

Hi again,

Sorry maybe I wasn't clear enough in my previous post.

I am opening an application, (for example notepad), with the ShellExecuteWait function.

example:

$val = ShellExecuteWait("Notepad.exe")

What I want to do is make sure that this notepad window is always on top and always has focus until and unless it is closed by the user or programatically by the script.

Is that possible to do???

Hope it is clearer now.

Thanks.

the123punch

Edited by the123punch

Share this post


Link to post
Share on other sites
rasim

the123punch

CODE

WinActive()

WinActivate()

WinSetOnTop()

Share this post


Link to post
Share on other sites
the123punch

Along with what Rasim said, you might want to disable you other GUI's...

GUISetState(@SW_Disable)
Hi Thank you both for your answers.

Rasim, I tried using WinSetOnTop() but it only forces the current window to remain on top. It does not prevent it from losing focus, therefore my SendKeys are sent to the wrong windows if the focus is ever lost from that main window.

Achilles, your solution seems to be working if I specifically know which window is running in the backgroud. But the problem is that at runtime, usually I wouldn't know which other windows are open so I cannot code to disable specific windows. Is there a way to pool the desktop to see which other windows are open, and to disable them for the time this little script is running and to re-enable them once it is finished??

Thank you guys for the help.

the123punch

Share this post


Link to post
Share on other sites
Achilles

Hi Thank you both for your answers.

Rasim, I tried using WinSetOnTop() but it only forces the current window to remain on top. It does not prevent it from losing focus, therefore my SendKeys are sent to the wrong windows if the focus is ever lost from that main window.

Achilles, your solution seems to be working if I specifically know which window is running in the backgroud. But the problem is that at runtime, usually I wouldn't know which other windows are open so I cannot code to disable specific windows. Is there a way to pool the desktop to see which other windows are open, and to disable them for the time this little script is running and to re-enable them once it is finished??

Thank you guys for the help.

the123punch

There is a way.. Using WinList, look at the example in the helpfile. however, I don't think you should have to disable all the other windows in order for this to work.

Edit: You could try this: Instead of sending the text just use the clipboard functions (ClipSet() I think..), before you send what's in the clipboard (Send('^v')) use a WinActivate()...

Edited by Achilles

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites
james3mg

Can you just write a script like so?

Global $WindowTitle="My Database"
While 1
  WinWaitNotActive($WindowTitle)
  If WinExists($WindowTitle) Then WinActivate($WindowTitle)
WEnd
Edited by james3mg

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites
Achilles

Can you just write a script like so?

Global $WindowTitle="My Database"
While 1
  WinWaitNotActive($WindowTitle)
  If WinExists($WindowTitle) Then WinActivate($WindowTitle)
WEnd
That would work, but I personally don't like stuff like that, it seems like there should be a better way. Plus, there probably should be a sleep in there somewhere.. Edited by Achilles

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites
james3mg

That would work, but I personally don't like stuff like that, it seems like there should be a better way. Plus, there probably should be a sleep in there somewhere..

Why would you need a sleep? It's going to sit there at line 3 without doing anything until the window isn't active! Then it'll activate it and go back to waiting at line 3...

But I'll leave it to the OP to take the method he wants, if you can get your cleaner method working as you want. :mellow:

Edited by james3mg

"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites
ahha

I am having the exact same issue on losing focus. I am writing to several logs from multiple programs.

james3mg - your approach works sometimes as long as the focus is not lost between the last activate and the code writing to, for example, the notepad.

We are talking about a small window to time that is needed to guarantee that the focus is not lost. Does autoit have any atomic write operations?

Share this post


Link to post
Share on other sites
ahha

Compile these scripts and see what happens. By clicking on the window that loses focus you'll see that the wrong entry goes into the other window. Sometimes you can watch it ping pong for a while before focus is lost. If you hit it just right 121212 will appear in one window.

So is there a way to lock focus for a window upon acquiring it and then release it when we are done in that window?

CODE

#include <Date.au3>

HotKeySet ( "^1", "EndProgram" ); CTRL+1

$programname = "Notepad 1.au3"

$notepadonoff = "on" ;set to 'on' or 'off'

;==== set up a notepad for display of operations

If $notepadonoff = "on" Then

$npname = "notepad 1.txt" ;notepad filename

If FileExists($npname) Then FileDelete($npname) ;close it if prior one open

$x = FileOpen($npname, 2) ;open up a blank file overwriting anything that exists

FileClose($x)

Run("notepad.exe " & $npname)

_notepad("Filename: " & $npname & @CRLF & "Currently running program: " & @AutoItExe & @CRLF & _NowDate() & " " & _NowTime() ) ;let's put in filename and date and time

Else

;off so don't open the notepad

EndIf

While 1 ;loop forever

_notepad(_NowDate() & " " & _NowTime() & " 1") ;"1" should be only in notepad 1.txt

Sleep (1000) ;every second to bring out the problem

WEnd

Func EndProgram()

_notepad(_NowDate() & " " & _NowTime() & " Exiting at user request.")

Exit

EndFunc

;------------------------------------------------------

; this is set above at top of program $notepadonoff = "on" ;set to 'on' or 'off'

Func _notepad($string)

If $notepadonoff = "on" Then

WinActivate($npname & " - Notepad")

WinWaitActive($npname & " - Notepad")

;Send($string & @CR) ;slow but sure

;ControlCommand($npname & " - Notepad", "", "Edit1", "EditPaste", String($string) & @CRLF) ;not sure faster

;fastest is to put on the clipboard and paste it in

ClipPut($string) ;copy to clipboard

Send("^v" & @CR) ;paste it

Else

;off so just return

EndIf

EndFunc

CODE

#include <Date.au3>

HotKeySet ( "^2", "EndProgram" ); CTRL+2

$programname = "Notepad 2.au3"

$notepadonoff = "on" ;set to 'on' or 'off'

;==== set up a notepad for display of operations

If $notepadonoff = "on" Then

$npname = "notepad 2.txt" ;notepad filename

If FileExists($npname) Then FileDelete($npname) ;close it if prior one open

$x = FileOpen($npname, 2) ;open up a blank file overwriting anything that exists

FileClose($x)

Run("notepad.exe " & $npname)

_notepad("Filename: " & $npname & @CRLF & "Currently running program: " & @AutoItExe & @CRLF & _NowDate() & " " & _NowTime() ) ;let's put in filename and date and time

Else

;off so don't open the notepad

EndIf

While 1 ;loop forever

_notepad(_NowDate() & " " & _NowTime() & " 2") ;"1" should be only in notepad 1.txt

Sleep (1100) ;every 1.1 second

WEnd

Func EndProgram()

_notepad(_NowDate() & " " & _NowTime() & " Exiting at user request.")

Exit

EndFunc

;------------------------------------------------------

; this is set above at top of program $notepadonoff = "on" ;set to 'on' or 'off'

Func _notepad($string)

If $notepadonoff = "on" Then

WinActivate($npname & " - Notepad")

WinWaitActive($npname & " - Notepad")

;Send($string & @CR) ;slow but sure

;ControlCommand($npname & " - Notepad", "", "Edit1", "EditPaste", String($string) & @CRLF) ;not sure faster

;fastest is to put on the clipboard and paste it in

ClipPut($string) ;copy to clipboard

Send("^v" & @CR) ;paste it

Else

;off so just return

EndIf

EndFunc

Share this post


Link to post
Share on other sites
james3mg

For your case, where you're inputting text to a window, could you use ControlSend() instead of Send()? That way, it doesn't matter if the window has focus or not...


"There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110

Share this post


Link to post
Share on other sites
ahha

For your case, where you're inputting text to a window, could you use ControlSend() instead of Send()? That way, it doesn't matter if the window has focus or not...

Tried it and while it doesn't send the contents to the other window it also does not always send it. That is, if you click on one of the windows it will prevent the other window from updating. Ive made the code smaller to illustrate the problem. The timestamp shows the missed content as it updates about every second. (BTW how do you paste in code so that it keeps the indents. It looks good in preview and is collapsed in the post view. See upload.)

CODE

#include <File.au3>

#include <Date.au3>

HotKeySet ( "^1", "EndProgram" ); CTRL+1

$npname = "window1.txt"

_FileCreate($npname)

Run("notepad.exe " & $npname)

While 1

WinActivate($npname & " - Notepad")

WinWaitActive($npname & " - Notepad")

ControlSend($npname & " - Notepad", "", "Edit1", _NowDate() & " " & _NowTime() & " should be in window 1" & @CR) ;for notepad ClassnameNN = Edit1

WEnd

Func EndProgram()

Send("Exiting at user request.")

Exit

EndFunc

CODE

#include <File.au3>

#include <Date.au3>

HotKeySet ( "^2", "EndProgram" ); CTRL+2

$npname = "window2.txt"

_FileCreate($npname)

Run("notepad.exe " & $npname)

While 1

WinActivate($npname & " - Notepad")

WinWaitActive($npname & " - Notepad")

ControlSend($npname & " - Notepad", "", "Edit1", _NowDate() & " " & _NowTime() & " should be in window 2" & @CR) ;for notepad ClassnameNN = Edit1

WEnd

Func EndProgram()

Send("Exiting at user request.")

Exit

EndFunc

Window_1.au3

Edited by ahha

Share this post


Link to post
Share on other sites
ahha

Also tried

SendKeepActive($npname & " - Notepad") ;try and keep focus

Send(_NowDate() & " " & _NowTime() & " should be in window 2" & @CR) ;DOES NOT WORK

SendKeepActive("") ;done with Send so let go of focus

and it does not work. In fact if you click on a third window (need to click several times till it hits at the right moment) it will stop updates to both the windows. Also HotKeySet does not seem to work reliably.

So how does one keep focus until done with a window?

Share this post


Link to post
Share on other sites
ken82m

Are you more worried about the user changing focus or something else popping up and changing focus?


My Contributions _StringMultiReplace PC Builders Console - Secure PDF Creator - Cisco VPN Installer MS DNS Server Backup Script - MS DHCP Backup Script IT Admin Console - Toggle Admin Mode - MyMovies-Add Discs Script - IT Help Desk and System Information Tool - Set On Lid Close Power Option - Streaming Media Server & Website "I believe that when we leave a place, part of it goes with us and part of us remains... Go anywhere, when it is quiet, and just listen.. After a while, you will hear the echoes of all our conversations, every thought and word we've exchanged.... Long after we are gone our voices will linger in these walls for as long as this place remains."

Share this post


Link to post
Share on other sites
ahha

Are you more worried about the user changing focus or something else popping up and changing focus?

Something else popping up and changing focus.

Share this post


Link to post
Share on other sites
johnmcconnell

here try this a little some thing i made up to keep my password prg from losing focus

the udf

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****

#AutoIt3Wrapper_Version=beta

#AutoIt3Wrapper_Outfile=1.exe

#AutoIt3Wrapper_Res_Fileversion=1.0.0.0

#AutoIt3Wrapper_Res_FileVersion_AutoIncrement=p

#AutoIt3Wrapper_Res_LegalCopyright=Micro-tech

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#AutoIt3Wrapper_Run_Tidy=y

#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

; Includes

#include-once

;===============================================================================

;

; Function Name: _WinKeepActive()

; Description: Monitors your app window to ensure it is always active

; Syntax.........:_WInKeepActive(title,text)

;

;

;

;Author: John McConnell

;Notes:

;

;Returns @error = 1 ($KeepActive = Not compiled Script)

;

;===============================================================================

Func _WinKeepActive($sTitle, $sText)

Local $sKeepActive, $stemp

Local $hTemp = ''

If Not @Compiled Then Return SetError(1)

If Not IsDeclared("sKeepActive") Then Exit MsgBox(0, "Error", "$sKeepActive is not declared")

$sKeepActive = 'Opt ("TrayIconHide",1)' & @CRLF & _

"WinWaitActive('" & $sTitle & "')" & @CRLF & _ ; wait here for window to come up and Active

"While 1" & @CRLF & _

"sleep(200)" & @CRLF & _

"WinActivate('" & $sTitle & "','" & $sText & "')" & @CRLF & _

"If WinExists('" & $sTitle & "') = 0 Then" & @CRLF & _ ; if window dose not exist then exit

" EXIT" & @CRLF & _

"EndIf " & @CRLF & _

"Wend"

$hTemp = FileOpen(@TempDir & "\KeepActive.au3", 2) ; write file to temp dir

FileWrite($hTemp, $sKeepActive)

FileClose($HTemp)

$sKeepActive = Run(FileGetShortName(@AutoItExe) & " /Autoit3ExecuteScript " & @TempDir & "\KeepActive.au3", @TempDir) ; run file from temp dir

ProcessSetPriority($sKeepActive, 3)

Return SetError(0)

EndFunc ;==>_WinKeepActive

how to use

#include "_WinKeepActive.au3"

_WinKeepActive("TEST", ">")

$a = InputBox("TEST",">")

let me know how it works

john

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.