2015-07-12 155 views
0

我有以下代碼在metatrader 4中打開離線圖表。 但是我所能做的只是打開脫機文件列表。我不是 非常熟悉Windows編程,所以有人可以告訴我我做錯了什麼?使用[user32.dll]和[kernel32.dll]在MQL4中打開離線圖表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

這是UI自動化的工作。 –

回答

0

我不是WinApi的專家,問題顯然很古老,但它仍然相關。所以問題在於你使用的是使用ANSI字符串的FindFirstFileA(),但是在600版本之後MT4使用的是Unicode,所以你需要使用FindFirstFileW()。此外,而不是SendMessage()你應該使用PostMessage()(請不要問我爲什麼)。因此,這裏的工作代碼:

#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);去所以,如果你不使用的符號自定義名稱,可以取代所有以剛一行碼。