Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Asembler - focus kontrolki okna dialogowego

Remeknapr 21 Maj 2009 19:12 1251 12
  • #1 21 Maj 2009 19:12
    Remeknapr
    Poziom 33  

    Witam

    OS Windows98 SE. Język programowania assembler - Masm32.

    Jak sprawdzić w programie, która kontrolka okna dialogowego jest "podświetlona", czyli ma ustawiony Focus?

    Pozdrawiam

    0 12
  • Pomocny post
    #2 21 Maj 2009 20:16
    Akane
    Poziom 27  

    Funkcją GetFocus

    Code:
    invoke GetFocus
    
    and    eax,eax
    jz     quit
    ; HWND->id
    invoke GetWindowLong, eax, GWL_ID
    quit:

    Lub lepiej funkcją GetGUIThreadInfo która wypełnia strukturę GUITHREADINFO.

    0
  • #3 21 Maj 2009 21:24
    Remeknapr
    Poziom 33  

    Akane napisał:
    Funkcją GetFocus ...


    Piękne dzięki!! W swoim programie stosuję identyfikatory kontrolek zdefiniowane jaki stałe. Teraz muszę pogłówkować jak uzyskany uchwyt powiązać z ID.

    Przepraszam. Przecież mi napisałeś.

    GWL_ID - Odzyskuje identyfikator okna.

    0
  • #4 22 Maj 2009 13:42
    Remeknapr
    Poziom 33  

    Niestety nie takie to proste. Mój program to kalkulator z dwiema kontrolkami edycyjnymi na dane wejściowe i przyciskami imitującymi klawiaturę. Cyfry wprowadzane przyciskami wprowadzanymi z klawiatury maja trafiać do kontrolki z focusem. Niestety funkje GetFocus i GetWindowLong podaja ID naciśniętego aktualnie klawisza. Jak to obejść? Może da się odpowiednio ułożyć pętle komunikatów?

    Asembler - focus kontrolki okna dialogowego

    0
  • Pomocny post
    #5 22 Maj 2009 13:59
    Akane
    Poziom 27  

    Jest dużo możliwości. Na przykład obsługując WM_COMMAND, w pierwszej kolejności sprawdź czy bardziej znaczący WORD z wParam jest równy EN_KILLFOCUS lub EN_SETFOCUS. Jeżeli jest, to sprawdź czy id kontrolki (mniej znaczący WORD) jest jednym z editów które mają przyjmować cyfry. Jeżeli tak, to zapisz to id gdzieś i użyj go zamiast pobierać fokus.
    W ten sposób zawsze będziesz wiedział który edit jako ostatni miał fokus.

    EN_KILLFOCUS jest wysyłany gdy edit traci fokus, czyli tutaj w momencie klikania buttona.

    0
  • #6 23 Maj 2009 10:34
    Szymon Tarnowski
    Poziom 27  

    Remeknapr napisał:
    Niestety funkje GetFocus i GetWindowLong podaja ID naciśniętego aktualnie klawisza. Jak to obejść? Może da się odpowiednio ułożyć pętle komunikatów?
    Błąd projektowy, focus ZAWSZE będzie trafiał do naciskanego klawisza. Ja bym po prostu zapamiętywał które pole miał ostatni raz focus, najlepiej byłoby złapać komunikat o przejęciu focusu przez określone pole edycyjne.

    0
  • #7 23 Maj 2009 17:16
    Remeknapr
    Poziom 33  

    Szymon Tarnowski napisał:
    Błąd projektowy, focus ZAWSZE będzie trafiał do naciskanego klawisza.


    To juz wiemy.

    Cytat:
    Ja bym po prostu zapamiętywał które pole miał ostatni raz focus, najlepiej byłoby złapać komunikat o przejęciu focusu przez określone pole edycyjne.


    Niestety nie takie to proste. Owszem po wykonaniu pętli:

    Code:
    invoke GetFocus 
    
    and    eax,eax
    jz     quit
    ; HWND->id
    invoke GetWindowLong, eax, GWL_ID
    quit:


    Mogę zapamiętać uzyskany ID w jakiejś zmiennej. Tyle, że po naciśnięciu klawisza ta pętelka jest również wykonywana i do zmiennej trafia już ID tego klawisza. Najlepiej wrzucę gdzieś kawałek kodu, aby było o czym rozmawiać. Trochę to potrwa, bo cały tekst ma kilka tysięcy linii. Muszę go "odchudzić" do niezbędnego minimum.

    Kalc.asm

    0
  • #8 23 Maj 2009 21:41
    Szymon Tarnowski
    Poziom 27  

    Remeknapr napisał:

    Niestety nie takie to proste. Owszem po wykonaniu pętli:

    Code:
    invoke GetFocus 
    
    and    eax,eax
    jz     quit
    ; HWND->id
    invoke GetWindowLong, eax, GWL_ID
    quit:


    Mogę zapamiętać uzyskany ID w jakiejś zmiennej. Tyle, że po naciśnięciu klawisza ta pętelka jest również wykonywana i do zmiennej trafia już ID tego klawisza.
    Nie o to mi chodziło, chodziło mi o żeby złapać komunikat oznaczający tyle że obiekt edycyjna ma focus, a nie testowac.

    0
  • #9 23 Maj 2009 22:17
    Remeknapr
    Poziom 33  

    Szymon Tarnowski napisał:


    Nie o to mi chodziło, chodziło mi o żeby złapać komunikat oznaczający tyle że obiekt edycyjna ma focus, a nie testowac.


    Nie bardzo rozumiem o co Ci może chodzić. Co to znaczy "złapać komunikat"? I jaki? Jak wykryć, która kontrolka ma focus napisał Akane w drugim poscie. I co dalej?

    0
  • #10 23 Maj 2009 22:54
    Akane
    Poziom 27  

    Panie Remeknapr, skoro próba z GetFocus nie działa jak powinna, to usuń ją z kodu i zrób jak w dalszej części wspomniano, bo wnioskuję że moja druga odpowiedź została przeczytana, ale nie zawiera nic wartościowego.

    0
  • #11 23 Maj 2009 23:07
    Remeknapr
    Poziom 33  

    Akane napisał:

    wnioskuję że moja druga odpowiedź została przeczytana, ale nie zawiera nic wartościowego.


    Wszystkie Twoje rady są dla mnie wartościowe i "ćwiczę je". Nie zawsze z braku czasu odpowiadam na bieżąco. Jeśli chodzi o funkcje z drugiej porady, to problem podobny. Działa tylko raz. Drugie naciśnięcie klawisza już wpisuje do zmiennej ID klawisza poprzednio wciśniętego. Problemem jest takie skonstruowanie pętli, aby .... No właśnie. Nie wiem dokładnie w czym rzecz. Jednak mimo wszystko już sobie z tym poradziłem w prosty sposób. Po GetWindowLong sprawdzam czy ID jest "od" editów. Są tylko dwa do wyboru. Jeśli jest inne, ignoruję wynik i nie wpisuję do zmiennej niczego nowego. I to działa. Pozostał juz tylko jak myślę drobny problem, a mianowicie między operacjami wyzerowanie bufora na znaki wisywane do drugiej kontrolki.

    0
  • Pomocny post
    #12 24 Maj 2009 00:09
    Akane
    Poziom 27  

    Ojej, nie używaj ani getFocus, ani GetWindowLong. Zapomnij o nich skoro nie wychodzi.
    Spójrz na to

    Code:
    // gdzieś w WM_INITDIALOG
    
       id_aktywego_edita = arg_1

    // gdzieś dalej
    if uMsg == WM_COMMAND
       ax = wParam >> 16
       dx = wParam & 65535
       if ax == EN_KILLFOCUS or ax == EN_SETFOCUS
          if dx == arg_1 or dx == arg_2
             id_aktywego_edita = dx
          endif
       endif

       // tu cała reszta dla WM_COMMAND
    endif

    0
  • #13 25 Maj 2009 16:32
    Remeknapr
    Poziom 33  

    Akane napisał:
    Ojej, nie używaj ani getFocus, ani GetWindowLong. ...


    Dzięki! Naprowadziłeś mnie na właściwy sposób myślenia. Póki co wszystko działa. Chyba, że okaże się że nie dla wszystkich danych wejściowych. To jednak już inna sprawa.

    Pozdrawiam

    0