버튼 및 마우스 클릭을 가로채는 자동화. - 페이지 11

 
DKeN :
cm=GetDlgItem(hdlg,ID_SYMBOL);
int pos=SendMessageA(cm,CB_GETCOUNT,0,0);//목록의 금액 가져오기
//쌍 찾기
문자열 fs="";
for(int l=0;l<pos;l++){
int ll=SendMessageA(cm,CB_GETLBTEXT,l,fs);
인쇄(ll," ",fs);
}

주문 창(F9)에서 악기 목록을 가져오는 방법을 알려주세요.

요소 수를 얻었지만 숫자로 행을 정확히 가져올 수 없으며 -1을 반환합니다.

#define ID_SYMBOL 0x053E //선택할 기호 이름

cm 핸들 콤보박스

텍스트를 수신하기 전에 먼저 이 텍스트를 수신할 만큼 충분히 큰 버퍼를 준비해야 합니다. 그리고 fs 문자열의 길이는 전혀 0입니다. 그런 치욕 때문에 당신의 단말기가 떨어지지 않는 것이 이상합니다. 따라서 fs는 미리 충분히 긴 문자열 로 초기화해야 합니다. 일반적인 경우, 수신된 문자열의 길이가 전혀 클 수 있는 경우 필요한 버퍼 크기를 알기 위해 먼저 CB_GETLBTEXTLEN 메시지를 사용하여 이 길이를 찾아야 합니다.
 
lasso :

Alexey, 덕분에 기능이 작동하지만 ..


스레드 ID만 필요합니다. 두 개의 터미널이 있습니다.

헤더 식별을 통해 빠져나왔지만 테스터 아래에서 스레드 ID를 확인하는 방법을 여전히 알고 싶습니다.

GetCurrentProcessId() 함수를 사용하여 현재 스레드의 ID를 얻을 수 있습니다.
 
Meat :
텍스트를 수신하기 전에 먼저 이 텍스트를 수신할 만큼 충분히 큰 버퍼를 준비해야 합니다. .......

그런데!!!

내가 당신의 기능을 내 필요에 맞게 조정했을 때

 int FindWindow( string class , string caption, bool captionexactly= false )

함수 수준에서 로컬로 선언된 문자열 버퍼 문자열 textbuf 가 첫 번째 호출에서 한 번만 초기화된다는 사실에 직면하여,

이후로는 정적 변수 처럼 작동합니다.

 string  textbuf= "Абвгдежзийклмнопрсту";   // В_ЭТОЙ_СТРОКЕ_255_СИМВОЛОВ
Print("textbuf после инициализации =",textbuf);
이 상황에 대해 논평할 수 있습니까?
 
lasso :

그런데!!!

내가 당신의 기능을 내 필요에 맞게 조정했을 때

함수 수준에서 로컬로 선언된 문자열 버퍼 문자열 textbuf 가 첫 번째 호출에서 한 번만 초기화된다는 사실에 직면하여,

이후로는 정적 변수처럼 작동합니다.

이 상황에 대해 논평할 수 있습니까?

무슨 내용인지 이해했습니다. GetText에서 받은 이전 값이 버퍼에 저장된다는 의미입니다. 저도 놀랐던 기억이 납니다. 그러나 이것은 MQL의 기능입니다. 포럼 어딘가에서 개발자들은 컴파일러 수준에서 설정한 모든 상수 문자열 이 메모리에 영구적으로 별도의 위치에 저장되며 함수를 종료할 때 손실(덮어쓰지 않음)되지 않는다고 말했습니다. 그들의 주소는 처음에 알려져 있으며 프로그램 작동 중에 변경되지 않습니다. 따라서 함수를 다시 호출할 때 동일한 상수 문자열에 액세스할 때 동일한 주소에서 가져옵니다. 그러나 GetText 함수에 의해 배치된 다른 텍스트가 이미 있습니다.
마찬가지로 간단히 Print("Abvgdeziyklmnoprstu")를 수행하면 다른 텍스트도 얻을 수 있습니다. 그것은 textbuf 변수에 관한 것이 아니라 상수 문자열에 관한 것입니다. 컴파일 단계에서는 모든 상수 문자열을 확인하여 그대로 데이터베이스에 배치하고 고유한 문자열만 배치합니다. 동일한 행이 발견되면 데이터베이스에서 해당 행에 대해 하나의 공통 인스턴스만 생성됩니다. 따라서 작업 중에 이 인스턴스를 엉망으로 만들면 프로그램의 어느 곳에서나 해당 라인에 대한 모든 호출도 손상된 결과를 반환합니다.

이것이 적합하지 않으면 프로그래밍 방식으로 버퍼를 만들 수 있습니다.

 string textbuf= "" ;
for ( int i= 0 ; i< 255 ; i++)
  textbuf=textbuf+ " " ;

그러면 그런 문제는 없을 것입니다. 그게 가능한지 솔직히 기억이 안나요. 저장소 접근에 오류가 있을지... 시도해보세요.

 
Meat :
그러면 그런 문제는 없을 것입니다. 그게 가능한지 솔직히 기억이 안나요. 저장소 접근에 오류가 있을지... 시도해보세요.

'화면에 255자가 안 들어가고 포럼 시야가 나빠진다'는 기사를 보자마자 바로 그렇게 했다.

하지만 이 옵션이 작동하지 않았고 API 함수가 아무 것도 반환하지 않았습니다... 그래서 저는 당신의 옵션을 남겼습니다.

......

아무튼 또 자세한 답변 정말 감사합니다.

 
lasso :

'화면에 255자가 안 들어가고 포럼 시야가 나빠진다'는 기사를 보자마자 바로 그렇게 했다.

하지만 이 옵션이 작동하지 않았고 API 함수가 아무 것도 반환하지 않았습니다... 그래서 저는 당신의 옵션을 남겼습니다.

......

아무튼 또 자세한 답변 정말 감사합니다.


천만에요.

내가 이해하는 한, 그 이유는 이 경우 참조가 변수에 속한 원래 텍스트 버퍼가 아니라 그 복사본에 전달되기 때문입니다. 함수를 호출 하기 전에 생성되는 임시 버퍼. 따라서 함수가 이 버퍼의 텍스트를 변경하더라도 원래 버퍼가 변경되지 않은 채로 있기 때문에 아무 것도 제공하지 않습니다. 그리고 함수가 종료되면 임시 버퍼에 대한 참조가 손실됩니다. 나는 한 번 문자열을 DLL로 전송할 때 이것 때문에 고통을 겪었습니다. 그러나 해결책이 있습니다. 함수 에 문자열 배열의 요소 를 전달해야 합니다. 이 경우 중간 버퍼가 생성되지 않고 함수는 원래 버퍼에 대한 링크를 받습니다.

 string buffer[ 1 ]={""};
for ( int i= 0 ; i< 500 ; i++)
  buffer[ 0 ]=buffer[ 0 ]+ " " ;

GetWindowTextA(h,buffer[0],500);

이것이 작동하는 방식입니다.

 
void SetSymbol( int hdlg, string symbol, int len){
   int cm=GetDlgItem(hdlg,ID_SYMBOL);
   int pos=SendMessageA(cm,CB_GETCOUNT, 0 , 0 ); //получим количество в списке
   string fs,ff;
   
   for ( int l= 0 ;l<pos;l++){
       //SendMessageA(cm,CB_SETCURSEL,l,0);
       int len_text=SendMessageA(cm,CB_GETLBTEXTLEN,l, 0 );
       fs= " " ;
       for ( int m= 0 ;m<len_text+ 1 ;m++) fs= StringConcatenate (fs, " " );
       int ll=SendMessageA(cm,CB_GETLBTEXT,l,fs);
       Print (len_text, " = " ,fs); //пусто!!! длину получает.

          
       ff= StringSubstr (fs, 0 ,len);
       // Print(symbol);
       if (ff==symbol) {
            SendMessageA(cm,CB_SETCURSEL,l, 0 );
             break ;
       }
   }
}

나는 정상적으로 길이를 얻지 만 텍스트를 얻을 수 없습니다 :-(

string 을 올바르게 초기화 하는 방법을 설명하고 외부 dll 없이 이것을 구현할 수도 있습니까?

이것은 도구 목록에서 기호를 찾아 선택하는 데 필요합니다.


 
DKeN :

나는 정상적으로 길이를 얻지 만 텍스트를 얻을 수 없습니다 :-(

문자열을 올바르게 초기화하는 방법을 설명하고 일반적으로 외부 dll 없이 이것을 구현할 수 있습니까?

이것은 도구 목록에서 기호를 찾아 선택하는 데 필요합니다.

문자열 초기화에 관해서는 이전 메시지에서 친구 올가미 에 대해 설명한 적이 있습니다. 문자열 배열의 요소를 사용하거나 단순히 충분한 길이의 상수로 문자열 변수를 초기화해야 합니다. 귀하의 경우 결과 문자열의 크기가 78바이트를 초과하지 않는다는 것을 미리 알고 있기 때문에 상수를 사용하는 것이 더 쉽습니다.

12바이트(기기 티커) + 2바이트(쉼표 및 공백) + 64바이트(전체 기기 이름) . 이것은 가능한 최대 문자열 길이입니다. 글쎄, 당신은 80까지 반올림 할 수 있습니다.

그러나 목록에서 특정 도구를 선택하려는 경우에는 이름을 알 필요가 없습니다. CB_SELESTRING 메시지를 사용하면 됩니다. 거기에서 문자열 매개변수로 이름의 첫 부분("EURUSD")만 보내면 충분하며 목록에서 적절한 요소를 찾아 선택합니다.

 

근미래의 밀리언 달러 로봇 API: 터미널에서 많은 수익을 내는 거래를 끌어냅니다... :) 그리고 새로운 백만장자가 한 두 달 안에 브로커로부터 이익을 인출하려고 했을 때 그는 단 한 건도 없었음을 알게 됩니다. 무역... 고문이 끝났습니다... :)))))))))))

 

여러분, 주문 창에서 구매/판매 버튼의 핸들을 정의하는 데 도움을 주세요. 주문 창에서 핸들을 찾았습니다.

 int chart_handle = WindowHandle ( Symbol (), Period ());
int MT_handle = GetAncestor(chart_handle, GA_ROOT); // GA_ROOT 2
PostMessageA(MT_handle, WM_KEYDOWN, VK_F9, 0 ); // открываем окошко Ордер
Sleep ( 1000 ); // Wait. This is important!
int Order_handle = GetLastActivePopup(MT_handle); // хэндл от Ордер-а

그런 다음 버튼 핸들(예: Bai)을 확인하려고 시도하지만 응답으로 0을 얻습니다.

 int Buy_handle = GetDlgItem(Order_handle, 0x40C ); // 0x40C найдено с помощью WinSpy++

가장 흥미로운 점은 " 즉시 실행 " 상자의 어떤 요소에서도 핸들을 찾을 수 없다는 것입니다. 그리고 즉시 성취 자체에서도 찾을 수 없습니다. WinSpy++는 이를 별도의 요소로 보고 ID 0xFFFF를 표시하지만.

엄밀히 판단하지 마세요, 저는 초보자입니다.