MQL5でのAutoItの使用
はじめに
DLLを経由したメタトレーダーターミナルの管理稿では、著者は、カスタムメイドのダイナミックリンクライブラリ(dll)を使用してアプリケーションのグラフィカルユーザーインターフェイス(gui)をプログラムで制御することによってMetatrader 4を管理する方法について詳しく説明しています。この記事では類似するものを検討しますが、カスタムdllを作成する代わりにAutoItが提供する機能を活用します。AutoItを使用して、MQL5だけでは実行できないタスクの自動化を可能にするクラスを作成します。
これらのタスクは次のとおりです。
- スクリプトまたはエキスパートアドバイザーをチャートに追加および削除する機能
- ツールボックスウィンドウでのターミナルの[エキスパート]および[操作ログ]タブからの読み取り
- アラートを自動的に処理する機能(アラートメッセージの読み取りとアラートダイアログの自動終了)
- 最後に、MetaTrader 4の記事で示したのと同じ機能、つまりターミナル設定でMetaQuotes IDを設定する機能を実装します。
AutoIt
AutoItは、Microsoft Windowsのグラフィカルユーザーインターフェイスを自動化するためのスクリプト言語です。ウィンドウ管理、ユーザーインターフェイスコンポーネントへの直接アクセス、およびマウスとキーボードの両方のストロークの入力シミュレーションなどの機能が提供されます。AutoItの一部はAutoItXです。これは、AutoItスクリプト言語の機能の一部を実装するdllです。このdllとインターフェイスすることで、MQL5に同様のGUIスクリプト機能が得られます。
インストール
AutoItソフトウェアは、こちらのリンクから無料で入手できます。AutoItはWindows10までのすべてのx86バージョンのMicrosoft Windowsで機能し、AutoItXの64ビットバージョンを含むさまざまな64ビットコンポーネントに同梱されている32ビットアプリケーションです。AutoItの詳細を知りたい場合、アプリケーションのインストールの一部であるヘルプファイルを読むことが不可欠です。先に進む前に、AutoItの制限事項を知っておく必要があります。
制限事項
AutoItには、Win32APIによって提供される標準のMicrosoft Windowsコンポーネントでのみ確実に動作できるという制限があります。プログラムがカスタムメイドのコンポーネントを使用している場合、AutoItは機能しません。これは主に、クロスプラットフォームフレームワークを使用して作成されたソフトウェアに当てはまります。プログラムのユーザーインターフェイスがAutoItと互換性があるかどうかはAutoItウィンドウ情報ツールを使用して確認できます。知っておくべきもう1つの制限は、AutoItXがAutoItスクリプト言語の機能の一部のみを実装することによってもたらされます。コンポーネントはAutoItで動作してもAutoItXでは同じ機能を利用できない場合があります。
AutoItウィンドウ情報ツール
AutoItには、アプリケーションウィンドウに関する情報を取得するために使用されるAutoItウィンドウ情報ツールと呼ばれるアプリケーションが付属しています。
Finderツールをターゲットアプリケーションの任意の部分にドラッグすることで、特定のコンポーネントのプロパティを取得できます。これらのコンポーネントは、コントロールと呼ばれます。コントロールの例は、ボタン、ドロップダウンメニュー、タブですが、これらはほんの一例であり、アプリケーションの構築には多くの種類のコントロールが使用されています。各コントロールはウィンドウに関連付けられています。アプリケーションは、複数のウィンドウで構成されている場合があります。通常、メインウィンドウがあり、その上に他の子ウィンドウが接続またはドッキングされます。子ウィンドウがメインアプリケーションウィンドウに接続またはドッキングされている場合、それらの子ウィンドウで囲まれているすべてのコントロールがメインアプリケーションウィンドウの一部になります。AutoItを使用してコントロールを正確に見つける場合、子ウィンドウであろうとメインアプリケーションウィンドウであろうと、コントロールが関連付けられているウィンドウは重要です。
下の図を見ると、FinderツールがMetatrader 5アプリケーションのさまざまな領域にドラッグされていることがわかります。[オプション]メニューが選択されている場合は、ウィンドウ情報ツールの設定に注意してください。[フリーズ]、[常に最前面]、[Spy++コントロール検出ロジックの使用]オプションがオンになっています。
[ウィンドウ]タブには、フォーカスされているアプリケーションウィンドウのプロパティが表示されます。ここには、ウィンドウのタイトルとクラスが一覧表示されます。これらのプロパティを使用して、一意に識別できます。[コントロール]タブに移動すると、コントロールのプロパティが表示されます。ここで重要なのは、ClassnameNNプロパティです(AutoItコンテキストのクラス名はコントロールのタイプを参照しています)。このプロパティは、コントロールタイプとインスタンス識別子を数値の形式で組み合わせます。コントロールのタイプを知ることは、AutoIt関数呼び出しがそれに対して機能するかどうかを決定するので不可欠です。
AutoItX統合
MetaTrader 5との統合を成功させるには、ターミナルが実行時に必要なdllを見つけられるようにする必要があります。これを実現するには、必要なdllをMetaTrader5インストールのLibrariesフォルダにコピーするだけです。デフォルトのAutoIt3インストールディレクトリは、プログラムファイル(x86)フォルダにあります。その中のAutoItXフォルダには、dllで公開されているすべての関数プロトタイプを一覧表示するAutoItX3_Dllヘッダーを含む、すべてのAutoItX関連コンポーネントが含まれています。MetaTrader 5(64または32ビット)のビルドに適したdllを入手することが重要です。
#pragma once /////////////////////////////////////////////////////////////////////////////// // // AutoItX v3 // // Copyright (C)1999-2013: // - Jonathan Bennett <jon at autoitscript dot com> // - See "AUTHORS.txt" for contributors. // // This file is part of AutoItX. Use of this file and the AutoItX DLL is subject // to the terms of the AutoItX license details of which can be found in the helpfile. // // When using the AutoItX3.dll as a standard DLL this file contains the definitions, // and function declarations required to use the DLL and AutoItX3_DLL.lib file. // /////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus #define AU3_API extern "C" #else #define AU3_API #endif // Definitions #define AU3_INTDEFAULT (-2147483647) // "Default" value for _some_ int parameters (largest negative number) // // nBufSize // When used for specifying the size of a resulting string buffer this is the number of CHARACTERS // in that buffer, including the null terminator. For example: // // WCHAR szBuffer[10]; // AU3_ClipGet(szBuffer, 10); // // The resulting string will be truncated at 9 characters with the the terminating null in the 10th. // /////////////////////////////////////////////////////////////////////////////// // Exported functions /////////////////////////////////////////////////////////////////////////////// #include <windows.h> AU3_API void WINAPI AU3_Init(void); AU3_API int AU3_error(void); AU3_API int WINAPI AU3_AutoItSetOption(LPCWSTR szOption, int nValue); AU3_API void WINAPI AU3_ClipGet(LPWSTR szClip, int nBufSize); AU3_API void WINAPI AU3_ClipPut(LPCWSTR szClip); AU3_API int WINAPI AU3_ControlClick(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPCWSTR szButton, int nNumClicks, int nX = AU3_INTDEFAULT, int nY = AU3_INTDEFAULT); AU3_API int WINAPI AU3_ControlClickByHandle(HWND hWnd, HWND hCtrl, LPCWSTR szButton, int nNumClicks, int nX = AU3_INTDEFAULT, int nY = AU3_INTDEFAULT); AU3_API void WINAPI AU3_ControlCommand(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPCWSTR szCommand, LPCWSTR szExtra, LPWSTR szResult, int nBufSize); AU3_API void WINAPI AU3_ControlCommandByHandle(HWND hWnd, HWND hCtrl, LPCWSTR szCommand, LPCWSTR szExtra, LPWSTR szResult, int nBufSize); AU3_API void WINAPI AU3_ControlListView(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPCWSTR szCommand, LPCWSTR szExtra1, LPCWSTR szExtra2, LPWSTR szResult, int nBufSize); AU3_API void WINAPI AU3_ControlListViewByHandle(HWND hWnd, HWND hCtrl, LPCWSTR szCommand, LPCWSTR szExtra1, LPCWSTR szExtra2, LPWSTR szResult, int nBufSize); AU3_API int WINAPI AU3_ControlDisable(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl); AU3_API int WINAPI AU3_ControlDisableByHandle(HWND hWnd, HWND hCtrl); AU3_API int WINAPI AU3_ControlEnable(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl); AU3_API int WINAPI AU3_ControlEnableByHandle(HWND hWnd, HWND hCtrl); AU3_API int WINAPI AU3_ControlFocus(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl); AU3_API int WINAPI AU3_ControlFocusByHandle(HWND hWnd, HWND hCtrl); AU3_API void WINAPI AU3_ControlGetFocus(LPCWSTR szTitle, LPCWSTR szText, LPWSTR szControlWithFocus, int nBufSize); AU3_API void WINAPI AU3_ControlGetFocusByHandle(HWND hWnd, LPWSTR szControlWithFocus, int nBufSize); AU3_API HWND WINAPI AU3_ControlGetHandle(HWND hWnd, LPCWSTR szControl); AU3_API void WINAPI AU3_ControlGetHandleAsText(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPCWSTR szControl, LPWSTR szRetText, int nBufSize); AU3_API int WINAPI AU3_ControlGetPos(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPRECT lpRect); AU3_API int WINAPI AU3_ControlGetPosByHandle(HWND hWnd, HWND hCtrl, LPRECT lpRect); AU3_API void WINAPI AU3_ControlGetText(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPWSTR szControlText, int nBufSize); AU3_API void WINAPI AU3_ControlGetTextByHandle(HWND hWnd, HWND hCtrl, LPWSTR szControlText, int nBufSize); AU3_API int WINAPI AU3_ControlHide(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl); AU3_API int WINAPI AU3_ControlHideByHandle(HWND hWnd, HWND hCtrl); AU3_API int WINAPI AU3_ControlMove(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, int nX, int nY, int nWidth = -1, int nHeight = -1); AU3_API int WINAPI AU3_ControlMoveByHandle(HWND hWnd, HWND hCtrl, int nX, int nY, int nWidth = -1, int nHeight = -1); AU3_API int WINAPI AU3_ControlSend(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPCWSTR szSendText, int nMode = 0); AU3_API int WINAPI AU3_ControlSendByHandle(HWND hWnd, HWND hCtrl, LPCWSTR szSendText, int nMode = 0); AU3_API int WINAPI AU3_ControlSetText(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPCWSTR szControlText); AU3_API int WINAPI AU3_ControlSetTextByHandle(HWND hWnd, HWND hCtrl, LPCWSTR szControlText); AU3_API int WINAPI AU3_ControlShow(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl); AU3_API int WINAPI AU3_ControlShowByHandle(HWND hWnd, HWND hCtrl); AU3_API void WINAPI AU3_ControlTreeView(LPCWSTR szTitle, LPCWSTR szText, LPCWSTR szControl, LPCWSTR szCommand, LPCWSTR szExtra1, LPCWSTR szExtra2, LPWSTR szResult, int nBufSize); AU3_API void WINAPI AU3_ControlTreeViewByHandle(HWND hWnd, HWND hCtrl, LPCWSTR szCommand, LPCWSTR szExtra1, LPCWSTR szExtra2, LPWSTR szResult, int nBufSize); AU3_API void WINAPI AU3_DriveMapAdd(LPCWSTR szDevice, LPCWSTR szShare, int nFlags, /*[in,defaultvalue("")]*/LPCWSTR szUser, /*[in,defaultvalue("")]*/LPCWSTR szPwd, LPWSTR szResult, int nBufSize); AU3_API int WINAPI AU3_DriveMapDel(LPCWSTR szDevice); AU3_API void WINAPI AU3_DriveMapGet(LPCWSTR szDevice, LPWSTR szMapping, int nBufSize); AU3_API int WINAPI AU3_IsAdmin(void); AU3_API int WINAPI AU3_MouseClick(/*[in,defaultvalue("LEFT")]*/LPCWSTR szButton, int nX = AU3_INTDEFAULT, int nY = AU3_INTDEFAULT, int nClicks = 1, int nSpeed = -1); AU3_API int WINAPI AU3_MouseClickDrag(LPCWSTR szButton, int nX1, int nY1, int nX2, int nY2, int nSpeed = -1); AU3_API void WINAPI AU3_MouseDown(/*[in,defaultvalue("LEFT")]*/LPCWSTR szButton); AU3_API int WINAPI AU3_MouseGetCursor(void); AU3_API void WINAPI AU3_MouseGetPos(LPPOINT lpPoint); AU3_API int WINAPI AU3_MouseMove(int nX, int nY, int nSpeed = -1); AU3_API void WINAPI AU3_MouseUp(/*[in,defaultvalue("LEFT")]*/LPCWSTR szButton); AU3_API void WINAPI AU3_MouseWheel(LPCWSTR szDirection, int nClicks); AU3_API int WINAPI AU3_Opt(LPCWSTR szOption, int nValue); AU3_API unsigned int WINAPI AU3_PixelChecksum(LPRECT lpRect, int nStep = 1); AU3_API int WINAPI AU3_PixelGetColor(int nX, int nY); AU3_API void WINAPI AU3_PixelSearch(LPRECT lpRect, int nCol, /*default 0*/int nVar, /*default 1*/int nStep, LPPOINT pPointResult); AU3_API int WINAPI AU3_ProcessClose(LPCWSTR szProcess); AU3_API int WINAPI AU3_ProcessExists(LPCWSTR szProcess); AU3_API int WINAPI AU3_ProcessSetPriority(LPCWSTR szProcess, int nPriority); AU3_API int WINAPI AU3_ProcessWait(LPCWSTR szProcess, int nTimeout = 0); AU3_API int WINAPI AU3_ProcessWaitClose(LPCWSTR szProcess, int nTimeout = 0); AU3_API int WINAPI AU3_Run(LPCWSTR szProgram, /*[in,defaultvalue("")]*/LPCWSTR szDir, int nShowFlag = SW_SHOWNORMAL); AU3_API int WINAPI AU3_RunWait(LPCWSTR szProgram, /*[in,defaultvalue("")]*/LPCWSTR szDir, int nShowFlag = SW_SHOWNORMAL); AU3_API int WINAPI AU3_RunAs(LPCWSTR szUser, LPCWSTR szDomain, LPCWSTR szPassword, int nLogonFlag, LPCWSTR szProgram, /*[in,defaultvalue("")]*/LPCWSTR szDir, int nShowFlag = SW_SHOWNORMAL); AU3_API int WINAPI AU3_RunAsWait(LPCWSTR szUser, LPCWSTR szDomain, LPCWSTR szPassword, int nLogonFlag, LPCWSTR szProgram, /*[in,defaultvalue("")]*/LPCWSTR szDir, int nShowFlag = SW_SHOWNORMAL); AU3_API void WINAPI AU3_Send(LPCWSTR szSendText, int nMode = 0); AU3_API int WINAPI AU3_Shutdown(int nFlags); AU3_API void WINAPI AU3_Sleep(int nMilliseconds); AU3_API int WINAPI AU3_StatusbarGetText(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, /*[in,defaultvalue(1)]*/int nPart, LPWSTR szStatusText, int nBufSize); AU3_API int WINAPI AU3_StatusbarGetTextByHandle(HWND hWnd, /*[in,defaultvalue(1)]*/int nPart, LPWSTR szStatusText, int nBufSize); AU3_API void WINAPI AU3_ToolTip(LPCWSTR szTip, int nX = AU3_INTDEFAULT, int nY = AU3_INTDEFAULT); AU3_API int WINAPI AU3_WinActivate(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API int WINAPI AU3_WinActivateByHandle(HWND hWnd); AU3_API int WINAPI AU3_WinActive(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API int WINAPI AU3_WinActiveByHandle(HWND hWnd); AU3_API int WINAPI AU3_WinClose(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API int WINAPI AU3_WinCloseByHandle(HWND hWnd); AU3_API int WINAPI AU3_WinExists(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API int WINAPI AU3_WinExistsByHandle(HWND hWnd); AU3_API int WINAPI AU3_WinGetCaretPos(LPPOINT lpPoint); AU3_API void WINAPI AU3_WinGetClassList(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPWSTR szRetText, int nBufSize); AU3_API void WINAPI AU3_WinGetClassListByHandle(HWND hWnd, LPWSTR szRetText, int nBufSize); AU3_API int WINAPI AU3_WinGetClientSize(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPRECT lpRect); AU3_API int WINAPI AU3_WinGetClientSizeByHandle(HWND hWnd, LPRECT lpRect); AU3_API HWND WINAPI AU3_WinGetHandle(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API void WINAPI AU3_WinGetHandleAsText(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPWSTR szRetText, int nBufSize); AU3_API int WINAPI AU3_WinGetPos(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPRECT lpRect); AU3_API int WINAPI AU3_WinGetPosByHandle(HWND hWnd, LPRECT lpRect); AU3_API DWORD WINAPI AU3_WinGetProcess(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API DWORD WINAPI AU3_WinGetProcessByHandle(HWND hWnd); AU3_API int WINAPI AU3_WinGetState(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API int WINAPI AU3_WinGetStateByHandle(HWND hWnd); AU3_API void WINAPI AU3_WinGetText(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPWSTR szRetText, int nBufSize); AU3_API void WINAPI AU3_WinGetTextByHandle(HWND hWnd, LPWSTR szRetText, int nBufSize); AU3_API void WINAPI AU3_WinGetTitle(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPWSTR szRetText, int nBufSize); AU3_API void WINAPI AU3_WinGetTitleByHandle(HWND hWnd, LPWSTR szRetText, int nBufSize); AU3_API int WINAPI AU3_WinKill(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText); AU3_API int WINAPI AU3_WinKillByHandle(HWND hWnd); AU3_API int WINAPI AU3_WinMenuSelectItem(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, LPCWSTR szItem1, LPCWSTR szItem2, LPCWSTR szItem3, LPCWSTR szItem4, LPCWSTR szItem5, LPCWSTR szItem6, LPCWSTR szItem7, LPCWSTR szItem8); AU3_API int WINAPI AU3_WinMenuSelectItemByHandle(HWND hWnd, LPCWSTR szItem1, LPCWSTR szItem2, LPCWSTR szItem3, LPCWSTR szItem4, LPCWSTR szItem5, LPCWSTR szItem6, LPCWSTR szItem7, LPCWSTR szItem8); AU3_API void WINAPI AU3_WinMinimizeAll(); AU3_API void WINAPI AU3_WinMinimizeAllUndo(); AU3_API int WINAPI AU3_WinMove(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nX, int nY, int nWidth = -1, int nHeight = -1); AU3_API int WINAPI AU3_WinMoveByHandle(HWND hWnd, int nX, int nY, int nWidth = -1, int nHeight = -1); AU3_API int WINAPI AU3_WinSetOnTop(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nFlag); AU3_API int WINAPI AU3_WinSetOnTopByHandle(HWND hWnd, int nFlag); AU3_API int WINAPI AU3_WinSetState(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nFlags); AU3_API int WINAPI AU3_WinSetStateByHandle(HWND hWnd, int nFlags); AU3_API int WINAPI AU3_WinSetTitle(LPCWSTR szTitle,/*[in,defaultvalue("")]*/ LPCWSTR szText, LPCWSTR szNewTitle); AU3_API int WINAPI AU3_WinSetTitleByHandle(HWND hWnd, LPCWSTR szNewTitle); AU3_API int WINAPI AU3_WinSetTrans(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nTrans); AU3_API int WINAPI AU3_WinSetTransByHandle(HWND hWnd, int nTrans); AU3_API int WINAPI AU3_WinWait(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nTimeout = 0); AU3_API int WINAPI AU3_WinWaitByHandle(HWND hWnd, int nTimeout); AU3_API int WINAPI AU3_WinWaitActive(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nTimeout = 0); AU3_API int WINAPI AU3_WinWaitActiveByHandle(HWND hWnd, int nTimeout); AU3_API int WINAPI AU3_WinWaitClose(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nTimeout = 0); AU3_API int WINAPI AU3_WinWaitCloseByHandle(HWND hWnd, int nTimeout); AU3_API int WINAPI AU3_WinWaitNotActive(LPCWSTR szTitle, /*[in,defaultvalue("")]*/LPCWSTR szText, int nTimeout); AU3_API int WINAPI AU3_WinWaitNotActiveByHandle(HWND hWnd, int nTimeout = 0); ///////////////////////////////////////////////////////////////////////////////
AutoItXライブラリを使用するMetaTrader5プログラムは、まずその関数をインポートする必要があります。便宜上、ライブラリによって公開されているすべての関数プロトタイプをインポートすることを唯一の目的とするインクルードファイルautoIt.mqhを作成します。
厳密にはAutoItはWindows APIを活用するMicrosoftWindowsオペレーティングシステムツールであって、これが、AuotItXライブラリがWin32API固有のデータ型を広範囲に使用する理由です。MQL5との互換性を確保するために、これらのデータ型をMQL5に実装することもできますが、これは必須ではありません。代わりに、Win32APIをMQL5に統合するためのMetaQuotesの取り組みの一部であるwindef.mqhファイルを使用できます。このファイルには、Windows APIで使用されるほとんどのデータ型定義が含まれています。
dllからインポートされたすべての関数プロトタイプを含むautoit.mqhファイルにwindef.mqhを含めます。autoit.mqhコードファイルはこれで次のようになります。
//+------------------------------------------------------------------+ //| autoIt.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include <WinAPI\windef.mqh> #define LPPOINT POINT& #define LPRECT RECT& #define WORD ushort #define DWORD int #define HWND int #import "AutoItX3_x64.dll" void AU3_Init(void); int AU3_error(void); int AU3_AutoItSetOption(string, int); void AU3_ClipGet(string&, int); void AU3_ClipPut(string); int AU3_ControlClick(string, string, string, string, int, int, int); int AU3_ControlClickByHandle(HWND, HWND, string, int, int, int); void AU3_ControlCommand(string, string, string, string, string, string&, int); void AU3_ControlCommandByHandle(HWND, HWND, string, string, string&, int); void AU3_ControlListView(string, string, string, string, string, string, string&, int); void AU3_ControlListViewByHandle(HWND, HWND, string, string, string, string&, int); int AU3_ControlDisable(string, string, string); int AU3_ControlDisableByHandle(HWND, HWND); int AU3_ControlEnable(string, string, string); int AU3_ControlEnableByHandle(HWND, HWND); int AU3_ControlFocus(string, string, string); int AU3_ControlFocusByHandle(HWND, HWND); void AU3_ControlGetFocus(string, string, string&, int); void AU3_ControlGetFocusByHandle(HWND, string&, int); HWND AU3_ControlGetHandle(HWND, string); void AU3_ControlGetHandleAsText(string, string, string, string&, int); int AU3_ControlGetPos(string, string, string, LPRECT); int AU3_ControlGetPosByHandle(HWND, HWND, LPRECT); void AU3_ControlGetText(string, string, string, string&, int); void AU3_ControlGetTextByHandle(HWND, HWND, string&, int); int AU3_ControlHide(string, string, string); int AU3_ControlHideByHandle(HWND, HWND); int AU3_ControlMove(string, string, string, int, int, int, int); int AU3_ControlMoveByHandle(HWND, HWND, int, int, int, int); int AU3_ControlSend(string, string, string, string, int); int AU3_ControlSendByHandle(HWND, HWND, string, int); int AU3_ControlSetText(string, string, string, string); int AU3_ControlSetTextByHandle(HWND, HWND, string); int AU3_ControlShow(string, string, string); int AU3_ControlShowByHandle(HWND, HWND); void AU3_ControlTreeView(string, string, string, string, string, string, string&, int); void AU3_ControlTreeViewByHandle(HWND, HWND, string, string, string, string&, int); void AU3_DriveMapAdd(string, string, int, string, string, string&, int); int AU3_DriveMapDel(string); void AU3_DriveMapGet(string, string&, int); int AU3_IsAdmin(void); int AU3_MouseClick(string, int, int, int, int); int AU3_MouseClickDrag(string, int, int, int, int, int); void AU3_MouseDown(string); int AU3_MouseGetCursor(void); void AU3_MouseGetPos(LPPOINT); int AU3_MouseMove(int, int, int); void AU3_MouseUp(string); void AU3_MouseWheel(string, int); int AU3_Opt(string, int); unsigned int AU3_PixelChecksum(LPRECT, int); int AU3_PixelGetColor(int, int); void AU3_PixelSearch(LPRECT, int, int, int, LPPOINT); int AU3_ProcessClose(string); int AU3_ProcessExists(string); int AU3_ProcessSetPriority(string, int); int AU3_ProcessWait(string, int); int AU3_ProcessWaitClose(string, int); int AU3_Run(string, string, int); int AU3_RunWait(string, string, int); int AU3_RunAs(string, string, string, int, string, string, int); int AU3_RunAsWait(string, string, string, int, string, string, int); void AU3_Send(string, int); int AU3_Shutdown(int); void AU3_Sleep(int); int AU3_StatusbarGetText(string, string, int, string&, int); int AU3_StatusbarGetTextByHandle(HWND, int, string&, int); void AU3_ToolTip(string, int, int); int AU3_WinActivate(string, string); int AU3_WinActivateByHandle(HWND); int AU3_WinActive(string, string); int AU3_WinActiveByHandle(HWND); int AU3_WinClose(string, string); int AU3_WinCloseByHandle(HWND); int AU3_WinExists(string, string); int AU3_WinExistsByHandle(HWND); int AU3_WinGetCaretPos(LPPOINT); void AU3_WinGetClassList(string, string, string&, int); void AU3_WinGetClassListByHandle(HWND, string&, int); int AU3_WinGetClientSize(string, string, LPRECT); int AU3_WinGetClientSizeByHandle(HWND, LPRECT); HWND AU3_WinGetHandle(string, string); void AU3_WinGetHandleAsText(string, string, string&, int); int AU3_WinGetPos(string, string, LPRECT); int AU3_WinGetPosByHandle(HWND, LPRECT); DWORD AU3_WinGetProcess(string, string); DWORD AU3_WinGetProcessByHandle(HWND); int AU3_WinGetState(string, string); int AU3_WinGetStateByHandle(HWND); void AU3_WinGetText(string, string, string&, int); void AU3_WinGetTextByHandle(HWND, string&, int); void AU3_WinGetTitle(string, string, string&, int); void AU3_WinGetTitleByHandle(HWND, string&, int); int AU3_WinKill(string, string); int AU3_WinKillByHandle(HWND); int AU3_WinMenuSelectItem(string, string, string, string, string, string, string, string, string, string); int AU3_WinMenuSelectItemByHandle(HWND, string, string, string, string, string, string, string, string); void AU3_WinMinimizeAll(); void AU3_WinMinimizeAllUndo(); int AU3_WinMove(string, string, int, int, int, int); int AU3_WinMoveByHandle(HWND, int, int, int, int); int AU3_WinSetOnTop(string, string, int); int AU3_WinSetOnTopByHandle(HWND, int); int AU3_WinSetState(string, string, int); int AU3_WinSetStateByHandle(HWND, int); int AU3_WinSetTitle(string, string, string); int AU3_WinSetTitleByHandle(HWND, string); int AU3_WinSetTrans(string, string, int); int AU3_WinSetTransByHandle(HWND, int); int AU3_WinWait(string, string, int); int AU3_WinWaitByHandle(HWND, int); int AU3_WinWaitActive(string, string, int); int AU3_WinWaitActiveByHandle(HWND, int); int AU3_WinWaitClose(string, string, int); int AU3_WinWaitCloseByHandle(HWND, int); int AU3_WinWaitNotActive(string, string, int); int AU3_WinWaitNotActiveByHandle(HWND, int); #import //+------------------------------------------------------------------+
使用法の予備知識
MQL5でライブラリを使用するには、まずAU3_Init関数を呼び出してdllを初期化する必要があります。これは、他のインポートされた関数が呼び出される前に実行する必要があります。関数シグネチャは、AutoItスクリプト言語で使用されるものと類似しています。つまり、関数のパラメーターと戻り値のタイプは類似しています。関数がどのように機能するかを理解するには、AutoItスクリプト言語に精通している必要があります。この情報はすべて、アプリケーションのインストールの一部であるヘルプファイルで入手できます。
最初の例
以下の例は、MQL5でのAutoItX関数の使用法を示しています。以下のスクリプトでは、AU3_WinGetHandle関数を使用して、ターミナルのメインウィンドウのハンドルを取得します。ターミナルは、ウィンドウのタイトルバーに表示されるアクティブな口座番号によって一意に識別できます。
//+------------------------------------------------------------------+ //| TerminalUIComponents.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #property version "1.00" #include<autoIt.mqh> string sbuffer; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- AU3_Init();//initialize the library if(!StringInit(sbuffer,1000))// set buffer length for string Print("Failed to set string bufferlength with error - "+string(GetLastError())); HWND window_handle=AU3_WinGetHandle(IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN)),"");// get the terminal's handle if(!window_handle) Print("Could not find main app window. Error is "+string(AU3_error())); AU3_WinGetClassListByHandle(window_handle,sbuffer,1000);// get classnames of all user interface componets of the terminal Print(sbuffer); } //+------------------------------------------------------------------+
メインウィンドウのハンドルを取得すると、AU3_WinGetClassListByHandle関数を呼び出して操作できるGUIコンポーネントに関する詳細情報を取得できます。提供されたウィンドウハンドルに関連付けられたすべてのユーザーインターフェイスコンポーネントのクラス名である文字列のリストが返されます。
以下にスクリプトを実行した結果を示します。
より堅牢な例に進む前に、インポートされたAutoIt関数のほとんどをラップするクラスを作成しましょう。
CAutoitクラス
CAutoitは、AutoItXライブラリを使用する他のクラスの派生元となる基本クラスになり、初期化ライブラリ関数AU3_Init()が呼び出されたかどうかを指定する単一の静的プロパティを含みます。
他の唯一のプロパティm_buffer_sizeは、メソッド呼び出しで使用される文字列のバッファ長を特定します。
//+------------------------------------------------------------------+ //| autoitbase.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #include<autoIt.mqh> enum ENUM_WINDOW_STATE { SW_HIDE=0, SW_SHOW, SW_MINIMIZE, SW_MAXIMIZE, SW_RESTORE }; //+------------------------------------------------------------------+ //| Class CAutoIt. | //| Purpose: class for working with autoit. | //+------------------------------------------------------------------+ class CAutoIt { private: int m_buffer_size; //string buffer size // --- static property common to all object instances static bool m_initialized; //flag for checking initialization state //--- private methods void ResetBuffer(string &buffer) { StringFill(buffer,0); } public: //--- constructor, destructor CAutoIt(void); ~CAutoIt(void); void Init(void); //--- static method static bool IsInitialized(void) { return(m_initialized); } //--- general purpose methods int Error(void) { return (AU3_error()); } void Sleep(const int milliseconds) { AU3_Sleep(milliseconds); } void SetBufferLen(const int n_bufferlen) { m_buffer_size=(n_bufferlen>0)?n_bufferlen:1000; } int GetBufferLen(void) { return(m_buffer_size); } protected: int Run(const string exefile,const string path,const ENUM_WINDOW_STATE w_state) { return(AU3_Run(exefile,path,int(w_state))); } //--- system clipboard manipulation void ClipGet(string & out); void ClipPut(string copy); //--- void ControlPosition(HWND window_handle,HWND control_handle, LPRECT rect) { AU3_ControlGetPosByHandle(window_handle,control_handle, rect);} //--- methods for simulating clicks int ControlRightClick(HWND window_handle, HWND control_handle,int number_of_clicks=1,int x=1,int y=1); int ControlLeftClick(HWND window_handle, HWND control_handle,int number_of_clicks=1,int x=1,int y=1); //--- general Control Command method bool ControlCommand(HWND window_handle, HWND control_handle, string command, string command_option); //--- methods for interacting with comboboxes, buttons,radio buttons string GetCurrentComboBoxSelection(HWND window_handle, HWND control_handle); bool IsControlEnabled(HWND window_handle, HWND control_handle); bool IsControlVisible(HWND window_handle, HWND control_handle); int EnableControl(HWND window_handle, HWND control_handle) { return(AU3_ControlEnableByHandle(window_handle,control_handle));} int ShowControl(HWND window_handle, HWND control_handle) { return(AU3_ControlShowByHandle(window_handle,control_handle)); } int ControlFocus(HWND window_handle,HWND control_handle) { return(AU3_ControlFocusByHandle(window_handle,control_handle)); } bool IsButtonChecked(HWND window_handle, HWND control_handle); bool CheckButton(HWND window_handle, HWND control_handle); bool UnCheckButton(HWND window_handle, HWND control_handle); //--- methods for interacting with system32tab control string GetCurrentTab(HWND window_handle, HWND control_handle); bool TabRight(HWND window_handle, HWND control_handle); bool TabLeft(HWND window_handle, HWND control_handle); long TotalTabs(HWND window, HWND systab); //--- methods for interacting with syslistview32 control bool ControlListView(HWND window_handle, HWND control_handle, string command, string command_option1, string command_option2); long GetListViewItemCount(HWND window_handle, HWND control_handle); long FindListViewItem(HWND window_handle, HWND control_handle, string find_item,string sub_item); string GetSelectedListViewItem(HWND window_handle, HWND control_handle); long GetSelectedListViewCount(HWND window_handle, HWND control_handle); long GetListViewSubItemCount(HWND window_handle, HWND control_handle); string GetListViewItemText(HWND window_handle, HWND control_handle,string item_index,string sub_item_index); bool IsListViewItemSelected(HWND window_handle, HWND control_handle, string item_index); bool SelectListViewItem(HWND window_handle, HWND control_handle, string from_item_index,string to_item_index); bool SelectAllListViewItems(HWND window_handle, HWND control_handle); bool ClearAllListViewItemSelections(HWND window_handle, HWND control_handle); bool ViewChangeListView(HWND window_handle, HWND control_handle); //--- general methods for various types of controls HWND ControlGetHandle(HWND window_handle, string control_id); string ControlGetText(HWND window_handle, HWND control_handle); int ControlSetText(HWND window_handle,HWND control_handle,string keys) { return(AU3_ControlSetTextByHandle(window_handle,control_handle,keys));} int ControlSend(HWND window_handle, HWND control_handle, string keys, int mode); bool SetFocus(HWND window_handle,HWND control_handle) { return(AU3_ControlFocusByHandle(window_handle,control_handle)>0); } //--- methods for interacting with systreeview32 control bool ControlTreeView(HWND window_handle, HWND control_handle, string command, string command_option1, string command_option2); long GetTreeViewItemCount(HWND window_handle, HWND control_handle, string item); string GetSelectedTreeViewItem(HWND window_handle, HWND control_handle); string GetTreeViewItemText(HWND window_handle, HWND control_handle,string item); bool SelectTreeViewItem(HWND window_handle, HWND control_handle,string item); //--- general methods for application windows, subwindows and dialogues int WinClose(string window_title, string window_text) { return(AU3_WinClose(window_title,window_text)); } int WinClose(HWND window_handle) { return(AU3_WinCloseByHandle(window_handle)); } string WinGetText(HWND window_handle); int WinMenuSelectItem(HWND window_handle, string menu_name_1, string menu_name_2, string menu_name_3, string menu_name_4, string menu_name_5, string menu_name_6, string menu_name_7, string menu_name_8); int WinSetState(HWND window_handle, ENUM_WINDOW_STATE new_state); string WinGetTitle(HWND window_handle); ENUM_WINDOW_STATE WinGetState(HWND window_handle) { return((ENUM_WINDOW_STATE)AU3_WinGetStateByHandle(window_handle)); } HWND WinGetHandle(string window_title, string window_text); void WinGetPosition(HWND window_handle, LPRECT winpos) { AU3_WinGetPosByHandle(window_handle,winpos); } void WinClientSize(HWND window_handle, LPRECT winsize) { AU3_WinGetClientSizeByHandle(window_handle,winsize); } int WinExists(HWND window_handle) { return(AU3_WinExistsByHandle(window_handle)); } int WinExists(string window_title, string window_text) { return(AU3_WinExists(window_title,window_text)); } }; bool CAutoIt::m_initialized=false; //+------------------------------------------------------------------+ //| Constructor without parameters | //+------------------------------------------------------------------+ CAutoIt::CAutoIt(void): m_buffer_size(1000) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CAutoIt::~CAutoIt(void) { } //+------------------------------------------------------------------+ //|Initializes AutoIt library | //+------------------------------------------------------------------+ void CAutoIt::Init(void) { if(!m_initialized) { AU3_Init(); m_initialized=true; } } //+------------------------------------------------------------------+ //|Reads and outputs textual contents of system clipboard | //+------------------------------------------------------------------+ void CAutoIt::ClipGet(string &out) { if(StringBufferLen(out)<m_buffer_size) StringInit(out,m_buffer_size); ResetBuffer(out); AU3_ClipGet(out,m_buffer_size); } //+------------------------------------------------------------------+ //|Writes text to system clipboard | //+------------------------------------------------------------------+ void CAutoIt::ClipPut(string copy) { AU3_ClipPut(copy); } //+------------------------------------------------------------------+ //|Simulates a left click | //+------------------------------------------------------------------+ int CAutoIt::ControlLeftClick(int window_handle,int control_handle,int number_of_clicks=1,int x=1,int y=1) { return(AU3_ControlClickByHandle(window_handle,control_handle,"left",number_of_clicks,x,y)); } //+------------------------------------------------------------------+ //|Simulates a right click | //+------------------------------------------------------------------+ int CAutoIt::ControlRightClick(int window_handle,int control_handle,int number_of_clicks=1,int x=1,int y=1) { return(AU3_ControlClickByHandle(window_handle,control_handle,"right",number_of_clicks,x,y)); } //+------------------------------------------------------------------+ //|Sends a command to a control | //+------------------------------------------------------------------+ bool CAutoIt::ControlCommand(int window_handle,int control_handle,string command,string command_option) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlCommandByHandle(window_handle,control_handle,command,command_option,m_buffer,m_buffer_size); if(StringFind(m_buffer,"0")>=0) return(false); return(true); } //+------------------------------------------------------------------+ //|Retrieves text of currently selected option of a Combobox Control | //+------------------------------------------------------------------+ string CAutoIt::GetCurrentComboBoxSelection(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlCommandByHandle(window_handle,control_handle,"GetCurrentSelection","",m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|Checks if a button is clickable | //+------------------------------------------------------------------+ bool CAutoIt::IsControlEnabled(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"IsEnabled","")); } //+------------------------------------------------------------------+ //|Checks if a control is visible | //+------------------------------------------------------------------+ bool CAutoIt::IsControlVisible(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"IsVisible","")); } //+------------------------------------------------------------------+ //|Checks if tickbox is ticked | //+------------------------------------------------------------------+ bool CAutoIt::IsButtonChecked(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"IsChecked","")); } //+------------------------------------------------------------------+ //| Ticks a tick box | //+------------------------------------------------------------------+ bool CAutoIt::CheckButton(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"Check","")); } //+------------------------------------------------------------------+ //|Unticks a tick box | //+------------------------------------------------------------------+ bool CAutoIt::UnCheckButton(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"UnCheck","")); } //+------------------------------------------------------------------+ //|Gets text of currently enabled tab of SysTabControl32 control | //+------------------------------------------------------------------+ string CAutoIt::GetCurrentTab(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlCommandByHandle(window_handle,control_handle,"CurrentTab","",m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|Enables the tab to the left in SysTabControl32 control | //+------------------------------------------------------------------+ bool CAutoIt::TabLeft(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"TabLeft","")); } //+------------------------------------------------------------------+ //|Enables the tab to the right in SysTabControl32 control | //+------------------------------------------------------------------+ bool CAutoIt::TabRight(int window_handle,int control_handle) { return(ControlCommand(window_handle,control_handle,"TabRight","")); } //+------------------------------------------------------------------+ //|Sends a command to a ListView32 control | //+------------------------------------------------------------------+ bool CAutoIt::ControlListView(int window_handle,int control_handle,string command,string command_option1,string command_option2) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,command,command_option1,command_option2,m_buffer,m_buffer_size); if(StringFind(m_buffer,"1")>=0) return(true); return(false); } //+------------------------------------------------------------------+ //|Gets number of items in ListView32 control | //+------------------------------------------------------------------+ long CAutoIt::GetListViewItemCount(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"GetItemCount","","",m_buffer,m_buffer_size); return(StringToInteger(m_buffer)); } //+-------------------------------------------------------------------------------------------+ //|retrievs the index of a ListView32 control item that matches find_item and sub_item strings| //+-------------------------------------------------------------------------------------------+ long CAutoIt::FindListViewItem(int window_handle,int control_handle,string find_item,string sub_item) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"FindItem",find_item,sub_item,m_buffer,m_buffer_size); return(StringToInteger(m_buffer)); } //+------------------------------------------------------------------+ //|gets the string list of all selected ListView32 control items | //+------------------------------------------------------------------+ string CAutoIt::GetSelectedListViewItem(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"GetSelected","1","",m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|returns number of currently selected ListView32 control items | //+------------------------------------------------------------------+ long CAutoIt::GetSelectedListViewCount(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"GetSelectedCount","","",m_buffer,m_buffer_size); return(StringToInteger(m_buffer)); } //+------------------------------------------------------------------+ //|gets number of sub items in ListView32 control | //+------------------------------------------------------------------+ long CAutoIt::GetListViewSubItemCount(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"GetSubItemCount","","",m_buffer,m_buffer_size); return(StringToInteger(m_buffer)); } //+---------------------------------------------------------------------+ //|returns text of single ListView32 control item referenced by an index| //+---------------------------------------------------------------------+ string CAutoIt::GetListViewItemText(int window_handle,int control_handle,string item_index,string sub_item_index) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"GetText",item_index,sub_item_index,m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|Checks if a certain ListView32 control item is selected | //+------------------------------------------------------------------+ bool CAutoIt::IsListViewItemSelected(int window_handle,int control_handle,string item_index) { return(ControlListView(window_handle,control_handle,"IsSelected",item_index,"")); } //+------------------------------------------------------------------+ //|Selects a certain ListView32 control | //+------------------------------------------------------------------+ bool CAutoIt::SelectListViewItem(int window_handle,int control_handle,string from_item_index,string to_item_index) { return(ControlListView(window_handle,control_handle,"Select",from_item_index,to_item_index)); } //+------------------------------------------------------------------+ //|selects all listview items | //+------------------------------------------------------------------+ bool CAutoIt::SelectAllListViewItems(int window_handle,int control_handle) { return(ControlListView(window_handle,control_handle,"SelectAll","","")); } //+------------------------------------------------------------------+ //|Deselects all currently selected item in a ListView32 control | //+------------------------------------------------------------------+ bool CAutoIt::ClearAllListViewItemSelections(int window_handle,int control_handle) { return(ControlListView(window_handle,control_handle,"SelectClear","","")); } //+------------------------------------------------------------------+ //| Change listview control view to details mode | //+------------------------------------------------------------------+ bool CAutoIt::ViewChangeListView(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlListViewByHandle(window_handle,control_handle,"ViewChange","list","",m_buffer,m_buffer_size); if(StringFind(m_buffer,"1")>=0) return(true); return(false); } //+------------------------------------------------------------------+ //|returns handle for a control | //+------------------------------------------------------------------+ HWND CAutoIt::ControlGetHandle(int window_handle,string control_id) { return(AU3_ControlGetHandle(window_handle,control_id)); } //+------------------------------------------------------------------+ //|returns visible text from a control | //+------------------------------------------------------------------+ string CAutoIt::ControlGetText(int window_handle,int control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlGetTextByHandle(window_handle,control_handle,m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|directs keyboard presses to a certain control | //+------------------------------------------------------------------+ int CAutoIt::ControlSend(int window_handle,int control_handle,string keys,int mode) { return(AU3_ControlSendByHandle(window_handle,control_handle,keys,mode)); } //+------------------------------------------------------------------+ //|Sends a command to a TreeView32 control | //+------------------------------------------------------------------+ bool CAutoIt::ControlTreeView(int window_handle,int control_handle,string command,string command_option1,string command_option2) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlTreeViewByHandle(window_handle,control_handle,command,command_option1,command_option2,m_buffer,m_buffer_size); if(StringFind(m_buffer,"1")>=0) return(true); return(false); } //+-----------------------------------------------------------------------------+ //|returns number of children on a a TreeView32 control item with selected index| //+-----------------------------------------------------------------------------+ long CAutoIt::GetTreeViewItemCount(HWND window_handle, HWND control_handle, string item_index) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlTreeViewByHandle(window_handle,control_handle,"GetItemCount",item_index,"",m_buffer,m_buffer_size); return(StringToInteger(m_buffer)); } //+------------------------------------------------------------------+ //|gets index in string format of selected TreeView32 control item | //+------------------------------------------------------------------+ string CAutoIt::GetSelectedTreeViewItem(HWND window_handle, HWND control_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlTreeViewByHandle(window_handle,control_handle,"GetSelected","","",m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|retrieves the text of a a TreeView32 control item | //+------------------------------------------------------------------+ string CAutoIt::GetTreeViewItemText(HWND window_handle, HWND control_handle,string item) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_ControlTreeViewByHandle(window_handle,control_handle,"GetText",item,"",m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|selects a a TreeView32 control item | //+------------------------------------------------------------------+ bool CAutoIt::SelectTreeViewItem(HWND window_handle, HWND control_handle,string item) { return(ControlTreeView(window_handle,control_handle,"Select",item,"")); } //+------------------------------------------------------------------+ //|returns handle of window by its window title | //+------------------------------------------------------------------+ HWND CAutoIt::WinGetHandle(string window_title, string window_text="") { return(AU3_WinGetHandle(window_title,window_text)); } //+------------------------------------------------------------------+ //|return all text that is visible within a window | //+------------------------------------------------------------------+ string CAutoIt::WinGetText(HWND window_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_WinGetTextByHandle(window_handle,m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|Invokes a menu item of a window | //+------------------------------------------------------------------+ int CAutoIt::WinMenuSelectItem(HWND window_handle, string menu_name_1, string menu_name_2, string menu_name_3, string menu_name_4, string menu_name_5, string menu_name_6, string menu_name_7, string menu_name_8) { return(AU3_WinMenuSelectItemByHandle(window_handle,menu_name_1,menu_name_2,menu_name_3,menu_name_4,menu_name_5,menu_name_6,menu_name_7,menu_name_8)); } //+------------------------------------------------------------------+ //|Shows, hides, minimizes, maximizes, or restores a window | //+------------------------------------------------------------------+ int CAutoIt::WinSetState(HWND window_handle, ENUM_WINDOW_STATE new_state) { return(AU3_WinSetStateByHandle(window_handle,(int)new_state)); } //+------------------------------------------------------------------+ //|retrieves window title | //+------------------------------------------------------------------+ string CAutoIt::WinGetTitle(int window_handle) { string m_buffer; StringInit(m_buffer,m_buffer_size); AU3_WinGetTitleByHandle(window_handle,m_buffer,m_buffer_size); return(m_buffer); } //+------------------------------------------------------------------+ //|Gets total number of tabs in systab32 control | //+------------------------------------------------------------------+ long CAutoIt::TotalTabs(const int window,const int systab) { if(!WinExists(window)) { return(0); } string index=GetCurrentTab(window,systab); long shift=-1; while(TabRight(window,systab)) { index=""; index=GetCurrentTab(window,systab); } shift=StringToInteger(index); return(shift); } //+------------------------------------------------------------------+
CTerminalControllerクラス
次に、terminalcontroller.mqhファイルにCTerminalControllerクラスを作成しましょう。
まず、CAutoItクラスを含むautoitbase.mqhファイルをインクルードします。クラスが動作するユーザーインターフェイスコンポーネントを識別する文字列定数を、プリプロセッサディレクティブを使用して定義します。
クラスを指定する前に、MetaTrader5プログラムをスクリプトまたはエキスパートアドバイザーとして分類するカスタム列挙を宣言します。
//+------------------------------------------------------------------+ //| terminalcontroller.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #include<autoItbase.mqh> #define JOURNAL_TAB "SysListView321" #define EXPERTS_TAB "SysListView327" #define NAVIGATOR "SysTreeView321" #define NAVIGATOR_TAB_BAR "AfxWnd140su3" #define PROGRAM_WINDOW_TAB "SysTabControl321" #define EXPERTS_WINDOW_LISTVIEW "SysListView321" #define EXPERTS_REMOVE_BUTTON "Button2" #define DLLCHECK_BUTTON "Button1" #define ALGOTRADECHECK_BUTTON "Button4" #define OK_BUTTON_1 "Button7" #define OK_BUTTON_2 "Button3" #define OK_BUTTON_3 "Button5" #define LOAD_BUTTON "Button1" #define YES_BUTTON "Button1" #define FILENAME_EDIT "Edit1" #define OPTWINDOW_TAB "SysTabControl321" #define OPTWINDOW_CHECK_1 "Button1" #define OPTWINDOW_CHECK_2 "Button2" #define OPTWINDOW_CHECK_3 "Button6" #define OPTWINDOW_OK "Button7" #define OPTWINDOW_EDIT "Edit1" #define EXPERTS_WINDOW "Experts" #define NAVIGATORWINDOW "Navigator" #define TOOLBOXWINDOW "Toolbox" #define FILEDIALOGE_WINDOW "Open" #define WINDOWTEXT_DLL "Allow DLL" #define WINDOWTEXT_EA "Expert Advisor settings" #define WINDOWTEXT_INPUT "Input" #define OPTWINDOW "Options" #define NOTIFICATIONS_TEXT "Enable Push notifications" #define ALERTWINDOW "Alert" #define MENU_TOOLS "&Tools" #define MENU_OPTIONS "&Options" #define MENU_WINDOW "&Window" #define MENU_TILEWINDOWS "&Tile Windows" #define MENU_VIEW "&View" #define MENU_NAVIGATOR "&Navigator" #define MENU_CHARTS "&Charts" #define MENU_EXPERTS_LIST "&Expert List" enum ENUM_TYPE_PROGRAM { ENUM_TYPE_EXPERT=0,//EXPERT_ADVISOR ENUM_TYPE_SCRIPT//SCRIPT };
HWND型のprivateプロパティは、クラスで使用されるウィンドウハンドルとコントロールハンドルです。
//+------------------------------------------------------------------+ //|Class CTerminalController | //| Purpose: class for scripting the terminal | //+------------------------------------------------------------------+ class CTerminalController:public CAutoIt { private: HWND m_terminal; //terminal window handle HWND m_journaltab; //journal tab handle HWND m_expertstab; //experts tab handle HWND m_navigator; //navigator systreeview HWND m_navigatortabs; //navigator tab header HWND m_navigatorwindow; //navigator window HWND m_systab32; //handle to inputs tabbed control with in inputs dialogue HWND m_program; //window handle for user inputs dialogue HWND m_expwindow; //handle to window showing list of experts HWND m_explistview; //list view control for experts list in m_expwindow long m_chartid; //chart id long m_accountNum; //account number string m_buffer; //string buffer
m_chartidは、MQL5関数chartID()を呼び出すことによって定義されたチャート識別子を参照します。
m_accountNumは、ターミナルのアプリケーションタイトルバーに表示されるアクティブな口座番号です。この値は、アクティブなターミナルウィンドウを別のウィンドウから識別するために使用されます。
m_buffer文字列には、問題が発生した場合に詳細なエラーメッセージが書き込まれます。
public: //default constructor CTerminalController(void): m_terminal(0), m_journaltab(0), m_expertstab(0), m_navigator(0), m_navigatortabs(0), m_navigatorwindow(0), m_systab32(0), m_program(0), m_expwindow(0), m_explistview(0), m_chartid(-1), m_buffer("") { m_accountNum=AccountInfoInteger(ACCOUNT_LOGIN); StringInit(m_buffer,1000); } //destructor ~CTerminalController(void) { }
CTerminalControllerには単一のコンストラクタがあります。デフォルトのコンストラクタは、AccountInfoInteger関数の呼び出しによって返された現在アクティブなターミナル口座でm_accountNumを初期化します。
メソッド
//public methods string GetErrorDetails(void) { return(m_buffer); } bool ChartExpertAdd(const ENUM_TYPE_PROGRAM p_type,const string ea_name,const string ea_relative_path,const string ea_set_file,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf); bool ChartExpertRemove(const string ea_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf); bool ChartExpertRemoveAll(void); void CloseAlertDialogue(void); void GetLastExpertsLogEntry(string &entry); void GetLastExpertsLogEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry); void GetLastJournalEntry(string &entry); void GetLastJournalEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry); bool Initialize(const long accountNumber=0); bool SwitchToNewChart(string n_symbol, const ENUM_TIMEFRAMES n_tf); bool SetNotificationId(const string MetaQuotes_id); bool ToggleAutoTrading(void); private: //helper methods void SetErrorDetails(const string text); void Findbranch(const long childrenOnBranch,const string index,const string pname,string& sbuffer); bool Findprogram(const ENUM_TYPE_PROGRAM pr_type, const string program_name,const string relative_path,string& sbuffer); string PeriodToString(const ENUM_TIMEFRAMES chart_tf); bool RemoveExpert(const string program_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf); string BrokerName(void); };
エラーメッセージを取得するには、GetErrorDetails()があります。この関数はprivateメンバーm_bufferの内容を返します。一方、SetErrorDetails()は、m_buffer文字列メンバーの内容を設定するために内部的に使用されるprivateメソッドです。
//+------------------------------------------------------------------+ //| Set error details | //+------------------------------------------------------------------+ void CTerminalController::SetErrorDetails(const string _text) { StringFill(m_buffer,0); m_buffer=_text; return; }
Initialize()メソッドは、他のメソッドの前に、プログラムの初期化時に少なくとも1回呼び出す必要があります。このメソッドには、単一のデフォルトパラメータaccountNumberがあります。引数がゼロ以外の場合、m_accountNumクラスプロパティの値と他のすべてのクラスプロパティがリセットされ、m_accountNumプロパティで識別されるメインターミナルウィンドウの検索がトリガーされます。メインウィンドウが見つかると、他のすべてのコントロールハンドルが取得され、残りのクラスプロパティを設定するために使用されます。
//+------------------------------------------------------------------+ //| sets or resets window and control handles used in the class | //+------------------------------------------------------------------+ bool CTerminalController::Initialize(const long accountNumber=0) { Init(); if(accountNumber>0 && accountNumber!=m_accountNum) { m_accountNum=accountNumber; m_program=m_expwindow=m_systab32=m_explistview=m_navigatorwindow=0; m_terminal=m_journaltab=m_expertstab=m_navigator=m_navigatortabs=0; m_chartid=0; } if(m_terminal) return(true); m_terminal=WinGetHandle(IntegerToString(m_accountNum)); if(!m_terminal) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Terminal window "+IntegerToString(m_accountNum)+" not found"); return(false); } m_journaltab=ControlGetHandle(m_terminal,JOURNAL_TAB); if(!m_journaltab) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+JOURNAL_TAB+" not found"); return(false); } m_expertstab=ControlGetHandle(m_terminal,EXPERTS_TAB); if(!m_expertstab) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_TAB+" not found"); return(false); } m_navigatorwindow=ControlGetHandle(m_terminal,NAVIGATORWINDOW); if(!m_navigatorwindow) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+NAVIGATORWINDOW+" not found"); return(false); } m_navigator=ControlGetHandle(m_terminal,NAVIGATOR); if(!m_navigator) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+NAVIGATOR+" not found"); return(false); } m_navigatortabs=ControlGetHandle(m_terminal,NAVIGATOR_TAB_BAR); if(!m_navigatortabs) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+NAVIGATOR_TAB_BAR+" not found"); return(false); } StringInit(m_buffer,1000); return(true); }
ChartExpertAdd()は、エキスパートアドバイザーまたはスクリプトをチャートに添付するために使用されます。関数パラメータは次のとおりです。
- p_type - エキスパートアドバイザーまたはスクリプトのいずれかのプログラムタイプ
- ea_name - スクリプトまたはエキスパートアドバイザーのナビゲータウィンドウでの表示名(ファイル拡張子の名前を含めることはできない)
- ea_relative_path - ea_nameパラメータで指定されたプログラムを含むScriptsフォルダまたはExpertsフォルダ内のサブフォルダへの相対パス(例:次の図で、Controlsエキスパートアドバイザーは、Expertsフォルダ内のExamplesサブフォルダであるControlsという名前のフォルダに含まれており、そのパスはExamples\Controlsになる)。プログラムがScriptsフォルダまたはExpertsフォルダのいずれのサブフォルダにもない場合、この引数はNULLまたは ""に設定する必要があります。
- ea_set_fileは、.setファイルのファイル名です。この引数では、ファイル拡張子.setを指定する必要があります
- chart_symbolおよびcharttf引数は、プログラムが追加されるチャートのプロパティを指定します
まずSwitchToNewChart()メソッドが呼び出されます。このメソッドは、現在開いているチャートウィンドウから要求されたチャートを検索します。見つかった場合はそれにフォーカスが設定され、そうでない場合はChartOpen()関数を使用して新しいチャートを開きます。このメソッドは、クラスのm_chartidプロパティの設定も担当します。
次に、m_chartidプロパティを使用して、プログラムがすでにチャートに追加されているかどうかを確認します。プログラムが存在する場合、メソッドは「true」を返します。
//+------------------------------------------------------------------+ //|sets focus to existing or new chart window | //+------------------------------------------------------------------+ bool CTerminalController::SwitchToNewChart(string n_symbol,const ENUM_TIMEFRAMES n_tf) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } string sarray[]; StringToUpper(n_symbol); string newchartname=n_symbol+","+PeriodToString(n_tf); if(!WinMenuSelectItem(m_terminal,MENU_WINDOW,MENU_TILEWINDOWS,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to select menu item: Tile Windows"); return(false); } Sleep(200); string windowtext=WinGetText(m_terminal); int find=StringFind(windowtext,ChartSymbol(ChartFirst())+","+PeriodToString(ChartPeriod(ChartFirst()))); string chartstring=StringSubstr(windowtext,find); StringReplace(chartstring,"\n\n","\n"); int sarraysize=StringSplit(chartstring,StringGetCharacter("\n",0),sarray); bool found=false; int i; long prevChart=0; m_chartid=ChartFirst(); for(i=0; i<sarraysize; i++,) { if(sarray[i]=="") continue; if(i>0) m_chartid=ChartNext(prevChart); if(StringFind(sarray[i],newchartname)>=0) { found=true; break; } prevChart=m_chartid; } ArrayFree(sarray); HWND frameview=0; if(found) frameview=ControlGetHandle(m_terminal,newchartname); else if(ChartOpen(n_symbol,n_tf)) frameview=ControlGetHandle(m_terminal,newchartname); if(frameview) { if(!WinSetState(frameview,SW_MAXIMIZE)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Could not maximize "+newchartname+" chart window"); return(false); } } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Chart window "+newchartname+" not found"); return(false); } return(true); }
プログラムが見つからない場合は、ナビゲータペインを検索する準備が行われます。ナビゲータペインの[共通]タブが表示されていない場合は、有効になっています。
有効にすると、Findprogram()メソッドが呼び出され、systreeview32コントロールでMetaTrader5プログラムが検索されます。このメソッドは、再帰メソッドFindBranch()の助けを借ります。
//+---------------------------------------------------------------------+ //|searches navigator for a program and outputs its location on the tree| //+---------------------------------------------------------------------+ bool CTerminalController::Findprogram(const ENUM_TYPE_PROGRAM pr_type,const string program_name,const string relative_path,string &sbuffer) { long listsize=GetTreeViewItemCount(m_terminal,m_navigator,"#0"); if(!listsize) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Root treeview control is empty"); return(false); } else { string rpath=""; if(relative_path=="") rpath=relative_path; else { if(StringFind(relative_path,"\\")==0) rpath=StringSubstr(relative_path,1); else rpath=relative_path; if(StringFind(rpath,"\\",StringLen(rpath)-1)<0) rpath+="\\"; } switch(pr_type) { case ENUM_TYPE_EXPERT: { string fullpath="Expert Advisors\\"+rpath+program_name; Findbranch(listsize,"#0",fullpath,sbuffer); break; } case ENUM_TYPE_SCRIPT: { string fullpath="Scripts\\"+rpath+program_name; Findbranch(listsize,"#0",fullpath,sbuffer); break; } default: Findbranch(listsize,"#0","",sbuffer); break; } } if(sbuffer=="") { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Operation failed could not find "+program_name); return(false); } else return(true); }
FindBranch()はコントロールをトラバースし、systreeview32コントロール上のプログラムの場所へのパスである文字列参照IDを作成します。プログラムの参照IDは、AutoItを使用して選択し、チャートに追加できるようにするために必要です。
//+-----------------------------------------------------------------------+ //|recursively searches systreeview for program and builds location string| //+-----------------------------------------------------------------------+ void CTerminalController::Findbranch(const long childrenOnBranch,const string index,const string pname,string &sbuffer) { if(pname=="" || index=="") { sbuffer=index; return; } else { if(childrenOnBranch<=0) return; else { int find=StringFind(pname,"\\"); long ss=0; long i; for(i=0; i<childrenOnBranch; i++) { ss=GetTreeViewItemCount(m_terminal,m_navigator,index+"|#"+IntegerToString(i)); string search=(find>=0)?StringSubstr(pname,0,find):pname; string treebranchtext=GetTreeViewItemText(m_terminal,m_navigator,index+"|#"+IntegerToString(i)); if(StringFind(treebranchtext,search)>=0 && StringLen(treebranchtext)==StringLen(search)) break; } string npath=(find>=0)?StringSubstr(pname,find+1):""; Findbranch(ss,(i<childrenOnBranch)?index+"|#"+IntegerToString(i):"",npath,sbuffer); } } return; }
この時点で、プログラムがエキスパートアドバイザーであり、すでにチャートに別のEAがある場合は、現在実行中のエキスパートアドバイザーの置き換えを確認するダイアログが表示されます。
起動したプログラムに入力がある場合、do ... whileループがタブを循環して、.setファイルが設定され、必要に応じて自動取引とdllエクスポートを有効にするチェックボタンがオンにされます。
最後に、メソッドは、プログラムがチャートに追加されているかどうかを確認するために、チャートを再確認した結果を返します。
//+------------------------------------------------------------------+ //| Adds EA,Script,Service to a chart | //+------------------------------------------------------------------+ bool CTerminalController::ChartExpertAdd(const ENUM_TYPE_PROGRAM p_type,const string ea_name,const string ea_relative_path,const string ea_set_file,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf) { if(!SwitchToNewChart(chart_symbol,chart_tf)) { return(false); } if(StringFind((p_type==ENUM_TYPE_EXPERT)?ChartGetString(m_chartid,CHART_EXPERT_NAME):ChartGetString(m_chartid,CHART_SCRIPT_NAME),ea_name)>=0) { return(true); } if(p_type==ENUM_TYPE_EXPERT && StringFind(ChartGetString(m_chartid,CHART_EXPERT_NAME),ChartGetString(ChartID(),CHART_EXPERT_NAME))>=0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Cannot replace currenlty running Expert"); return(false); } if(StringLen(ea_set_file)>0) { if(StringFind(ea_relative_path,".set")<0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Incorrect parameter setting, set file name should contain .set file extension"); return(false); } } if(!IsControlVisible(m_terminal,m_navigator)) { if(!IsControlVisible(m_terminal,m_navigatorwindow)) { if(!WinMenuSelectItem(m_terminal,MENU_VIEW,MENU_NAVIGATOR,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to select menu item : Navigator"); return(false); } } if(!ControlLeftClick(m_terminal,m_navigatortabs,1,5,5)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to click on Navigator, Common tab"); return(false); } } string treepath=""; if(!Findprogram(p_type,ea_name,ea_relative_path,treepath)) return(false); if(!SelectTreeViewItem(m_terminal,m_navigator,treepath)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to select treeview item: "+treepath); return(false); } if(!ControlSend(m_terminal,m_navigator,"{SHIFTDOWN}{F10}{SHIFTUP}c",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Control Send failure"); return(false); } Sleep(500); m_program=WinGetHandle(ea_name); HWND dialogue=WinGetHandle(BrokerName()+" - MetaTrader 5",ea_name); if(!m_program && !dialogue) { if(p_type==ENUM_TYPE_EXPERT && StringFind(ChartGetString(m_chartid,CHART_EXPERT_NAME),ea_name)<0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Could not add program to chart"); return(false); } else { return(true); } } if(!m_program && dialogue)// replace current ea { HWND button = ControlGetHandle(dialogue,YES_BUTTON); if(button) { if(ControlLeftClick(dialogue,button)) { Sleep(200); m_program=WinGetHandle(ea_name); } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed left click on yes button"); WinClose(dialogue); return(false); } } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Yes button for dialogue not found"); WinClose(dialogue); return(false); } } m_systab32=ControlGetHandle(m_program,PROGRAM_WINDOW_TAB); if(!m_systab32) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+PROGRAM_WINDOW_TAB+ "not found"); return(false); } long totaltabs=TotalTabs(m_program,m_systab32); bool algoenabled=false; bool inputmod=false; bool dllenabled=(totaltabs<3)?true:false; do { string windowtext=WinGetText(m_program); if(StringFind(windowtext,WINDOWTEXT_DLL)>=0) { StringFill(windowtext,0); HWND button=ControlGetHandle(m_program,DLLCHECK_BUTTON); if(!button) { WinClose(m_program); { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"DLL check button not found"); return(false); } } if(!IsButtonChecked(m_program,button)) { if(CheckButton(m_program,button)) dllenabled=true; } else dllenabled=true; if(dllenabled) { if(TabLeft(m_program,m_systab32)) if(!TabLeft(m_program,m_systab32)) { inputmod=true; } } else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Could not enable DLL loading"); return(false); } } else if(StringFind(windowtext,WINDOWTEXT_EA)==0) { StringFill(windowtext,0); HWND button=ControlGetHandle(m_program,ALGOTRADECHECK_BUTTON); if(!button) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Algo check button not found"); return(false); } if(!IsButtonChecked(m_program,button)) { if(CheckButton(m_program,button)) algoenabled=true; } else algoenabled=true; if(algoenabled) { if(!inputmod) { if(!TabRight(m_program,m_systab32)) { HWND okbutton=ControlGetHandle(m_program,OK_BUTTON_3); if(!okbutton) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed find Ok button"); return(false); } if(!ControlLeftClick(m_program,okbutton)) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Left Click failure"); return(false); } else { break; } } } else { HWND okbutton=ControlGetHandle(m_program,OK_BUTTON_3); if(!okbutton) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed find Ok button"); return(false); } if(!ControlLeftClick(m_program,okbutton)) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Left Click failure"); return(false); } } } else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Unable to enable autotrading"); return(false); } } else if(StringFind(windowtext,WINDOWTEXT_INPUT)==0) { StringFill(windowtext,0); HWND button=ControlGetHandle(m_program,LOAD_BUTTON); HWND okbutton=ControlGetHandle(m_program,(totaltabs>2)?OK_BUTTON_1:OK_BUTTON_2); if(!okbutton) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to find OK button"); return(false); } if(StringLen(ea_set_file)>0) { if(!button) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to find .set file load button"); return(false); } if(!ControlLeftClick(m_program,button)) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Left click failure"); return(false); } HWND filewin=0; int try =50; while(!filewin && try >0) { filewin=WinGetHandle(FILEDIALOGE_WINDOW); try --; Sleep(200); } HWND filedit=ControlGetHandle(filewin,FILENAME_EDIT); if(!filedit || !filewin) { if(!filedit) { if(filewin) WinClose(filewin); } WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" File dialogue failure"); return(false); } if(ControlSetText(filewin,filedit,"")) { if(ControlSend(filewin,filedit,ea_set_file,1)) { Sleep(200); if(ControlSend(filewin,filedit,"{ENTER}",0)) Sleep(300); } } if(WinExists(filewin)) { WinClose(filewin); WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to set .set file through file dialogue"); return(false); } } inputmod=true; if(algoenabled) { if(ControlLeftClick(m_program,okbutton)) break; else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to click OK button"); return(false); } } else { if(!TabLeft(m_program,m_systab32)) { if(ControlLeftClick(m_program,okbutton)) break; else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to click OK button"); return(false); } } } } } while(!inputmod||!dllenabled||!algoenabled); int try =50; while(WinExists(m_program) && try >0) { Sleep(500); try --; } if(WinExists(m_program) && !try) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to add program to chart"); return(false); } if(p_type==ENUM_TYPE_EXPERT && StringFind(ChartGetString(m_chartid,CHART_EXPERT_NAME),ea_name)<0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Operation failed could not add program to chart"); return(false); } return(true); }
ChartExpertRemove()は、スクリプトまたはエキスパートアドバイザーのいずれかをチャートから切り離します。これは、メインアプリケーションのメニューからエキスパートウィンドウダイアログを呼び出すことによって行われます。次に、このメソッドはプログラムのリストを反復処理し、プログラム名とチャートのプロパティ(つまり、チャートの銘柄と時間枠)に基づいて一致するものを見つけます。
ChartExpertRemoveAll()関数は、実際に削除を実行しているプログラムを除くすべてのEAとスクリプトを削除します。
//+------------------------------------------------------------------+ //|Removes EA,Script from a chart | //+------------------------------------------------------------------+ bool CTerminalController::ChartExpertRemove(const string ea_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf) { return(RemoveExpert(ea_name,chart_symbol,chart_tf)); }
//+------------------------------------------------------------------+ //|Helper function detaches program from a chart | //+------------------------------------------------------------------+ bool CTerminalController::RemoveExpert(const string program_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } if(!WinMenuSelectItem(m_terminal,MENU_CHARTS,MENU_EXPERTS_LIST,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Menu selection failure."); return(false); } Sleep(200); m_expwindow=WinGetHandle(EXPERTS_WINDOW); if(!m_expwindow) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_WINDOW+" window not found"); return(false); } m_explistview=ControlGetHandle(m_expwindow,EXPERTS_WINDOW_LISTVIEW); if(!m_explistview) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_WINDOW_LISTVIEW+" control not found"); return(false); } HWND remove_button=ControlGetHandle(m_expwindow,EXPERTS_REMOVE_BUTTON); if(!remove_button) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Remove button not found"); return(false); } long listsize=GetListViewItemCount(m_expwindow,m_explistview); if(listsize<=0) { return(true); } string newchartname=chart_symbol; StringToUpper(newchartname); newchartname+=","+PeriodToString(chart_tf); bool found=false; ClearAllListViewItemSelections(m_expwindow,m_explistview); for(int i=0; i<int(listsize); i++) { if(!SelectListViewItem(m_expwindow,m_explistview,IntegerToString(i),"")) continue; string pname=GetListViewItemText(m_expwindow,m_explistview,IntegerToString(i),"0"); string chartname=GetListViewItemText(m_expwindow,m_explistview,IntegerToString(i),"1"); if(StringFind(pname,program_name)>=0 && StringFind(chartname,newchartname)>=0) { if(IsControlEnabled(m_expwindow,remove_button)) if(ControlLeftClick(m_expwindow,remove_button)) found=true; } if(found) break; ClearAllListViewItemSelections(m_expwindow,m_explistview); } WinClose(m_expwindow); return(found); }
GetLastExpertsLogEntry()メソッドとGetLastJournalEntry()メソッドは、それぞれエキスパートログと操作ログで最後に生成された文字列への参照を出力します。
これらのメソッドは、[操作ログ]タブまたは[エキスパート]タブのいずれかと相互作用し、実際のログファイルからの読み取りは行いません。基本的に、テキストはlistview32コントロールから取得されます。タブが手動でクリアされた場合、メソッドはログファイルから直接データを取得できません。
//+------------------------------------------------------------------+ //|Gets the last journal entry | //+------------------------------------------------------------------+ void CTerminalController::GetLastJournalEntry(string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } long listsize=GetListViewItemCount(m_terminal,m_journaltab); if(listsize<=0) return; ClipPut(""); if(!ClearAllListViewItemSelections(m_terminal,m_journaltab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(!SelectListViewItem(m_terminal,m_journaltab,IntegerToString(listsize-1),"")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select last listview item"); return; } if(!ControlSend(m_terminal,m_journaltab,"{LCTRL down}c{LCTRL up}",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(entry); StringTrimRight(entry); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_journaltab); return; } //+------------------------------------------------------------------+ //|Gets last entry made to experts log file | //+------------------------------------------------------------------+ void CTerminalController::GetLastExpertsLogEntry(string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } long listsize=GetListViewItemCount(m_terminal,m_expertstab); if(listsize<=0) return; ClipPut(""); if(!ClearAllListViewItemSelections(m_terminal,m_expertstab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(!SelectListViewItem(m_terminal,m_expertstab,IntegerToString(listsize-1),"")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select last listview item"); return; } if(!ControlSend(m_terminal,m_expertstab,"{LCTRL down}c{LCTRL up}",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(entry); StringTrimRight(entry); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_expertstab); return; }
GetLastExpertsLogEntryByText()関数とGetLastJournalEntryByText()関数は、text_to_search_forパラメータに一致する最後のログエントリを返します。これらの関数は、最新のログエントリから時間を遡って検索を開始します。反復するログエントリの最大数はmax_items_to_search_inパラメータで設定されます。たとえば、このパラメータが10に設定されている場合、関数は最後の10個のログエントリを反復処理して、一致するものを探します。このパラメータが0または負の数に設定されている場合、関数はすべてのログエントリを反復処理します。
//+------------------------------------------------------------------+ //|Gets last entry made to experts log file containg certain string | //+------------------------------------------------------------------+ void CTerminalController::GetLastExpertsLogEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } string items; string itemsarray[]; long listsize=GetListViewItemCount(m_terminal,m_expertstab); if(listsize<=0) return; long stop=(max_items_to_search_in>0)? listsize-max_items_to_search_in:0; if(!ClearAllListViewItemSelections(m_terminal,m_expertstab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(stop<=0) { if(!SelectAllListViewItems(m_terminal,m_expertstab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select all listview items"); return; } StringInit(items,int(listsize)*1000); } else { if(!SelectListViewItem(m_terminal,m_expertstab,IntegerToString(stop),IntegerToString(listsize-1))) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select "+IntegerToString(stop)+" listview items"); return; } StringInit(items,int(stop)*1000); } ClipPut(""); if(!ControlSend(m_terminal,m_expertstab,"{LCTRL down}c",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(items); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_expertstab); int a_size=StringSplit(items,StringGetCharacter("\n",0),itemsarray); for(int i=(a_size-1); i>=0; i--) { if(itemsarray[i]=="") continue; if(StringFind(itemsarray[i],text_to_search_for,24)>=24) { entry=itemsarray[i]; StringTrimRight(entry); break;; } } ArrayFree(itemsarray); return; } //+------------------------------------------------------------------+ //|Gets last entry made to journal containing certain string | //+------------------------------------------------------------------+ void CTerminalController::GetLastJournalEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } string items; string itemsarray[]; long listsize=GetListViewItemCount(m_terminal,m_journaltab); if(listsize<=0) return; long stop=(max_items_to_search_in>0)? listsize-max_items_to_search_in:0; if(!ClearAllListViewItemSelections(m_terminal,m_journaltab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(stop<=0) { if(!SelectAllListViewItems(m_terminal,m_journaltab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select all listview items"); return; } StringInit(items,int(listsize)*1000); } else { if(!SelectListViewItem(m_terminal,m_journaltab,IntegerToString(stop),IntegerToString(listsize-1))) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select "+IntegerToString(stop)+" listview items"); return; } StringInit(items,int(stop)*1000); } ClipPut(""); if(!ControlSend(m_terminal,m_journaltab,"{LCTRL down}c",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(items); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_journaltab); int a_size=StringSplit(items,StringGetCharacter("\n",0),itemsarray); for(int i=(a_size-1); i>=0; i--) { if(itemsarray[i]=="") continue; if(StringFind(itemsarray[i],text_to_search_for,24)>=24) { entry=itemsarray[i]; StringTrimRight(entry); break;; } } ArrayFree(itemsarray); return; }
SetNotificationId()メソッドは、この概念の元のデモンストレーションに逆戻りするもので、最大4つのMetaQuotes ID文字列パラメータを受け取ります。
//+------------------------------------------------------------------+ //|set the MetaQuotes id | //+------------------------------------------------------------------+ bool CTerminalController::SetNotificationId(const string MetaQuotes_id) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } string itemsarray[]; int totalids=StringSplit(MetaQuotes_id,StringGetCharacter(",",0),itemsarray); if(totalids>4) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Invalid parameter settings, Only maximum of 4 MetaQuotes ID's allowed"); return(false); } HWND opt_window,opt_tab,edit,ok,checkbutton1,checkbutton2,checkbutton3; if(!WinMenuSelectItem(m_terminal,MENU_TOOLS,MENU_OPTIONS,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Menu selection failure."); return(false); } Sleep(200); opt_window=WinGetHandle(OPTWINDOW); if(!opt_window) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Options Window not found."); return(false); } opt_tab=ControlGetHandle(opt_window,OPTWINDOW_TAB); if(!opt_tab) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Options Window tab control not found"); WinClose(opt_window); return(false); } RECT wnsize; WinClientSize(opt_window,wnsize); int y=5; int x=5; string wintext=WinGetText(opt_window); while(StringFind(wintext,NOTIFICATIONS_TEXT)<0) { if(x<wnsize.right && ControlLeftClick(opt_window,opt_tab,1,x,5)) { wintext=WinGetText(opt_window); x+=y; } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Notification settings tab not found"); WinClose(opt_window); return(false); } } checkbutton1=ControlGetHandle(opt_window,OPTWINDOW_CHECK_1); if(!checkbutton1) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Enable Notifications check button not found"); WinClose(opt_window); return(false); } checkbutton2=ControlGetHandle(opt_window,OPTWINDOW_CHECK_2); if(!checkbutton2) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Enable Notifications from terminal check button not found"); WinClose(opt_window); return(false); } checkbutton3=ControlGetHandle(opt_window,OPTWINDOW_CHECK_3); if(!checkbutton3) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Enable Notifications from trade server check button not found"); WinClose(opt_window); return(false); } ok=ControlGetHandle(opt_window,OPTWINDOW_OK); if(!ok) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"OK button not found"); WinClose(opt_window); return(false); } edit=ControlGetHandle(opt_window,OPTWINDOW_EDIT); if(!checkbutton1) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Notification Ids edit control not found"); WinClose(opt_window); return(false); } string current_id=ControlGetText(opt_window,edit); if(!StringCompare(current_id,MetaQuotes_id)) { WinClose(opt_window); return(true); } if(!IsButtonChecked(opt_window,checkbutton1)) CheckButton(opt_window,checkbutton1); if(IsControlEnabled(opt_window,checkbutton2) && !IsButtonChecked(opt_window,checkbutton2)) CheckButton(opt_window,checkbutton2); if(IsControlEnabled(opt_window,checkbutton3) && !IsButtonChecked(opt_window,checkbutton3)) CheckButton(opt_window,checkbutton3); if(ControlSetText(opt_window,edit,"")) ControlSend(opt_window,edit,MetaQuotes_id,1); if(ControlLeftClick(opt_window,ok)) Sleep(200); if(WinExists(opt_window)) WinClose(opt_window); return(true); }
CloseAlertDialogue()は呼び出されると、アラートポップアップの存在を確認し、存在する場合には閉じます。
//+------------------------------------------------------------------+ //| closes any pop up alert window | //+------------------------------------------------------------------+ void CTerminalController::CloseAlertDialogue(void) { static datetime lastcheck; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } if(WinExists(ALERTWINDOW,"")) { string alertmessage; StringInit(alertmessage,200); GetLastExpertsLogEntryByText(ALERTWINDOW,0,alertmessage); if(StringLen(alertmessage)>0) { datetime check=StringToTime(StringSubstr(alertmessage,0,24)); if(check>lastcheck && check>iTime(NULL,PERIOD_D1,0)) { WinClose(ALERTWINDOW,""); lastcheck=check; } } } return; }
クラス全体のコードを以下に示します。
//+------------------------------------------------------------------+ //| terminalcontroller.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #include<autoItbase.mqh> #define JOURNAL_TAB "SysListView321" #define EXPERTS_TAB "SysListView327" #define NAVIGATOR "SysTreeView321" #define NAVIGATOR_TAB_BAR "AfxWnd140su3" #define PROGRAM_WINDOW_TAB "SysTabControl321" #define EXPERTS_WINDOW_LISTVIEW "SysListView321" #define EXPERTS_REMOVE_BUTTON "Button2" #define DLLCHECK_BUTTON "Button1" #define ALGOTRADECHECK_BUTTON "Button4" #define OK_BUTTON_1 "Button7" #define OK_BUTTON_2 "Button3" #define OK_BUTTON_3 "Button5" #define LOAD_BUTTON "Button1" #define YES_BUTTON "Button1" #define FILENAME_EDIT "Edit1" #define OPTWINDOW_TAB "SysTabControl321" #define OPTWINDOW_CHECK_1 "Button1" #define OPTWINDOW_CHECK_2 "Button2" #define OPTWINDOW_CHECK_3 "Button6" #define OPTWINDOW_OK "Button7" #define OPTWINDOW_EDIT "Edit1" #define EXPERTS_WINDOW "Experts" #define NAVIGATORWINDOW "Navigator" #define TOOLBOXWINDOW "Toolbox" #define FILEDIALOGE_WINDOW "Open" #define WINDOWTEXT_DLL "Allow DLL" #define WINDOWTEXT_EA "Expert Advisor settings" #define WINDOWTEXT_INPUT "Input" #define OPTWINDOW "Options" #define NOTIFICATIONS_TEXT "Enable Push notifications" #define ALERTWINDOW "Alert" #define MENU_TOOLS "&Tools" #define MENU_OPTIONS "&Options" #define MENU_WINDOW "&Window" #define MENU_TILEWINDOWS "&Tile Windows" #define MENU_VIEW "&View" #define MENU_NAVIGATOR "&Navigator" #define MENU_CHARTS "&Charts" #define MENU_EXPERTS_LIST "&Expert List" enum ENUM_TYPE_PROGRAM { ENUM_TYPE_EXPERT=0,//EXPERT_ADVISOR ENUM_TYPE_SCRIPT//SCRIPT }; //+------------------------------------------------------------------+ //|Class CTerminalController | //| Purpose: class for scripting the terminal | //+------------------------------------------------------------------+ class CTerminalController:public CAutoIt { private: HWND m_terminal; //terminal window handle HWND m_journaltab; //journal tab handle HWND m_expertstab; //experts tab handle HWND m_navigator; //navigator systreeview HWND m_navigatortabs; //navigator tab header HWND m_navigatorwindow; //navigator window HWND m_systab32; //handle to inputs tabbed control with in inputs dialogue HWND m_program; //window handle for user inputs dialogue HWND m_expwindow; //handle to window showing list of experts HWND m_explistview; //list view control for experts list in m_expwindow long m_chartid; //chart id long m_accountNum; //account number string m_buffer; //string buffer public: //default constructor CTerminalController(void): m_terminal(0), m_journaltab(0), m_expertstab(0), m_navigator(0), m_navigatortabs(0), m_navigatorwindow(0), m_systab32(0), m_program(0), m_expwindow(0), m_explistview(0), m_chartid(-1), m_buffer("") { m_accountNum=AccountInfoInteger(ACCOUNT_LOGIN); StringInit(m_buffer,1000); } //destructor ~CTerminalController(void) { } //public methods string GetErrorDetails(void) { return(m_buffer); } bool ChartExpertAdd(const ENUM_TYPE_PROGRAM p_type,const string ea_name,const string ea_relative_path,const string ea_set_file,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf); bool ChartExpertRemove(const string ea_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf); bool ChartExpertRemoveAll(void); void CloseAlertDialogue(void); void GetLastExpertsLogEntry(string &entry); void GetLastExpertsLogEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry); void GetLastJournalEntry(string &entry); void GetLastJournalEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry); bool Initialize(const long accountNumber=0); bool SwitchToNewChart(string n_symbol, const ENUM_TIMEFRAMES n_tf); bool SetNotificationId(const string MetaQuotes_id); bool ToggleAutoTrading(void); private: //helper methods void SetErrorDetails(const string text); void Findbranch(const long childrenOnBranch,const string index,const string pname,string& sbuffer); bool Findprogram(const ENUM_TYPE_PROGRAM pr_type, const string program_name,const string relative_path,string& sbuffer); string PeriodToString(const ENUM_TIMEFRAMES chart_tf); bool RemoveExpert(const string program_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf); string BrokerName(void); }; //+------------------------------------------------------------------+ //| sets or resets window and control handles used in the class | //+------------------------------------------------------------------+ bool CTerminalController::Initialize(const long accountNumber=0) { Init(); if(accountNumber>0 && accountNumber!=m_accountNum) { m_accountNum=accountNumber; m_program=m_expwindow=m_systab32=m_explistview=m_navigatorwindow=0; m_terminal=m_journaltab=m_expertstab=m_navigator=m_navigatortabs=0; m_chartid=0; } if(m_terminal) return(true); m_terminal=WinGetHandle(IntegerToString(m_accountNum)); if(!m_terminal) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Terminal window "+IntegerToString(m_accountNum)+" not found"); return(false); } m_journaltab=ControlGetHandle(m_terminal,JOURNAL_TAB); if(!m_journaltab) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+JOURNAL_TAB+" not found"); return(false); } m_expertstab=ControlGetHandle(m_terminal,EXPERTS_TAB); if(!m_expertstab) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_TAB+" not found"); return(false); } m_navigatorwindow=ControlGetHandle(m_terminal,NAVIGATORWINDOW); if(!m_navigatorwindow) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+NAVIGATORWINDOW+" not found"); return(false); } m_navigator=ControlGetHandle(m_terminal,NAVIGATOR); if(!m_navigator) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+NAVIGATOR+" not found"); return(false); } m_navigatortabs=ControlGetHandle(m_terminal,NAVIGATOR_TAB_BAR); if(!m_navigatortabs) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+NAVIGATOR_TAB_BAR+" not found"); return(false); } StringInit(m_buffer,1000); return(true); } //+------------------------------------------------------------------+ //|sets focus to existing or new chart window | //+------------------------------------------------------------------+ bool CTerminalController::SwitchToNewChart(string n_symbol,const ENUM_TIMEFRAMES n_tf) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } string sarray[]; StringToUpper(n_symbol); string newchartname=n_symbol+","+PeriodToString(n_tf); if(!WinMenuSelectItem(m_terminal,MENU_WINDOW,MENU_TILEWINDOWS,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to select menu item: Tile Windows"); return(false); } Sleep(200); string windowtext=WinGetText(m_terminal); int find=StringFind(windowtext,ChartSymbol(ChartFirst())+","+PeriodToString(ChartPeriod(ChartFirst()))); string chartstring=StringSubstr(windowtext,find); StringReplace(chartstring,"\n\n","\n"); int sarraysize=StringSplit(chartstring,StringGetCharacter("\n",0),sarray); bool found=false; int i; long prevChart=0; m_chartid=ChartFirst(); for(i=0; i<sarraysize; i++,) { if(sarray[i]=="") continue; if(i>0) m_chartid=ChartNext(prevChart); if(StringFind(sarray[i],newchartname)>=0) { found=true; break; } prevChart=m_chartid; } ArrayFree(sarray); HWND frameview=0; if(found) frameview=ControlGetHandle(m_terminal,newchartname); else if(ChartOpen(n_symbol,n_tf)) frameview=ControlGetHandle(m_terminal,newchartname); if(frameview) { if(!WinSetState(frameview,SW_MAXIMIZE)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Could not maximize "+newchartname+" chart window"); return(false); } } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Chart window "+newchartname+" not found"); return(false); } return(true); } //+------------------------------------------------------------------+ //| Adds EA,Script,Service to a chart | //+------------------------------------------------------------------+ bool CTerminalController::ChartExpertAdd(const ENUM_TYPE_PROGRAM p_type,const string ea_name,const string ea_relative_path,const string ea_set_file,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf) { if(!SwitchToNewChart(chart_symbol,chart_tf)) { return(false); } if(StringFind((p_type==ENUM_TYPE_EXPERT)?ChartGetString(m_chartid,CHART_EXPERT_NAME):ChartGetString(m_chartid,CHART_SCRIPT_NAME),ea_name)>=0) { return(true); } if(p_type==ENUM_TYPE_EXPERT && StringFind(ChartGetString(m_chartid,CHART_EXPERT_NAME),ChartGetString(ChartID(),CHART_EXPERT_NAME))>=0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Cannot replace currenlty running Expert"); return(false); } if(StringLen(ea_set_file)>0) { if(StringFind(ea_relative_path,".set")<0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Incorrect parameter setting, set file name should contain .set file extension"); return(false); } } if(!IsControlVisible(m_terminal,m_navigator)) { if(!IsControlVisible(m_terminal,m_navigatorwindow)) { if(!WinMenuSelectItem(m_terminal,MENU_VIEW,MENU_NAVIGATOR,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to select menu item : Navigator"); return(false); } } if(!ControlLeftClick(m_terminal,m_navigatortabs,1,5,5)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to click on Navigator, Common tab"); return(false); } } string treepath=""; if(!Findprogram(p_type,ea_name,ea_relative_path,treepath)) return(false); if(!SelectTreeViewItem(m_terminal,m_navigator,treepath)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to select treeview item: "+treepath); return(false); } if(!ControlSend(m_terminal,m_navigator,"{SHIFTDOWN}{F10}{SHIFTUP}c",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Control Send failure"); return(false); } Sleep(500); m_program=WinGetHandle(ea_name); HWND dialogue=WinGetHandle(BrokerName()+" - MetaTrader 5",ea_name); if(!m_program && !dialogue) { if(p_type==ENUM_TYPE_EXPERT && StringFind(ChartGetString(m_chartid,CHART_EXPERT_NAME),ea_name)<0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Could not add program to chart"); return(false); } else { return(true); } } if(!m_program && dialogue)// replace current ea { HWND button = ControlGetHandle(dialogue,YES_BUTTON); if(button) { if(ControlLeftClick(dialogue,button)) { Sleep(200); m_program=WinGetHandle(ea_name); } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed left click on yes button"); WinClose(dialogue); return(false); } } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Yes button for dialogue not found"); WinClose(dialogue); return(false); } } m_systab32=ControlGetHandle(m_program,PROGRAM_WINDOW_TAB); if(!m_systab32) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+PROGRAM_WINDOW_TAB+ "not found"); return(false); } long totaltabs=TotalTabs(m_program,m_systab32); bool algoenabled=false; bool inputmod=false; bool dllenabled=(totaltabs<3)?true:false; do { string windowtext=WinGetText(m_program); if(StringFind(windowtext,WINDOWTEXT_DLL)>=0) { StringFill(windowtext,0); HWND button=ControlGetHandle(m_program,DLLCHECK_BUTTON); if(!button) { WinClose(m_program); { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"DLL check button not found"); return(false); } } if(!IsButtonChecked(m_program,button)) { if(CheckButton(m_program,button)) dllenabled=true; } else dllenabled=true; if(dllenabled) { if(TabLeft(m_program,m_systab32)) if(!TabLeft(m_program,m_systab32)) { inputmod=true; } } else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Could not enable DLL loading"); return(false); } } else if(StringFind(windowtext,WINDOWTEXT_EA)==0) { StringFill(windowtext,0); HWND button=ControlGetHandle(m_program,ALGOTRADECHECK_BUTTON); if(!button) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Algo check button not found"); return(false); } if(!IsButtonChecked(m_program,button)) { if(CheckButton(m_program,button)) algoenabled=true; } else algoenabled=true; if(algoenabled) { if(!inputmod) { if(!TabRight(m_program,m_systab32)) { HWND okbutton=ControlGetHandle(m_program,OK_BUTTON_3); if(!okbutton) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed find Ok button"); return(false); } if(!ControlLeftClick(m_program,okbutton)) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Left Click failure"); return(false); } else { break; } } } else { HWND okbutton=ControlGetHandle(m_program,OK_BUTTON_3); if(!okbutton) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed find Ok button"); return(false); } if(!ControlLeftClick(m_program,okbutton)) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Left Click failure"); return(false); } } } else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Unable to enable autotrading"); return(false); } } else if(StringFind(windowtext,WINDOWTEXT_INPUT)==0) { StringFill(windowtext,0); HWND button=ControlGetHandle(m_program,LOAD_BUTTON); HWND okbutton=ControlGetHandle(m_program,(totaltabs>2)?OK_BUTTON_1:OK_BUTTON_2); if(!okbutton) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to find OK button"); return(false); } if(StringLen(ea_set_file)>0) { if(!button) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to find .set file load button"); return(false); } if(!ControlLeftClick(m_program,button)) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Left click failure"); return(false); } HWND filewin=0; int try =50; while(!filewin && try >0) { filewin=WinGetHandle(FILEDIALOGE_WINDOW); try --; Sleep(200); } HWND filedit=ControlGetHandle(filewin,FILENAME_EDIT); if(!filedit || !filewin) { if(!filedit) { if(filewin) WinClose(filewin); } WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" File dialogue failure"); return(false); } if(ControlSetText(filewin,filedit,"")) { if(ControlSend(filewin,filedit,ea_set_file,1)) { Sleep(200); if(ControlSend(filewin,filedit,"{ENTER}",0)) Sleep(300); } } if(WinExists(filewin)) { WinClose(filewin); WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to set .set file through file dialogue"); return(false); } } inputmod=true; if(algoenabled) { if(ControlLeftClick(m_program,okbutton)) break; else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to click OK button"); return(false); } } else { if(!TabLeft(m_program,m_systab32)) { if(ControlLeftClick(m_program,okbutton)) break; else { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to click OK button"); return(false); } } } } } while(!inputmod||!dllenabled||!algoenabled); int try =50; while(WinExists(m_program) && try >0) { Sleep(500); try --; } if(WinExists(m_program) && !try) { WinClose(m_program); SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Failed to add program to chart"); return(false); } if(p_type==ENUM_TYPE_EXPERT && StringFind(ChartGetString(m_chartid,CHART_EXPERT_NAME),ea_name)<0) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+" Operation failed could not add program to chart"); return(false); } return(true); } //+------------------------------------------------------------------+ //|Removes EA,Script from a chart | //+------------------------------------------------------------------+ bool CTerminalController::ChartExpertRemove(const string ea_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf) { return(RemoveExpert(ea_name,chart_symbol,chart_tf)); } //+------------------------------------------------------------------+ //| Removes all scripts and experts from all charts | //+------------------------------------------------------------------+ bool CTerminalController::ChartExpertRemoveAll(void) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } if(!WinMenuSelectItem(m_terminal,MENU_CHARTS,MENU_EXPERTS_LIST,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Menu selection failure."); return(false); } Sleep(200); m_expwindow=WinGetHandle(EXPERTS_WINDOW); if(!m_expwindow) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_WINDOW+" window not found"); return(false); } m_explistview=ControlGetHandle(m_expwindow,EXPERTS_WINDOW_LISTVIEW); if(!m_explistview) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_WINDOW_LISTVIEW+" control not found"); WinClose(m_expwindow); return(false); } HWND remove_button=ControlGetHandle(m_expwindow,EXPERTS_REMOVE_BUTTON); if(!remove_button) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Remove button not found"); WinClose(m_expwindow); return(false); } long listsize=GetListViewItemCount(m_expwindow,m_explistview); if(listsize<=1) { WinClose(m_expwindow); return(true); } string prgname; ENUM_PROGRAM_TYPE mql_program=(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE); switch(mql_program) { case PROGRAM_SCRIPT: { prgname=ChartGetString(ChartID(),CHART_SCRIPT_NAME); break; } case PROGRAM_EXPERT: { prgname=ChartGetString(ChartID(),CHART_EXPERT_NAME); break; } default: prgname=""; } if(prgname=="") { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Unable to determine name of current program"); WinClose(m_expwindow); return(false); } do { ClearAllListViewItemSelections(m_expwindow,m_explistview); for(int i=0; i<int(listsize); i++) { if(!SelectListViewItem(m_expwindow,m_explistview,IntegerToString(i),"")) continue; string pname=GetListViewItemText(m_expwindow,m_explistview,IntegerToString(i),"0"); if(StringFind(pname,prgname)<0) { if(IsControlEnabled(m_expwindow,remove_button)) { if(ControlLeftClick(m_expwindow,remove_button)) { listsize--; Sleep(500); break; } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Failed to click remove button"); break; } } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Remove button is disabled"); break; } } else { ClearAllListViewItemSelections(m_expwindow,m_explistview); continue; } } } while(listsize>1); while(WinExists(m_expwindow)) WinClose(m_expwindow); return(true); } //+------------------------------------------------------------------+ //|Gets the last journal entry | //+------------------------------------------------------------------+ void CTerminalController::GetLastJournalEntry(string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } long listsize=GetListViewItemCount(m_terminal,m_journaltab); if(listsize<=0) return; ClipPut(""); if(!ClearAllListViewItemSelections(m_terminal,m_journaltab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(!SelectListViewItem(m_terminal,m_journaltab,IntegerToString(listsize-1),"")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select last listview item"); return; } if(!ControlSend(m_terminal,m_journaltab,"{LCTRL down}c{LCTRL up}",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(entry); StringTrimRight(entry); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_journaltab); return; } //+------------------------------------------------------------------+ //|Gets last entry made to experts log file | //+------------------------------------------------------------------+ void CTerminalController::GetLastExpertsLogEntry(string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } long listsize=GetListViewItemCount(m_terminal,m_expertstab); if(listsize<=0) return; ClipPut(""); if(!ClearAllListViewItemSelections(m_terminal,m_expertstab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(!SelectListViewItem(m_terminal,m_expertstab,IntegerToString(listsize-1),"")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select last listview item"); return; } if(!ControlSend(m_terminal,m_expertstab,"{LCTRL down}c{LCTRL up}",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(entry); StringTrimRight(entry); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_expertstab); return; } //+------------------------------------------------------------------+ //|Gets last entry made to experts log file containg certain string | //+------------------------------------------------------------------+ void CTerminalController::GetLastExpertsLogEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } string items; string itemsarray[]; long listsize=GetListViewItemCount(m_terminal,m_expertstab); if(listsize<=0) return; long stop=(max_items_to_search_in>0)? listsize-max_items_to_search_in:0; if(!ClearAllListViewItemSelections(m_terminal,m_expertstab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(stop<=0) { if(!SelectAllListViewItems(m_terminal,m_expertstab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select all listview items"); return; } StringInit(items,int(listsize)*1000); } else { if(!SelectListViewItem(m_terminal,m_expertstab,IntegerToString(stop),IntegerToString(listsize-1))) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select "+IntegerToString(stop)+" listview items"); return; } StringInit(items,int(stop)*1000); } ClipPut(""); if(!ControlSend(m_terminal,m_expertstab,"{LCTRL down}c",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(items); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_expertstab); int a_size=StringSplit(items,StringGetCharacter("\n",0),itemsarray); for(int i=(a_size-1); i>=0; i--) { if(itemsarray[i]=="") continue; if(StringFind(itemsarray[i],text_to_search_for,24)>=24) { entry=itemsarray[i]; StringTrimRight(entry); break;; } } ArrayFree(itemsarray); return; } //+------------------------------------------------------------------+ //|Gets last entry made to journal containing certain string | //+------------------------------------------------------------------+ void CTerminalController::GetLastJournalEntryByText(const string text_to_search_for,const int max_items_to_search_in,string &entry) { entry=""; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } string items; string itemsarray[]; long listsize=GetListViewItemCount(m_terminal,m_journaltab); if(listsize<=0) return; long stop=(max_items_to_search_in>0)? listsize-max_items_to_search_in:0; if(!ClearAllListViewItemSelections(m_terminal,m_journaltab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to deselect all listview items"); return; } if(stop<=0) { if(!SelectAllListViewItems(m_terminal,m_journaltab)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select all listview items"); return; } StringInit(items,int(listsize)*1000); } else { if(!SelectListViewItem(m_terminal,m_journaltab,IntegerToString(stop),IntegerToString(listsize-1))) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to select "+IntegerToString(stop)+" listview items"); return; } StringInit(items,int(stop)*1000); } ClipPut(""); if(!ControlSend(m_terminal,m_journaltab,"{LCTRL down}c",0)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"failed to send keys to control"); return; } ClipGet(items); ClipPut(""); ClearAllListViewItemSelections(m_terminal,m_journaltab); int a_size=StringSplit(items,StringGetCharacter("\n",0),itemsarray); for(int i=(a_size-1); i>=0; i--) { if(itemsarray[i]=="") continue; if(StringFind(itemsarray[i],text_to_search_for,24)>=24) { entry=itemsarray[i]; StringTrimRight(entry); break;; } } ArrayFree(itemsarray); return; } //+------------------------------------------------------------------+ //|Helper function detaches program from a chart | //+------------------------------------------------------------------+ bool CTerminalController::RemoveExpert(const string program_name,const string chart_symbol,const ENUM_TIMEFRAMES chart_tf) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } if(!WinMenuSelectItem(m_terminal,MENU_CHARTS,MENU_EXPERTS_LIST,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Menu selection failure."); return(false); } Sleep(200); m_expwindow=WinGetHandle(EXPERTS_WINDOW); if(!m_expwindow) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_WINDOW+" window not found"); return(false); } m_explistview=ControlGetHandle(m_expwindow,EXPERTS_WINDOW_LISTVIEW); if(!m_explistview) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+EXPERTS_WINDOW_LISTVIEW+" control not found"); return(false); } HWND remove_button=ControlGetHandle(m_expwindow,EXPERTS_REMOVE_BUTTON); if(!remove_button) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Remove button not found"); return(false); } long listsize=GetListViewItemCount(m_expwindow,m_explistview); if(listsize<=0) { return(true); } string newchartname=chart_symbol; StringToUpper(newchartname); newchartname+=","+PeriodToString(chart_tf); bool found=false; ClearAllListViewItemSelections(m_expwindow,m_explistview); for(int i=0; i<int(listsize); i++) { if(!SelectListViewItem(m_expwindow,m_explistview,IntegerToString(i),"")) continue; string pname=GetListViewItemText(m_expwindow,m_explistview,IntegerToString(i),"0"); string chartname=GetListViewItemText(m_expwindow,m_explistview,IntegerToString(i),"1"); if(StringFind(pname,program_name)>=0 && StringFind(chartname,newchartname)>=0) { if(IsControlEnabled(m_expwindow,remove_button)) if(ControlLeftClick(m_expwindow,remove_button)) found=true; } if(found) break; ClearAllListViewItemSelections(m_expwindow,m_explistview); } WinClose(m_expwindow); return(found); } //+------------------------------------------------------------------+ //|helper method converts period names to string format | //+------------------------------------------------------------------+ string CTerminalController::PeriodToString(const ENUM_TIMEFRAMES chart_tf) { string strper=""; switch(chart_tf) { case PERIOD_MN1: strper="Monthly"; break; case PERIOD_W1: strper="Weekly"; break; case PERIOD_D1: strper="Daily"; break; default: strper=StringSubstr(EnumToString(chart_tf),StringFind(EnumToString(chart_tf),"_")+1); break; } return strper; } //+---------------------------------------------------------------------+ //|searches navigator for a program and outputs its location on the tree| //+---------------------------------------------------------------------+ bool CTerminalController::Findprogram(const ENUM_TYPE_PROGRAM pr_type,const string program_name,const string relative_path,string &sbuffer) { long listsize=GetTreeViewItemCount(m_terminal,m_navigator,"#0"); if(!listsize) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Root treeview control is empty"); return(false); } else { string rpath=""; if(relative_path=="") rpath=relative_path; else { if(StringFind(relative_path,"\\")==0) rpath=StringSubstr(relative_path,1); else rpath=relative_path; if(StringFind(rpath,"\\",StringLen(rpath)-1)<0) rpath+="\\"; } switch(pr_type) { case ENUM_TYPE_EXPERT: { string fullpath="Expert Advisors\\"+rpath+program_name; Findbranch(listsize,"#0",fullpath,sbuffer); break; } case ENUM_TYPE_SCRIPT: { string fullpath="Scripts\\"+rpath+program_name; Findbranch(listsize,"#0",fullpath,sbuffer); break; } default: Findbranch(listsize,"#0","",sbuffer); break; } } if(sbuffer=="") { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Operation failed could not find "+program_name); return(false); } else return(true); } //+-----------------------------------------------------------------------+ //|recursively searches systreeview for program and builds location string| //+-----------------------------------------------------------------------+ void CTerminalController::Findbranch(const long childrenOnBranch,const string index,const string pname,string &sbuffer) { if(pname=="" || index=="") { sbuffer=index; return; } else { if(childrenOnBranch<=0) return; else { int find=StringFind(pname,"\\"); long ss=0; long i; for(i=0; i<childrenOnBranch; i++) { ss=GetTreeViewItemCount(m_terminal,m_navigator,index+"|#"+IntegerToString(i)); string search=(find>=0)?StringSubstr(pname,0,find):pname; string treebranchtext=GetTreeViewItemText(m_terminal,m_navigator,index+"|#"+IntegerToString(i)); if(StringFind(treebranchtext,search)>=0 && StringLen(treebranchtext)==StringLen(search)) break; } string npath=(find>=0)?StringSubstr(pname,find+1):""; Findbranch(ss,(i<childrenOnBranch)?index+"|#"+IntegerToString(i):"",npath,sbuffer); } } return; } //+------------------------------------------------------------------+ //| Get the broker name from the terminal window title | //+------------------------------------------------------------------+ string CTerminalController::BrokerName(void) { string full_title=WinGetTitle(m_terminal); int find=StringFind(full_title,"-"); string m_brokername=StringSubstr(full_title,find+1,StringFind(full_title,"-",find+1)-find-1); StringTrimLeft(m_brokername); StringTrimRight(m_brokername); return(m_brokername); } //+------------------------------------------------------------------+ //| Set error details | //+------------------------------------------------------------------+ void CTerminalController::SetErrorDetails(const string _text) { StringFill(m_buffer,0); m_buffer=_text; return; } //+------------------------------------------------------------------+ //|set the MetaQuotes id | //+------------------------------------------------------------------+ bool CTerminalController::SetNotificationId(const string MetaQuotes_id) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } string itemsarray[]; int totalids=StringSplit(MetaQuotes_id,StringGetCharacter(",",0),itemsarray); if(totalids>4) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Invalid parameter settings, Only maximum of 4 MetaQuotes ID's allowed"); return(false); } HWND opt_window,opt_tab,edit,ok,checkbutton1,checkbutton2,checkbutton3; if(!WinMenuSelectItem(m_terminal,MENU_TOOLS,MENU_OPTIONS,"","","","","","")) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Menu selection failure."); return(false); } Sleep(200); opt_window=WinGetHandle(OPTWINDOW); if(!opt_window) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Options Window not found."); return(false); } opt_tab=ControlGetHandle(opt_window,OPTWINDOW_TAB); if(!opt_tab) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Options Window tab control not found"); WinClose(opt_window); return(false); } RECT wnsize; WinClientSize(opt_window,wnsize); int y=5; int x=5; string wintext=WinGetText(opt_window); while(StringFind(wintext,NOTIFICATIONS_TEXT)<0) { if(x<wnsize.right && ControlLeftClick(opt_window,opt_tab,1,x,5)) { wintext=WinGetText(opt_window); x+=y; } else { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Notification settings tab not found"); WinClose(opt_window); return(false); } } checkbutton1=ControlGetHandle(opt_window,OPTWINDOW_CHECK_1); if(!checkbutton1) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Enable Notifications check button not found"); WinClose(opt_window); return(false); } checkbutton2=ControlGetHandle(opt_window,OPTWINDOW_CHECK_2); if(!checkbutton2) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Enable Notifications from terminal check button not found"); WinClose(opt_window); return(false); } checkbutton3=ControlGetHandle(opt_window,OPTWINDOW_CHECK_3); if(!checkbutton3) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Enable Notifications from trade server check button not found"); WinClose(opt_window); return(false); } ok=ControlGetHandle(opt_window,OPTWINDOW_OK); if(!ok) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"OK button not found"); WinClose(opt_window); return(false); } edit=ControlGetHandle(opt_window,OPTWINDOW_EDIT); if(!checkbutton1) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"Notification Ids edit control not found"); WinClose(opt_window); return(false); } string current_id=ControlGetText(opt_window,edit); if(!StringCompare(current_id,MetaQuotes_id)) { WinClose(opt_window); return(true); } if(!IsButtonChecked(opt_window,checkbutton1)) CheckButton(opt_window,checkbutton1); if(IsControlEnabled(opt_window,checkbutton2) && !IsButtonChecked(opt_window,checkbutton2)) CheckButton(opt_window,checkbutton2); if(IsControlEnabled(opt_window,checkbutton3) && !IsButtonChecked(opt_window,checkbutton3)) CheckButton(opt_window,checkbutton3); if(ControlSetText(opt_window,edit,"")) ControlSend(opt_window,edit,MetaQuotes_id,1); if(ControlLeftClick(opt_window,ok)) Sleep(200); if(WinExists(opt_window)) WinClose(opt_window); return(true); } //+------------------------------------------------------------------+ //| closes any pop up alert window | //+------------------------------------------------------------------+ void CTerminalController::CloseAlertDialogue(void) { static datetime lastcheck; if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return; } if(WinExists(ALERTWINDOW,"")) { string alertmessage; StringInit(alertmessage,200); GetLastExpertsLogEntryByText(ALERTWINDOW,0,alertmessage); if(StringLen(alertmessage)>0) { datetime check=StringToTime(StringSubstr(alertmessage,0,24)); if(check>lastcheck && check>iTime(NULL,PERIOD_D1,0)) { WinClose(ALERTWINDOW,""); lastcheck=check; } } } return; } //+------------------------------------------------------------------+ //|Enable and disable autotrading | //+------------------------------------------------------------------+ bool CTerminalController::ToggleAutoTrading(void) { if(!IsInitialized()) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } if(!ControlSend(m_terminal,m_navigatortabs,"{LCTRL down}e{LCTRL up}",1)) { SetErrorDetails(__FUNCTION__+" "+string(__LINE__)+". "+"AutoIt library not Initialized"); return(false); } return(true); } //+------------------------------------------------------------------+
CTerminalControllerクラスの使用
最初の例では、チャートにプログラムを追加して削除する方法を示しています。プログラムの名前を追加し、チャートを指定します。最後の入力パラメータは、追加されたプログラムが実行される時間を秒単位で指定します。プログラムは、指定された時間の後にまだ実行中の場合に削除されます。
//+------------------------------------------------------------------+ //| TerminalController.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #property version "1.00" #include<terminalcontroller.mqh> //--- input parameters input string ProgramName="Controls"; input string Path="Examples\\Controls"; input string Symbolname="BTCUSD"; input ENUM_TIMEFRAMES Timeframe=PERIOD_D1; input ENUM_TYPE_PROGRAM Type=0; input string SetFileName=""; input int RemoveProgramTimer=10;//Max seconds added program will run CTerminalController terminal; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- if(!terminal.Initialize()) { Print("Service failed to initialize CTerminalController instance"); return(INIT_FAILED); } if(!terminal.ChartExpertAdd(Type,ProgramName,Path,SetFileName,Symbolname,Timeframe)) Print("Failed to add "+ProgramName+" to chart. Error > "+terminal.GetErrorDetails()); if(RemoveProgramTimer>0) EventSetTimer(RemoveProgramTimer); else EventSetTimer(10); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| Expert timer function | //+------------------------------------------------------------------+ void OnTimer(void) { if(!terminal.ChartExpertRemove(ProgramName,Symbolname,Timeframe)) { Print("Failed to remove "+ProgramName+". Error > "+terminal.GetErrorDetails()); } else { string comment; terminal.GetLastJournalEntry(comment); Print(comment); ExpertRemove(); } } //+------------------------------------------------------------------+
HandleAlertsエキスパートアドバイザーは、新しいバーごとに視覚的なポップアップアラートを送信します。次に、CloseAlertDialogue()メソッドを使用して、ターミナルによって生成されたポップアップダイアログを閉じます。
//+------------------------------------------------------------------+ //| HandleAlerts.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #property version "1.00" #include<terminalcontroller.mqh> //--- input parameters input int Seconds=5; CTerminalController terminal; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- if(!terminal.Initialize()) { Print("Service failed to initialize CTerminalController instance"); return(INIT_FAILED); } if(Seconds>0) EventSetTimer(Seconds); else EventSetTimer(10); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- static datetime lastsend; if(iTime(NULL,0,0)!=lastsend) { Alert("New Alert message sent at "+TimeToString(TimeCurrent())); } } //+------------------------------------------------------------------+ //| Expert Timer functions | //+------------------------------------------------------------------+ void OnTimer() { terminal.CloseAlertDialogue(); } //+------------------------------------------------------------------+
最後の例はSendPushスクリプトです。このスクリプトは「DLLを経由したメタトレーダーターミナルの管理」稿で提供されている例と同様に機能します。
//+------------------------------------------------------------------+ //| Send_Push.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com " #property version "1.00" #property script_show_inputs #include<terminalcontroller.mqh> //--- input parameters input string message_text="test"; input string Mq_ID="1C2F1442,2C2F1442,3C2F1442,4C2F1442"; CTerminalController terminal; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- if(!terminal.Initialize()) { Print("Service failed to initialize CTerminalController instance"); return; } if(!terminal.SetNotificationId(Mq_ID)) { Print("Failed to set MetaQuotes id's. Error > "+terminal.GetErrorDetails()); return; } if(!SendNotification(message_text)) { int Err=GetLastError(); switch(Err) { case 4515: Alert("Waiting: Failed to send ", Mq_ID); break; case 4516: Alert("Err: Invalid message text ", message_text); return; break; case 4517: Alert("Waiting: Invalid ID list ", Mq_ID); break; case 4518: Alert("Err: Too frequent requests! "); return; break; } } } //+------------------------------------------------------------------+
終わりに
この記事では、AutoItを使用する方法について簡単に説明しました。AutoItXライブラリをMQL5と統合して使用する方法に注意を向け、AutoItdllを使用するクラスの作成についても文書化しました。ライブラリの使用時に見つかった唯一の制限は、AutoItXを使用する2つ以上のMetaTrader5プログラムが同時に実行された場合にアクセス違反エラーが発生するということです。よって、AutoItXコードを参照するMetaTrader5プログラムの単一インスタンスを実行することをお勧めします。
フォルダ | 目次 | 説明 |
---|---|---|
MetaTrader 5zip\MQL5\include | autoIt.mqh、autoItbase.mqh、terminalcontroller.mqh | autoIt.mqhにはAutoItX関数のインポートステートメントが含まれます。autoItbase.mqhにはCAutoItクラス、terminalcontroller.mqhにはCTerminalControllerクラスが含まれます |
MetaTrader 5zip\MQL5\Experts | TerminalController.mq5、HandleAlerts.mq5 | TerminalController は、チャートからエキスパートアドバイザーまたはスクリプトを自動的に削除および追加する方法を示しています HandleAlertsは、ポップアップアラートウィンドウの処理を自動化する方法を示しています |
MetaTrader 5zip\MQL5\Scripts | TerminalUIComponents.mq5、Send_Push.mq5 | TerminalUICommpentsは、インポートされた関数を直接呼び出すことでAutoItXの使用法を示します。Send_Pushスクリプトは、通知を送信する前に新しいMetaQuotes IDをターミナルに追加します |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/10130
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索