//+------------------------------------------------------------------+
//| Çàãðóçêà àðõèâà êîòèðîâîê.mq4 |
//| Spy |
//| |
//+------------------------------------------------------------------+
#property copyright "Spy"
#property link ""
#property version "1.00"
#property strict
#property show_inputs
// îáúÿâëåíèÿ
#define BM_CLICK 0x00F5
#define WM_KEYDOWN 0x0100
#define WM_LBUTTONDBLCLK 0x0203
#define VK_F2 0x71
#define WS_DISABLED 0x08000000
#define TV_FIRST 0x1100 // TreeView messages
#define TVM_EXPAND (TV_FIRST + 2)
#define TVM_GETNEXTITEM (TV_FIRST + 10)
#define TVM_SELECTITEM (TV_FIRST + 11)
#define TVM_GETITEMW (TV_FIRST + 62)
#define TVGN_ROOT 0x0000
#define TVGN_PARENT 0x0003
#define TVGN_CHILD 0x0004
#define TVGN_NEXTVISIBLE 0x0006
#define TVGN_CARET 0x0009
#define TVE_COLLAPSE 0x0001
#define TVE_EXPAND 0x0002
#define TVIF_TEXT 0x0001
struct HISTDIALOG
{
uint hWnd;
uint hTreeView;
uint hLoadBtn;
uint hCloseBtn;
};
struct TVITEM
{
uint uMask;
uint hItem;
uint uState;
uint uStateMask;
uint pBuff;
int nBuffLen;
int nImage;
int nSelectedImage;
int nChildren;
uint lParam;
};
#import "user32.dll"
int PostMessageW(uint hWnd, uint uMsg, uint wParam, uint lParam);
int SendMessageW(uint hWnd, uint uMsg, uint wParam, uint lParam);
bool SendMessageW(uint hWnd, uint uMsg, uint wParam, TVITEM &tv);
uint GetParent(uint hWnd);
uint GetForegroundWindow();
bool IsWindow(uint hWnd);
uint FindWindowExW(uint hwndParent, uint hwndChildAfter, string sClass, string sTitle);
uint SetActiveWindow(uint hWnd);
uint GetWindowLongW(uint hWnd, int nIndex);
#import "kernel32.dll"
uint LocalAlloc(uint uFlags, uint uBytes);
uint LocalFree(uint hMem);
void RtlMoveMemory(string &pDest, uint pSrc, int bytes);
#import
// inputs
input bool bConfirmMQ = true; // Ðàçðåøèòü çàãðóçêó ñî ñòîðîííåãî ñåðâåðà
input bool bConfirmReculc = true; // Ïîäòâåðæäàòü ïåðåñ÷¸ò òàéìôðåéìîâ
input bool bPeriod_M1 = false; // Çàãðóçèòü M1
input bool bPeriod_M5 = false; // Çàãðóçèòü M5
input bool bPeriod_M15 = false; // Çàãðóçèòü M15
input bool bPeriod_M30 = false; // Çàãðóçèòü M30
input bool bPeriod_H1 = false; // Çàãðóçèòü H1
input bool bPeriod_H4 = false; // Çàãðóçèòü H4
input bool bPeriod_D1 = false; // Çàãðóçèòü D1
input bool bPeriod_W1 = false; // Çàãðóçèòü W1
input bool bPeriod_MN = false; // Çàãðóçèòü MN
// globals
string g_sLang = "";
int g_nSymbolsNumber = 0;
string g_sSymbolsList[1];
string g_sSymbolGroup[1];
int g_nPeriod[9] = {PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1};
// -----------------------------------------------------------------------------------------------
int OnInit()
{
// ïðîâåðêà ðàçðåøåíèÿ dll
if(!IsDllsAllowed())
{
printf("Âûçîâ DLL äîëæåí áûòü ðàçðåø¸í.");
return(INIT_FAILED);
}
// òîëüêî äëÿ ðóññêîãî è àíãëèéñêîãî ÿçûêîâ òåðìèíàëà
g_sLang = TerminalInfoString(TERMINAL_LANGUAGE);
if(g_sLang != "English" && g_sLang != "Russian")
{
printf("English and russian languages only!");
return(INIT_FAILED);
}
// ÷èòàåì ôàéëû symbols.sel è symgroups.raw, ôîðìèðóåì ñïèñîê ñèìâîëîâ äëÿ çàêà÷êè
int hFile = FileOpenHistory("symbols.sel", FILE_BIN|FILE_READ);
int hFileGroups = FileOpenHistory("symgroups.raw", FILE_BIN|FILE_READ);
if(hFile <= 0)
{
printf("Îøèáêà îòêðûòèÿ ôàéëà symbols.sel.");
return(INIT_FAILED);
}
if(hFileGroups <= 0)
{
printf("Îøèáêà îòêðûòèÿ ôàéëà symgroups.raw.");
return(INIT_FAILED);
}
g_nSymbolsNumber = ((int)FileSize(hFile) - 4) / 128;
ArrayResize(g_sSymbolsList, g_nSymbolsNumber);
ArrayResize(g_sSymbolGroup, g_nSymbolsNumber);
FileSeek(hFile, 4, SEEK_SET);
for(int i = 0; i < g_nSymbolsNumber; i++)
{
g_sSymbolsList[i] = FileReadString(hFile, 12);
FileSeek(hFile, 116, SEEK_CUR);
// èìÿ
FileSeek(hFile, 4 + i*128, SEEK_SET);
g_sSymbolsList[i] = FileReadString(hFile, 12);
// íîìåð ãðóïïû
FileSeek(hFile, 4 + i*128 + 24, SEEK_SET);
int nGroupNumber = FileReadInteger(hFile);
// íàçâàíèå ãðóïïû èç ôàéëà symgroups.raw
FileSeek(hFileGroups, 80 * nGroupNumber, SEEK_SET);
g_sSymbolGroup[i] = FileReadString(hFileGroups, 16);
}
FileClose(hFileGroups);
FileClose(hFile);
// ôîðìèðóåì ñïèñîê òðåáóåìûõ òàéìôðåéìîâ
g_nPeriod[0] *= bPeriod_M1;
g_nPeriod[1] *= bPeriod_M5;
g_nPeriod[2] *= bPeriod_M15;
g_nPeriod[3] *= bPeriod_M30;
g_nPeriod[4] *= bPeriod_H1;
g_nPeriod[5] *= bPeriod_H4;
g_nPeriod[6] *= bPeriod_D1;
g_nPeriod[7] *= bPeriod_W1;
g_nPeriod[8] *= bPeriod_MN;
if(g_nPeriod[ArrayMaximum(g_nPeriod)] == 0)
{
printf("Íå âûáðàíî íè îäíîãî òàéìôðåéìà.");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
// -----------------------------------------------------------------------------------------------
void OnStart()
{
// õýíäë ÷àðòà
long hChart = ChartGetInteger(ChartID(), CHART_WINDOW_HANDLE);
// õýíäë ãëàâíîãî îêíà òåðìèíàëà
uint hMT = (uint) hChart;
while(GetParent(hMT))
hMT = GetParent(hMT);
// øë¸ì îêíó òåðìèíàëà íàæàòèå êëàâèøè F2
PostMessageW(hMT, WM_KEYDOWN, VK_F2, 0);
// îêíî àðõèâà êîòèðîâîê è åãî ýëåìåíòû
HISTDIALOG oArch;
oArch.hWnd = 0;
oArch.hTreeView = 0;
oArch.hLoadBtn = 0;
oArch.hCloseBtn = 0;
// èùåì îòêðûâøååñÿ îêíî àðõèâà è ïîëó÷àåì åãî õýíäë è õýíäëû åãî ýëåìåíòîâ
// ïîñêîëüêó ôóíêöèÿ PostMessageW âîçâðàùàåòñÿ, íå äîæèäàÿñü îáðàáîòêè ñîîáùåíèÿ, æä¸ì îêíî 1 ñåêóíäó,
// äî åãî îòêðûòèÿ àêòèâíûì áóäåò îêíî òåðìèíàëà
for(int i = 0; i <1000; i += 50)
{
if(GetForegroundWindow() == hMT)
{
Sleep(50);
continue;
}
else
{
oArch.hWnd = GetForegroundWindow();
break;
}
}
if(!oArch.hWnd)
{
printf("Íå óäàëîñü îòêðûòü îêíî àðõèâà êîòèðîâîê.");
return;
}
// äåðåâî èíñòðóìåíòîâ
oArch.hTreeView = FindWindowExW(oArch.hWnd, NULL, "SysTreeView32", "Tree1");
if (!oArch.hTreeView)
return;
// êíîïêà çàãðóçêè
if(g_sLang == "Russian")
oArch.hLoadBtn = FindWindowExW(oArch.hWnd, NULL, "Button", "Çà&ãðóçèòü");
else
oArch.hLoadBtn = FindWindowExW(oArch.hWnd, NULL, "Button", "D&ownload");
if (!oArch.hLoadBtn)
return;
// êíîïêà çàêðûòèÿ
if(g_sLang == "Russian")
oArch.hCloseBtn = FindWindowExW(oArch.hWnd, NULL, "Button", "&Çàêðûòü");
else
oArch.hCloseBtn = FindWindowExW(oArch.hWnd, NULL, "Button", "&Close");
if (!oArch.hCloseBtn)
return;
// çàãðóçêà âûáðàííûõ äàííûõ
for(int i = 0, nResult = 0; i < g_nSymbolsNumber && nResult == 0; i++)
{
for(int j = 0; j < 9; j++)
{
if(g_nPeriod[j] == 0)
continue;
// çàêà÷êà
nResult = LoadArchiveHistory(oArch, g_sSymbolsList[i], g_sSymbolGroup[i], j);
switch(nResult)
{
case 0:
printf("%s%d: Çàãðóçêà óñïåøíî çàâåðøåíà.", g_sSymbolsList[i], g_nPeriod[j]);
break;
case 1:
printf("Ñåðâåð èñòîðèè îòëè÷àåòñÿ îò òîðãîâîãî ñåðâåðà.");
break;
case 2:
printf("%s%d: Íåò íîâûõ äàííûõ.", g_sSymbolsList[i], g_nPeriod[j]);
nResult = 0; // ïðîäîëæàåì
break;
case 3:
printf("%s%d: Íåò íîâûõ äàííûõ. Âñå òàéìôðåéìû ïåðåñ÷èòàíû.", g_sSymbolsList[i], g_nPeriod[j]);
nResult = 0; // ïðîäîëæàåì
break;
case 4:
printf("%s%d: Íåò íîâûõ äàííûõ. Ïåðåñ÷¸ò âñåõ òàéìôðåéìîâ îòìåí¸í.", g_sSymbolsList[i], g_nPeriod[j]);
nResult = 0; // ïðîäîëæàåì
break;
default:
printf("%s%d: Îøèáêà ðàáîòû ñêðèïòà. Ñêðèïò çàâåðø¸í.", g_sSymbolsList[i], g_nPeriod[j]);
break;
}
}
}
// çàêðûâàåì îêíî àðõèâà
while(IsWindow(oArch.hWnd))
{
SetActiveWindow(oArch.hWnd);
SendMessageW(oArch.hCloseBtn, BM_CLICK, 0, 0);
Sleep(50);
}
}
// -----------------------------------------------------------------------------------------------
int LoadArchiveHistory(const HISTDIALOG &oArch, const string sSymbol, const string sGroup, int nPeriodID)
{
// âîçâðàùàåìîå çíà÷åíèå
int nRetVal = 0;
// äëÿ óäîáñòâà
uint hArch = oArch.hWnd;
uint hTree = oArch.hTreeView;
uint hLoadBtn = oArch.hLoadBtn;
// ýëåìåíòû äåðåâà
uint hRootItem = 0;
uint hGroupItem = 0;
uint hSymbolItem = 0;
uint hPeriodItem = 0;
// âñïîìîãàòåëüíûå ôëàãè
bool bGroupFound = false;
bool bSymbolFound = false;
bool bPeriodFound = false;
string sRootItemText;
// âûáèðàåì è ðàñêðûâàåì êîðíåâîé ýëåìåíò äåðåâà
hRootItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_ROOT, NULL);
// èùåì íóæíóþ ãðóïïó
if (hRootItem)
{
// òåêñò êîðíåâîãî ýëåìåíòà - ïîíàäîáèòñÿ íèæå, ïðè ïîèñêå äèàëîãîâûõ îêîí ïî çàãîëîâêó
sRootItemText = GetItemText(hTree, hRootItem);
// ðàñêðûâàåì êîðíåâîé ýëåìåíò
SendMessageW(hTree, TVM_EXPAND, TVE_EXPAND, hRootItem);
hGroupItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_CHILD, hRootItem);
while(SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_PARENT, hGroupItem) == hRootItem)
{
string sGroupItemText = GetItemText(hTree, hGroupItem);
if(sGroupItemText != sGroup) // íå òà ãðóïïà
{
SendMessageW(hTree, TVM_EXPAND, TVE_COLLAPSE, hGroupItem);
hGroupItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hGroupItem);
continue;
}
else
{
SendMessageW(hTree, TVM_EXPAND, TVE_EXPAND, hGroupItem);
bGroupFound = true;
break;
}
}
}
else // çàêðûòî îêíî àðõèâà?
return (-1);
// èùåì íóæíûé ñèìâîë
if (bGroupFound)
{
hSymbolItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_CHILD, hGroupItem);
while (bGroupFound && SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_PARENT, hSymbolItem) == hGroupItem)
{
string sSymbolItemText = GetItemText(hTree, hSymbolItem);
if (sSymbolItemText != sSymbol) // íå òîò ñèìâîë
{
SendMessageW(hTree, TVM_EXPAND, TVE_COLLAPSE, hSymbolItem);
hSymbolItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hSymbolItem);
continue;
}
else
{
SendMessageW(hTree, TVM_SELECTITEM, TVGN_CARET, hSymbolItem);
SendMessageW(hTree, WM_LBUTTONDBLCLK, 0, 0);
SendMessageW(hTree, TVM_EXPAND, TVE_EXPAND, hSymbolItem);
bSymbolFound = true;
break;
}
}
}
// ïåðåìåùàåìñÿ ê òðåáóåìîìó òàéìôðåéìó
if (bSymbolFound)
{
hPeriodItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_CHILD, hSymbolItem);
for (int i = 0; i < nPeriodID; i++)
hPeriodItem = SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hPeriodItem);
if (SendMessageW(hTree, TVM_GETNEXTITEM, TVGN_PARENT, hPeriodItem) == hSymbolItem)
{
SendMessageW(hTree, TVM_SELECTITEM, TVGN_CARET, hPeriodItem);
SendMessageW(hTree, WM_LBUTTONDBLCLK, 0, 0);
bPeriodFound = true;
}
}
// çàêà÷êà
if (bPeriodFound)
{
// æì¸ì êíîïêó "Çàãðóçèòü"
SetActiveWindow(hArch);
PostMessageW(hLoadBtn, BM_CLICK, 0, 0);
// ïîñëå íàæàòèÿ êíîïêè çàãðóçêè íóæíî äîæäàòüñÿ êàêîé-òî ðåàêöèè: ëèáî êíîïêà äîëæíà ñòàòü íåàêòèâíîé,
// ëèáî äîëæíî ïîÿâëèòüñÿ îêíî ñ ñîîáùåíèåì îá îòñóòñòâèè íîâûõ äàííûõ
// öèêëè÷åñêàÿ ïðîâåðêà ñîñòîÿíèÿ êíîïêè "Çàãðóçèòü" êàæäûå 250 ìñ. Öèêë ïðîäîëæàåòñÿ, ïîêà êíîïêà íåàêòèâíà
for(bool bRepeat = true; (GetWindowLongW(hLoadBtn, -16) & WS_DISABLED) > 0 || bRepeat; )
{
Sleep(250);
// êíîïêà ñòàëà íåàêòèâíîé
if((GetWindowLongW(hLoadBtn, -16) & WS_DISABLED) > 0)
bRepeat = false;
// ïðîâåðÿåì, íåò ëè îêíà ñ ïðåäóïðåæäåíèåì î çàãðóçêå ñ ÷óæîãî ñåðâåðà
{
uint hMQ = 0;
uint hOK = 0;
uint hCancel = 0;
if(g_sLang == "Russian")
{
hMQ = FindWindowExW(NULL, NULL, "#32770", "Ïðåäóïðåæäåíèå ïåðåä çàãðóçêîé");
hOK = FindWindowExW(hMQ, NULL, "Button", "OK");
hCancel = FindWindowExW(hMQ, NULL, "Button", "Îòìåíà");
}
else
{
hMQ = FindWindowExW(NULL, NULL, "#32770", "Download Warning");
hOK = FindWindowExW(hMQ, NULL, "Button", "OK");
hCancel = FindWindowExW(hMQ, NULL, "Button", "Cancel");
}
if(hMQ && hOK && hCancel)
{
if (bConfirmMQ)
{
while(IsWindow(hMQ))
{
SetActiveWindow(hMQ);
SendMessageW(hOK, BM_CLICK, 0, 0);
Sleep(50);
}
printf("%s%d: Ðàçðåøåíà çàãðóçêà ñ ñåðâåðà %s", sSymbol, g_nPeriod[nPeriodID], sRootItemText);
bRepeat = true; // âîçìîæíî ïîÿâëåíèå ñîîáùåíèÿ îá îòñóòñòâèè íîâûõ äàííûõ, êîòîðîå îòêðîåòñÿ ñ íåêîòîðîé çàäåðæêîé,
// ëèáî ìîæåò ñðàçó íà÷àòüñÿ çàãðóçêà. Íåîáõîäèìî äîæäàòüñÿ êàêîãî-òî èç ýòèõ ñîáûòèé
}
else
{
while(IsWindow(hMQ))
{
SetActiveWindow(hMQ);
SendMessageW(hCancel, BM_CLICK, 0, 0);
Sleep(50);
}
printf("%s%d: Çàãðóçêà ñ ñåðâåðà %s îòìåíåíà.", sSymbol, g_nPeriod[nPeriodID], sRootItemText);
nRetVal = 1; // çàãðóçêà ñ ÷óæîãî ñåðâåðà îòìåíåíà
break; // âûõîäèì èç öèêëà
}
}
}
// ïðîâåðÿåì, íåò ëè îêíà ñ ïðåäëîæåíèåì ïåðåñ÷èòàòü âñå òàéìôðåéìû
{
uint hDlg = 0;
uint hOK = 0;
uint hCancel = 0;
hDlg = FindWindowExW(NULL, NULL, "#32770", sRootItemText); // çàãîëîâîê îêíà ñîâïàäàåò ñ òåêñòîì êîðåâîãî ýëåìåíòà äåðåâà (èìÿ ñåðâåðà èñòîðèè)
if(hDlg)
{
hOK = FindWindowExW(hDlg, NULL, "Button", "&Äà");
hCancel = FindWindowExW(hDlg, NULL, "Button", "&Íåò");
if(!hOK) // ÿçûê ñèñòåìû - àíãëèéñêèé?
{
hOK = FindWindowExW(hDlg, NULL, "Button", "&Yes");
hCancel = FindWindowExW(hDlg, NULL, "Button", "&No");
}
if(hOK && !hCancel) // åñëè íåò êíîïêè îòìåíû, òî ýòî ïðîñòî óâåäîìëåíèå îá îñóòñòâèè íîâûõ äàííûõ, æì¸ì ÎÊ è âûõîäèì
{
while(IsWindow(hDlg))
{
SetActiveWindow(hDlg);
SendMessageW(hOK, BM_CLICK, 0, 0);
Sleep(50);
}
nRetVal = 2; // íåò íîâûõ äàííûõ
break;
}
if(hOK && hCancel) // äèàëîã ñ ïðåäëîæåíèåì ïåðåñ÷èòàòü âñå òàéìôðåéìû
{
if(bConfirmReculc)
{
while(IsWindow(hDlg))
{
SetActiveWindow(hDlg);
SendMessageW(hOK, BM_CLICK, 0, 0);
Sleep(50);
}
nRetVal = 3; // ïîäòâåðæä¸í ïåðåñ÷¸ò òàéìôðåéìîâ
// âíîâü æì¸ì êíîïêó "Çàãðóçèòü"
SetActiveWindow(hArch);
PostMessageW(hLoadBtn, BM_CLICK, 0, 0);
bRepeat = true; // Íåîáõîäèìî äîæäàòüñÿ çàãðóçêè
}
else
{
while(IsWindow(hDlg))
{
SetActiveWindow(hDlg);
SendMessageW(hCancel, BM_CLICK, 0, 0);
Sleep(50);
}
nRetVal = 4; // îòìåí¸í ïåðåñ÷¸ò òàéìôðåéìîâ, âûõîäèì èç öèêëà
break;
}
}
}
}
}
}
return (nRetVal);
}
// -----------------------------------------------------------------------------------------------
string GetItemText(uint hTreeView, uint hItem)
{
string sItemText;
StringInit(sItemText, 256, '.');
TVITEM tv;
tv.uMask = TVIF_TEXT;
tv.hItem = hItem;
tv.nBuffLen = StringBufferLen(sItemText);
tv.pBuff = LocalAlloc(0, tv.nBuffLen);
SendMessageW(hTreeView, TVM_GETITEMW, 0, tv);
RtlMoveMemory(sItemText, tv.pBuff, tv.nBuffLen);
LocalFree(tv.pBuff);
return (sItemText);
}
// -----------------------------------------------------------------------------------------------
Comments