;---- 0 - BEGIN
;
;************************************************************************
;Titre      : AblGestion.pb
;Auteur     : (C) 2019 CAGE
;Date       : 2019/03/10
;Version PB : PureBasic 5.70 LTS (Windows - x86)
;Version PB : PureBasic 5.70 LTS (Windows - x64)
;Compiler Options
;Compiler Options : Enable moderm theme support (for Windows X and above)
;Compiler Options : Request Administrator mode for Windows Vista and above
;Compile/Run      : Create temporary executable in the source directory
;
;Libairies: aucunes
;
;************************************************************************
;

EnableExplicit

OnErrorGoto(?ErrorHandler)

Global AppName$ = GetFilePart(ProgramFilename(), #PB_FileSystem_NoExtension)
Global AppPath$ = GetPathPart(ProgramFilename())

;;; https://msdn.microsoft.com/en-us/library/windows/desktop/cc144179%28v=vs.85%29.aspx
Global TB_Message = RegisterWindowMessage_("TaskbarCreated")

#homemail$ = "pbcage@free.fr"
#homesite$ = "http://pbcage.free.fr"
#homepure$ = "http://www.purebasic.com"

#bgcolor = 14474460 ; bgcolor = RGB(220,220,220) $00DCDCDC
#fgcolor = 0        ; fgcolor = RGB(0,0,0)

#MyServiceName$ = "AbleTaskKill"
Global MyServiceExe$ = AppPath$ + #MyServiceName$ + ".exe"

Global Mutex, Message$

CompilerIf #PB_Compiler_Debugger
  ;;; We are in the IDE
  #WinApp = 999
CompilerElse
  #WinApp = 666 ; use by Mutex if needed
  If TB_Message
    Mutex = CreateMutex_(#Null, #False, AppName$)
    If GetLastError_() = #ERROR_ALREADY_EXISTS
      ;;;
      ;;; Same Mutex in memory, that same app is running ???
      ;;; 
      Define hWnd = FindWindow_("WindowClass_"+Str(#WinApp), #NUL)
      If hWnd
        ;;;
        ;;; Same Mutex in memory and same ClassName, no doubt, is the same app.
        ;;;
        SendMessage_(hWnd,#WM_SYSCOMMAND, #SC_RESTORE,0)
        SetForegroundWindow_(hWnd)
        End
      EndIf
    EndIf
  Else
    ;;; Desktop is not activated, then no TaskBar (TB)
    End
  EndIf
CompilerEndIf

Enumeration Menus
  #MenuApp
  #MenuTray
EndEnumeration

Enumeration FormMenu
  ;
  #MenuAppHide
  #MenuAppHelp1
  #MenuAppHelp2
  #MenuAppHelp3
  ;
  #MenuAppHome
  #MenuAppPage
  #MenuAppFolder
  #MenuAppTaskmgr
  #MenuAppServices
  #MenuAppQuit
  #MenuAppShow
  #MenuAppAbout
EndEnumeration

Enumeration Gadgets
  #Gadget
  #GadgetBtnT  ; (T)askmgr.exe
  #GadgetBtnS  ; (S)ervices.msc
  #GadgetBtnGo ; (Go) -> Lancer
  #GadgetBtnQ  ; (Q)uitter
  #GadgetComboBox1
  #GadgetComboBox2
  #GadgetComboBox3
  #GadgetEditor        ; zone d'affichage des résultats de la commande passée
  #GadgetEnd           ; fin de changement des couleurs bg/fg
EndEnumeration

DataSection ; Images
  Image_App:
  IncludeBinary "AbleGestion.ico"
EndDataSection

Enumeration Images
  #Image_App
EndEnumeration

Enumeration Fonts
  #Font0
  #Font1
EndEnumeration

Global optMinimize = #True

Global IconApp = CatchImage(#Image_App  , ?Image_App)

Global Event, IndexMenu
Global indexGadget, indexGadgetType

Procedure messageBox(request = #False)
  If Message$ = #Null$
    ProcedureReturn -1
  EndIf
  Protected flag = #PB_MessageRequester_Ok ;|#MB_ICONINFORMATION
  If request
    flag = #PB_MessageRequester_YesNo ; |#MB_ICONQUESTION
  EndIf
  ProcedureReturn MessageRequester(AppName$, Message$, flag | #MB_TOPMOST)
EndProcedure

Procedure initSysTray()
  If FindWindow_("Progman", #NUL) <> 0
    AddSysTrayIcon(#WinApp, WindowID(#WinApp), IconApp)
    SysTrayIconToolTip(#WinApp, AppName$)
  EndIf
EndProcedure

Procedure window_Callback(win, msg, wParam, lParam)
  Protected Result = #PB_ProcessPureBasicEvents
  Select Msg
    Case TB_Message ; explorer crash
      initSysTray()
  EndSelect
  ProcedureReturn Result
EndProcedure

Procedure hideAppWindow()
  HideWindow(#WinApp, #True)
  SetWindowState(#WinApp, #PB_Window_Minimize)
EndProcedure

Procedure showAppWindow()
  HideWindow(#WinApp, #False)
  SetWindowState(#WinApp, #PB_Window_Normal)
EndProcedure

Procedure appAbout()
  Protected confirm
  Protected home.s = GetFilePart(#homepure$)
  Message$ = AppName$ + #CRLF$ + #CRLF$
  Message$ + "Cette application est copyright © 2019 CAGE" + #CRLF$ + #CRLF$
  Message$ + "Mes remerciements à l'équipe PureBasic" + #CRLF$ + #CRLF$
  message$ + "Souhaitez-vous visiter le site " + #homepure$
  confirm = messageBox(#True)
  If confirm = #PB_MessageRequester_Yes
    RunProgram(#homepure$)
  EndIf
EndProcedure

Procedure set_service(service$=#Null$, program$=#Null$, action$=#Null$)
  Protected parameters$, status$, rc=#False
  Protected myexe$  = MyServiceExe$
  Protected scexe$  = "sc.exe"
  Protected netexe$ = "net.exe"
  DisableGadget(#GadgetBtnGo, #True)
  ClearClipboard()
  ClearGadgetItems(#GadgetEditor)
  service$ = Chr(34)+service$+Chr(34)
  Select LCase(action$)
    Case "start"           :                     action$ = "start   " + service$
    Case "stop"            :                     action$ = "stop    " + service$
    Case "create"          : AddGadgetItem(#GadgetEditor, 0, "Action non traitée.") : ProcedureReturn 0
    Case "delete"          : program$ = scexe$ : action$ = "delete  " + service$
    Case "query"           : program$ = scexe$ : action$ = "query   " + service$
    Case "queryex"         : program$ = scexe$ : action$ = "queryex " + service$
    Case "auto"            : program$ = scexe$ : action$ = "config  " + service$ + " start= auto"
    Case "delayed-auto"    : program$ = scexe$ : action$ = "config  " + service$ + " start= delayed-auto"
    Case "demand"          : program$ = scexe$ : action$ = "config  " + service$ + " start= demand"
    Case "disabled"        : program$ = scexe$ : action$ = "config  " + service$ + " start= disabled"
    ;;; Les trois commandes suivantes sont spécifique au service lui même.
    Case "/help"           : program$ = myexe$ : action$ = "/help"
    Case "/install"        : program$ = myexe$ : action$ = "/install"
    Case "/uninstall"      : program$ = myexe$ : action$ = "/uninstall"
    Default
      action$ = #Null$
  EndSelect
  If action$ <> #Null$
    If program$ = myexe$
      Select LCase(action$)
        Case "/uninstall"
          parameters$ = "/c "+netexe$+" stop "+service$+" 2>&1|clip" : Debug parameters$
          rc = RunProgram("cmd.exe",parameters$,#Null$,#PB_Program_Wait|#PB_Program_Hide)
      EndSelect
      parameters$ = "/c "+program$+" "+action$+" &&pause" : Debug parameters$
      rc = RunProgram("cmd.exe",parameters$,#Null$)
    Else
      parameters$ = "/c "+program$+" "+action$+" 2>&1|clip" : Debug parameters$
      rc = RunProgram("cmd.exe",parameters$,#Null$,#PB_Program_Wait|#PB_Program_Hide)
    EndIf
    AddGadgetItem(#GadgetEditor, 0, GetClipboardText())
    ClearClipboard()
  EndIf
  DisableGadget(#GadgetBtnGo, #False)
  ProcedureReturn rc
EndProcedure

ExamineDesktops()
#WinAppWidth  = 600
#WinAppHeight = 260
Define X = (DesktopWidth(0)-#WinAppWidth)/2
Define Y = (DesktopHeight(0)-#WinAppHeight)/2

Define Flags = #PB_Window_TitleBar|#PB_Window_ScreenCentered|#PB_Window_SystemMenu

If OpenWindow(#WinApp, X, Y, #WinAppWidth, #WinAppHeight, AppName$ + " - " + #MyServiceName$, Flags)
  ;;; choix de couleur et de police a faie avant de construire l'interface
  SetWindowColor(#WinApp, #bgcolor)
  
  SetWindowCallback(@window_Callback(),#WinApp) ; crash explorer
  
  initSysTray()
  
  If CreatePopupImageMenu(#MenuTray, #PB_Menu_ModernLook)
    MenuItem(#MenuAppShow  , AppName$ , IconApp)
    MenuBar()
    MenuItem(#MenuAppAbout ,"About")
    MenuItem(#MenuAppQuit  ,"Quitter")
  EndIf
  
  If CreateImageMenu(#MenuApp, WindowID(#WinApp), #PB_Menu_ModernLook)
    MenuTitle("Fichier")
      MenuItem(#MenuAppFolder        , "Ouvrir le dossier de l'application")
      MenuBar()
      MenuItem(#MenuAppTaskmgr       , "Lancer le Gestionnaire de tâches")
      MenuItem(#MenuAppServices      , "Lancer le Gestionnaire de services")
      MenuBar()
      MenuItem(#MenuAppHome          , "Visiter le site " + #homesite$)
      MenuItem(#MenuAppPage          , "Consulter la page de l'application")
      MenuBar()
      MenuItem(#MenuAppQuit          , "Quitter")
    MenuTitle("?")
      MenuItem(#MenuAppAbout         , "About")
  EndIf
  
  Define X,Y,W,H,G
  
  X=2:Y=2:W=55:H=24
  ButtonGadget(#GadgetBtnT, X, Y, W, H, "Taskmgr")
  GadgetToolTip(#GadgetBtnT, " Cliquez pour lancer le Gestionnaire de tâches (Taskmgr.exe) ")
  ;
  X+W+1
  ButtonGadget(#GadgetBtnS, X, Y, W, H, "Services")
  GadgetToolTip(#GadgetBtnS, " Cliquez pour lancer la console services.msc ")
  ;
  X+W+12:Y=2:W=60:H=24
  ButtonGadget(#GadgetBtnGo, X, Y, W, H, "Exécuter >")
  GadgetToolTip(#GadgetBtnGo, " Cliquez pour lire ou modifier le status du service " + #MyServiceName$)
  ;
  X+W+2:Y=3:W=100:H=22
  ComboBoxGadget(#GadgetComboBox3, X, Y, W, H)
  AddGadgetItem(#GadgetComboBox3, -1, "sc.exe")
  AddGadgetItem(#GadgetComboBox3, -1, "net.exe")
  AddGadgetItem(#GadgetComboBox3, -1, LCase(#MyServiceName$)+".exe")
  SetGadgetState(#GadgetComboBox3, 0)
  ;
  X+W+4:W=120
  ComboBoxGadget(#GadgetComboBox2, X, Y, W, H)
  AddGadgetItem(#GadgetComboBox2, -1, "query")
  AddGadgetItem(#GadgetComboBox2, -1, "queryex")
  AddGadgetItem(#GadgetComboBox2, -1, "start")
  AddGadgetItem(#GadgetComboBox2, -1, "stop")
  AddGadgetItem(#GadgetComboBox2, -1, "create")
  AddGadgetItem(#GadgetComboBox2, -1, "delete")
  AddGadgetItem(#GadgetComboBox2, -1, "delayed-auto")
  AddGadgetItem(#GadgetComboBox2, -1, "auto")
  AddGadgetItem(#GadgetComboBox2, -1, "demand")
  AddGadgetItem(#GadgetComboBox2, -1, "disabled")
  AddGadgetItem(#GadgetComboBox2, -1, "/help")
  AddGadgetItem(#GadgetComboBox2, -1, "/install")
  AddGadgetItem(#GadgetComboBox2, -1, "/uninstall")
  SetGadgetState(#GadgetComboBox2, 0)
  ;
  X+W+2:Y=3:W=120:H=22
  ComboBoxGadget(#GadgetComboBox1, X, Y, W, H)
  AddGadgetItem(#GadgetComboBox1, -1, #MyServiceName$)
  SetGadgetState(#GadgetComboBox1, 0)
  DisableGadget(#GadgetComboBox1, #True)
  ;
  W=45:H=24:X=#WinAppWidth-W-2:H=24
  ButtonGadget(#GadgetBtnQ, X, Y, W, H, "Quitter")
  GadgetToolTip(#GadgetBtnQ, " Cliquez pour fermer l'application ")
  ;
  X=2:Y=27:H=208
  EditorGadget(#GadgetEditor, X , Y , #WinAppWidth-4 , H, #PB_Editor_ReadOnly)
  SetGadgetColor(#GadgetEditor, #PB_Gadget_BackColor , #bgcolor)
  SetGadgetColor(#GadgetEditor, #PB_Gadget_FrontColor, RGB(0,0,0))
  ;
  Define G
  
  For G = #Gadget + 1 To #GadgetEnd - 1
    SetGadgetColor(G, #PB_Gadget_BackColor , #bgcolor)
    SetGadgetColor(G, #PB_Gadget_FrontColor, RGB(0,0,0))
  Next
  
  If LoadFont(#Font1, "Consolas", 9)
    SetGadgetFont(#GadgetEditor , FontID(#Font1))
  EndIf
  
  Define input$ = #Null$
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Menu
        indexMenu = EventMenu()
        Select indexMenu
          Case #MenuAppQuit
            Break
          Case #MenuAppFolder
            RunProgram(AppPath$,#Null$,AppPath$)
          Case #MenuAppTaskmgr
            RunProgram("taskmgr.exe")
          Case #MenuAppServices
            RunProgram("services.msc")
          Case #MenuAppAbout
            appAbout()
          Case #MenuAppHome
            RunProgram(#homesite$)
          Case #MenuAppPage
            RunProgram(#homesite$+"/pb/abletaskkill.html")
        EndSelect
        
;;;;;;;;;
;;;;;;;;; Events GADGETS
;;;;;;;;;
;---- Events GADGETS
      Case #PB_Event_Gadget
        indexGadget     = EventGadget()
        indexGadgetType = EventType()
        Select indexGadget
          Case #GadgetBtnGo
            Define service$ = GetGadgetText(#GadgetComboBox1)
            Define status$  = GetGadgetText(#GadgetComboBox2)
            Define program$ = GetGadgetText(#GadgetComboBox3)
            set_service(service$, program$, status$)
          Case #GadgetBtnS
            RunProgram("services.msc")
          Case #GadgetBtnT
            RunProgram("taskmgr.exe")
          Case #GadgetBtnQ
            Break
          Case #GadgetComboBox2, #GadgetComboBox3
            Select indexGadgetType
              Case #PB_EventType_Change
                If GetGadgetState(#GadgetComboBox3) = 2
                  SetGadgetState(#GadgetComboBox3, 0)
                EndIf
                input$ = GetGadgetText(#GadgetComboBox2)
                Select input$
                  Case "start","stop"
                  Case "create","delete"
                    SetGadgetState(#GadgetComboBox3, 0)
                  Case "help","install","uninstall"
                    SetGadgetState(#GadgetComboBox3, 2)
                  Default : SetGadgetState(#GadgetComboBox3, 0)
                EndSelect
            EndSelect
        EndSelect
;;;;;
;---- Events SYSTEM SYSTRAY
;;;;;
      Case #PB_Event_SysTray
        Select EventType()
          Case #PB_EventType_RightClick
            DisplayPopupMenu(#MenuTray, WindowID(#WinApp))
            
          Case #PB_EventType_LeftClick
            If GetWindowState(#WinApp) = #PB_Window_Normal
              hideAppWindow()
            Else
              showAppWindow()
              StickyWindow(#WinApp, #True)
            EndIf
        EndSelect
;;;;;
;;;;; Events system window
;;;;;
;---- Events SYSTEM WINDOW
      Case #PB_Event_CloseWindow
        hideAppWindow()
      Case #PB_Event_MinimizeWindow
        If optMinimize
          HideWindow(#WinApp, #True)
        EndIf
      Case #PB_Event_MaximizeWindow
        ;
      Case #PB_Event_RestoreWindow
        ;
    EndSelect
  ForEver
EndIf
;---- Events ERROR HANDLER
ErrorHandler:
  
  Define lHwd = FindWindow_("Progman", #NUL)
  ShowWindow_(lHwd, 8)
  RemoveSysTrayIcon(#WinApp)
  ReleaseMutex_(Mutex)
  End
; IDE Options = PureBasic 5.70 LTS (Windows - x64)
; CursorPosition = 194
; FirstLine = 77
; Folding = AQ9--
; EnableThread
; EnableXP
; CompileSourceDirectory
; EnablePurifier