Problemy z PostMessageW w MQL4
Strona 1 z 2 12 OstatniOstatni
Pokaż wyniki od 1 do 10 z 13

Wątek: Problemy z PostMessageW w MQL4

  1. #1
    Cześć wszystkim,

    Zastanawiam się, czy jakiś guru kodu może pomóc mi wskazać właściwy kierunek w tej sprawie. Jestem przeciwieństwem profesjonalnego programisty, ale spędziłem niezliczone godziny na panelu handlowym, który bardzo ładnie się układa i trafiam na kilka błędów, przez które po prostu nie mogę wymyślić, jak się przez to przedostać. Ten post dotyczy pierwszego błędu. Z góry przepraszam za długość.

    Znalazłem i użyłem bloku kodu z tego wątku, aby umożliwić mi dodawanie wskaźników z mojego własnego niestandardowego interfejsu użytkownika na żądanie:
    https://www.mql5.com/en/forum/73391/page3(post #27 autorstwa Kray). Musiałem dokonać drobnych poprawek w zakresie korzystania z poleceń Sleep i klawiszy i ogólnie działało. (Zauważ, jak przyznaję poniżej, jestem hackiem, więc jeśli uważasz, że moje użycie tych poleceń jest duplikatem i głupie, jestem pewien, że masz rację - ale kiedy znalazłem kombinację, która zadziałała, nie chciałem zadzierać z nim, ponieważ jest dla mnie kruchy.)
    Kopalnia poniżej:

    Wstawiono kod #import user32.dll int GetAncestor(int, int); int RegisterWindowMessageW(ciąg NazwaWiadomości);/Dla niestandardowego wskaźnika Start int PostMessageW(int hwnd,int msg,int wparam,uchar Name#91;#93;);/Dla niestandardowego wskaźnika Start int FindWindowW(string lpszClass,string lpszWindow);/Dla niestandardowego wskaźnika Start/int keybd_event(int bVk, int bScan, int dwFlags, int dwExtraInfo);/Dla niestandardowego wskaźnika Uruchom #import #define VK_RETURN 13/ENTER key#import/Dla niestandardowego wskaźnika Uruchom void StartCustomIndicator(int hWnd,string IndicatorName,bool AutomaticallyAcceptDefaults=true)/true = pomiń okno dialogowe wskaźnika { Sleep( 100); nazwa uchar2#91;#93;; StringToCharArray(NazwaWskaźnika,nazwa2,0,StringL en(NazwaWskaźnika)); Print(NazwaWskaźnika= NazwaWskaźnika); Print(Rozmiar tablicy(nazwa2)= Rozmiar tablicy(nazwa2)); for (int i = 0; i lt; Rozmiar tablicy(nazwa2); i ){ Print(nazwa2#91; i #93;= nazwa2#91;i#93;); } int MessageNumber=RegisterWindowMessageW(MetaTrader4_I nternal_Message); sen (100); int r=PostMessageW(hWnd,MessageNumber,15,name2); sen (200); if(Automatycznie AkceptujDomyślne) { keybd_event(13, 0, 0, 0); int ind_settings = FindWindowW(NULL, wskaźnik niestandardowy — nazwa_wskaźnika); PostMessageW(ind_settings,0x100,VK_RETURN,name2); keybd_event(13, 0, 0, 0); } }
    Problem na początku polega na tym, że zawodził. Otrzymałbym błąd „Nie można otworzyć ścieżki” pliku. To był bloker na początku, ale potem zdałem sobie sprawę, że jeśli nadałem nazwę pliku wskaźnika dokładnie 15 znaków, zostałem odblokowany. Trwało to na ogół pomyślnie przez kilka dni, może nawet tydzień lub dwa. Ale sporadycznie miałbym problem, w którym mój wskaźnik i ciąg ścieżki były interpretowane niepoprawnie przez to, co mogę określić tylko jako funkcję PostMessageW. Kiedy to się nie powiodło, zgłaszał dodatkowe lub w inny sposób bezsensowne znaki w nazwie pliku, który próbuje otworzyć. Więc zamiast mówić Cannot open file 'MyIndies\MyIndicator.ex4', zostanie napisane Cannot open file 'MyIndies\MyIndicator?L .ex4'. Tak więc przez dobry tydzień lub dwa zwykle wskaźnik ładowałby się dobrze, ale sporadycznie ścieżka i nazwa wskaźnika byłyby niepoprawnie interpretowane. W takich przypadkach (być może po tym, jak zmieniłem ramki wykresów, kliknąłem na inne zakładki lub nie było mnie przez jakiś czas), zwykle mogłem po prostu ponownie załadować mój szablon lub EA i wrócić do stanu dobrego. Co ciekawe, we wszystkich przypadkach moje instrukcje Print w powyższym bloku kodu zawsze zwracają spójne wyniki. Są one spójne pod względem pomyślnego wywołania wskaźnika, a także interpretacji wielu wariantów nieprawidłowej nazwy pliku. Mogę się tylko domyślać, że błąd występuje w poleceniu PostMessageW, chociaż nie udało mi się zmusić go do odtworzenia błędu na żądanie, a na pewno nie mam pojęcia, dlaczego.

    W ciągu ostatniego dnia lub dwóch nagle zawsze otrzymywałem komunikaty o błędach. Odkryłem metodą prób i błędów, że jeśli skróciłem długość nazwy wskaźnika z 15 do 14, wróciłbym do porządku. 15 było wcześniej bardzo wyraźnie magiczną liczbą, a teraz magiczna liczba to 14. Nie wiem, dlaczego jakakolwiek liczba byłaby magiczną liczbą, nie mówiąc już o tym, dlaczego wyraźnie i definitywnie zmieniła się dzień lub dwa temu. Jestem całkowicie skazany na zrozumienie tego wszystkiego i ślepy na to, jak działa ten interfejs API Windows, a także jestem noobem, jeśli chodzi o pracę z ucharami. Spędziłem godziny googlując i próbując to rozwiązać, ale bez powodzenia.

    Jeśli ktoś może to wyjaśnić, pomóc mi rozwiązać, a nawet wskazać mi źródło, w którym mogę sobie pomóc, byłbym bardzo wdzięczny.

    Jeśli doczytałeś tak daleko, bardzo dziękuję.
    FtN

  2. #2
    2 Załącznik(i) Przetestowano w języku angielskim, niemieckim, rosyjskim, arabskim i chińskim. Jak dla mnie działa wszędzie (najnowszy MT4/MetaEditor 5.00 build 2318). W załączeniu skrypt testowy, który działa dla mnie.
    https://www.forex-instant.com/attach...1979508731.mq4
    https://www.forex-instant.com/attach...1931182141.ex4

  3. #3

    Cytat Zamieszczone przez ;
    {quote} Okno dialogowe wskaźnika otwiera się, ale brakuje kliknięcia OK - więc okno dialogowe wskaźnika pozostaje otwarte na zawsze i otrzymuję komunikat Błąd: Nie znaleziono okna dialogowego wskaźnika (funkcja FindWindowW() nie znajduje okna dialogowego - hWnd pozostaje 0)
    Zastępuję kliknięcie całego przycisku odpowiednim komunikatem systemu Windows. Mogłem po prostu poszukać OK, ale wtedy znowu się nie powiedzie, jeśli użytkownik zmieni język terminala. A teraz testowałem przed wgraniem :-) Czy to działa dla Ciebie? Poprawiona wersja robocza: Wstawiono kod #import user32.dll int RegisterWindowMessageW(string lpString); int FindWindowW(ciąg lpNazwaKlasy, ciąg lpNazwaOkna); int GetDlgItem(int hdlg, int nIdDlgItem); int SetActiveWindow(int hWnd); bool PostMessageA(int hWnd, int msg, int wParam, uchar lParam#91;#93; bool PostMessageW(int hWnd, int msg, int wParam, int lParam); #import #define MAX_PATH 260/np. max. ścieżka na dysku D to D:\some-256-chars-path-stringlt;NULgt; #define MT4_LOAD_CUSTOM_INDICATOR 15 #define IDC_CUSTOM_INDICATOR_OK 1/identyfikator kontrolny przycisku OK w oknie dialogowym wskaźnika niestandardowego #define BM_CLICK 0x00F5 uchar buffer#91;MAX_PATH#93;;** * */void StartCustomIndicator(int hWnd, string indicatorName, bool autoCloseDlg = true) { StringToCharArray(indicatorName, buffer); int WM_MT4 = RegisterWindowMessageW(MetaTrader4_Internal_Messag e); PostMessageA (hWnd, WM_MT4, MT4_LOAD_CUSTOM_INDICATOR, bufor); if (autoCloseDlg) { string className, title = Wskaźnik niestandardowy - indicatorName; int i = 0; podczas (I lt; 5) { Sen(200); int hWndDlg = FindWindowW(nazwaklasy, tytuł); if (hWndDlg != 0) { int hWndOk = GetDlgItem(hWndDlg, IDC_CUSTOM_INDICATOR_OK); if (hWndOk != 0) { SetActiveWindow(hWndDlg); PostMessageW(hWndOk, BM_CLICK, 0, 0); } else Print(Błąd: nie znaleziono przycisku \OK\); przerwanie; } i ; if (i gt;= 5) Print(Błąd: dialog \ tytuł \ nie znaleziono); } }

  4. #4

    Cytat Zamieszczone przez ;
    {cytat} Tak, to nonsens MQL5. Jako obejście musiałem dodać drugi import funkcji. Czy to naprawia? Dziękuję :-)
    Okno dialogowe wskaźnika otwiera się, ale brakuje kliknięcia OK - więc okno dialogowe wskaźnika pozostaje otwarte na zawsze i otrzymuję komunikat Błąd: Nie znaleziono okna dialogowego wskaźnika (funkcja FindWindowW() nie znajduje okna dialogowego - hWnd pozostaje 0)

  5. #5

    Cytat Zamieszczone przez ;
    {cytat} Pojawia się ten błąd podczas kompilacji (MT4/MetaEditor 5.00 build 2302) {image}
    Tak, to MQL5 w najlepszym wydaniu. Jako obejście musiałem dodać drugi import funkcji. Uruchomiono VirtualBox i przetestowano z kompilatorem MT5. Wydaje się to naprawić. Dziękuję :-)

  6. #6
    1 załącznik(i)
    Cytat Zamieszczone przez ;
    Czy ktoś z wiedzą na temat MQL4.5 może potwierdzić, że lokalne łańcuchy są jawnie inicjowane ze wskaźnikiem NULL? Czym są inicjowane globalne/statyczne ciągi? Wskaźnik NULL? Pusty ciąg? Dziękuję
    Pojawia się ten błąd podczas próby kompilacji (MT4/MetaEditor 5.00 build 2302)

  7. #7
    Czy ktoś ze znajomością MQL4.5 może potwierdzić, że lokalne łańcuchy są jawnie inicjowane ze wskaźnikiem NULL? Czym są inicjowane globalne/statyczne ciągi? Wskaźnik NULL? Pusty ciąg? Dzięki

  8. #8

    Cytat Zamieszczone przez ;
    To było niesamowite...
    W twoim skrypcie jest więcej błędów. (1) nie należy używać keybd_event(). To kłopotliwe i podatne na błędy. Masz dwa razy identyczną instrukcję w swoim kodzie i to nie działa. Już samo to potwierdza mój punkt widzenia. (2) Wywołanie FindWindowW() jest nieprawidłowe. Jako pierwszy parametr podajesz NULL, który w rzeczywistości jest int (zero). Ponieważ podpis importu oczekuje ciągu, liczba całkowita 0 jest konwertowana na ciąg 0 i przekazywana jako nazwa klasy. FindWindow() nigdy nie znajdzie czegoś takiego, ponieważ klasa o nazwie 0 nie istnieje w systemie. Wypróbuj załączony fragment kodu w swoim kodzie. Usunąłem elementy związane z klawiaturą i zamiast tego bezpośrednio kliknąłem przycisk OK w oknie dialogowym. Znacznie lepiej niż obsługa za pomocą wirtualnych kodów klawiszy. Mogą występować ostrzeżenia/błędy kompilatora, ponieważ mogłem je przetestować tylko za pomocą kompilatora ANSI MQL. Zepsuta wersja, poprawiona wersja w poście nr 11 Wstawiony kod #import user32.dll int RegisterWindowMessageW(string lpString); bool PostMessageA(int hWnd, int msg, int wParam, uchar lParam#91;#93; bool PostMessageW(int hWnd, int msg, int wParam, int lParam); int FindWindowW(ciąg lpNazwaKlasy, ciąg lpNazwaOkna); #import #define MAX_PATH 260/np. max. ścieżka na dysku D to D:\some-256-chars-path-stringlt;NULgt; #define MT4_LOAD_CUSTOM_INDICATOR 15 #define WM_COMMAND 0x0111 #define IDC_CUSTOM_INDICATOR_OK 1/identyfikator kontrolny przycisku OK w oknie dialogowym wskaźnika niestandardowego #define IDC_CUSTOM_INDICATOR_CANCEL 2/... #define IDC_CUSTOM_INDICATOR_OK 1/RESET 123_CUSTOM_INDICATOR_CANCEL bufor#91 ...; ;** * */void StartCustomIndicator(int hWnd, string indicatorName, bool autoCloseDlg = true) { StringToCharArray(indicatorName, buffer); int WM_MT4 = RegisterWindowMessageW(MetaTrader4_Internal_Messag e); PostMessageA (hWnd, WM_MT4, MT4_LOAD_CUSTOM_INDICATOR, bufor); if (autoCloseDlg) { string className, title = Wskaźnik niestandardowy - indicatorName; int i = 0; podczas (I lt; 5) { Sen(200); hWnd = FindWindowW(nazwaklasy, tytuł); if (hWnd != 0) { PostMessageW(hWnd, WM_COMMAND, IDC_CUSTOM_INDICATOR_OK, 0); przerwanie; } i ; if (i gt;= 5) Print(Błąd: nie znaleziono okna dialogowego wskaźnika); } } } Jak widać, jako pierwszy parametr do FindWindow() przekazuję prawdziwy wskaźnik NULL (nie zainicjowany ciąg). Dlaczego Twój kod czasami działał, a czasami nie? Z powodu użycia keybd_event(). Naciskanie klawiszy w systemie operacyjnym rzadko działa. Czasami tak się dzieje. Twoje drugie wywołanie PostMessage() nigdy się nie powiodło, ponieważ użyte dojście było zawsze nieprawidłowe. edytuj: zmienna poprawkowa jest już zdefiniowana edytuj: parametr poprawkowy przekazany jako odniesienie, oczekiwana zmienna

  9. #9
    To było niesamowite. Zrobiłem aktualizacje i jestem całkowicie odblokowany w tej kwestii. Bardzo dziękuję za pomoc! W poprzednim poście wspomniałem, że to tylko jeden błąd. Inne są mniej dotkliwe, ale wciąż staram się je rozwiązać. Kolejnym jest to, że dwa z moich niestandardowych wskaźników odmawiają automatycznego zamknięcia okna dialogowego wskaźnika, gdy próbuję je automatycznie włączyć za pomocą kodu z mojego poprzedniego postu; dla tych dwóch wskaźników pojawia się okno i pozostaje tam, dopóki nie kliknę OK. Jedyną wspólną cechą, jaką widzę między nimi, jest to, że faktycznie rysują linie na wykresie – jedna rysuje wiele pionowych linii; druga wykreśla wiele linii poziomych. Nie wydaje się to wystarczającym powodem, aby ich okna dialogowe wskaźników nie zamykały się samoczynnie, gdy robią to wszystkie inne, ale to jedyna rzecz, którą widzę, że różnią się one od pozostałych. Czy są jakieś oczywiste lub logiczne powody, dla których wiele wskaźników z powodzeniem automatycznie zamknie okno dialogowe przy użyciu mojego powyższego kodu, ale te dwa uparte nie? Z góry jeszcze raz dziękuję, FtN

  10. #10
    Konwersja ciągu na tablicę powinna być po prostu: Wstawiony kod StringToCharArray(IndicatorName,name2); Spowoduje to skopiowanie ciągu i zawiera kończące zero.

Uprawnienia umieszczania postów

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Używamy cookies
Używamy cookies, aby jak najlepiej dostosować witrynę do Twoich potrzeb. Kontynuowanie przeglądania tej strony, oznacza zgodę na używanie plików cookies. Aby uzyskać więcej informacji zapoznaj się z naszą Polityką Prywatności.