AutoHotkey Community

It is currently May 27th, 2012, 8:17 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Single Instance Force
PostPosted: January 24th, 2012, 5:15 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
This script forces the app to be singleinstance.
It handles other instances, passes the data and closses them.

1. It activates the window of the first instance when a second instance is opened.
2. It passes the commandline from the second instance to the first one.
3. it handles commandline from the first instance
4. It handles Files dropped on the GUI
Code:
#SingleInstance off                                ; We handle instances ourselves
if !A_iscompiled {
   msgbox,you need to compile this to test, this is for a real app, not for a script
   exitapp
   }
ForceSingleInstance()                              ; force single instance ourselve
gosub,ParseCommandLine1Instance                    ; check the commandline
Gui, show ,w600 h50,thegui                         ; show a gui to see if it activates when we open a second instance
Return
ForceSingleInstance() {   
   global                                          ; make commandlineparrameters accesable
   local FirstInstancePID                          ; this is the only var used in the first instance, so i make it local
   Process, Exist,%A_ScriptName%                   ; this allways gets the pid from the 1 instance in the ErrorLevel
   FirstInstancePID:=ErrorLevel                    ; store the pid of the instance
   if (FirstInstancePID=DllCall("GetCurrentProcessId")) ; if the first instance is this script
      return,OnMessage(0x4A,"Receive_WM_COPYDATA") ; set the function that Get's the Commandline from 2... instances
   else {                                          ; if not the first instance(2 instance or 3 ...)
      winshow,ahk_pid %FirstInstancePID% ahk_class AutoHotkeyGUI ; show the first window if hidden
      winactivate,ahk_pid %FirstInstancePID% ahk_class AutoHotkeyGUI ; Activate the first window
      IfEqual,0,0,ExitApp                          ; Exit the second istance when ,no Parameter is passed
      Loop,%0%                                     ; Loop all commandlineitems
         args .= args ? "`n" %A_Index% : %A_Index% ; put them in the string, sepporated by a newline
      Send_WM_COPYDATA(args,"ahk_pid" FirstInstancePID) ; send the arguments to the first instance
      exitapp                                      ; exit the second istance
      }
   }
Send_WM_COPYDATA(StringToSend,TargetScriptTitle) { ; from the manual, onmessage (customized by me)
    VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0)  ; Set up the structure's memory area.
    SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
    NumPut(SizeInBytes, CopyDataStruct, A_PtrSize)  ; OS requires that this be done.
    NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize)  ; Set lpData to point to the string itself.
    A_OldDHW := A_DetectHiddenWindows               ; store the curent setting for DetectHiddenWindows
    DetectHiddenWindows, On                         ; to detect our own hidden window
    SendMessage, 0x4a, 0, &CopyDataStruct,, %TargetScriptTitle%  ; 0x4a is WM_COPYDATA. Must use Send not Post.
    DetectHiddenWindows,%A_OldDHW%                  ; restore the old setting for DetectHiddenWindows
    return ErrorLevel  ; Return SendMessage's reply back to our caller.
    }
Receive_WM_COPYDATA(wParam,lParam,Msg,hWnd ) {      ; Function to handle WM_COPYDATA Message(the messages send by other instances)
    global args                                     ; make the arguments accesable to the rest of the script
    A_OldDHW := A_DetectHiddenWindows               ; store the curent setting for DetectHiddenWindows
    DetectHiddenWindows, On                         ; to detect our own hidden window
    WinGet, PPath, ProcessPath, ahk_id %hWnd%       ; Get the path of the app that send the message
    DetectHiddenWindows,%A_OldDHW%                  ; restore the old setting for DetectHiddenWindows
    IfNotEqual,PPath,%A_ScriptFullPath%,Return,0    ; if the message is not from the second instance(the same app),Return
    args := StrGet(NumGet( lParam + 8 ))            ; Get the arguments
    Gosub,ParseCommandLine2Instance                 ; call our label
    Return,1                                        ; as to reply with a TRUE to Caller, ASAP
    }
ParseCommandLine1Instance:
   if (A_ThisLabel="ParseCommandLine1Instance") {  ; Check if we called for parsecommandline
      _0_:= 0                                      ; reset the array
      Loop,%0%                                     ; Loop all commandlineitems
         _0_ := A_Index ,_%A_Index%_ := %A_Index%  ; Increase the nr ofitems and Store this line in the next array element.
      }
GuiDropFiles:   ; note no return the script continues ; Catch all files droped on the application
   if (A_ThisLabel="GuiDropFiles")   {             ; check if it is this label that was called
      _0_:= 0                                      ; reset the array
      Loop,parse, A_GuiEvent, `n                   ; Converting the drop files to array
         _0_:=A_Index,_%A_Index%_:=A_LoopField     ; Increase the nr ofitems and Store this line in the next array element.
      }
ParseCommandLine2Instance:   ; note no return the script continues
   If (A_ThisLabel="ParseCommandLine2Instance") {  ; check if it is this label that was called
      _0_:= 0
      Loop,parse, args, `n                         ; Converting the argument files to array
         _0_:=A_Index,_%A_Index%_:=A_LoopField     ; Increase the nr ofitems and Store this line in the next array element.
      }
   Loop, %_0_%
      Msgbox,% A_ThisLabel ": " _%A_Index%_        ; show all arguments
   Return                                          ; this is the return for all 3 labels
GuiEscape:                                         ; pres escape when the gui is active to hide the gui
GuiClose:
   Gui, hide
   Return
The simple version (window activation only)
feel free to comment

_________________
Stopwatch emdkplayer
the code i post falls under the: WTFYW-WTFPL license


Last edited by emmanuel d on January 24th, 2012, 9:50 pm, edited 5 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 5:16 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
reserved for unicode version
:roll:

_________________
Stopwatch emdkplayer
the code i post falls under the: WTFYW-WTFPL license


Last edited by emmanuel d on January 24th, 2012, 7:32 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 5:16 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
simple version works for ANSI and UNICODE

1. activates the first instance when a second instance is opened.

Code:
#SingleInstance off                           ; We handle instances ourselves
ForceSingleInstance()                        ; force single instance ourselve
Gui, show ,w100 h100,thegui                     ; show a gui to see if it activates when we open a second instance
Return
ForceSingleInstance() {   
   Process, Exist,%A_ScriptName%               ; this allways gets the pid from the 1 instance in the ErrorLevel
   FirstInstancePID:=ErrorLevel               ; store the pid of the instance
   if (FirstInstancePID=DllCall("GetCurrentProcessId"))   ; if the first instance is this script
      return                              ; Return
   else { winshow,ahk_pid %FirstInstancePID% ahk_class AutoHotkeyGUI         ; show the window if hidden
      winactivate,ahk_pid %FirstInstancePID% ahk_class AutoHotkeyGUI      ; Activate the first instance
      exitapp                              ; we have a return for the first instance so exit the app
      }
   }
GuiEscape:
guiclose:
   Gui, hide
   return

_________________
Stopwatch emdkplayer
the code i post falls under the: WTFYW-WTFPL license


Last edited by emmanuel d on January 24th, 2012, 7:26 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 5:23 pm 
Offline
User avatar

Joined: May 18th, 2010, 3:10 pm
Posts: 1179
Location: Sweden
Thanks for a useful function, and alot of comments in the script. I should be able to modify this to my needs if I need it.

I'm not totally sure if the commandline input works though, only the first letter seems to show in the MsgBox.

The reason why I am interested in this is because I had an issue with a script where I want to be able to launch the script with some extra commandline parameters - even while running, to add items to a GUI.

_________________
~sumon Appifyer AHK Nova halted Recommended: AHK_L (Why?)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 5:25 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
Quote:
I'm not totally sure if the commandline input works though, only the first letter seems to show in the MsgBox.


that is becouse you are using unicode version of autohotkey

_________________
Stopwatch emdkplayer
the code i post falls under the: WTFYW-WTFPL license


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 5:34 pm 
Offline
User avatar

Joined: May 18th, 2010, 3:10 pm
Posts: 1179
Location: Sweden
emmanuel d wrote:
Quote:
I'm not totally sure if the commandline input works though, only the first letter seems to show in the MsgBox.


that is becouse you are using unicode version of autohotkey


Right, my bad, that explains it. I'm le tired. Simple version works fine, but I see there's no commandline support there. Well, if you haven't figured why it does not work with Unicode, I may be willing (but maybe not cunning) to help out.

Good function nevertheless :)

_________________
~sumon Appifyer AHK Nova halted Recommended: AHK_L (Why?)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 5:51 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
Quote:
Well, if you haven't figured why it does not work with Unicode
the problem is the wm_copydata structure

_________________
Stopwatch emdkplayer
the code i post falls under the: WTFYW-WTFPL license


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 24th, 2012, 7:29 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
works now on unicode autohotkey

_________________
Stopwatch emdkplayer
the code i post falls under the: WTFYW-WTFPL license


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Aravind, Google Feedfetcher, sks, Stigg and 12 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group