我有以下代码在metatrader 4中打开离线图表。 但我能做的就是打开离线文件列表。我不是 非常熟悉Windows编程,所以有人能告诉我我做错了什么吗?
#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()
(请不要问我为什么)。所以这是工作代码:
#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 );
一起使用起来要简单得多。因此,如果您不使用自定义名称作为符号,则可以将所有内容替换为只需一行代码。