WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

dział ogólny

WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez zeno32167 » poniedziałek, 1 września 2008, 20:25

SendMessage tego nie obsługuje. Oczywiście chcę tego użyć z HWND do okna:
Kod: Zaznacz cały
HWND h =FindWindow(NULL,"blablabla");
SendMessage(h,WM_KEYDOWN, VK_RETURN,0);
SendMessage(h,WM_KEYUP,VK_RETURN,0);


próbowałem też pod VK_RETURN wstawiać jego odpowiednik 0x0D, ale też nic nie dało.

Natomiast z WM_CHAR
Kod: Zaznacz cały
HWND h =FindWindow(NULL,"blablabla");
SendMessage(h,WM_CHAR, VK_RETURN,0);

Aplikacja odbiera mi ten komunikat ale tylko przez 2 sekundy, potem jakby niedocierał, też próbowałem z 0x0D i nic.

A i jeszcze w pętli for dla przykładu:
Kod: Zaznacz cały
void __fastcall TForm5::Button1Click(TObject *Sender)
{
int i = 0;
HWND h =FindWindow(NULL,"blablabla");
for(i;i<10;i++)
{
  SendMessage(h,WM_CHAR, VK_RETURN,0);
  Sleep(500);
}
}

Ani razu nie doszedł ten komunikat, a bez pętli for podczas klikania przycisku dochodzi przez pierwsze 2 sekundy od pierwszego kliknięcia.


Da się jakoś to zrobić żeby stymulować na klawiaturze, oczywiście w formie komunikatu(żeby okno nie było na wierzchu tylko zminimalizowane na pasku) naciskanie cały czas ENTER? Myszkę już umiem, brakuje tylko tej klawiatury a konkretnie to tego ENTERa.

swoją drogą jak użyć w pętli for ProgressBar np:
Kod: Zaznacz cały
for(i=1;i<100;i++)
{
Sleep(1000);
}


i żeby mi się zapełniał z biegiem pętli, czytałem na cyfrowym baronie ale nie chce mi się bawić z manifestami i wole prosty zwyczajny postęp a niestety nie wiem jak.

A i jak już pytam to podczas wykonywania powyższej fukncji która jest pod przyciskiem Start. Po naciśnieciu Start, przycisk się tak jakby zawiesza i cały program też i dopiero przycisk odskakuje po wykonaniu całej pętli i program się odwiesza czyli w tym przypadku po 100 sekundach. Chciałbym zrobić tak żeby drugi przycisk Stop był aktywny podczas wcisniętego przycisku Start czyli pomiędzy tymi 1-100 sekund to wtedy wsadziłbym sobie pod przycisk Stop że i = 100 i pętla by się odrazu zakończyła.

Z góry Dziekuję za pomoc.
Avatar użytkownika
zeno32167
Bladawiec
Bladawiec
 
Posty: 23
Dołączył(a): sobota, 30 sierpnia 2008, 17:15
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez Cyfrowy Baron » wtorek, 2 września 2008, 08:30

Komunikaty WM_KEY[...} faktycznie w ten sposób nie działają, nie do tego służą.
Musisz wysyłać komunikat WM_CHAR, który po prostu wysyła konkretną wartość klawisza, a nie symuluje kliknięcie klawisza.
Wysyłanie dziesięciu komunikatów na raz do okna z góry jest skazane na niepowodzenie, nie zapominaj, że w przesyłaniu komunikatów pośredniczy system, a konkretnie API systemu, więc jeżeli wysyłasz te komunikaty jeden z drugim to system może nie zdążyć przesłać wszystkich. Kiedyś sam tego próbowałem, ale odstęp czasu między kolejnymi komunikatami ustawiałem na 2 sekundy i wtedy na ogół działało prawidłowo, jeżeli system nie musiał obsługiwać zbyt wielu innych komunikatów wysyłanych przez inne programy. Funkcja SendMessage działa w oparciu o haki systemowe, a tych system obsługuje mnóstwo, każdy ruch wskaźnikiem myszki to już hak systemowy.
Zamiast funkcji SendMessage, która wysyła komunikat i nie sprawdza czy komunikat dotarł, możesz użyć funkcji PostMessage, która oczekuje na odpowiedź czy komunikat dotarł czy nie. Jak wspomniałem funkcja oczekuje na odpowiedź, co oznacza, że nie musisz używać funkcji Sleep wstrzymującej aplikację (przynajmniej w teorii), nie oznacza to jednak, że komunikat zawsze dotrze. Jeżeli komunikat dotrze do programu to funkcja PostMessage zwraca wartość większą do 0, jeżeli nie dotrze zwraca wartość 0. Wiedząc to można tak zbudować pętlę, żeby wysyłała komunikaty do skutku:


Kod: Zaznacz cały

  for(int i = 0; i < 10; i++)
  {
    lab1: // na końcu jest dwukropek nie średnik, etykieta powrotu
    if(PostMessageh(h, WM_CHAR, VK_RETURN, 0) == 0)
    {
     goto lab1; // ale tutaj na końcu jest średnik, powtórzenie komunikatu jeżeli nie dotarł
    }
  }



Istnieje tutaj ryzyko, że program się zawiesie, jeżeli komunikaty nie będą docierały.
Można też tak, ryzyko zawieszenia programu jest mniejsze:

Kod: Zaznacz cały
  int i = 0;
  while(i < 10) // po wysłaniu i odebraniu 10 komunikatów pętla kończy działanie
  {
    if(PostMessageh(h, WM_CHAR, VK_RETURN, 0) != 0)
    {
     i++; // zlicza komunikaty
    }
  }



Nie wiem, czy to rozwiąże 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
    NieznanyNieznana

Re: WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez zeno32167 » wtorek, 2 września 2008, 09:14

Niestety PostMessage działa przez 2 sekundy, potem komunikat też nie dociera. To chyba wina tej aplikacji do której jest wysyłany ten komunikat. Ale myszką mogę klikać ile chce i zawsze wszystkie komunikaty dochodzą.

A co do tego przycisku Start i Stop, i progressbara o którym pisałem wcześniej to da się cos z tym zrobic?

Dzięki za pomoc
Avatar użytkownika
zeno32167
Bladawiec
Bladawiec
 
Posty: 23
Dołączył(a): sobota, 30 sierpnia 2008, 17:15
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez Cyfrowy Baron » wtorek, 2 września 2008, 10:33

Możesz wstawić w pętle polecenie odświeżenia aplikacji w każdym obiegu, co pozwoli na użycie przycisku Stop, jednak nie pozwoli na użycie innej funkcji dopóki pętla nie zakończy działania, chyba że pod Stop będzie jakieś polecenie kończące działanie funkcji:

Kod: Zaznacz cały
  for(int i = 0; i < 10; i++)
  {
    SendMessage(h,WM_CHAR, VK_RETURN,0);
    Application->ProcessMessages(); // odświeżenie
  }


Lepsze byłoby jednak rozwiązanie z wątkami, wtedy program w czasie działania pętli mógłby wykonywać inne operacje.
Co do tego ProgressBar to nie wiem o co chodzi.

Możesz zamiast SendMessage spróbować funkcji keybd_event:

Kod: Zaznacz cały
  keybd_event( VK_RETURN, 0, KEYEVENTF_KEYUP, 0);


Ta funkcja jednak nie pobiera uchwytu do żadnego konkretnego okna, lecz po prostu symuluje wciśniecie klawisza w aktywnym oknie, więc przed wywołaniem tej symulacji musisz uaktywnić okno w którym ma być ten komunikat wywołany.
Opis przywoływania okna na pierwszy plan znajdziesz w serwisie Cyfrowy Baron w dziale: porady | API | przywoływanie okna programu na pierwszy plan.

Istnieje jeszcze funkcja SendInput, ale ona też nie pobiera uchwytu do okna, jest bardziej skomplikowana w użyciu i nie wnosi nic nowego.
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
    NieznanyNieznana

Re: WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez zeno32167 » wtorek, 2 września 2008, 12:58

hm to raczej nie dam rady zrobić z tym keyevent ponieważ aplikacja musi być zminimalizowana.

z tym ProgressBar to chodzi mi o to:

Kod: Zaznacz cały
for(i=1;1<100;i++)
{
pętla działa jak pętla
}


jak zrobić progressbar dla tej pętli żeby był zależny od "i". Dla i = 1 na 1% progressbara jest zapełnione, w miarę mykonywania pętli gdy i = 5, to wtedy 5% progressbara zapełnione, dla i = 100, to wtedy 100% bara jest zapełnione bo pętla konczy działanie.
Poprostu jak go wsprzędz w ta petlę tak abym patrzył na progress bar i wiedzial ile powtórzeń zostało już wykonane w tej pętli.
Avatar użytkownika
zeno32167
Bladawiec
Bladawiec
 
Posty: 23
Dołączył(a): sobota, 30 sierpnia 2008, 17:15
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez wargo » wtorek, 2 września 2008, 15:33

Wpisz w pętlę:
Kod: Zaznacz cały
ProgressBar1->StepBy(1);

gdzie w 1 możesz wpisać wartość co ile ma pokazywać po każym wywołaniu. np. gdy wpiszesz 2 to przy 50 razy wykonane i będziesz już miał 100% ;]
Avatar użytkownika
wargo
Mądrosław
Mądrosław
 
Posty: 389
Dołączył(a): niedziela, 13 lipca 2008, 16:44
Podziękował : 12
Otrzymał podziękowań: 3
System operacyjny: Windows 7
Kompilator: C++ Builder 6 Personal
Gadu Gadu: 6259515
    NieznanyNieznana

Re: WM_KEYDOWN WM_KEYUP jaka funkcja to obsluży?

Nowy postprzez zeno32167 » wtorek, 2 września 2008, 17:17

ok dzięki, działa
Avatar użytkownika
zeno32167
Bladawiec
Bladawiec
 
Posty: 23
Dołączył(a): sobota, 30 sierpnia 2008, 17:15
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

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

cron