Rozszerzenie COM z AutoIt - krótkie wprowadzenie

edytuj

Czym jest COM?

edytuj

COM oznacza "Component Object Model". Jest to droga Microsoft do łączenia oprogramowania przy użyciu wspólnego interfejsu. Interfejsy te są zdefiniowane w obiektach COM.


Obiekty COM

edytuj

W naszych przykładach będziemy mieli do czynienia z obiektami. Czym one są w technologii COM? Otóż, każdy obiekt zawiera w sobie pewne zbiory danych oraz funkcji, które działają na tych danych.

Obiekty COM charakteryzują się tym, że dostęp do danych obiektu realizowany jest wyłącznie poprzez jeden lub kilka zbiorów funkcji powiązanych z obiektem.

Te zbiory funkcji są nazywane interfejsami, a poszczególne funkcje z danego zbioru nazywane są metodami.


Czy konieczne jest używanie obiektów COM w skryptach AutoIt?

edytuj

To po prostu zależy. Autoit ma wiele wbudowanych funkcji oraz ogromną bibliotekę UDF. Można z ich pomocą napisać prawie każdy program. Jednak jeśli potrzebujesz szczególną procedurę z użyciem interfejsów innych aplikacji, za pomocą obiektów COM może zaoszczędzić znaczną ilość linii kodu. Czasami jednak użycie obiektów COM jest nieuniknione jeżeli dane zagadnienie np. format dokumentu lub urządzenie, jest możliwe do obsługi tylko z poziomu dodatkowych bibliotek.

Programista musi mieć świadomość, że istnienie obiektów COM uzależnione jest od systemu operacyjnego i zainstalowanego oprogramowania.

Przykład użycia COM w AutoIt

edytuj

Powiedzmy, że chcesz, zminimalizować wszystkie otwarte okna. Można to zrobić za pomocą zwykłych funkcji AutoIt. Jednak dwie linie kodu z użyciem obiektów COM dadzą ten sam efekt:

$oShell = ObjCreate("shell.application")
$oShell.MinimizeAll()

Przeanalizujmy pokrótce powyższy przykład. W pierwszym wierszu tworzymy nowy obiekt o nazwie "shell.application". To jest wewnętrzny obiekt Windows, zdefiniowany w bibliotece shell32.dll. Wskaźnik do tego nowego obiektu jest przypisany do zmiennej $oShell. $oShell jest od teraz zmienną obiektową.

W drugiej linii, używamy metody o nazwie "MinimizeAll" do obiektu oShell. Pozwoli to zminimalizować wszystkie okna.

Jeżeli metoda nie przyjmuje żadnych parametrów to nawiasy po jej nazwie można pominąć:

$oShell = ObjCreate("shell.application")
$oShell.MinimizeAll

UWAGA: Tak naprawdę AutoIt nie jest językiem obiektowym i nie można w nim utworzyć nowego obiektu. Funkcja ObjCreate nie tworzy obiektu lecz jedynie odnośnik (referencję) do już istniejącego. (np. zawartego w systemie operacyjnym, lub innym zainstalowanym programie). Dzieje się to poprzez pobranie wskaźnika do obiektu.

Oczywiście interfejs obiektu „shell.application” nie zawiera tylko jednej metody:

$oShell = ObjCreate("shell.application")
$oShell.MinimizeAll
sleep(2000)
$oShell.UndoMinimizeAll
sleep(2000)
$oShell.SetTime
sleep(2000)
$oShell.Help
sleep(2000)
$oShell.ShellExecute("notepad.exe")

W ostatnim wierszu użyliśmy metody z parametrem (metoda „ShellExecute” jest dokładnym odpowiednikiem funkcj AutoIt o tej samej nazwie).

Wszystkie wersje Windows mają ogromną ilość wewnętrznych obiektów dla różnych celów. Także aplikacje, takie jak Excel czy Word mają swój własny zestaw obiektów.

Cała trudność polega na uzyskani informacji o interesujących nas obiektach. Musimy znać nazwy obiektów i zawartych w nich metod. Musimy wiedzieć jakie parametry można przekazać do metod i jakie jest ich działanie.

Dla obiektu "shell.application" pomocna może być strona:

Aby uzyskać informacje o wszystkich obiektach aktualnie zainstalowanego w systemie, można użyć programu "OLE / COM Object Viewer". To bardzo pomocne narzędzie zostanie opisane w oddzielnym podrozdziale.

Oto jeszcze jeden przykład. Chcielibyśmy, uzyskać kod źródłowy HTML z pewnej strony internetowej. Można skorzystać z funkcji InetGet(), aby zapisać wynik do pliku i pobrać go ponownie za pomocą FileRead(). Ale poniższe linie kodu zrobią to samo:

$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$oHTTP.Open("GET","http://www.AutoItScript.com")
$oHTTP.Send()
$HTMLSource = $oHTTP.Responsetext

Zmienna $HTMLSource zawiera teraz kompletny kod HTML strony domowej AutoItScript.com.

(Informacje na temat obiektu "winhttp.winhttprequest" można znaleźć na stronie:

Należy pamiętać, że istnienie obiektów zależy od systemu operacyjnego i zainstalowanych w nim programów. Na przykład obiekt winhttp.winhttprequest.5.1 istnieje tylko na komputerach, które mają zainstalowany Internet Explorer co najmniej w wersji 5. Podczas udostępniania skryptów, które wykorzystują obiekty COM, muszą się one znajdować na wszystkich komputerach.

Zmienne obiektowe zachowują się nieco inaczej niż inne rodzaje zmiennych AutoIt. Nie zawierają one realnej wartości, ale wskaźnik do obiektu na zewnętrz skryptu. Nie można na nich wykonywać operacji arytmetycznych, ani stosować operatorów relacji. Przypisanie zmiennej obiektowej innej wartości spowoduje automatycznie zwolnienie obiektu. Można na przykład wymusić usunięcie obiektu przypisując zmiennej obiektowej dowolną liczbę lub tekst.

$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")   ;tworzenie obiektu
$oHTTP=0                                           ;usunięcie obiektu

Nie musimy usuwać ręcznie obiektów. Jeśli skrypt kończy działanie AutoIt uwalnia wszystkie aktywne odwołania do obiektów, które zostały stworzone w skrypcie. To samo dzieje się w momencie wyjścia z funkcji, w której zdefiniowano lokalną zmienną obiektową.

Z użyciem obiektów COM można "zautomatyzować" wiele popularnych programów. Zamiast korzystać z funkcji AutoIt, takich jak Send() lub WinActivate(), można skorzystać z obiektów, które są zdefiniowane w programie i poprzez nie sterować jego działaniem. Metoda te wymaga wiedzy o dostępnych obiektach i sposobie ich wykorzystania. Najczęściej daje jednak lepsze i pewniejsze rezultaty, a kod skryptu jest krótszy i bardziej czytelny.

Oto przykład,jak można "zautomatyzować" Microsoft Excel:

$oExcel = ObjCreate("Excel.Application")                   ;tworzenie obiektu Excel'a
$oExcel.Visible = 1                                        ;wyświetlenie Excel'a
$oExcel.WorkBooks.Add                                      ;dodanie nowego skoroszytu
$oExcel.ActiveWorkBook.ActiveSheet.Cells(1,1).Value="test" ;wypełnienie komórki
sleep(4000)                                                ;wyświetlanie wyniku przez 4 sek.
$oExcel.ActiveWorkBook.Saved = 1                           ;symulacja zapisu skoroszytu
$oExcel.Quit                                               ;wyjście z Excel'a


WITH..ENDWITH

edytuj

Powyższy przykład możemy zapisać z pomocą konstrukcji programowej WITH..ENDWITH. Jest to rodzaj nawiasów określający, że wszystkie wywołane wewnątrz metody odnoszą się do obiektu o nazwie zmiennej obiektowej podanej po WITH:

$oExcel = ObjCreate("Excel.Application")                ;tworzenie obiektu Excel'a
WITH $oExcel 
    .Visible = 1                                        ;wyświetlenie Excel'a
    .WorkBooks.Add                                      ;dodanie nowego skoroszytu
    .ActiveWorkBook.ActiveSheet.Cells(1,1).Value="test" ;wypełnienie komórki
    sleep(4000)                                         ;wyświetlanie wyniku przez 4 sek.
    .ActiveWorkBook.Saved = 1                           ;symulacja zapisu skoroszytu
    .Quit                                               ;wyjście z Excel'a
ENDWITH


Analogiczny skrypt dla Libre Office Calc będzie wyglądał tak:

Dim $aPar[1]
$oSM = ObjCreate("com.sun.star.ServiceManager")
$aPar[0] = $oSM.Bridge_GetStruct("com.sun.star.beans.PropertyValue")
$oDesktop = $oSM.createInstance("com.sun.star.frame.Desktop")
$oCurCom = $oDesktop.loadComponentFromURL( "private:factory/scalc", "_blank", 0, $aPar)

$oCurCom.getSheets.getByIndex(0).getCellByPosition(0,0).String = "test"
Sleep(4000)
$oCurCom.Close(1)


FOR..IN – pętla po kolekcji

edytuj

Kolekcja (kontener) – struktura danych, której zadaniem jest przechowywanie w zorganizowany sposób zbioru danych lub obiektów. Najprostszą kolekcją jest tablica. Działanie pętli FOR..IN dla tablic zostało omówione w rozdziale AutoIt/Instrukcje sterujące.

Kolekcje obiektów

edytuj

Kolekcja obiektów jest obiektem przechowującym wskaźniki do innych obiektów. Tworzą one jednowymiarową tablicę, w której komórkach są wskaźniki do kolejnych obiektów kolekcji. Analogicznie jak dla zwykłej tablicy, można pobierać te wskaźniki z pomocą pętli FOR..IN.

Poniższy przykład dla Arkusza Excel'a pokazuje sposób użycia pętli po elementach kolekcji (kolekcję stanowią komórki z określonego zakresu arkusza):

$oExcel = ObjCreate("Excel.Application") ;tworzenie obiektu Excel'a
$oExcel.Visible = 1                      ;wyświetlenie Excel'a
$oExcel.WorkBooks.Add                    ;dodanie nowego skoroszytu

dim $arr[16][16]                         ;tworzenie tablicy z danymi 
for $i = 0 to 15  
   for $j =  0 to 15 
      $arr[$i][$j] = $i 
   next 
next

;wpisanie wartości z tablicy do komórek arkusza
$oExcel.activesheet.range("A1:O16").value = $arr 

sleep(2000)

;w pętli po kolekcji sprawdzanie wartości
;w poszczególnych komórkach arkusza
;jeżeli wartość < 5 to do komórki wstawiamy 0
For $cell in $oExcel.ActiveSheet.Range("A1:O16")
  If $cell.Value < 5 Then 
    $cell.Value = 0 
  Endif 
Next 

sleep(2000)
$oExcel.ActiveWorkBook.Saved = 1         ;symulacja zapisu skoroszytu
$oExcel.Quit


Zaawansowane użycie COM

edytuj

Opisane dalej sposoby użycia obiektów w AutoIt, wymaga głębokiej znajomości zdarzeń i błędów COM.

Jeśli jesteś nowicjuszem w programowaniu COM, przeczytaj jakąś dobrą dokumentację COM.

Biblią COM jest książka pod tytułem "Inside OLE 2" (Kraig Brockschmidt - Microsoft Press).

Można również znaleźć pewne zasoby COM w Internecie np.:


COM – programowanie zdarzeniowe

edytuj

Normalna automatyzacja COM wykorzystuje głównie jednostronną komunikację. Nasz skrypt żąda jakiejś odpowiedzi lub działania od metody, a metoda realizuje to żądanie.

Jednak obiekt COM w skrypcie może sam zainicjować działanie. Może to być bardzo przydatne w przypadku, gdy trzeba czekać na jakąś akcję związaną z obiektami COM.

Zamiast tworzenia czegoś w rodzaju pętli i odpytywania w niej obiektu czy coś interesującego nas się wydarzyło, możemy pozwolić aby sam obiekt generował komunikaty o zdarzeniach.

W międzyczasie (prawie) jednocześnie skrypt może wykonywać inne operacje. Gdy obiekt COM wygeneruje komunikat o zdarzeniu, w odpowiedzi na niego nasz skrypt podejmie zaprogramowane działanie.

Nie wszystkie obiekty wspierają zdarzenia, aby się o tym dowiedzieć musimy zapoznać się z ich dokumentacją. AutoIt może odbierać od obiektów COM tylko zdarzenia typu 'dispatch'.

Należy znać nazwy zdarzeń, które obiekt potrafi wygenerować oraz ich argumenty (jeśli są). Jeżeli posiadamy wszystkie te informacje, możemy rozpocząć tworzenie skryptu AutoIt, korzystającego ze zdarzeń COM.

Poniższy przykład pokazuje jak odbierać zdarzenia z Internet Explorer'a:

#include "GUIConstantsEx.au3"
$GUIMain=GUICreate( "Test obsługi zdarzeń",600,500 )
$GUIEdit=GUICtrlCreateEdit( "Logi:" & @CRLF, 10, 20, 580, 400)
$GUIProg=GUICtrlCreateProgress (10, 5, 580, 10)
$GUIExit=GUICtrlCreateButton(" Koniec ", 250, 450, 80, 30)
GUISetState()

#include "GUIConstantsEx.au3"
$GUIMain=GUICreate( "Test obsługi zdarzeń",600,500 )
$GUIEdit=GUICtrlCreateEdit( "Logi:" & @CRLF, 10, 20, 580, 400)
$GUIProg=GUICtrlCreateProgress (10, 5, 580, 10)
$GUIExit=GUICtrlCreateButton(" Koniec ", 250, 450, 80, 30)
GUISetState()

$oIE=ObjCreate("InternetExplorer.Application.1")
With $oIE
   .Visible=1
   .Top = (@DesktopHeight-400)/2
   .Height=400 ;wysokość GUI IE
   .Width=600  ;szerokość GUI IE
   .Silent=1 ;nie pokazuj okien dialogowych IE
   $IEWnd=HWnd(.hWnd) ;zapamiętanie uchwytu okna IE
EndWith

;wybieramy interfejs o nazwie 'DWebBrowserEvents'
;AutoIt, być może, nie potrafiłby znaleźć samodzielnie prawidłowego interfejsu
$EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents")
if @error then
   Msgbox(0,"AutoIt COM test", _
   "Nie można użyć interfejsu 'DWebBrowserEvents'. Kod błędu: " & hex(@error,8))
Exit
endif

$URL = "http://www.AutoItScript.com/" ;adres strony do wczytania
$oIE.Navigate( $URL )
sleep(2000) ;czekanie na załadowanie strony

GUISwitch( $GUIMain )

;oczekiwanie na zamknięcie GUI
Do
   $msg=GUIGetMsg()
Until $msg=$GUI_EVENT_CLOSE Or $msg=$GUIExit

$EventObject.Stop ;zakończenie odbierania zdarzeń
$EventObject=0 ;likwidacja obiektu
If WinExists($IEWnd) then $oIE.Quit ;zamknięcie okna IE
$oIE=0 ;likwidacja obiektu

GUIDelete() ;likwidacja GUI

Exit ;koniec skryptu

;funkcje do obsługi zdarzeń

Func IEEvent_BeforeNavigate( $URL, $Flags, $TargetFrameName, $PostData, $Headers, $Cancel )
;Uwaga: deklaracja jest różna od tej w witrynie MSDN (pominęty wskaźnik do interfejsu IDispatch)
   GUICtrlSetData( $GUIEdit, "Do znalezienia: " & $URL & " Flags: " & $Flags & " tgframe: " & _
                             $TargetFrameName & " Postdat: " & $PostData & " Hdrs: " & $Headers & _
                             " canc: " & $Cancel & @CRLF , "append" )
EndFunc

Func IEEvent_ProgressChange( $Progress, $ProgressMax )
   If $ProgressMax > 0 Then
      GUICtrlSetData($GUIProg, ($Progress * 100) / $ProgressMax )
   EndIf
EndFunc

Func IEEvent_StatusTextChange($Text)
   If $Text Then GUICtrlSetData( $GUIEdit, "Opis stanu IE: " & $Text & @CRLF , "append" )
EndFunc

Func IEEvent_PropertyChange( $szProperty)
   GUICtrlSetData( $GUIEdit, "IE zmienił wartość właściwości: " & $szProperty & @CRLF , "append" )
EndFunc

Func IEEvent_DownloadBegin()
   GUICtrlSetData( $GUIEdit, "IE rozpoczął operację nawigacyjną" & @CRLF , "append" )
EndFunc

Func IEEvent_DownloadComplete()
   GUICtrlSetData( $GUIEdit, "IE zakończył operację nawigacyjną" & @CRLF , "append" )
EndFunc

Func IEEvent_NavigateComplete($URL)
;Uwaga: deklaracja jest różna od tej w witrynie MSDN (pominęty wskaźnik do interfejsu IDispatch)
   GUICtrlSetData( $GUIEdit, "IE zakończył ładowanie URL: " & $URL & @CRLF , "append" )
EndFunc

Func IEEvent_($EventName)
;nieobowiązkowa funkcja przechwytywania nieokreślonego zdarzenia, parametr zawiera nazwę zdarzenia
   GUICtrlSetData ( $GUIEdit, "Zdarzenie nieprzechwycone: " & $EventName & @CRLF , "append" )
EndFunc

Pełna lista funkcji zdarzeń IE w dokumentacji MSDN: http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx

Najważniejsza linia w powyższym skrypcie to: $EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents")

Funkcja ObjEvent przyjmuje obiekt $oIE, a następnie przekierowuje przechwycone zdarzenia na funkcje AutoIt, których nazwy zaczynają się IEEvent_.

Trzeci parametr będący nazwa interfejsu, jest opcjonalny. Jest on stosowany, gdy obiekt posiada wiele interfejsów zdarzeń, a nie chcemy aby AutoIt sam wybrał jeden z nich.

Zmienną obiektową $EventObject w zasadzie nie musimy się już zajmować, chyba że chcemy zatrzymać przechwytywanie zdarzeń.

Aby anulować przekierowanie zdarzeń, nie można po prostu usunąć zmiennej obiektowej przypisując jej dowolną wartość, np.: $EventObject = "".

Powodem jest to, że przekierowanie będzie w dalszym ciągu aktywne mimo zlikwidowania samego obiektu.

Można rozwiązać ten problem poprzez zabicie przekierowania zdarzeń za pomocą metody $EventObject.Stop. Następnie możesz (ale nie jest to konieczne) zabić wydarzenie, przypisując mu np. pusty string: $EventObject = "".

Pisząc funkcje przechwytujące zdarzenia musimy pamiętać, że:

- nazwa funkcji po prefiksie musi być zgodna z funkcją przechwytywanego zdarzenia w wybranym interfejsie

- do funkcji przekazujemy tyle parametrów i w takiej kolejności jak dla funkcji w interfejsie. Wyjątek stanowi parametr będący wskaźnikiem do interfejsu Idispatch. Ten należy pominąć.

Potrzebne informacje możemy znaleźć w dokumentacji danego interfejsu, np. dla interfejsu DwebBrowserEvents można skorzystać ze strony:

Przyjrzyjmy się tutaj zdarzeniu BeforeNavigate. Przyjmuje ono 7 parametrów. Pierwszy jest wskaźnikiem do interfejsu Idispatch, więc go pomijamy. Pozostałe 6 musimy umieścić w deklaracji naszej funkcji przechwytującej.

Szkielet tej funkcji musi więc wyglądać następująco:

Func IEEvent_BeforeNavigate($URL, $Flags, $TargetFrameName, $PostData, $Headers, $Cancel)
   ;...
   ;treść funkcji
   ;...
EndFunc

W treści funkcji możemy oczywiście używać wszystkich parametrów, które zdarzenie do niej przekazuje.

Jeśli z jakiegoś powodu nie znamy nazwy zdarzeń, możemy użyć w skrypcie funkcji o nazwie takiej jak sam prefiks, np.: Func IEEvent_ ($Eventname).

Kiedy zostanie przechwycone zdarzenie, dla którego nie stworzono funkcji przechwytującej, to niejako zastępczo zostanie wywołana właśnie ta funkcja, a w zmiennej $Eventname będzie umieszczona nazwa przechwyconego zdarzenia.

Jeżeli nie mamy utworzonych wszystkich funkcji zdarzeń, to nie realizowane będą po prostu ignorowane.


Obsługa błędów obiektów COM

edytuj

Korzystanie z COM bez odpowiedniej obsługi błędów może być bardzo trudne. Skrypt AutoIt natychmiast zatrzymuje wykonywanie, gdy wykryje błąd COM. Jest to ustawienie domyślne, a także najbardziej bezpieczne. W tym przypadku należy tak zmodyfikować skrypt aby błąd nie występował.

Tylko jeśli nie ma sposobu, aby zapobiec powstawaniu błędów COM, można zainstalować ich "przechwytywanie", w których będzie podejmowane działanie jeżeli błąd wystąpi.

Nie jest to oczywiście metoda zapewnienia by skrypt zawsze działał poprawnie. Błędów związanych z kodem samego skryptu, a nie z obiektami COM nie da się przechwycić.

Obsługa błędów jest realizowana w taki sam sposób jak normalne zdarzenie COM, za pomocą ObjEvent() i zdefiniowanej przez użytkownika funkcji obsługi zdarzenia. Jedyną różnicą jest użycie stringu "AutoIt.Error" jako nazwy obiektu.

Przykład:

Global $eventerror = 0  ;wskanik przechwycenia błędu, po użyciu zresetować

$oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ;instalowanie przechwytywania błędów

;specjalnie wywołujemy nieistniejący obiekt
$oIE = ObjCreate("InternetExplorer.Application")
$oIE.visible = 1
$oIE.blebleble      ;tu świadomie błędna nazwa
if $eventerror then Msgbox(0,"","Błąd w poprzednim wierszu.")
$eventerror = 0
;...
;...
;...
Exit

;funkcja obsługi błędów
Func MyErrFunc()
   $eventerror = 1 ;aby można sprawdzić czy funkcja była wywołana
Endfunc

Obiekt AutoIt.Error zawiera kilka użytecznych właściwości i metod:

.number - wartość HRESULT z wywołania COM (nr błędu)

.windescription - FormatWinError() tekst pochodzący z .number

.source - Nazwa obiektu generującego błąd (treść z ExcepInfo.source)

.description - Obiekt źródłowy opisu błędu (treść z ExcepInfo.description)

.helpfile - Obiekt źródłowy plik pomocy do opisu błędu (treść z ExcepInfo.helpfile)

.helpcontext - Obiekt źródłowy nr ID kontekstowego pliku pomocy (z ExcepInfo.helpcontext)

.lastdllerror - Liczba zwracana z GetLastError()

.scriptline - Linia skryptu, w której jest wykryty błąd

Przykład:

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

$oIE = ObjCreate("InternetExplorer.Application")
$oIE.blebleble   ;błędna nazwa metody

Exit

;funkcja obsługi błędów
Func _ErrorFunction()
   Msgbox(0,"","Błąd nr (hex): " & Hex($oMYError.number) & _
                @LF & "W wierszu: " & $oMYError.scriptline)
Endfunc

Uwaga dla programistów:

W skrypcie AutoIt można w prosty sposób sprawdzić czy aktywne jest przechwytywanie błędów. Wystarczy użyć funkcji ObjEvant tylko z parametrem ”Autoit.Error”.

ObjEvant zwraca wtedy nazwę funkcji obsługi błędów lub pusty string, gdy obsługi błędów nie ma. Jest to pokazane w poniższym przykładzie:

$sFuncName = ObjEvent("AutoIt.Error")
if $sFuncName ="" then Msgbox (0,"Test","Obsługa błędów nie jest zainstalowana!")
;...
$oMyError = ObjEvent("AutoIt.Error","_ErrorFunction") ;instalowanie przechwytywania błędów
;...
$sFuncName = ObjEvent("AutoIt.Error")
if $sFuncName <>"" then Msgbox (0,"Test","Zainstalowano funkcję obsługi błędów: " & $sFuncName)
;...
Exit

;funkcja obsługi błędów
Func _ErrorFunction()
   ;...
Endfunc

OLE/COM Object Viewer

edytuj

"OLE/COM Object Viewer" jest bardzo wygodnym narzędziem do przeglądania wszystkich obiektów COM aktualnie zainstalowanych w systemie. Jest częścią Windows 2000 Resource Kit można pobrać za darmo z:

Konfiguracja tego programu jest nieco kłopotliwe. Nie tworzy on ikony na pulpicie, ani w menu start. Zamiast tego, plik o nazwie oleview.exe zostanie zainstalowany w katalogu C:\Program Files\Resource Kit (instalacja domyślna).

Podczas uruchamiania oleview.exe, w niektórych systemach będą zgłaszać brak pliku o nazwie iviewers.dll. Plik ten jest wymagany, ale o dziwo nie jest zawarty w instalce programu.

Trzeba go pobrać oddzielnie z instalką starszej wersji oleview.exe np. ze strony:

Następnie instalujemy tą wersją domyślnie do katalogu C:\MSTOOLS\bin. Potrzebujemy tylko pliku iviewer.dll. Należy skopiować go do katalogu, w którym zainstalowano nową wersję oleview.exe. Następnie katalog C:\MSTOOLS można usunąć.

A teraz przykład korzystania z programu.

Uruchommy Oleviewer i rozwińmy drzewo: Object Classes->Grouped by Component Category->Control->Przeglądarka sieci Web firmy Microsoft.

W lewej kolumnie zobaczysz wszystkie interfejsy COM, które zostały zdefiniowane dla tego obiektu. Pomówimy o tym później.

Przyjrzyjmy się prawej kolumnie. Zawiera wiele informacji potrzebnych do korzystania z tego obiektu w skrypcie AutoIt. Najważniejszy jest "VersionIndependentProgID". Jest to nazwa do wykorzystania w funkcjach ObjCreate, ObjGet oraz ObjEvent.

Ponadto można tu znaleźć nazwę katalogu i pliku zawierającego obiekt. Plik może być typu EXE, DLL lub OCX.

Obiekt musi także zawierać biblioteki typów ("TypeLib ="), inaczej nie może być stosowany w skryptach AutoIt.

Interfejsy w lewej kolumnie są używane przez kilka sposobów interakcji z obiektem. AutoIt do automatyzacji wykorzystuje interfejs IDispatch. Jeśli nie istnieje, nie można użyć obiektu w skrypcie.

Przyjrzyjmy się temu interfejsowi. Klikamy prawym przyciskiem myszy na nazwę IDispatch i wybieramy "Wiev ..." z menu kontekstowego. Następnie klikamy przycisk "Wiev TypeInfo ...".

Uwaga: Jeżeli przycisk ten jest nieaktywny, nie mamy pliku iviewers.dll lub obiekt nie posiada biblioteki typów.

Okno "ITypeInfo Viewer" pokazuje informację, która dostarczone są wraz z obiektem. Jeśli deweloper zdecydował żeby nie dołączać plik pomocy, będą tu widoczne tylko nazwy metody/właściwości i nic więcej.

W "Web Microsoft Browser" biblioteka typów jest jednak dość obszerna. Wystarczy kliknąć element w lewej kolumnie, a opis pojawi się po prawej stronie. Składnia w opisie metod/właściwości jest w stylu C / C++.

Właściwość opisana jako "HRESULT Resizable([in] VARIANT_BOOL pbOffline)", musi być zapisane w AutoIt w postaci:

$Resizable = $Object.Resizable (zmienna $Obiekt zawiera wskażnik do obiektu utworzony przez ObjCreate lub ObjGet).


Opis funkcji związanych z obsługą obiektów COM

edytuj

ObjCreate

edytuj
ObjCreate ( "nazwa_klasy" [, "nazwa_serwera" [,"nazwa_użytkownika", ["hasło"]]] )

Funkcja tworzy referencję do obiektu COM. Zwraca wskaźnik do obiektu lub 0 gdy wystąpił błąd (makro @error przyjmuje wartość 1).

"nazwa_klasy" - nazwa klasy obiektu w formacie "appname.objectype", można też użyć identyfikatorów CLSID.

Pozostałe opcjonalnie:

"nazwa_serwera" - nazwa zdalnego komputera, z którego obiekt musi być uzyskany.

"nazwa_użytkownika" - nazwa użytkownika na komputerze zdalnym, musi być wprowadzona w formacie "nazwa_komputer \ nazwa_użytkownika" lub "domena \ nazwa_użytkownika".

"hasło" - hasło do konta użytkownika na komputerze zdalnym.

UWAGA:

Użyj ObjCreate() jeśli chcesz mieć nową instancję aplikacji. Jeśli chcesz podłączyć się do istniejącego procesu, użyj ObjGet().

Pamiętajm, że nie wszystkie komputery mają ten sam zestaw obiektów. Tak więc zawsze sprawdzaj błędy po wywołaniu ObjCreate().

Poniższe wymogi stosuje się, jeśli chcemy uzyskać dostęp do obiektów na komputerach zdalnych:

- użytkownik uruchamiający skrypt musi posiadać odpowiednie uprawnienia

- obiekt na komputerze zdalnym muszą obsługiwać DCOM (Distributed COM)

- komputer zdalny musi mieć aktywną usługę "Rejestr zdalny" (Remote Registry Service) oraz "Udostępnianie plików i drukarek".


ObjGet

edytuj
ObjGet ( "nazwa_pliku" [, "nazwa_klasy" [, instancja ] ] )

Funkcja tworzy referencję do obiektu COM w aktywnym procesie. Zwraca wskaźnik do obiektu lub 0 gdy wystąpił błąd (makro @error przyjmuje wartość 1).

"nazwa_pliku" - pełna ścieżka i nazwa pliku zawierającego obiekt.

"nazwa_klasy" - nazwa klasy obiektu w formacie "appname.objectype".

instancja - nr wystąpienia (dla obiektów tej samej klasy)

UWAGA:

Nazwa pliku jest opcjonalna, jeśli chcesz używać tylko nazwy klasy, ale parametr nie mogą zostać pominięte. Użyj pustego stringu zamiast nazwy pliku (np.: $Object=ObjGet("","Excel.Application").

Jeśli chcesz użyć nazwy pliku, nazwa klasy jest opcjonalna. Wymagana jest tylko w przypadku wielu klas zdefiniowanych w tym samym pliku, a my chcemy uzyskać dostęp do określonej klasy.

ObjEvent - obsługa zdarzeń

edytuj
ObjEvent ( zmienna_obiektowa, "prefiks" [, "nazwa_interfejsu"] )

Funkcja włącza przechwytywanie zdarzeń pochodzących z danego obiektu COM. Zwraca nazwę obiektu lub metody, albo pusty string "" gdy wystąpił błąd (makro @error przyjmuje wartość 1).

"zmienne_obiektowa" - zmienna zawierająca wskaźnik do obiektu, z którego przechwytywane mają być zdarzenia.

"prefiks" - prefiks nazwy funkcji przechwytującej zdarzenia (prefiks poprzedza w nazwie definiowanej przez użytkownika funkcji nazwę metody, wg schematu "prefiks.nazwa_metody").

"nazwa_interfejsu" - (opcjonalnie) nazwa interfejsu zdarzeń (AutoIt może korzystać tylko z interfejsów typu DISPATCH).


ObjEvent - obsługa błędów

edytuj
ObjEvent ( "AutoIt.Error" [, "nazwa_funkcji"] )

Funkcja włącza przechwytywanie błędów z obiektów COM. Zwraca wskaźnik do obiektu "AutoitError", lub pusty string "" gdy wystąpił błąd (makro @error przyjmuje wartość 1).

"nazwa_funkcji" - (opcjonalnie) nazwa zdefiniowanej przez użytkownika funkcji obsługującej błędy obiektów COM. Jeżeli parametr zostanie pominięty to ObjEvent zwraca nazwę funkcji obsługi błędów lub pusty string gdy funkcja obsługi błędów nie została zdefiniowana.

ObjName

edytuj
ObjName ( zmienna_obiektowa [,flaga] )

Funkcja zwraca nazwę lub opis interfejs obiektu, lub string pusty "" gdy wystąpił błąd (makro @error przyjmuje wartość 1).

zmienna_obiektowa - zmienna obiektowa obiektu, którego nazwę chcesz pobrać.

flaga - (opcjonalnie) rodzaj zwracanej wartości:

1 - nazwa obiektu (domyślnie)
2 - string opisu obiektu
3 - ProgID obiektu
4 - nazwa plik związany w rejestrze
5 - nazwa modułu, w którym działa obiekt
6 - CLSID obiektu
7 - IID interfejsu obiektu

UWAGA: Nie wszystkie obiekty wspierają flagi od 2 do 7. Należy skontrolować @error, aby się o tym przekonać.

Przykład:

$oInternet = ObjCreate("InternetExplorer.Application")

MsgBox(0, "", "Nazwa obiektu		:  " & ObjName($oInternet) & @LF & _
              "Opis obiektu		:  " & ObjName($oInternet, 2) & @LF & _
              "ProgID obiektu		:  " & ObjName($oInternet, 3) & @LF & _
              "Plik związany w rejestrze	:  " & ObjName($oInternet, 4) & @LF & _
              "Nazwa modułu		:  " & ObjName($oInternet, 5) & @LF & _
              "CLSID obiektu		:  " & ObjName($oInternet, 6) & @LF & _
              "IID interfejsu obiektu		:  " & ObjName($oInternet, 7))


GUICtrlCreateObj

edytuj
GUICtrlCreateObj ( zmienna_obiektowa, x, y [, szerokość [, wysokość ]] )

Funkcja tworzy kontrolkę ActiveX w GUI. Zwraca ID kontrolki, lub 0 gdy wystąpił błąd.

Zmienna_obiektowa - nazwa utworzonej wcześniej zmiennej obiektowej.

x i y - położenie wewnątrz okna GUI (w pikselach).

Pozostałe parametry opcjonalne:

szerokość i wysokość - wielkość pola kontrolki (w pikselach).

Funkcja ta próbuje osadzić wewnątrz GUI kontrolki ActiveX lub Document Object. Nie każda kontrolka może być osadzona. Musi ona przynajmniej posiadać interfejs IDispatch.

Document Object będą widoczne tylko wtedy, gdy użyto stylu $WS_CLIPCHILDREN przy tworzeniu okna funkcją GUICreate().

Funkcje GUICtrlRead i GUICtrlSet nie mają wpływu na te kontrolki. Mogą być one sterowane tylko za pomocą metod interfejsu obiektu.

Przykład:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$oIE = ObjCreate("Shell.Explorer.2")

;tworzenie GUI
GUICreate("Test GUICtrlCreateObj()", 800, 600, Default, Default, _
		  BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPCHILDREN))

GUICtrlCreateObj($oIE, 10, 10, 780, 530)
$Back = GUICtrlCreateButton("Cofnij", 10, 560, 100, 30)
$Forward = GUICtrlCreateButton("Do przodu", 120, 560, 100, 30)
$Home = GUICtrlCreateButton("Powrót", 230, 560, 100, 30)
$Stop = GUICtrlCreateButton("Stop", 330, 560, 100, 30)

GUISetState() ;wyświetlenie GUI
$oIE.navigate("http://www.autoitscript.com")

;pętla oczekiwania na użycie lub zamknięcie okna
Do
   $msg = GUIGetMsg()
   Select
      Case $msg = $Home
         $oIE.navigate("http://www.autoitscript.com")
      Case $msg = $Back
         $oIE.GoBack
      Case $msg = $Forward
         $oIE.GoForward
      Case $msg = $Stop
         $oIE.Stop
   EndSelect
Until $msg = $GUI_EVENT_CLOSE


IsObj ( nazwa_zmiennej )

Funkcja sprawdza czy zmienna o podanej nazwie jest zmienną obiektową. Zwraca 1 gdy tak, 0 gdy nie.

Przykład:

$var1 = ObjCreate("shell.application")
$var2 = ""

MsgBox(0, "Test zmiennej $var1", kom($var1))
MsgBox(0, "Test zmiennej $var2", kom($var2))

Func kom($var)
   If IsObj($var) Then
      Return "To jest zmienna obiektowa"
   Else
      Return "To nie jest zmienna obiektowa"
   EndIf
EndFunc


VarGetType

edytuj
VarGetType ( nazwa_zmiennej )

Funkcja zwraca string z typem zmiennej o podanej nazwie.

Jeżeli zminna jest zmienną obiektową to zwracany jest string "Object".

Dla pozostałych typów - patrz opis w rozdziale: AutoIt/Zmienne w AutoIt.

Przykład:

$var1 = ObjCreate("shell.application")
$var2 = ""

MsgBox(0, "Test zmiennej $var1", "Zmienna jest typu:  " & VarGetType($var1))
MsgBox(0, "Test zmiennej $var2", "Zmienna jest typu:  " & VarGetType($var2))