Jump to content

singeton problems


Recommended Posts

i have a similar problem as i'm trying to send commands to update a treeview in an existing instance, the additional commands passed to the existing instance should check if it already exists..if not then it should exit. if it does exist(its gui) then it should update the treeview according to those commands, i tried several methods and switches but i couldn't let the first instance accept and parse the additional commands, any ideas? thanks

; AutoIt Version: 3.3.0

; Language: that's it!

; Platform: Win9x/NT

#NoTrayIcon

#Include <Misc.au3>

#include <file.au3>

#Include <String.au3>

#include <Array.au3>

#include <GUIConstantsEx.au3>

#include <WindowsConstants.au3>

#include <TreeViewConstants.au3>

#include <StaticConstants.au3>

#include <GuiTreeView.au3>

Global $_sole_instance

; this is the additional part causing me trouble

$_sole_instance = _Singleton("tabsviewer", 1); Returns 0 if another instance found.

If Not $_sole_instance and $cmdline[0]=2 and $cmdline[2]=("-deltitem") and winexists("Tabs Viewer", "") then

deltitem()

elseif Not $_sole_instance and $cmdline[0]=2 and $cmdline[2]=("-addtitem") and winexists("Tabs Viewer", "") then

addtitem()

else

if Not $_sole_instance and $cmdline[0]=2 and winexists("Tabs Viewer", "")=0 then

exit

elseif Not $_sole_instance and winexists("Tabs Viewer", "") then

endprocess()

EndIf

endif

; end of troublesome part/parsing commands to same instance

If $cmdline[0]<2 or processexists("k-meleon.exe")=0 then

exit

endif

;$procfile=(@scriptdir & "\proc.log")

;ref http://www.opensource.org/docs/definition.php|https://developer.mozilla.org/en/Gecko|http://www.mozilla.com/en-US/|resource:///readme.html|http://kmeleon.sourceforge.net/|http://www.opensource.org/docs/definition.php

;ref2 http://kmeleon.sourceforge.net/<>K-Meleon - ReleaseNotes15<>The Open Source Definition (Annotated) | Open Source Initiative<>Gecko - MDC<>The Free Software Definition - GNU Project - Free Software Foundation (FSF)<>K-Meleon 1.5.4<>K-Meleon

Opt("GUIOnEventMode", 1)

$tabstotal=$cmdline[1]

$kmwin=WinGetPos("[CLASS:KMeleon Browser Window]", "")

$extra=ControlGetPos ("[CLASS:KMeleon Browser Window]", "", 59396 )

$tab=ControlGetPos ("[CLASS:KMeleon Browser Window]", "", 1080 )

$status=ControlGetPos ("[CLASS:KMeleon Browser Window]", "", 59393 )

$pendurls=ClipGet ( )

$Gui=GUICreate("Tabs Viewer | " & $tabstotal & " tabs", 300, 400, 0, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

$Trv = GUICtrlCreateTreeView(8,2, 284,392, BitOR( $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_STATICEDGE )

;$exb=GUICtrlCreatePic(@scriptdir & "\exit.bmp", 220, 2 , 16 , 16)

;$infoti=GUICtrlCreateLabel ( " Tabs Viewer | " & $tabstotal & " tabs", 4, 4 , 200, 14)

$remlast1=StringInStr ($pendurls, "<>" , 0, -1)

$remlast2=StringMid($pendurls, 1, $remlast1-1)

$array = StringSplit($remlast2, '<>', 1)

$Item=$array

For $x = 1 to $array[0]

Dim $entry

Local $entry = GUICtrlCreateTreeViewItem($array[$x] , $Trv)

Next

GUISetOnEvent($GUI_EVENT_CLOSE, "Event", $Gui)

GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "SysEvents", $Gui)

$seluno=_GUICtrlTreeView_GetFirstItem($Trv)

_GUICtrlTreeView_SelectItem($Trv, $seluno)

GUISetState(@SW_HIDE)

if $CmdLine[3]=1 then

$setpos=($kmwin[3]-$extra[3]-$tab[3]-$tab[3]-$status[3]-11)

else

$setpos=($kmwin[3]-$extra[3]-$tab[3]-$status[3]-9)

endif

ClipPut("")

WinMove("Tabs Viewer", "", $kmwin[0]+5, $kmwin[1]+$extra[3]+$tab[3]+3, 220, $setpos)

GUISetState(@SW_SHOW)

WinSetTrans ( "Tabs Viewer", "", 220 )

WinSetOnTop ( "Tabs Viewer", "", 1)

winactivate("[CLASS:KMeleon Browser Window]", "")

While winexists("[CLASS:KMeleon Browser Window]", "")

$frfrac=wingettitle("[CLASS:KMeleon Browser Window]", "")

$liveipchk=StringInStr($frfrac, " ::: ", 0, -1)

$pendcustit=(" (" & $cmdline[2] & ")")

if $liveipchk>0 and processexists("liveipplus.exe") and $cmdline[2]<>("") then

$clnfrits=stringmid($frfrac, 1, $liveipchk)

$frtits=stringreplace($clnfrits, $pendcustit, "")

elseif $liveipchk>0 and processexists("liveipplus.exe") and $cmdline[2]=("") then

$frtits=stringmid($frfrac, 1, $liveipchk)

else

if $liveipchk=0 and $cmdline[2]<>("") then

$frtits=stringreplace($frfrac, $pendcustit, "")

elseif $liveipchk=0 and $cmdline[2]=("") then

$frtits=$frfrac

else

$frtits=$frfrac

endif

endif

$getseli=_GUICtrlTreeView_GetSelection($Trv)

$getftab=_GUICtrlTreeView_FindItem($Trv,$frtits, false)

if $getftab<>0 then

_GUICtrlTreeView_SelectItem($Trv, $getftab)

else

$getseli=_GUICtrlTreeView_GetSelection($Trv)

sleep(588)

$getftab2=_GUICtrlTreeView_FindItem($Trv,$frtits, true)

if $getftab2<>0 then

_GUICtrlTreeView_SelectItem($Trv, $getftab2)

else

_GUICtrlTreeView_SetText($Trv, $getseli, $frtits)

endif

endif

sleep(8)

$kmwin=WinGetPos("[CLASS:KMeleon Browser Window]", "")

$extra=ControlGetPos ("[CLASS:KMeleon Browser Window]", "", 59396 )

$tab=ControlGetPos ("[CLASS:KMeleon Browser Window]", "", 1080 )

$status=ControlGetPos ("[CLASS:KMeleon Browser Window]", "", 59393 )

if $CmdLine[3]=1 then

$setpos=($kmwin[3]-$extra[3]-$tab[3]-$tab[3]-$status[3]-11)

else

$setpos=($kmwin[3]-$extra[3]-$tab[3]-$status[3]-9)

endif

WinMove("Tabs Viewer", "", $kmwin[0]+5, $kmwin[1]+$extra[3]+$tab[3]+3, 220, $setpos)

WinSetOnTop ( "Tabs Viewer", "", 1)

$prim=_GUICtrlTreeView_GetSelection($Trv)

$initial=_GUICtrlTreeView_GetText($Trv, $prim)

$tabinitial1=StringLeft ( $initial, 2)

$tabinitial=stringreplace($tabinitial1, " ", "")

$tabinidex=(_GUICtrlTreeView_Index($Trv, $prim)+1)

Sleep(24)

WEnd

exit

processclose("tabsviewer.exe")

exit

Func Event()

$cID = @GUI_CtrlId

Switch $cID

Case $GUI_EVENT_CLOSE

guidelete()

Exit

EndSwitch

EndFunc

Func SysEvents()

Switch @GUI_CtrlId

Case $GUI_EVENT_PRIMARYDOWN

$Item =_GUICtrlTreeView_GetSelection($Trv)

$litind=(_GUICtrlTreeView_Index($Trv, $Item)+1)

;GUISetState ($GUI_DISABLE)

if $tabinidex<>$litind then

$Itemprev=_GUICtrlTreeView_GetPrevSibling($Trv, $Item)

$iprevindi=(_GUICtrlTreeView_Index($Trv, $Itemprev)+1)

$Itemprevcnt=_GUICtrlTreeView_GetText($Trv, $Itemprev)

$tabprev1=StringLeft ( $Itemprev, 2)

$tabcalc=($litind-$tabinidex)

$tabcln=Stringreplace($tabcalc, "-", "")

$tabcalc2=($tabstotal-$tabcln)

$tabscnt=StringInStr($tabcalc, "-", "")

if $tabcalc>0 then

$ftabsend=$tabcalc

else

$ftabsend=$tabcalc2

endif

winactivate("[CLASS:KMeleon Browser Window]", "")

WinwaitActive("[CLASS:KMeleon Browser Window]")

$dsend=("""" & "^" & "{" & "TAB" & $tabscnt & "}" & """")

send("{CTRLDOWN}")

Send("{TAB " & $ftabsend & "}")

send("{CTRLUP}")

endif

winactivate("Tabs Viewer", "")

;GUISetState ($GUI_ENABLE)

EndSwitch

EndFunc

; functions related to troublesome part

func endprocess()

while processexists("tabsviewer.exe")

processclose("tabsviewer.exe")

wend

exit

endfunc

func deltitem()

if winexists("[CLASS:KMeleon Browser Window]", "")=0 then

processclose("tabsviewer.exe")

exit

endif

$tabirem=$cmdline[1]

$itemdel=_GUICtrlTreeView_FindItem($Trv,$tabirem, false)

_GUICtrlTreeView_Delete($Trv, $itemdel)

endfunc

func addtitem()

if winexists("[CLASS:KMeleon Browser Window]", "")=0 then

processclose("tabsviewer.exe")

exit

endif

endfunc

; end of functions related to troublesome part

Link to comment
Share on other sites

instead of something like this "... if Not $_sole_instance and $cmdline[0]=2 ..."

Try

"

...

If not $_sole_instance then

if $cmdline[0]=2 then

"

nah, i tried that before..thanks dictator. i think it's not possible to make a single instance accept more commands as it's already working with the first launch parameters..it actually isn't logical so it has to be a second instance or a different script which i don't want.

i came up with an idea that overcomes that limitation if anyone is facing that same problem. of course depending on what your programme is meant to do it might not be functional.

in my case, when i want to add or remove an entry from the treeeview, i copy the string required to the clipboard..in that case it's a url.

then without running the programme again or passing additional commands we can make the script check periodically the clipboard or after it has finished a certain function. this way we can easily control when and where the treeview can be updated or changed.

to ensure the script won't just parse anything in the clipboard we can add a unique prefix in the clipboard eg. "thisisforautoitonly:$clipcontents"

if it finds the unique prefix, only then it will extract the rest of the clip and continue to compare clipcontents against the treeview

Link to comment
Share on other sites

You're correct, you can not use the program launch/command-line mechanism to pass data to an already running process. You'll need to have your program periodically poll for new data, and when found, process it. Whether you pass that data via the clipboard, registry entries, a file, environment variables, a database, or with another method is entirely up to you.

Edit: And you're right again, you can run into trouble using the clipboard method as other programs can interact with it. I'd probably use a file.

Edited by Spiff59
Link to comment
Share on other sites

Do I understand the problem correctly, you need AutoIt Instance "B" to talk to an already running Instance "A"?

If so, I've had good success using Windows messages and an input control. The following are snippets from a much larger project, so you can't use them directly. But they might give you the basic idea.

; HotRod (The running program)

; Creates a Windows "private" message WM_ACMXEQ and links receipt of that message to the function GUI_fncAcmXeq.

    Global Const $GLB_GUI_WM_ACMXEQ = _WinAPI_RegisterWindowMessage('WM_ACMXEQ')
    Global $GUI_fncAcmXeq = "GUI_fncAcmXeq"
    GUIRegisterMsg( $GLB_GUI_WM_ACMXEQ, $GUI_fncAcmXeq )

; Creates an input control named $GUI_inpAci to receive messages.
    
    Local $InputAci = GUICtrlCreateInput("", 18, 654, 665, 24)
    GUICtrlSetFont($InputAci, 10, 400, 0, "Courier New")
    $GUI_inpAci = $InputAci

; When a WM_ACMXEQ message is received, it kicks off the GUI_fncAcmXeq function which reads the input control.

    Func GUI_fncAcmXeq($hWnd = "", $iMsg = "", $wParam = "", $lParam = "")
    
        Local $CmdLine = _GUICtrlEdit_GetText( $GUI_inpAci )

; LinkOn (The calling program)

; Finds the handles to the HotRow main window and the input control.

    ; HotRod Main Window

    Global $LNK_HRMainAWD = "[CLASS:AutoIt v3 GUI; TITLE:" & $GLB_HRD_Title & "]"
    Global $LNK_HRMainHWnd

    ; HotRod Action Command Input Control

    Global $LNK_HRAciAWD = "[CLASS:Edit; INSTANCE:4]"
    Global $LNK_HRAciHWnd

    Func LNK_FindHR()
    Local Const $Func = "LNK_FindHR"

        $LNK_HRMainHWnd = WinGetHandle( $LNK_HRMainAWD )
        If @error <> 0 Then
            LNK_ErrExit( "Failed to find the HotRod main GUI window as '" & $LNK_HRMainAWD & "'." & @CRLF & "(Is HotRod running?)" )
        EndIf

        $LNK_HRAciHWnd = ControlGetHandle( $LNK_HRMainHWnd , "", $LNK_HRAciAWD )
        If @error <> 0 Then
            LNK_ErrExit( "Failed to find the HotRod Action Command Input control as '" & $LNK_HRAciAWD & "'." )
        EndIf

    EndFunc

; Waits for the input control to be enabled and empty (i.e. no other instance is using it).

    Func LNK_AciEnabled()
    Local Const $Func = "LNK_AciEnabled"

    Local Const $LoopCnt = 8
    Local Const $LoopSleep = 250

        For $LoopIx = 1 To $LoopCnt
            If ControlCommand( $LNK_HRMainHWnd , "", $LNK_HRAciAWD, "IsEnabled", "" ) = 1 Then Return
            Sleep( $LoopSleep )
        Next

        LNK_ErrExit( "HotRod Action Command Input control did not enable." & @CRLF & "Failed after " & $LoopCnt & " tries with a " & $LoopSleep & "ms delay." )

    EndFunc

    ; Wait for the HotRod Action Command Input control to be empty.

    Func LNK_AciEmpty()
    Local Const $Func = "LNK_AciEmpty"

    Local Const $LoopCnt = 8
    Local Const $LoopSleep = 250

        For $LoopIx = 1 To $LoopCnt
            If     _GUICtrlEdit_GetTextLen( $LNK_HRAciHWnd ) = 0 Then Return
            Sleep( $LoopSleep )
        Next

        LNK_ErrExit( "HotRod Action Command Input control did not clear." & @CRLF & "Failed after " & $LoopCnt & " tries with a " & $LoopSleep & "ms delay." )

    EndFunc

; Then sets the input control to the message text and sends a WM_ACMXEQ message.

    Func LNK_SendCmd()
    Local Const $Func = "LNK_SendCmd"

        ; Put the entire command line in the HotRod Action Command text box
        ; and send HotRod an execute message

        _GUICtrlEdit_SetText( $LNK_HRAciHWnd, $CmdLineRaw )
        _SendMessage( $LNK_HRMainHWnd, $GLB_GUI_WM_ACMXEQ )
        If @error Then
            LNK_ErrExit( "_SendMessage WM_ACMXEQ to the HotRod main window failed." )
        EndIf

    EndFunc
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...