Seite 1 von 1

Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 21.04.2012 17:45
von seschi
Hallo miteinander,

habe heute im Forum ein paar schöne Hinweise bekommen, wie man eine 2. Instanz einer EXE verhindert,
aaaaaber, wie hole ich dann die 1. Instanz in den Vordergrund bzw. aus der Taskleiste?

Weiß jemand Rat?
_

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 21.04.2012 17:55
von ts-soft
Hab in dem thread von Danilo ein schönes Beispiel gepostet, was auch dies berücksichtigt:
http://www.purebasic.fr/german/viewtopi ... 01#p301001

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 21.04.2012 22:24
von TheCube
Ja, in dem feinen Beispielcode von ts-soft gibts die Zeile

Code: Alles auswählen

....
SetForegroundWindow_(wParam)    ; und bringen die erste Instance in den Vordergrund
...
... aber das reicht bei mir nicht um ein minimiertes Fenster wiederherzustellen. (Openwindow vom Beispiel natürlich mit #PB_Window_MinimizeGadget erweitert)
Das Taskicon des minimierten Fensters wird zwar aktiv, aber zu sehen ist das Fenster nicht. (Win7-32)
Auch etwas Surferei/API-Guide, usw. brachten mich nicht auf die richtige Message oder den richtigen Befehl dafür.

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 21.04.2012 22:40
von RSBasic
Wenn du ein minimiertes Fenster wiederherstellen möchtest:

Code: Alles auswählen

SetWindowState(#Window,#PB_Window_Normal)
;Oder:
;ShowWindow_(WindowID(#Window),#SW_NORMAL)

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 21.04.2012 23:16
von TheCube
Danke RSBasic, der PB Befehl war mir bekannt, doch der API-Befehl "ShowWindow_" als Hinweis half,
auch wenn erst nach Änderung im Callback aus dem Beispiel funktionierend:

Code: Alles auswählen

...
ShowWindow_(wParam,#SW_SHOWNORMAL)  ; das muss zuerst
SetForegroundWindow_(wParam)   ; und bringen die erste Instance in den Vordergrund
... 
Callbacks, Messages & Co. werde ich trotzdem wohl nie so ganz durchblicken ....

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 22.04.2012 17:49
von seschi
Hallo miteinander,

@ts-soft mit Deinem Vorschlag war ich erst einmal überfordert, denn er lief nicht und ich konnte jetzt als Anfänger
keine Fehlersuche machen. Dennoch merkte ich, dass beim Openwindow der Schalter "#PB_Window_MinimizeGadget" zum Test
fehlte. Trotzdem klappte es erst mit den Hinweisen von TheCube bzw. RSBasic - Danke miteinander!

Das alles führt mich nun noch mal zu der Eingangsfrage zurück: Ist es möglich aus dem Code von ts-soft nur den Teil heraus zu
filtern, der die 1. Instanz aus der Taskleiste bzw. in den Vordergrund holt - also auch keine Parameter übergabe?

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 22.04.2012 17:58
von ts-soft
Ist schon möglich, macht das ganze aber auch nicht viel kürzer.

Code: Alles auswählen

EnableExplicit

#SI_SESSION_UNIQUE = $0001 ; Allow only one instance per login session
#SI_DESKTOP_UNIQUE = $0002 ; Allow only one instance on current desktop
#SI_TRUSTEE_UNIQUE = $0004 ; Allow only one instance for current user
#SI_SYSTEM_UNIQUE  = $0000 ; Allow only one instance at all (on the whole system)

Procedure.s CreateUniqueName(name.s, mode.l = #SI_DESKTOP_UNIQUE )
  Protected output.s = "Global\" + name
 
  If mode & #SI_DESKTOP_UNIQUE
    Protected hDesk.i, cchDesk.l, userinfo.s
    output   + "-"
    hDesk    = GetThreadDesktop_(GetCurrentThreadId_())
    cchDesk  = #MAX_PATH - Len(name) - 1
    userinfo = Space(#MAX_PATH)
   
    If GetUserObjectInformation_(hDesk, #UOI_NAME, @name, cchDesk, @cchDesk)
      output + Trim(name)
    Else
      output + "Win9x"
    EndIf
  EndIf
  If mode & #SI_SESSION_UNIQUE
    Protected hToken.i, cbBytes.l, *pTS
    If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_QUERY, @hToken)
      If GetTokenInformation_(hToken, #TokenStatistics, #Null, cbBytes, @cbBytes) = 0 And GetLastError_() = #ERROR_INSUFFICIENT_BUFFER
        *pTS = AllocateMemory(cbBytes)
        If *pTS
          If GetTokenInformation_(hToken, #TokenStatistics, *pTS, cbBytes, @cbBytes)
            output + "-" + RSet(Hex(PeekQ(*pts + 8), #PB_Quad), 16, "0")
          EndIf
          FreeMemory(*pTS)
        EndIf
      EndIf
    EndIf
  EndIf
  If mode & #SI_TRUSTEE_UNIQUE
    Protected user.s  , cchUser.l = 64
    Protected domain.s, cchDomain = 64
    user   = Space(cchUser)
    domain = Space(cchDomain)
    If GetUserName_(@user, @cchUser)
      output + "-" + Trim(user)
    EndIf
    cchDomain = GetEnvironmentVariable_("USERDOMAIN", @domain, cchDomain)
   
    output + "-" + Trim(domain)
  EndIf
 
  ProcedureReturn Left(output, #MAX_PATH)
EndProcedure

Procedure IsInstancePresent(name.s, mode.l = #SI_DESKTOP_UNIQUE)
  Protected err, uniqueName.s
  Static hMutex = #Null
  If hMutex = #Null
    uniqueName = CreateUniqueName(name, mode)
    hMutex = CreateMutex_(#Null, #False, @uniqueName)
    err = GetLastError_()
    If err = #ERROR_ALREADY_EXISTS : ProcedureReturn #True : EndIf
    If err = #ERROR_ACCESS_DENIED  : ProcedureReturn #True : EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

; Beispiel:
#myGUID$ = "{62880033-2E0A-47BD-A920-73B9C9E8DFE9}" ; einmalige ID

Global myAPPMsg = RegisterWindowMessage_(CreateUniqueName(#myGUID$))

Procedure myWinCB(hWnd, uMsg, wParam, lParam)
  Protected result = #PB_ProcessPureBasicEvents
 
  Select uMsg
    Case myAPPMsg
      If wParam = 0 ; wir übermitteln unser hWnd
        SendMessage_(lParam, myAPPMsg, WindowID(0), 0)
      ElseIf lParam = 0 ; unser hWnd ist angekommen, wir übermitteln die Parameter
        ShowWindow_(wParam, #SW_SHOWNORMAL)
        SetForegroundWindow_(wParam) ; und bringen die erste Instance in den Vordergrund
      EndIf
  EndSelect
 
  ProcedureReturn result
EndProcedure

If IsInstancePresent(#myGUID$)
  OpenWindow(0, 0, 0, 0, 0, "", #PB_Window_Invisible)
  SetWindowCallback(@myWinCB())
  SendMessage_(#HWND_BROADCAST, myAPPMsg, 0, WindowID(0))
  While WindowEvent() : Wend
  End
EndIf

OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "MainApp", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
SetWindowCallback(@myWinCB())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Bitte unbedingt eine eigene GUID für Deine Zwecke generieren.

Wenn Dich dieser Code überfordert, es gibt auch einfachere Lösungen, nicht so zuverlässig, aber evtl.
verständlicher.

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 22.04.2012 18:14
von ts-soft
Hier eine einfachere Möglichkeit, die ich zwar nicht unbedingt empfehle, aber für einfache Sachen sollte es genügen:

Code: Alles auswählen

EnableExplicit

; Beispiel:
#myGUID$ = "{62880033-2E0A-47BD-A920-73B9C9E8DFE9}" ; einmalige ID
Define FileToCheck.s = GetTemporaryDirectory() + #myGUID$
Define hWnd
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "MainApp", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_Invisible)

If FileSize(FileToCheck) > 0
  If ReadFile(0, FileToCheck)
    hWnd = Val(ReadString(0))
    CloseFile(0)
    If hWnd
      ShowWindow_(hWnd, #SW_SHOWNORMAL)
      SetForegroundWindow_(hWnd)
      While WindowEvent() : Wend
    EndIf
    End
  EndIf
Else
  If CreateFile(0, FileToCheck)
    WriteString(0, Str(WindowID(0)))
    CloseFile(0)
  EndIf
EndIf

HideWindow(0, #False)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

DeleteFile(FileToCheck)

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 22.04.2012 18:47
von seschi
Erst einmal Danke für die schnelle Anwort, werde sie in Ruhe durcharbeiten.
Bitte unbedingt eine eigene GUID für Deine Zwecke generieren.
Wie macht man das denn?

Re: Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Verfasst: 22.04.2012 19:13
von ts-soft
Steht eigentlich auch in dem Thread, aber hier nochmal, bzw. es gibt hier eine Boardsuche!

Code: Alles auswählen

Procedure.s MakeGUID()
  Protected guid.GUID, lpsz.s{76}
  
  If CoCreateGuid_(@guid) = #S_OK
    ProcedureReturn PeekS(@lpsz, StringFromGUID2_(guid, @lpsz, 76), #PB_Unicode)
  EndIf      
EndProcedure