Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   СОМ-интерфейс на AutoIt-е (http://forum.oszone.net/showthread.php?t=147134)

abb269 05-08-2009 10:29 1186020

СОМ-интерфейс на AutoIt-е
 
Здравствуйте,
Подскажите, пожалуйста, в каком направлении смотреть.
Нужно реализовать на AutoIt-е СОМ-интерфейс, который на VBA выглядит примерно так
Код:

' Обработка событий
Public WithEvents stClient As StServer

Private Sub Class_Initialize()
If stClient Is Nothing Then
    Set stClient = New StServer
    If Err.Number <> 0 Then MsgBox ("Error " & Err.Description)
    If stClient Is Nothing Then
      MsgBox ("Невозможно установить соединение")
    Else
      'MsgBox ("Соединение установлено")
    End If
End If
End Sub

Private Sub Class_Terminate()
If stClient Is Nothing Then
    MsgBox ("Соединение уже разорвано")
Else
    Set stClient = Nothing
    'MsgBox ("Соединение разорвано")
End If
End Sub

Private Sub stClient_Connected()
  ' обработка события 
  бла-бла-бла
End Sub

Private Sub stClient_Disconnected(ByVal reason As String)
  ' обработка события 
  бла-бла-бла
End Sub


'Методы
Private stSrv As StServerTest
Sub КнопкаСтарт_Щелчок()
' ---------------- установка соединения
If stSrv Is Nothing Then
    Set stSrv = New StServerTest
    If Not stSrv.stClient.IsConnected() Then MsgBox ("Убедитесь что установлено соединение с сервером")
  Else
    MsgBox ("Соединение уже установлено")
End If                      ' конец установки соединения

Call stSrv.stClient.Test(...)
...
end sub

Заранее спасибо за квалифицированный ответ.

amel27 05-08-2009 12:28 1186123

Цитата:

Цитата abb269
Нужно реализовать на AutoIt-е СОМ-интерфейс »

В такой формулировке задача нерешаема, т.к. AutoIt - процедурный язык, а не объектный... максимум, что можно сделать - реализовать часть методов на AutoIT через вызов внешнего AutoIT-скрипта с параметрами.

В чем, собственно, проблема? Описание размыто и непонятно, описание некоторых типов вообще пропущено.

abb269 05-08-2009 12:56 1186147

Спасибо за ответ.
А проблема вот в чем. Есть биржевой терминал с СОМ-интерфейсом, я подключаюсь к нему через экселевский VBA (из которого и взял фрагменты кода интерфейса). И за этой связкой (терминал-Эксель) присматривает супервизор, который я написал на AutoIt. Немного продвинувшись в среду AutoIt-а, я решил в своей конструкции выкинуть вообще эксель. С переносом вычислений особых проблем не возникло, а вот как перекинуть коннект?
Получается, что ни как. Жаль.
Еще раз спасибо.

amel27 05-08-2009 13:10 1186159

abb269, подключиться к существующему COM-серверу без проблем, нельзя определить свои COM-объекты... приведите полный код VBA-модулей, иначе не ясно, где ссылка на VBA-компоненты, а где на терминальные... и желательно: уже реализованную часть на AutoIT + описание интерфейсов терминала. Без полной картины нельзя дать однозначного ответа.

abb269 05-08-2009 15:14 1186266

Не могу не сказать еще раз спасибо.
Вот структура VBA-код модуля сервера (тип Class Modules, имя StserverTest)
Код:

Public WithEvents stClient As StServer

Private Sub Class_Initialize()
If stClient Is Nothing Then
    Set stClient = New StServer
    If Err.Number <> 0 Then MsgBox ("Error " & Err.Description)
    If stClient Is Nothing Then
      MsgBox ("Невозможно установить соединение")
    Else
      'MsgBox ("Соединение установлено")
    End If
End If
End Sub

Private Sub Class_Terminate()
If stClient Is Nothing Then
    MsgBox ("Соединение уже разорвано")
Else
    Set stClient = Nothing
    'MsgBox ("Соединение разорвано")
End If
End Sub

Private Sub stClient_Connected()
Range("connection_status_time").Value = Now
Range("connection_status").Value = "соединен"
End Sub

Private Sub stClient_Disconnected(ByVal reason As String)
Range("connection_status_time").Value = Now
Range("connection_status").Value = "НЕТ СОЕДИНЕНИЯ : " & reason
End Sub

Private Sub stClient_OrderFailed(ByVal cookie As Long, ByVal reason As String)
Range("order_status_time").Value = Now
Range("order_status").Value = 1        ' ОШИБКА ОТПРАВКИ приказа на сервер
Range("order_status_note").Value = reason & " * " & cookie
End Sub

Private Sub stClient_OrderSucceeded(ByVal cookie As Long)
Range("order_status_time").Value = Now
Range("order_status").Value = 0        ' успех отправки приказа на сервер
Range("order_status_note").Value = cookie
End Sub

Private Sub stClient_SetPortfolio( _
    ByVal portfolio As String, _
    ByVal cash As Double, _
    ByVal leverage As Double, _
    ByVal comission As Double, _
    ByVal saldo As Double)

Range("a_portfolio").Value = PortfolioArray
Range("set_portfolio_time") = Now

End Sub

Private Sub stClient_UpdateOrder( _
    ByVal portfolio As String, _
    ByVal symbol As String, _
    ByVal state As Long, _
    ByVal action As Long, _
    ByVal otype As Long, _
    ByVal validity As Long, _
    ByVal price As Double, _
    ByVal amount As Double, _
    ByVal stopp As Double, _
    ByVal filled As Double, _
    ByVal datetime As Date, _
    ByVal orderid As String, _
    ByVal orderno As String)
 
...
End Sub

Private Sub stClient_UpdatePosition( _
    ByVal portfolio As String, _
    ByVal symbol As String, _
    ByVal avprice As Double, _
    ByVal amount As Double, _
    ByVal planned As Double)
   
...
End Sub

Private Sub stClient_UpdateQuote( _
    ByVal symbol As String, _
    ByVal datetime As Date, _
    ByVal opn As Double, _
    ByVal high As Double, _
    ByVal low As Double, _
    ByVal closse As Double, _
    ByVal last As Double, _
    ByVal volume As Double, _
    ByVal size As Double, _
    ByVal bid As Double, _
    ByVal ask As Double, _
    ByVal bidsize As Double, _
    ByVal asksize As Double, _
    ByVal open_int As Double, _
    ByVal go_buy As Double, _
    ByVal go_sell As Double, _
    ByVal go_base As Double, _
    ByVal go_base_backed As Double)
 
...
End Sub

Private Sub stClient_AddBar( _
    ByVal symbol As String, _
    ByVal interval As Long, _
    ByVal datetime As Date, _
    ByVal opn As Double, _
    ByVal high As Double, _
    ByVal low As Double, _
    ByVal closse As Double, _
    ByVal volume As Double)

...   
End Sub

А в клиентской части (не знаю, верно ли использую это название), т.е. там где вызываются методы, вот такой код (тип Modules, имя abb)

Код:


Private stSrv As StServerTest

Sub RunConnect()
If stSrv Is Nothing Then
    Set stSrv = New StServerTest
    If Not stSrv.stClient.IsConnected() Then
      MsgBox ("Убедитесь что установлено соединение с сервером")
    End If
  Else
    MsgBox ("Соединение уже установлено")
End If
End Sub

Sub PlaceOrder()
  If stSrv Is Nothing Then
    MsgBox ("Соединение не установлено!")
  Else
    Response = MsgBox("Выставить приказ?", vbYesNo)
    If Response = vbYes Then
      Call stSrv.stClient.PlaceOrder( _
        Range("portfolio").Value, _
        Range("quote_ticker").Value, _
        Range("o_action_new").Value, _
        Range("o_type_new").Value, _
        Range("o_validity_new").Value, _
        Range("o_price_new").Value, _
        Range("o_amount_new").Value, _
        0, _
        0)
    End If
  End If
End Sub

и т.д.

Общая структура интерфейса такая

МЕТОД --> СОБЫТИЯ, вызываемые методом
ListenQuotes (1 параметр)/CancelQuotes (1 параметр) --> UpdateQuote (18 параметров)
ListenBidAsks (1 параметр)/CancelBidAsks (1 параметр) --> UpdateBidAsk (7 параметров)
ListenTicks (1 параметр)/CancelTicks (1 параметр) --> AddTick (4 параметра)
GetBars (4 параметра) --> AddBar (8 параметров)
ListenPortfolio (1 параметр)/CancelPortfolio (1 параметр) --> SetPortfolio (5 параметров);UpdateOrder (13 параметров);AddTrade (6 параметров);UpdatePosition (5 параметров)
PlaceOrder (9 параметров) --> OrderSucceeded (1 параметр);OrderFailed (2 параметра)
CancelOrder (3 параметра) --> -
GetSymbols() --> AddSymbol (10 параметров)
- --> Connected ()
- --> Disconnected (1 параметр)
IsConnected () -->??? True/False

А про код на AutoIt-е можно сказать, что он смысловой нагрузки не несет. Он просто входит в биржевой терминал (вводит имя и пароль), вводит в Эксель начальные установки (типа тикера, размера позиции и т.д), периодически читает данные в Экселе и посылает отчет в виде е-мейла.
Да забыл сказать, что все это что-то типа торгового робота.

amel27 06-08-2009 13:21 1187094

Цитата:

Цитата abb269
не знаю, верно ли использую это название »

Перенос программы с объектного языка на процедурный нетривиальная задача и без понимания всех деталей работы исходной программы лучше за нее не браться... Хотя ИМХО весь код, который не связан с обработкой асинхронных событий (т.е. вызванных внешними источниками - пользователем, сторонними процессами и т.п.) вполне можно вынести за пределы Excel на любую удобную платформу, но это лучше делать постепенно - заменяя события и прочие объектные фичи на прямой вызов методов (aka функций), чтобы не нарушать функциональность... Короче, нужно хорошо взвесить все ЗА и ПРОТИВ прежде чем браться за подобное мероприятие.

abb269 06-08-2009 22:06 1187574

2amel27
А можно чуть конкретнее?
Как написать свой обработчик какого-нибудь события на AutoIt? как его объявить?
Или лучше за это на AutoIt-e не браться, а просто оставить интерфейс на Экселе и вызывать экселевские макросы из AutoIt-а?..
На этот раз - извините.

amel27 07-08-2009 09:25 1187869

Цитата:

Цитата abb269
Как написать свой обработчик какого-нибудь события на AutoIt? »

хороший вопрос, вообще-то для этого есть ObjEvent(), но если для MS Word этот метод работает, то для MS Excel почему-то нет... :idontnow: на форуме оффсайта вопрос поднимался, но ответа никто так и не дал: Failing to hook Excel events. Error on ObjEvent() call with Excel, but not with Word... собственно, пример для WORD:
Код:

$oWord = ObjCreate("Word.Application")
$oWord.Visible = 1
$oWord.Activate ()
$hwnd = WinGetHandle("[ACTIVE]")

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

$oWord.Documents.Add ()
$oWord.Documents.Add ()
$oWord.ActiveDocument.Close ()

While WinExists($hwnd)
    Sleep(50)
WEnd

Func
Evt_DocumentBeforeClose()
    ConsoleWrite("Captured Mesage: DocumentBeforeClose" &@CRLF)
EndFunc

Func
Evt_NewDocument()
    ConsoleWrite("Captured Mesage: NewDocument" &@CRLF)
EndFunc

Func
Evt_Quit()
    ConsoleWrite("Captured Mesage: Quit" &@CRLF)
EndFunc

Func
MyErrFunc()
Dim $msgTxt
    $msgTxt
= "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

                Msgbox(0,"AutoItCOM Test", $msgTxt)
    ConsoleWrite($msgTxt & @LF)

    Local $err = $oMyError.number
    If $err = 0 Then $err = -1

    $g_eventerror = $err ; to check for after this function returns
Endfunc



Время: 05:25.

Время: 05:25.
© OSzone.net 2001-