problem z VK_..

dział ogólny

problem z VK_..

Nowy postprzez en_6280 » czwartek, 19 lutego 2009, 20:56

Witam mam problem z VK_ a mianowicie chciałbym aby jednocześnie gdy są wciśniete VK_RIGHT i VK_UP
Kod: Zaznacz cały
if(Key==VK_RIGHT){Form1->HorzScrollBar->Position+=100;}
if(Key==VK_UP){Form1->VertScrollBar->Position-=100;}

to żeby mi je czytał oba a nie tylko jeden. ProszE o pomoc.
Avatar użytkownika
en_6280
Bladawiec
Bladawiec
 
Posty: 3
Dołączył(a): czwartek, 19 lutego 2009, 20:52
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: problem z VK_..

Nowy postprzez Cyfrowy Baron » czwartek, 19 lutego 2009, 21:34

Chyba tak, ale nie sprawdzałem:

Kod: Zaznacz cały
  if(Key == VK_RIGHT && Key == VK_UP)
  {
    Form1->HorzScrollBar->Position += 100;
    Form1->VertScrollBar->Position -= 100;
  }
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: problem z VK_..

Nowy postprzez kinio » czwartek, 19 lutego 2009, 22:47

Witam!

Cyfrowy Baron napisał(a):Chyba tak, ale nie sprawdzałem:

To radzę sprawdzić.
Ja rozumiem że można pisać coś na szybko i popełnić jakiś błąd, ale taki?!
CB zajmujesz się tutaj doradzaniem w szczególności początkującym, wierzę że też nie jeden program napisałeś i pewne doświadczenie masz.
Tak więc zanim cokolwiek napiszesz lepiej się zastanów, może czasami lepiej nic nie napisać niż walnąć takiego byka.
To tak jakby pisarz napisał stuł - ok może się zdarza.

Powiedz CB kiedy ten warunek może być spełniony, podaj mi chociaż jeden przypadek!
Nie wiem en_6280 nie napisał jakiego typu jest zmienna Key, może to być najprawdopodobniej albo char, albo WORD.
Kurde, może to ja jestem na tyle głupi i nie powinienem pisać tego posta ale nie wiem kiedy taki warunek może być spełniony nic mi do głowy nie przychodzi. :mrgreen:
Może chodziło Ci żeby sprawdzić tą zmienną poprzez jakąś maskę np:
Kod: Zaznacz cały
if((Key & VK_UP) && (Key & VK_RIGHT))

to wtedy ma sens i taki warunek może być spełniony.

Nawet gdyby ten warunek mógłby być kiedykolwiek spełniony to chyba wprowadzasz dość poważne ograniczenie do programu, gdyż uniemożliwiasz sterowanie paskami przewijania tylko jednym klawiszem. Trzeba wcisnąć obydwa naraz aby spełnić warunek. A czasami jakiś użytkownik będzie chciał się przesunąć tylko w prawo - i co wtedy? - trochę kłopotliwe.

OK, nie ważne.
Widzę że chcesz wykorzystać klawisze do przesuwania pasków, w takim razie najprościej Ci będzie zrobić tak:
Kod: Zaznacz cały
if(GetKeyState(VK_UP)&0x8000)
     Form1-> VertScrollBar->Position+=100;
if(GetKeyState(VK_RIGHT)&0x8000)
     Form1->HorzScrollBar->Position+=100;

Nie wiem, w jakiej funkcji/metodzie jakiego obiektu masz umieszczony ten kod wiec nie gwarantuje że to co podałem na 100% zadziała.
Żeby zadziałało możesz umieścić ten kod w funkcji/metodzie wywoływanej przy naciśnięciu klawisza.
If a machine is expected to be infallible, it cannot also be intelligent.
-- A.Turing
Avatar użytkownika
kinio
Homos antropiczny
Homos antropiczny
 
Posty: 67
Dołączył(a): poniedziałek, 14 lipca 2008, 08:51
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: problem z VK_..

Nowy postprzez en_6280 » piÄ…tek, 20 lutego 2009, 17:11

DZieki kinio. Tyko nie bardzo rozumiem tego: &0x8000 to chodzi coÅ› z kodem szesnastkowym??
Avatar użytkownika
en_6280
Bladawiec
Bladawiec
 
Posty: 3
Dołączył(a): czwartek, 19 lutego 2009, 20:52
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: problem z VK_..

Nowy postprzez Cyfrowy Baron » sobota, 21 lutego 2009, 10:43

Fakt! Umknęło mi, że to ta sama zmienna i nie może mieć dwóch odmiennych wartości na raz.
Rzeczywiście pisałem szybko, ale chodziło mi o coś takiego:

Kod: Zaznacz cały
if(Key == (VK_RIGHT & VK_UP))
{
  HorzScrollBar->Position += 100;
  VertScrollBar->Position -= 100;
}


Proponuję inne rozwiązanie. Z kodu wnioskuję, że sterujesz paskami przewijania formularza, więc najprościej jest to zrobić w zdarzeniu OnKeyUp, przy czym trzeba ustawić właściwość KeyPreview formularza na true. Proponuję stworzyć odrębną funkcję:

Kod: Zaznacz cały
void __fastcall TForm1::Scroll(WORD &Key)
{
switch(Key){
         case VK_LEFT: HorzScrollBar->Position -= 100; break;
         case VK_RIGHT: HorzScrollBar->Position += 100; break;
         case VK_UP:     VertScrollBar->Position -= 100; break;
         case VK_DOWN: VertScrollBar->Position += 100; break;
         }
}
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key,
     TShiftState Shift)
{
Scroll(Key);
}
//---------------------------------------------------------------------------
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: problem z VK_..

Nowy postprzez kinio » sobota, 21 lutego 2009, 17:11

Hej!
en_6280 napisał(a):DZieki kinio. Tyko nie bardzo rozumiem tego: &0x8000 to chodzi coś z kodem szesnastkowym??

Nie ma za co.
Heh, taki zapis: 0x8000 jest zapisem w kodzie szesnastkowym.
Jak wiesz na klawiaturze są, można powiedzieć, dwa rodzaje klawiszy:
- takie jak spacja, enter, klawisze z literkami, które mogą być w jednym z dwóch stanów: góra albo dół.
- takie jak CapsLock, ScrollLock itp., które dodatkowo przełączają pewien stan. Np. Stan CapsLock może być włączony i wyłączony (zwykle pokazuje to dioda) natomiast sam klawisz może być dodatkowo góra albo dół. Tworzy nam to tak naprawdę 4 kombinacje:
1. CapsLock down oraz off
2. CapsLock down oraz on
3. CapsLock up oraz off
4. CapsLock up oraz on
Funckja GetKeyState uwzględnia oba powyższe przypadki i może zwrócić tak naprawdę 4 różne wartości.
Dla danego przypadku różne bity w zwracanej wartości są ustawiane bądź nie.
Więcej na ten temat możesz znaleść tutaj: http://msdn.microsoft.com/en-us/library/ms646301(VS.85).aspx
Zastosowanie tej maski tutaj nie wydaje się konieczne jednak w takim przypadku kod jest jednoznaczny i dla dowolnego przycisku na klawiaturze, warunek będzie spełniony jeżeli klawisz jest wciśnięty i tylko wciśnięty. Warunek nie będzie spełniony nawet w przypadku klawisza CapsLock, który będzie aktywny.
Bez zastosowania maski warunek będzie spełniony w obu przypadkach a to nie oto nam chodziło.

Mam nadzieje że w miarę jasno się wyraziłem.

Nie chcę być upierdliwy, ale ten kod CB też jest trochę bez sensu.
Cyfrowy Baron napisał(a):
Kod: Zaznacz cały
if(Key == (VK_RIGHT & VK_UP))

Jednak nie twierdzę że tak jest na pewno ponieważ nie znam kodów tych wszystkich klawiszy, kiedyś gdzieś to miałem a teraz mam to gdzieś jakie one są :)
W każdym razie, trzeba by mieć straszne szczęście aby ten warunek został kiedykolwiek spełniony w odpowiednim momencie (tzn. przy wciśniętych klawiszach VK_UP, VK_DOWN).
Z tego co pamiętam, to kody klawiszy nie są reprezentowane tak że każdy pojedynczy bit odpowiada dokładnie jednemu klawiszowi. Było by to nieefektywne, zresztą jakby się można było domyśleć taka liczba powinna się składać z ponad 100 bitów - trochę za dużo, kiedy zupełnie wystarczy nam ich 8 (256 wartości). Jak wiesz jest dość duża różnica pomiędzy operatorami && oraz &:
- && - jest operatorem logicznym dwuargumentowym który zwraca wartość logiczną true bądź false. true zwraca kiedy po obu jego stronach stoją wartości niezerowe! W przeciwnym wypadku zwraca false.
- & jest operatorem bitowym dwuargumentowym, wykonującym iloczyn bitowy dwóch wartości.
Czyli załóżmy (tak trochę abstrakcyjnie) że jeżeli Key = 0 to wciśnięty jest jakiś dowolny klawisz (dowolny oznacza że może być nawet taki który nie istnieje w rzeczywistości, czyli w rezultacie nie jest wciśnięty żaden). To takie założenie trochę abstrakcyjne pozwoli nam na jednoczesne rozpatrzenie dwóch przypadków:
- jeżeli Key = 0 to żaden rzeczywisty klawisz nie jest wciśnięty
- jeżeli Key = 0 to jakiś klawisz rzeczywisty jest wciśnięty.
Tak więc zakładając kod klawisza A (np spacji) może być 0x02, natomiast klawisza B (np. literki K) może być 0x04, wtedy z działanie:
A & B da nam 0 co odpowiada dowolnemu innemu klawiszowi różnemu od A i B. Powstaje nam tutaj co najmniej dwuznaczność (a nawet wieloznaczość)!!
Więc o ile z tym kodowaniem jest jak napisałem to Twój warunek jest niedobry ponieważ nie sądzę aby kiedykolwiek był on poprawnie spełniony.
Natomiast jeżeli każdy klawisz jest kodowany na osobnym bicie to warunek jest dwuznaczny - a to chyba nie oto nam chodzi. Przecież my chcemy aby nasz suwak był przesuwany tylko w jednym przypadku: kiedy VK_UP (czy tam VK_RIGHT) jest wciśnięty.

ProszÄ™ nie traktuj tego jako atak, ale bardziej jako konstruktywnÄ… krytykÄ™.
Ja się od Ciebie nauczyłem dużo rzeczy związanym z Borlandem, nie ukrywam. Ale to nie znaczy że Ty nie możesz się uczyć czegoś innego od innych. Nie mówię że ode mnie, bo mogę nie mieć zupełnie tutaj racji.
To że jesteś właścicielem tego forum i podjąłeś się podniosłej misji, jaką jest bezinteresowne pomaganie, nie definiuje Cię jako wszechwiedzącego i nieomylnego - co muszą zrozumieć inni, oraz Ty sam.
Nikt nie jest nie omylny, a to co tutaj napisałem nie napisałem żeby kogokolwiek urazić tylko żeby się podzielić swoim zdaniem i być może wywołać dyskusję. W końcu to jest forum dyskusyjne :)

Pozdrawiam!
If a machine is expected to be infallible, it cannot also be intelligent.
-- A.Turing
Avatar użytkownika
kinio
Homos antropiczny
Homos antropiczny
 
Posty: 67
Dołączył(a): poniedziałek, 14 lipca 2008, 08:51
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: problem z VK_..

Nowy postprzez Cyfrowy Baron » sobota, 21 lutego 2009, 20:33

Kod: Zaznacz cały
if(Key == (VK_RIGHT & VK_UP))


Warunek zostanie spełniony przy jednoczesnym wciśnięciu klawiszy VK_RIGHT i VK_UP, jak widzę tym razem Tobie nie chciało się tego sprawdzić.
Inna sprawa, że warunek jest spełniony nawet przy wciśnięciu innych dodatkowych klawiszu, czyli np. VK_RIGHT, VK_UP i VK_LEFT, itp.

Więc o ile z tym kodowaniem jest jak napisałem to Twój warunek jest niedobry ponieważ nie sądzę aby kiedykolwiek był on poprawnie spełniony.


Poniższy przykładowy program dowodzi, że jednak warunek jest spełniony.
scroll.rar


Nawet jeżeli użyję takiego kodu:
Kod: Zaznacz cały
if(Key == (0x26 & 0x27))
{
  HorzScrollBar->Position += 100;
  VertScrollBar->Position -= 100;
}


Problem w tym, że zadziała tylko kombinacja (VK_RIGHT & VK_UP).
Nie napisałem jednak nigdzie, że to dobre rozwiązanie i że powinno zadziałać, napisałem jednak, że pierwotnie chciałem tego użyć zamiast if(Key == VK_RIGHT && Key == VK_UP). Nie testowałem jednakże tego rozwiązania i nie zastanawiałem się nad nim.
W rozwiązaniu podałem inny kod:
Kod: Zaznacz cały
    void __fastcall TForm1::Scroll(WORD &Key)
    {
    switch(Key){
             case VK_LEFT: HorzScrollBar->Position -= 100; break;
             case VK_RIGHT: HorzScrollBar->Position += 100; break;
             case VK_UP:     VertScrollBar->Position -= 100; break;
             case VK_DOWN: VertScrollBar->Position += 100; break;
             }
    }
    void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key,
         TShiftState Shift)
    {
    Scroll(Key);
    }
    //---------------------------------------------------------------------------
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
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: problem z VK_..

Nowy postprzez kinio » niedziela, 22 lutego 2009, 08:59

Witam!
Cyfrowy Baron napisał(a):Poniższy przykładowy program dowodzi, że jednak warunek jest spełniony.

Tak, tym programem pokazałeś jedynie to że mówiłem prawdę:
kinio napisał(a):W każdym razie, trzeba by mieć straszne szczęście aby ten warunek został kiedykolwiek spełniony w odpowiednim momencie

i miałeś to szczęście ponieważ, już zadałem sobie tyle trudu i sprawdziłem kody klawiszy VK_UP i VK_RIGHT i są one takie jak Ty też użyłeś:
VK_UP = 0x26
VK_RIGHT = 0x27
hmm, jednak Twój program tak naprawdę nie reaguje na kombinację klawiszy VK_UP + VK_RIGHT, warunek jest spełniony również jeżeli zostanie wciśnięty tylko klawisz VK_UP, natomiast nie działa kiedy wciśnięty jest tylko klawisz VK_RIGHT.
A dlaczego? Bo jak pisałem w poprzednim poście: & jest operatorem bitowym, czyli jego działanie jest następujące:
VK_UP = 0x26 = 100110 (binarnie)
VK_RIGHT = 0x27 = 100111 (binarnie)
czyli jeżeli użyjemy operatora & to: VK_UP & VK_RIGHT = 0x26 & 0x27 = 100110 & 100111 = 100110 = VK_UP
dlatego program reaguje na VK_UP a nigdy na samo VK_RIGHT, jak nie wierzysz sprawdź zapisując warunek zamiast
Kod: Zaznacz cały
if(Key == (VK_RIGHT & VK_UP))

tak:
Kod: Zaznacz cały
if(Key == VK_UP)

efekt dostaniesz taki sam.
Jeżeli dalej mi nie wierzysz to np. zamiast VK_UP wstaw VK_DOWN (0x28 = 101000),:
Kod: Zaznacz cały
if(Key == (VK_RIGHT & VK_DOWN))

wtedy program przestanie reagować na jakiekolwiek z wymienionych przycisków ponieważ: VK_DOWN & VK_RIGHT = 0x28 & 0x27 = 101000 & 100111 = 100000 = VK_SPACE
a zacznie reagować na klawisz spacji.
I w ten sposób możesz przeprowadzać kolejne eksperymenty.
Avatar użytkownika
kinio
Homos antropiczny
Homos antropiczny
 
Posty: 67
Dołączył(a): poniedziałek, 14 lipca 2008, 08:51
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: problem z VK_..

Nowy postprzez Cyfrowy Baron » niedziela, 22 lutego 2009, 09:03

Aż tylu eksperymentów robić mi się nie chce, szczególnie, że nie upieram się iż mam co do tego rację. Tak naprawdę to Ty rozdmuchałeś tą sprawę mimo iż problem został już rozwiązany na dwa różne sposoby i podałem prawidłowe rozwiązanie.
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


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 7 gości