Jump to content

Recommended Posts

Posted

How do I handle gracefully a situation where an AutoIt COM object being closed unexpectedly thru the object's GUI.

I am using Excel at the moment.

TIA

myids

Posted

From the help file

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")

Func MyErrFunc()

  Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !"      & @CRLF  & @CRLF & _
             "err.description is: "    & @TAB & $oMyError.description    & @CRLF & _
             "err.windescription:"     & @TAB & $oMyError.windescription & @CRLF & _
             "err.number is: "         & @TAB & hex($oMyError.number,8)  & @CRLF & _
             "err.lastdllerror is: "   & @TAB & $oMyError.lastdllerror   & @CRLF & _
             "err.scriptline is: "     & @TAB & $oMyError.scriptline     & @CRLF & _
             "err.source is: "         & @TAB & $oMyError.source         & @CRLF & _
             "err.helpfile is: "       & @TAB & $oMyError.helpfile       & @CRLF & _
             "err.helpcontext is: "    & @TAB & $oMyError.helpcontext _
            )
Endfunc
Posted

Thanks very much for the reply.

This COM/Object stuff baffles me most of the time. I have more questions.

This isn't as importmant for me to know, but It looks like the custom error handler is executed in @error?

I am having some trouble implementing. Here's some of the code:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=..\..\..\..\..\..\Program Files (x86)\AutoIt3\Icons\ids_nl.ico
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstants.au3>
#include <GuiListView.au3>
#include <Excel.au3>
#include <Array.au3>
#Include <Constants.au3>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Define vars and capture values of PwrPCB object
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Global $Selected = 0
$powerPCBApp = ObjGet("", "PowerPCB.Application")
$powerPCBDoc = $powerPCBApp.ActiveDocument
$mcount = $powerPCBDoc.GetObjects(1).Count
$netcount = $powerPCBApp.Activedocument.Nets.Count
Dim $ListNets[$netcount]
Dim $cell_netlength, $cell_net, $mynet
Dim $NetProperties[2][$netcount]

Global $pcbname = $powerPCBApp.Activedocument.Name
Global $pcbpath = $powerPCBApp.Activedocument.Path
Global $pcbfullname = $powerPCBApp.Activedocument.FullName
Global $pcbssname = StringLeft($pcbname, StringLen($pcbname) - 4) & ".xls"
Global $ssisopen = ""
Global $ssfile = ""
Global $oExcel = ""
Global $oExcelIdent = ""
Global $g_eventerror = 0    ; to be checked to know if com error occurs. Must be reset after handling.
$oMyError = ""
$err = ""

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Setup the tray Icon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Opt("TrayMenuMode",1)   ; Default tray menu items (Script Paused/Exit) will not be shown.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Menu For tray Icon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$OpenSSItem  = TrayCreateItem("Open SpreadSheet")
TrayCreateItem("")
$RunItem  = TrayCreateItem("Run Length Check")
TrayCreateItem("")
$SaveSSItem  = TrayCreateItem("Save SpreadSheet")
TrayCreateItem("")
$CloseSSItem  = TrayCreateItem("Close Spreadsheet")
TrayCreateItem("")
$aboutitem  = TrayCreateItem("About")
TrayCreateItem("")
$exititem   = TrayCreateItem("Exit")
TraySetState()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Menu For tray Icon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Loop though events/Menu options in tray icon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
While 1
    $msg = TrayGetMsg()

            $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")    ; Initialize a COM error handler
            If $g_eventerror then
                $g_eventerror = 0
                Msgbox (0,"AutoItCOM test","Test passed: We got an error number: " & @error)
                Exit
            Else
                Msgbox (0,"AutoItCOM test","Test failed!")



    Select
        Case $msg = 0
            ContinueLoop
        Case $msg = $RunItem
            TrayItemSetState($RunItem, $TRAY_CHECKED)
            GetNetLengths()


        Case $msg = $CloseSSItem
            TrayItemSetState($CloseSSItem, $TRAY_CHECKED)
            CloseSS()
        Case $msg = $SaveSSItem
            TrayItemSetState($SaveSSItem, $TRAY_CHECKED)
            SaveSS()
        Case $msg = $OpenSSItem
            TrayItemSetState($OpenSSItem, $TRAY_CHECKED)
            OpenSS()
        Case $msg = $aboutitem
            TrayItemSetState($aboutitem, $TRAY_CHECKED)
            Msgbox(64, "about:", "Interactive Design Solutions")
        Case $msg = $exititem
            ExitLoop
    EndSelect

    Endif ; branch of COM error testing

WEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Loop though events/Menu options in tray icon
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Func MenuForTrayIcon()
;EndFunc

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function: GetNetLengths
; retrieves all nets in pcb db in 2d array
; reads spreadsheet net columns and retrieves each nets routed lengths
; writes the routed length to the spreadsheet
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func GetNetLengths()



    ;GUICreate($powerPCBApp.Activedocument.Name, 400, 200)
    ;GUISetIcon(@SystemDir & "\mspaint.exe", 0)
    ;GUISetState()
    $Index = 0
    For $nextNet In $powerPCBApp.Activedocument.Nets
        $NetProperties[0][$Index] = $nextNet.Name
        $NetProperties[1][$Index] = $nextNet.Length
        $cindex = $Index + 1
        ;GuiCtrlCreateListViewItem($nextNet.Name, $listView)
        ;_GUICtrlListView_AddItem ($ListView, $nextNet.Name)
        ;_ExcelWriteCell($oExcel, $nextNet.Name, $cindex, 1)
        ;_ExcelWriteCell($oExcel, RoutedNetLength ($nextNet.Name), $cindex, 2)
        $Index = $Index + 1
    Next
    ;_ArrayDisplay($NetProperties, "Net Properties", -1, 1)

    ;If $oExcel.ActiveSheet.Name Then
    ;   $Index = 0
    ;   For $i = 1 To 200 ;Loop
    ;       $cindex = $Index + 1
    ;       _ExcelWriteCell($oExcel, "0", $cindex, 2)
    ;       $Index = $Index + 1
    ;   Next
    ;EndIf

    $oMyError = ObjEvent("AutoIt.Error","MyErrFunc")
    If $g_eventerror then
    $g_eventerror = 0
        Msgbox (0,"AutoItCOM test","Test passed: We got an error number: " & @error)
    Else
        Msgbox (0,"AutoItCOM test","Test failed!")
    Endif


    If IsObj($oExcel) Then
        $Index = 0
        For $i = 1 To 200 ;Loop
            $cindex = $Index + 1
            $sCellValue = _ExcelReadCell($oExcel, $i, 1)
            $cell_net = StringStripWS($sCellValue, 3)
            If $cell_net = "Netname" Then
                $cell_net = ""
            EndIf
            ;ConsoleWrite( $cell_net & @CRLF)
            ;MsgBox(0, "", "cell_net is: " & @CRLF & $cell_net, 2)
            If StringLen($cell_net) Then
                $nlgth = FindNetinArray($cell_net)
                _ExcelWriteCell($oExcel, $nlgth, $i, 2)
            EndIf
            $Index = $Index + 1
        Next
    Else
        $oExcel = ""
        MsgBox(0, "SpreadSheet Was Not Open", "SpreadSheet Was Not Open" & @CRLF & "Open Spreadsheet, to Run a Length Check")
        ;OpenSS()
    EndIf
EndFunc

That should be all the relevant code. This version will always result in the "Test Failed" branch. Kind of obvious I guess. But I've tried embedded in getlength() and in the $RunItem CASE.

I don't understand enough for the mechanics of this. I could probably try for hours and days and finally get the code working, but I still don't know that I'll understand.

I can post the complete script if needed -- It doesn't seem to be relevent. NOTE: chances you can't run the whole script because of the other object being called?

hmmmm....does the other object I have open interfere? I don't think so because I can run the example from help file successfully.

Thanks very much for any tips on how to code this.

myids

Posted

That was a big help. Thanks.

I am not sure where I need to reset $g_eventerror to 0, if that is the correct thing to do, after a COM error is intercepted.

I am using:

If NOT $g_eventerror Then

to run code if no $g_eventerror.

TIA,

myids

Posted

This is another symptom if the Excel object was closed.

C:\Program Files (x86)\AutoIt3\Include\Excel.au3 (694) : ==> Missing right bracket ')' in expression.:

Return $oExcel.Activesheet.Cells($sRangeOrRow, $iColumn).Value

Return ^ ERROR

I think this is due to it being a second object, but not sure. Do I possibly need to setup a different flag or two?

Or

Is there a way to differentiate between objects for error handling?

TIA

myids

Posted

Richard,

Thanks very much. You know more than I do. You helped me through to a better scenario and something that is workable.

Maybe someone else can chime in with more insight.

myids

Posted

Well, I have a resolution although not so elegant and I'm not sure I understand it -- but, the code is behaving like I want it to so far. Luckily, this script isn't huge.

If NOT $g_eventerror then
   ;call/use the object/function here since there is no COM/Object error
Else
   ;reset/re-initialize the flag 
   $g_eventerror = 0
EndIf

Summary:

After getting the error handler working for a non-existent object, where previously the script would crash, multiple calls to multiple objects still crashed the script despite the error handler. My current solution is to use the above If/Else for EVERY single object usage and re-initialize the error handler flag so the next potential object error could be captured and messaged. I probably could have had the program EXIT once the COM error was intercepted, but, that isn't the behavior I was after. So, even though my solution is a bit of a hassle, it's the only thing that makes to me because The documentation advise on the error handler is that a reset is needed after every intercepted error.

Thanks for the help I received on this. If anyone has more thoughts and ideas for elegance, I'd love to read it.

myids

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...