CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Screenshot z okna

Screenshot z okna

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Re: Screenshot z okna

Nowy postprzez Mironas » czwartek, 22 września 2016, 09:35

A może zamiast przesuwać swoje okna na 'drugi plan' pozostaw je na wierzchu i uczyń niewidocznym?
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » czwartek, 22 września 2016, 19:44

Umieść w zdarzeniu OnTimer funkcję:

KOD cpp:     UKRYJ  
Application->ProcessMessages();


Gdziekolwiek w tym zdarzeniu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Arnold_S » czwartek, 22 września 2016, 21:33

Czy mógłbyś mi podpowiedzieć jaki wpływ w praktyce będzie miała ta funkcja na sytuację, którą opisałem wyżej?
Poczytałem troszkę o tej funkcji i myślę, że gdy zacznę łowić myszką okno mojego programu "ze spodu", to ten timer jakby się spauzuje. Co dalej w takim razie? Czy pętle, które wykonują się w tym timerze mogą zatrzymać się w "połowie drogi" do końca? Jaki to będzie miało efekt gdy nacisnę przycisk zatrzymujący program (czyli ten cały timer)?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » piątek, 23 września 2016, 09:18

Funkcja odświeża kolejkę komunikatów, pozwalając wykonać komunikaty oczekujące w kolejce. Po prostu sprawdź to. Wciąż nie bardzo rozumiem, co się dzieje z tym twoim programem. Może to okno "na wierzchu" powinno zostać uruchomione w oddzielnym procesie. Co tak w ogóle robi ten twój program w tym Timer'ze, że tak blokuje cały program. To nie powinno mieć miejsca. Timer to nie pętla. Nie sądzę by problem tkwił w Timer'ze, lecz jest to raczej jakiś błąd koncepcyjny.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez polymorphism » piątek, 23 września 2016, 10:19

W timerze powinieneś dawać rzeczy, które wykonują się szybko. Jeśli musisz używać ProcessMessages wewnątrz obsługi timera, to znaczy, że powinieneś rozważyć użycie wątków (choć w ostateczności).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » piątek, 23 września 2016, 12:38

Pokaż kod ze zdarzenia OnTimer. Może to rzuci choć trochę światłą na ten twój problem.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Arnold_S » piątek, 23 września 2016, 19:38

Co do tworzenia wątków, to nigdy tego nie robiłem i nie bardzo umiem z tego korzystać (obsługiwać to). Muszę o tym poczytać. Idzie mi to wolno ponieważ nie mam żadnej książki tylko czytam opisy funkcji na MSDN, github, stackoverflow i cpp0x.
Ta strona (http://programowanie.cal.pl) to prawdziwa kopalnia wiedzy i to po polsku!! :D Angielski znam komunikatywnie ale zrozumienie opisów trudniejszych zagadnień zajmuje mi sporo czasu.

Czy możecie zaproponować jakąś dobrą lekturę w jęz. polskim, która sporo wyjaśnia powstawanie procesów, wątków i wszystkich bardziej atomowych tworów, od strony programistycznej?

Co do mojego programu to muszę przemyśleć czy pomysł był dobry i ewentualnie ująć to w kodzie inaczej. Chyba najbardziej problematycznym w tym timerze jest moment, w którym wielokrotnie używam funkcji SendInput do przesuwania myszą, klikania, odklikiwania, wysyłania ESC, spacji etc. Robię to chyba zbyt "nachalnie" i za szybko.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » piątek, 23 września 2016, 19:43

I w tym tkwi problem. Wysyłasz za pomocą Timera całą masę komunikatów. Tworzy się duża kolejka, która musi zostać przetworzona. Komunikaty o zakończeniu pracy aplikacji też trafiają do tej kolejki na koniec. Aplikacja zostaje więc zamknięta dopiero wtedy gdy kolejka zostanie przetworzona w całości, a nie w momencie w którym chcesz zakończyć działania programu. Wyłączenie timera hotkey'em też się nie sprawdzi, gdyż komunikat wyłączenia tegoż timera również trafi do tej samej kolejki komunikatów.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez polymorphism » sobota, 24 września 2016, 14:04

@Arnold_S, jeśli chodzi o lektury w języku polskim, lepiej pogódź się z tym, że praktycznie wszystko, co jest godne uwagi, jest w języku angielskim. Im szybciej się przestawisz, tym lepiej na przyszłość.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Arnold_S » sobota, 24 września 2016, 20:35

...ehhh czyli jednak nie ominie mnie lektura po angielsku.

Kontynuując eliminację błędów, mam problem z synchronizowaniem tego SendInputa.
Przykład: wysyłam do okna takie sygnały:
event timera
{
klikniecie lp myszy, 3x backspace, Esc, Enter, Enter, login(znak po znaku w pętli for), Enter, klikniecie lp myszy, 3x backspace, haslo (znak po znaku w pętli for), Enter.
}

Niestety nie zawsze to działało ponieważ zauważyłem, że sygnały klawiszy nie docierają do okna w jednakowych odstępach czasu. Mam wrażenie, że czasem pierwsza litera loginu dociera później niż druga itd. Aby wyeliminować ten problem użyłem funkcji Sleep();
Okno zaczęło otrzymywać sygnały po kolei dopiero gdy ustawiłem sleep-em, delay-e między wciśnięciem klawisza a zwolnieniem go. Delay-e wynoszą u mnie 10ms, a w niektórych miejscach nawet 20ms.
Pomierzyłem czas wykonania całej tej funkcji i wyszło mi, że wykonuje to w 700 - 800 ms, a gdy system jest bardziej zajęty to musiałem ustawić takie delay-e, że cała funkcja wykonywała się w czasie 900-1100 ms.

Problem w tym, że Interval w Timerze nie może mieć więcej niż 750ms. Wychodzi na to, że czas wykonania funkcji umieszczonej w timerze jest dłuższy niż mogę przeznaczyć na Interval. :(

Poniżej umieszczam przykład (fragment) jak wypełniłem pola struktury INPUT i używam funkcji SendInput...być może robię to źle.

KOD cpp:     UKRYJ  
const unsigned short slowo[8] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; //ScanCody wyrazu "qwertyui" ..załóżmy, że to login.

INPUT aaa;
aaa.type = INPUT_KEYBOARD;
aaa.ki.dwFlags = 0;
aaa.ki.time = 0;
aaa.ki.dwExtraInfo = 0;

//wyslanie do okna slowa "qwertyui "
for(int i = 0 ; i < 8 ; i++)
        {
          aaa.ki.wScan = slowo[i];
          aaa.ki.dwFlags = KEYEVENTF_SCANCODE;  //wcisniecie klawisza
          SendInput(1, &aaa, sizeof(INPUT));
          Sleep(20);
          aaa.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;    //podniesienie klawisza
          SendInput(1, &aaa, sizeof(INPUT));
          Sleep(20);
        }
 


Czy istnieje jakiś sposób aby na funkcji SendInput wymusić nie wysyłanie następnego "sygnału" litery/znaku do puki ten wcześniejszy nie został odebrany przez okno.
Chciałbym uniknąć tej funkcji Sleep(); lub zminimalizować czas na wykonanie tych instrukcji.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » niedziela, 25 września 2016, 09:32

Te "sygnały" to są właśnie komunikaty (na komunikatach system leży)... Wysyłasz w Timer'ze całą masę komunikatów, nie wszystkie są wykonywane natychmiast, gdyż system nie nadąża je wykonywać, więc trafiają na kolejkę komunikatów. System potem przetwarza tą kolejkę z opóźnieniem. Niektóre komunikaty z kolejki z różnych przyczyn mogą być już nieaktualne, więc zostają pominięte przez system. Wprowadzenie opóźnienie za pomocą funkcji Sleep daje czas systemowi na przetworzenie otrzymanych komunikatów nim nadejdą nowe. Funkcja Sleep ma jednak tą wadę, że zamraża aplikację.

Arnold_S napisał(a):Problem w tym, że Interval w Timerze nie może mieć więcej niż 750ms.


Ależ jak najbardziej może być dłuższy. Chyba, że ty ustaliłeś sobie limit na 750.

Arnold_S napisał(a):Wychodzi na to, że czas wykonania funkcji umieszczonej w timerze jest dłuższy niż mogę przeznaczyć na Interval.


Czas ich wykonywania wcale nie musi być dłuższy. Jak już napisałem, komunikaty trafiają do kolejki i system przetwarza je po kolei. Problem w tym, że system musi przetworzyć całą masę komunikatów, nie tylko tych pochodzących z twojej aplikacji, więc je kolejkuje. Gdy dotrze do komunikatu wysłanego przez twoją aplikację, może się okazać, że jest on już nieaktualny lub z innych przyczyn nie można go już wykonać, gdyż np.aplikacja do której go wysyłasz nie może go przyjąć.

Wysyłasz komunikaty do kolejki nie czekając na to czy zostały przetworzone. Dla przykładu funkcja SendMessage wywołuje procedurę okna dla określonego okna i nie wraca, dopóki procedura okna nie przetworzy komunikatu.

Kolejna rzecz to pętla wewnątrz zdarzenia OnTimer wprowadza dodatkowe opóźnienie. Czy próbowałeś funkcję ProcessMessages, by odświeżać kolejkę komunikatów? Spróbuj właśnie ProcessMessages zamiast Sleep, dasz czas na przetworzenie komunikatów oczekujących w kolejce.



Ten Sleep może być jednak konieczny. Mam klawiaturę z programowalnymi dodatkowymi klawiszami. Mogę im przypisać makro zawierające kombinację nawet kilkudziesięciu klawiszy, by wykonywały się po kolei. I muszę wprowadzać opóźnienia by to zadziałało, ale nie wywołuję tego makra z częstotliwością ¾ sekundy.



Problem leży w tym, że system nie przetworzy odpowiednio szybko takiej kolejki komunikatów i część komunikatów odrzuci.



Czy istnieje jakiś sposób aby na funkcji SendInput wymusić nie wysyłanie następnego "sygnału" litery/znaku do puki ten wcześniejszy nie został odebrany przez okno.


Użyj funkcji SendMessage, ta funkcja wraca dopiero gdy komunikat zostanie przetworzony. Nie wiem jednak czy to rozwiąże twój problem, gdyż częstotliwość komunikatów spadnie, czyli będą wysyłane z mniejszą częstotliwością. Podobny efekt osiągniesz zmniejszając częstotliwość zegara Timer. SendInput łatwo może zostać zablokowana przez inny wątek. Możesz jednak przecież sprawdzać, czy komunikat doszedł czy nie. Przecież funkcja zwraca 0 jeżeli została zablokowana przez inny wątek, wtedy możesz ponownie wysłać komunikat, aż do skutku, czyli aż dojdzie. To jedyny sposób na sprawdzenie, czy komunikat doszedł.

KOD cpp:     UKRYJ  
//wyslanie do okna slowa "qwertyui "
for(int i = 0 ; i < 8 ; i++)
{
                  do
                  {
                   aaa.ki.wScan = slowo[i];
                   aaa.ki.dwFlags = KEYEVENTF_SCANCODE;  //wcisniecie klawisza
                  }
                  while( SendInput(1, &aaa, sizeof(INPUT) == 0);

                  Application->ProcessMessages();
                 
                  do
                  {
                   aaa.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;    //podniesienie klawisza
                  }
                  while(SendInput(1, &aaa, sizeof(INPUT) == 0);
}


W podanym przykładzie funkcja SendInput będzie wysyłać komunikaty o tej samej wartości tak długo jak długo funkcja zwraca wartość 0. Jeżeli komunikat dojdzie, funkcja zwróci wartość różną od 0 i przejdzie do następnego bloku kodu. Pętla for jest w tym czasie wstrzymywana. Dodałem ProcessMessages by możliwe było wykonania komunikatów po każdym obiegu pętli, a nie gdy pętla zakończy działanie. Pętle wstrzymują zegar, więc interwał będzie ulegał wydłużeniu, jeżeli komunikaty nie będą dochodziły.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Arnold_S
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez polymorphism » niedziela, 25 września 2016, 13:46

@Arnold_S, a dlaczego wysyłasz serię komunikatów w pętli, zamiast zrobić tablicę zdarzeń INPUT[], wypełnić ją odpowiednio kolejnymi komunikatami, po czym wysłać jednym wywołaniem SendInput?
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Arnold_S
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » niedziela, 25 września 2016, 13:48

Powinieneś podać kod, bo jak on sam zaznaczał jest początkujący.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez polymorphism » niedziela, 25 września 2016, 13:50

Spokojnie, więcej wiary w ludzi ;) Jeśli potrafił napisać kod, który wysyła komunikaty do innej aplikacji, to z tym też sobie poradzi.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » niedziela, 25 września 2016, 15:17

Sprawdziłem to i wyszło mi, że wypełnienie tablicy też będzie wymagało wielokrotnego wywołania struktury INPUT celem jej wypełniania, co de facto też sprowadza się do użycia pętli. Różnica jest taka, że strukturę można wypełnić poza Timer'em. Jeżeli jednak zawartość struktury ma się zmieniać, to wypełniania wewnątrz Timer'a poprzez pętle może okazać się konieczne. Niewiele wiec to zmieni.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Poprzednia stronaNastępna strona

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 5 gości

cron