Jump to content
Sign in to follow this  
ericjensen

need help with screenshot app - minimize to tray

Recommended Posts

ericjensen

Hi,

I'm not totally new to AutoIt, but this is the first GUI app I have tried to write and I am stuck on something. Plus I would like input on ways to make this app better.

First let me explain what I am trying to attempt:

We need a small program that will sit in the system tray and when a user clicks on it, the program will take a screen shot of the desktop.

Then the user will be presented with a window to fill in some information about the problem they where experiencing.

Then the user can click submit, this will email the screen shot and message off to our support department for their review.

I cannot take credit for the idea, it came from an open source project called Panic Button. I just wanted to write it in AutoIt instead of Python.

Everything works except when the gui gets minimized back to the tray, i can't click on the tray icon to show it up again. It works the first time, but thats it.

So here is my code, I cobbled it together from lots of posts here on the forums and I appreciate everyones contributions to the community.

;#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=InfoBox.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <GuiConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#Include <Date.au3>
#Include <Array.au3>
#include <INet.au3>
#Include <file.au3>
#include <ScreenCapture.au3> 
#include <GDIPlus.au3>
;Opt ("MustDeclareVars",1)
Opt("TrayOnEventMode",1)
Opt("TrayAutoPause",0) ;0=no pause, 1=Pause 
Opt("TrayMenuMode",1)
Opt("GUIOnEventMode", 1)
TraySetOnEvent($TRAY_EVENT_PRIMARYUP,"OpenGUI")
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN,"OpenGUI")
;##################################
; Variables
;##################################
Global $oMyRet[2]
Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
Global $txtSubject, $edtDescription, $frmPanicButton

$sysDateTime = ""
$sysCompName = ""
$sysIP = ""
$sysWinUser = ""
$sysSSOUSR = ""

$sysDomain = @LogonDNSDomain
$sysProcesses = ""
$SmtpServer = "mysmtpserver"              ; address for the smtp-server to use - REQUIRED
$FromName = ""                          ; name from who the email was sent
$FromAddress = ""                       ; address from where the mail should come
$ToAddress = "my email address"   ; destination address of the email - REQUIRED

$Subject = ""                           ; subject from the email - can be anything you want it to be
$Body = ""                              ; the messagebody from the mail - can be left blank but then you get a blank mail
$AttachFiles = ""                       ; the file(s) you want to attach seperated with a ; (Semicolon) - leave blank if not needed

$CcAddress = ""                         ; address for cc - leave blank if not needed
$BccAddress = ""                        ; address for bcc - leave blank if not needed
$Importance = "Normal"                  ; Send message priority: "High", "Normal", "Low"
$Username = ""                          ; username for the account used from where the mail gets sent - REQUIRED
$Password = ""                          ; password for the account used from where the mail gets sent - REQUIRED
$IPPort = 25                            ; port used for sending the mail
$ssl = 0                                ; enables/disables secure socket layer sending - put to 1 if using httpS

;~ $IPPort=465                          ; GMAIL port used for sending the mail
;~ $ssl=1                               ; GMAILenables/disables secure socket layer sending - put to 1 if using httpS

;file handle for the screen shot image
$strFile = "\" & @MON & "-" & @MDAY & "-" & @YEAR & "_" & @HOUR & "-" & @MIN & "-" & @SEC & "_" & "pic.png"

;##################################
; onload
;#################################
CreateGUI()
While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ;Exit
            MinimizeGUItoTray()
        Case $GUI_EVENT_MINIMIZE
            MinimizeGUItoTray()
    EndSwitch
Sleep(100)
WEnd


;##################################
; Functions
;#################################

;Create the Panic Button gui, and hide it.
Func CreateGUI()
    $frmPanicButton = GUICreate("Panic Button", 679, 443, 192, 124)
        GUISetOnEvent($GUI_EVENT_CLOSE, "MinimizeGUItoTray")
        GUISetOnEvent($GUI_EVENT_MINIMIZE, "MinimizeGUItoTray")
    $lblSubject = GUICtrlCreateLabel("Please enter a brief title of the problem you are experiencing.", 16, 8, 288, 17)
    $txtSubject = GUICtrlCreateInput("", 16, 32, 441, 21)
    $lblDescription = GUICtrlCreateLabel("Please discribe the problem you are expriencing in as much detail as possible.", 16, 64, 368, 17)
    $edtDescription = GUICtrlCreateEdit("", 16, 88, 441, 305)
        ;GUICtrlSetData(-1, "")
        
    $lblReq1 = GUICtrlCreateLabel("*", 8, 8, 8, 17)
        GUICtrlSetColor(-1, 0xFF0000)
    $lblReq2 = GUICtrlCreateLabel("*", 8, 67, 8, 17)
        GUICtrlSetColor(-1, 0xFF0000)
    $lblRequired = GUICtrlCreateLabel("= Required Field", 352, 8, 81, 17)
    $lblReq3 = GUICtrlCreateLabel("*", 339, 7, 8, 17)
        GUICtrlSetColor(-1, 0xFF0000)
    $grpOptionalInfo = GUICtrlCreateGroup("Optional Information", 472, 16, 193, 385)
        $lblComputer = GUICtrlCreateLabel("Computer:", 488, 48, 52, 17)
        $txtComputer = GUICtrlCreateInput("", 488, 64, 169, 21)
            GUICtrlSetData(-1,$sysCompName)
        $lblYourName = GUICtrlCreateLabel("Your Name:", 488, 96, 60, 17)
        $txtYourName = GUICtrlCreateInput("", 488, 112, 169, 21)
        $lblDepartment = GUICtrlCreateLabel("Department or Area:", 488, 144, 99, 17)
        $txtDepartment = GUICtrlCreateInput("", 488, 160, 169, 21)
        $lblCallBackNumber = GUICtrlCreateLabel("Call Back Number:", 488, 192, 92, 17)
        $txtCallBackNumber = GUICtrlCreateInput("", 488, 208, 121, 21)
    GUICtrlCreateGroup("", -99, -99, 1, 1) ;Close the group
    
    $btnSend = GUICtrlCreateButton("Send Report", 24, 400, 75, 25, 0)
        GUICtrlSetOnEvent(-1, "btnSendClick")
    $btnPreview = GUICtrlCreateButton("Preview Screen Shot", 120, 400, 123, 25, 0)
        GUICtrlSetOnEvent(-1, "btnPreviewClick")
    $btnCancel = GUICtrlCreateButton("Cancel", 264, 400, 75, 25, 0)
        GUICtrlSetOnEvent(-1, "MinimizeGUItoTray")
    ; now that the gui is created, lets hide it.    
    GUISetState(@SW_HIDE,$frmPanicButton)
EndFunc ;<-- CreateGUI


;minimize the gui to the tray and set options so when the user clicks the icon, it opens the gui back up
Func MinimizeGUItoTray()
    GUISetState(@SW_HIDE)
    TraySetOnEvent($TRAY_EVENT_PRIMARYUP,"OpenGUI")
    TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN,"OpenGUI")
    TraySetState(1) ; show
    TraySetToolTip ("Take a Screen Shot")
EndFunc

; event fired to show the gui, take a screen shot first, then show gui
Func OpenGUI()
    _TakeShot()
    GuiSetState(@SW_Show, $frmPanicButton)
    TraySetState(2) ; hide
    _GetSysInfo()
    
    ; ??? loop while we display the gui ???  <-- need to understand this better
    While 1
        Sleep(100)
    WEnd
EndFunc ;<-- OpenGUI


; take a screen shot of the desktop and save the file
Func _TakeShot()
    Local $hBmp
    ; check to make sure file doesnt exist
    If FileExists(@TempDir & $strFile) Then
        FileDelete(@TempDir & $strFile)
    EndIf
    ; Capture screen
    _ScreenCapture_SetJPGQuality(50)
    
    $hBmp = _ScreenCapture_Capture ("")
    _ScreenCapture_SaveImage (@TempDir & $strFile, $hBmp) ; <-- need to find a better way to compress the image, 500k images seem a bit high
    FileClose($hBmp)
EndFunc ;<-- _TakeShot()

; get some system information to add to the email.
Func _GetSysInfo()
    ; current date/time
    $sysDateTime = _Now()
    ; computer name
    $sysCompName = @ComputerName
    ; ip address
    $sysIP = @IPAddress1
    ; logged on user
    $sysWinUser = @UserName
    ; SSO USR (enviroment variable)
    $sysSSOUSR = EnvGet("SSOUSER")
EndFunc ;<-- _GetSysInfo()

; user clicked cancel button, lets delete the screen shot file and minimize to the tray
Func btnCancelClick()
    If FileExists(@TempDir & $strFile) Then
        FileDelete(@TempDir & $strFile)
    EndIf
    MinimizeGUItoTray()
EndFunc ;<-- btnCancelClick()

; user clicked the preview button, lets show them the screen shot.
Func btnPreviewClick()
    ;open the screen shot
    ShellExecuteWait(@TempDir & $strFile)  ; <-- need to look into a better way to do this, some desktops may not have default image viewer, etc.
EndFunc ;<-- btnPreviewClick()

; validates the required fields are filled in
Func formValidate()
    IF GUICtrlRead($txtSubject) = "" Then
        ; the subject is not empty, so we need to check the description
    ElseIf GUICtrlRead($edtDescription) = "" Then
        Return 0
    Else
        Return 1
    EndIf
    
EndFunc ;<-- formValidate()

; user clicked the send button so grab the system variables and attach the file, then send email off.
Func btnSendClick()
        $FromName = $sysWinUser & " - " & $sysSSOUSR
        $FromAddress = $sysWinUser & "@" & $sysDomain
        $AttachFiles = @TempDir & $strFile
        $Subject = GUICtrlRead($txtSubject)
        $Body = "Description:" & @TAB & GUICtrlRead($edtDescription) & @LF
        $Body = $Body & "Date/Time" & @TAB & $sysDateTime & @LF 
        $Body = $Body & "Computer:" & @TAB & $sysCompName & @LF 
        $Body = $Body & "IP Address:" & @TAB & $sysIP & @LF
        $Body = $Body & "SSO User:" & @TAB & $sysSSOUSR 

    If NOT formValidate() Then
        MsgBox(48,"Error occured","All required fields must be filled in before you can send the screen shot.")
    Else        
        $rc = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)
        If @error Then
            MsgBox(16, "Error sending message", "Error code:" & @error & "  Description:" & $rc)
        Else
            MsgBox(64, "Your message was sent","Your message and screen shot was sent. Thank you!",5)
        EndIf
        FileDelete(@TempDir & $strFile)
        MinimizeGUItoTray()
    EndIf
EndFunc ;<-- btnSendClick()

; if the user clicks the X to close, gui should minimize
Func frmPanicButtonClose()
    If FileExists(@TempDir & $strFile) Then
        FileDelete(@TempDir & $strFile)
    EndIf
    MinimizeGUItoTray()
EndFunc

; send out the screen shot in an email.
Func _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance="Normal", $s_Username = "", $s_Password = "", $IPPort = 25, $ssl = 0)
    Dim $oMyRet[2]
    Local $objEmail = ObjCreate("CDO.Message")
    $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>'
    $objEmail.To = $s_ToAddress
    Local $i_Error = 0
    Local $i_Error_desciption = ""
    If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress
    If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress
    $objEmail.Subject = $s_Subject
    If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then
        $objEmail.HTMLBody = $as_Body
    Else
        $objEmail.Textbody = $as_Body & @CRLF
    EndIf
    If $s_AttachFiles <> "" Then
        Local $S_Files2Attach = StringSplit($s_AttachFiles, ";")
        For $x = 1 To $S_Files2Attach[0]
            $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x])
;~          ConsoleWrite('@@ Debug : $S_Files2Attach[$x] = ' & $S_Files2Attach[$x] & @LF & '>Error code: ' & @error & @LF) ;### Debug Console
            If FileExists($S_Files2Attach[$x]) Then
                ConsoleWrite('+> File attachment added: ' & $S_Files2Attach[$x] & @LF)
                $objEmail.AddAttachment($S_Files2Attach[$x])
            Else
                ConsoleWrite('!> File not found to attach: ' & $S_Files2Attach[$x] & @LF)
                SetError(1)
                Return 0
            EndIf
        Next
    EndIf
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer
    If Number($IPPort) = 0 then $IPPort = 25
    $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort
    ;Authenticated SMTP
    If $s_Username <> "" Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password
    EndIf
    If $ssl Then
        $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
    EndIf
    ;Update settings
    $objEmail.Configuration.Fields.Update
    ; Set Email Importance
    Switch $s_Importance
        Case "High"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "High"
        Case "Normal"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Normal"
        Case "Low"
            $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Low"
    EndSwitch
    $objEmail.Fields.Update
    ; Sent the Message
    $objEmail.Send
    If @error Then
        SetError(2)
        Return $oMyRet[1]
    EndIf
    $objEmail=""
EndFunc   ;==>_INetSmtpMailCom

; Com Error Handler
Func MyErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    $oMyRet[0] = $HexNumber
    $oMyRet[1] = StringStripWS($oMyError.description, 3)
    ConsoleWrite("### COM Error !  Number: " & $HexNumber & "   ScriptLine: " & $oMyError.scriptline & "   Description:" & $oMyRet[1] & @LF)
    SetError(1); something to check for when this function returns
    Return
EndFunc   ;==>MyErrFunc

If anyone can point out why the minimize to tray doesn't work after the first time that would be great.

Also feel free to point out my mistakes, I am almost embarrassed to post my code here since I am sure its not very good or efficient.

Thanks in advanced for your input.

Eric Jensen

Share this post


Link to post
Share on other sites
Spiff59

; ??? loop while we display the gui ???  <-- need to understand this better
    While 1
        Sleep(100)
    WEnd

We all need to understand that one better. It seems to serve no purpose except to lock up your program. Try removing it.

I don't see a point in both of these event definitions:

TraySetOnEvent($TRAY_EVENT_PRIMARYUP,"OpenGUI")
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN,"OpenGUI")

It's going to kick off your program twice per click, I would think the PRIMARYUP event definitions alone would be sufficient.

Edited by Spiff59

Share this post


Link to post
Share on other sites
ericjensen

; ??? loop while we display the gui ???  <-- need to understand this better
    While 1
        Sleep(100)
    WEnd

We all need to understand that one better. It seems to serve no purpose except to lock up your program. Try removing it.

I don't see a point in both of these event definitions:

TraySetOnEvent($TRAY_EVENT_PRIMARYUP,"OpenGUI")
TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN,"OpenGUI")

It's going to kick off your program twice per click, I would think the PRIMARYUP event definitions alone would be sufficient.

Thank you Spiff59. :blink: Removing one of the events and the while loop seems to have fixed things. You rock!

Is there anything else I could do better to make the program more effecient?

thanks again.

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.