2015-07-12 2 views
0

У меня есть следующий код, чтобы открыть автономный график в метатрейдере 4. Но все, что я мог сделать, это открыть список автономных файлов. Я не очень знаком с программированием окон, так кто-то может сказать мне, что я делаю неправильно?Открыть автономный график на MQL4 с помощью вызовов [user32.dll] и [kernel32.dll] Win-API

#import "user32.dll" 
    int PostMessageA(  int hWnd, int Msg, int wParam, int lParam); 
    int SendMessageA(  int hWnd, int Msg, int wParam, int lParam); 
    int GetAncestor(  int hWnd, int gaFlags); 
    int GetLastActivePopup(int hWnd); 
    int GetDlgItem(  int hDlg, int nIDDlgItem); 
#import 

#import "kernel32.dll" 
    int FindFirstFileA( string Path, int& Answer[]); 
    bool FindNextFileA( int handle, int& Answer[]); 
    bool FindClose(  int handle); 
#import 

#define WM_COMMAND 0x0111 
#define WM_KEYDOWN 0x0100 
#define VK_DOWN  0x28 
#define BM_CLICK 0x00F5 
#define GA_ROOT   2 
#define PAUSE   100 

string BuffToString(int& Buffer[]) 
{ 
    string Str = ""; 
    int Pos = 11; 

    while (Pos < 75) { 
    while (Buffer[Pos] != 0) { 
      Str   = Str + CharToStr(Buffer[Pos] & 0xFF); 
      Buffer[Pos] /= 0x100; 
    } 
    Pos++; 
    } 

    return(Str); 
} 

int GetChartPos(string FileName) 
{ 
    int Buffer[79]; 
    int Pos = 0; 
    int handle = FindFirstFileA(TerminalPath() + "\history\\" + AccountServer() + "\\*.hst", Buffer); 

    if (BuffToString(Buffer) != FileName) { 
     Pos++; 

     while (FindNextFileA(handle, Buffer)) { 
       if (BuffToString(Buffer) == FileName) 
        break; 
       Pos++; 
     } 
    } 
    if (handle > 0) 
     FindClose(handle); 
    return(Pos); 
} 

int OpenOfflineList() 
{ 
    int hwnd = WindowHandle(Symbol(), Period()); 

    hwnd  = GetAncestor(hwnd, GA_ROOT); 
    SendMessageA(hwnd, WM_COMMAND, 33053, 0); 
    Sleep(PAUSE); 
    hwnd  = GetLastActivePopup(hwnd); 
    return(hwnd); 
} 

void OpenOfflineChartbyNum(int ChartPos) 
{ 
    int hwnd1 = OpenOfflineList(); 
    int hwnd2 = GetDlgItem(hwnd1, 1); 

    hwnd1  = GetDlgItem(hwnd1, 0x487); 
    while (ChartPos >= 0) { 
    SendMessageA(hwnd1, WM_KEYDOWN, VK_DOWN, 0); 
    ChartPos--; 
    } 
    Sleep(PAUSE); 
    SendMessageA(hwnd2, BM_CLICK, 0, 0); 
    return; 
} 

void OpenOfflineChart(string Symb, int period) 
{ 
    OpenOfflineChartbyNum(GetChartPos(Symb + period + ".hst")); 
    return; 
} 

int init() 
{ 
    OpenOfflineChart("AUDUSD", 120); 
    return; 
} 
+0

Это работа для автоматизации пользовательского интерфейса. –

ответ

0

Я не эксперт в WinApi, и вопрос, очевидно, старый, но он по-прежнему актуальный. Поэтому проблема заключается в том, что вы используете FindFirstFileA(), который использует строки ANSI, но после 600 выпуска MT4 использует Unicode, поэтому вам нужно вместо этого использовать FindFirstFileW(). Кроме того, вместо SendMessage() вы должны использовать PostMessage() (pls не спрашивают меня почему). Так вот рабочий код:

#import "user32.dll" 
    int PostMessageA(  int hWnd, int Msg, int wParam, int lParam); 
    int SendMessageA(  int hWnd, int Msg, int wParam, int lParam); 
    int GetAncestor(  int hWnd, int gaFlags); 
    int GetLastActivePopup(int hWnd); 
    int GetDlgItem(  int hDlg, int nIDDlgItem); 
#import 

#import "kernel32.dll" 
    int FindFirstFileW(string Path, ushort &Answer[]); 
    bool FindNextFileW( int handle, ushort &Answer[]); 
    bool FindClose(  int handle); 
#import 

#define WM_COMMAND 0x0111 
#define WM_KEYDOWN 0x0100 
#define VK_DOWN  0x28 
#define BM_CLICK 0x00F5 
#define GA_ROOT   2 
#define PAUSE   100 

string BuffToString(int& Buffer[]) 
{ 
    string Str = ""; 
    int Pos = 11; 

    while (Pos < 75) { 
    while (Buffer[Pos] != 0) { 
      Str   = Str + CharToStr(Buffer[Pos] & 0xFF); 
      Buffer[Pos] /= 0x100; 
    } 
    Pos++; 
    } 

    return(Str); 
} 

int GetChartPos(string FileName) 
    { 
    ushort Buffer[300]; 
    int Pos=-1; 
    string path = TerminalInfoString(TERMINAL_DATA_PATH) + "\\history\\" + AccountInfoString(ACCOUNT_SERVER) + "\\*.hst"; 
    int handle = FindFirstFileW(path, Buffer); 
    string name = ShortArrayToString(Buffer, 22, 152); 
    Pos++; 
    if(name!=FileName) 
    { 
     ArrayInitialize(Buffer,0); 
     while(FindNextFileW(handle,Buffer)) 
     { 
     name=ShortArrayToString(Buffer,22,152); 
     Pos++; 
     if(name==FileName) 
      { 
      break; 
      } 
     ArrayInitialize(Buffer,0); 
     } 
    } 

    if(handle>0) 
     FindClose(handle); 

    return(Pos); 
    } 

int OpenOfflineList() 
{ 
    int hwnd = WindowHandle(Symbol(), Period()); 

    hwnd  = GetAncestor(hwnd, GA_ROOT); 
    PostMessageA(hwnd, WM_COMMAND, 33053, 0); 
    Sleep(PAUSE); 
    hwnd  = GetLastActivePopup(hwnd); 
    return(hwnd); 
} 

void OpenOfflineChartbyNum(int ChartPos) 
{ 
    int hwnd1 = OpenOfflineList(); 
    int hwnd2 = GetDlgItem(hwnd1, 1); 

    hwnd1  = GetDlgItem(hwnd1, 0x487); 
    while (ChartPos >= 0) { 
    PostMessageA(hwnd1, WM_KEYDOWN, VK_DOWN, 0); 
    ChartPos--; 
    } 
    Sleep(PAUSE); 
    PostMessageA(hwnd2, BM_CLICK, 0, 0); 
    return; 
} 

void OpenOfflineChart(string Symb, int period) 
{ 
    OpenOfflineChartbyNum(GetChartPos(Symb + period + ".hst")); 
    return; 
} 

int init() 
{ 
    OpenOfflineChart("AUDUSD", 120); 
    return; 
} 

Но теперь (Build 970+) гораздо проще пойти с ChartOpen("AUDUSD", 2); Так что, если вы не используете собственные имена для символов, вы можете заменить все, что только с одной линией код.

 Смежные вопросы

  • Нет связанных вопросов^_^