Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Anfängerfragen zum Programmieren mit PureBasic.
seschi
Beiträge: 4
Registriert: 21.04.2012 13:29

Wie exe in den Vordegrund bzw. aus der Taskleiste holen

Beitrag 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?
_
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

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

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

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

Beitrag 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.
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

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

Beitrag 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)
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

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

Beitrag 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 ....
seschi
Beiträge: 4
Registriert: 21.04.2012 13:29

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

Beitrag 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?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

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

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

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

Beitrag 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)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
seschi
Beiträge: 4
Registriert: 21.04.2012 13:29

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

Beitrag 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?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

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

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten