CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Tworzenie nowych okien - formularzy
Strona 2 z 2

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: niedziela, 21 listopada 2010, 17:52
przez Darek_C++
Cyfrowy Baron napisał(a):Musisz podawać więcej informacji, gdyż zbyt dużo trzeba się tutaj domyślać. O wciśnięcie których klawiszy chodzi?]
Cały czas chodzi o okna otwierane sposobem jaki jest tematem pierwotnym tego wątku. A kodo:

KOD cpp:     UKRYJ  
void __fastcall TForm4::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
          ShowMessage(Key);
}


Jak sądzę ma za zadanie przechwytywanie wciśnięcia dowolnego klawisza podając jego nr np Insert = 45.... I przechwytuje wiele razy, ale gdy dam np:

KOD cpp:     UKRYJ  
void __fastcall TForm4::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
      Edit1->Text = Key;
}


Ale jak już dam z wywołaniem okna dialogowego:

KOD cpp:     UKRYJ  
void __fastcall TForm4::FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
{
          if(Key == 45)
          {
                if(Application->MessageBox("Zapisać","Komunikat", MB_YESNO | MB_ICONQUESTION) == IDNO)
                {
                        return;
                }
                else
                {
                        // Zapisać...
                }
          }
          BringWindowToFront(this->Handle);
}


Niestety tylko raz za pierwszym kliknięciem w Insert zadziała wyskoczenie okna monitu MessageBox nawet przy dodatnio Twojego funkcji
Wiec gdyby ktoś jednak chciał zapisać czyli powtórnie nacisnął klawisz Insert nie pojawi się już okno MessageBox przy czym okno formularza nadal jest jako pierwsze i aktywne :(



Dodam, że gdy okno dodatkowe znajdzie się pod głównym oknem programu już wcale nie reaguje na naciśniecie w klawisze

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: niedziela, 21 listopada 2010, 18:38
przez Cyfrowy Baron
Jak sądzę ma za zadanie przechwytywanie wciśnięcia dowolnego klawisza podając jego nr np Insert = 45.... I przechwytuje wiele razy, ale gdy dam np:

KOD cpp:     UKRYJ  
void __fastcall TForm4::FormKeyDown(TObject *Sender, WORD &Key,TShiftState Shift)
{
      Edit1->Text = Key;
}


Oczywiście, że to działa. Nie wywołujesz okna komunikatu, więc focus pozostaje na oknie w którym wciskasz klawisze. Problem powoduje właśnie okno komunikatu, które przechwytuje focus, więc na tym należy się skupić.



Dodam, że gdy okno dodatkowe znajdzie się pod głównym oknem programu już wcale nie reaguje na naciśniecie w klawisze


To oczywiste, przechwytywanie komunikatu o wciśnięciu klawisza w oknie działa, tylko gdy okno jest aktywne i ma ustawiony focus.



Niemniej jednak u mnie w C++Builder 2010, w WinXP to działa prawidłowo i nie ma znaczenia czy okno jest modalne czy niemodalne.
Próbuj ustawić focus na formularz:

KOD cpp:     UKRYJ  
void __fastcall TForm2::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
 if(Key == 45)
 {
  if(Application->MessageBox(L"Zapisać", L"Komunikat", MB_YESNO | MB_ICONQUESTION)
      == ID_NO) return;
  else
  {
    ;
  }
 }  

 this->SetFocus();
}


Znacznie pewniejszym rozwiązaniem jest użycie metody WindowProc. Ustawienie KeyPrewiew nie ma tutaj znaczenia, gdyż nie korzystamy z żadnego zdarzenia:

Plik nagłówkowy Unit2.h dynamicznie tworzonego formularz TForm2:
KOD cpp:     UKRYJ  
private:
        TWndMethod KeyApp;
        void __fastcall GetKeyApp(TMessage &Msg);


Plik źródłowy Unit2.cpp dynamicznie tworzonego formularz TForm2:
KOD cpp:     UKRYJ  
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
 KeyApp = this->WindowProc;
 this->WindowProc = GetKeyApp;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::GetKeyApp(TMessage &Msg)
{
 /* Przykłąd sprawdzenia który klawisz wciśnięto
 if(Msg.Msg == WM_KEYDOWN)
 {
  ShowMessage((String)Msg.WParam);
 }  */


 if(Msg.Msg == WM_KEYDOWN && Msg.WParam == 45)
 {
   if(Application->MessageBox(
       L"Zapisać", L"Komunikat", MB_YESNO | MB_ICONQUESTION) == IDNO)  return;
   else
   {
    ShowMessage("Zapisano");
   }
 }

 KeyApp(Msg);
}


Dodam, że gdy okno dodatkowe znajdzie się pod głównym oknem programu już wcale nie reaguje na naciśniecie w klawisze


By działało przechwytywanie klawiszy w oknie programu, okno w którym przechwytujemy klawisz musi być aktywne, czyli musi być na wierzchu i nie może być przesłonięte żadnym innym oknem.

Jeżeli chcesz przechwytywać wciśnięcie klawiszy, nie w oknie programu lecz w systemie, to musisz zamontować haka systemowego, czyli przechwytywać komunikaty systemowe. ► patrz serwis: Cyfrowy Baron dział: porady -> API -> Keyloger, czyli przechwytywanie wciśnięcia klawiszy we wszystkich programach.



Jeszcze raz przypominam: rób odstępy jednaj linii pomiędzy tagami BBCode. Twoje posty trudno się czyta, gdyż są źle formatowane. Nie musisz oszczędzać miejsca. Poza tym to nie są topicy, lecz wątki skłądające się z postów. To tak apropo Twojej wypowiedzi w ostatnim poście, który zmoderowałem.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: niedziela, 21 listopada 2010, 18:56
przez Darek_C++
Dziękuję za poświęcony czas 8-)

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: niedziela, 21 listopada 2010, 19:23
przez Cyfrowy Baron
Tu nie chodzi o to byś dziękował, ale o to czy kod zadziałał i który sposób, by inni użytkownicy czytający ten wątek wiedzieli co mają z tym zrobić.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 11:43
przez Darek_C++
@Tu nie chodzi o to byś dziękował
CB dziękowałem za poświęcony czas i to w niedzielę ;)

@ale o to czy kod zadziałał
Zła wiadomość jest taka, że teraz testowałem sposób jaki ostatnio Podałeś i niestety nie działa:
KOD cpp:     UKRYJ  
void __fastcall TForm4::GetKeyApp(TMessage &Msg)
{
        ShowMessage((String)Msg.WParam);
        KeyApp(Msg);
}
Przy wciskaniu klawiszy w ogóle nie pojawia się okno ShowMessage()
:(
----
Coś jest nie tak z formatowaniem wiadomości - chodzi o odstęp między kodem, a tekstem pod min nie ma tam spacji, a odstęp jest duży.
Zamieszczam screen okna formularza: http://img98.imageshack.us/img98/2829/oknoooo.jpg na którym to zobrazowałem.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 11:58
przez Cyfrowy Baron
Trzeba przechwytywać konkretny komunikat:

KOD cpp:     UKRYJ  
void __fastcall TForm4::GetKeyApp(TMessage &Msg)
{
  if(Msg.Msg == WM_KEYDOWN)
  {
    ShowMessage((String)Msg.WParam);
   }
}

 KeyApp(Msg);
Oczywiście zakładam, że podłączyłeś metodę WindowProc pod formularz w konstruktorze klasy - koniecznie w konstruktorze klasy:

KOD cpp:     UKRYJ  
__fastcall TForm4::TForm4(TComponent* Owner)
        : TForm(Owner)
{

 KeyApp = this->WindowProc;

 this->WindowProc = GetKeyApp; /* this->WindowProc jest równoznaczne z zapisem Form4->WindowProc */

}
To nie może nie działać, skoro u mnie działa. Bardziej prawdopodobne jest, że coś źle zrobiłeś.



Coś jest nie tak z formatowaniem wiadomości - chodzi o odstęp między kodem, a tekstem pod min nie ma tam spacji, a odstęp jest duży.


Problem dotyczy BBCode cpp, jeżeli tekst w znaczniku zawiera więcej linii niż 4 i mniej niż 9 to pojawia się problem z odstępem. Nie jestem w stanie tego naprawić, gdyż nie ja jestem autorem tego BBCode i nie znam się na PHP.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:11
przez Darek_C++
Cyfrowy Baron napisał(a):To nie może nie działać, skoro u mnie działa. Bardziej prawdopodobne jest, że coś źle zrobiłeś.

Zrobiłem dokładnie jak Podałeś i nie pojawia się komunikat przy wciskaniu klawiszy...

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:14
przez Cyfrowy Baron
Zamieść w załączniku - patrz na dole pola edycji zakładka Dodaj załącznik - pliki źródłowe.



Do cytowania postów masz BBCode quote, a nie małpkę @. Nie wydziwiaj po swojemu.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:15
przez Darek_C++
Testowałem w formularzu otwieranym za pomoca:
KOD cpp:     UKRYJ  
        TForm3 *Form3 = new TForm3(this);
        Form3->ShowModal();

I też to nie działa...

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:17
przez Cyfrowy Baron
Zamieść źródła.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:23
przez Darek_C++
Źródeł programu w którym nie działa nie zamieszczę, ale sprawdzałem w testowym projekcie z dwoma formularzami i faktycznie działa.
Muszę jeszcze raz sprawdzić w tym co nie działało.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:26
przez Cyfrowy Baron
Czyli tak jak pisałem, coś robisz źle.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:36
przez Darek_C++
Nagłówek
KOD cpp:     UKRYJ  
class TForm3 : public TForm
{
__published:    // IDE-managed Components
        TLabeledEdit *LabeledEdit1;
        TMemo *Memo1;
        TMemo *Memo2;
        TLabeledEdit *LabeledEdit2;
        TLabel *Label1;
        TLabel *Label2;
        TButton *Button1;
        TSaveTextFileDialog *SaveTextFileDialog1;
        TMainMenu *MainMenu1;
        TMenuItem *Akcja1;
        TMenuItem *Wczytajszablon1;
        TOpenTextFileDialog *OpenTextFileDialog1;
        TLabeledEdit *LabeledEdit3;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall Wczytajszablon1Click(TObject *Sender);
private:        // User declarations
        TWndMethod KeyApp;
        void __fastcall GetKeyApp(TMessage &Msg);
public:         // User declarations
        __fastcall TForm3(TComponent* Owner);
};

Implementacja:
KOD cpp:     UKRYJ  
#include <vcl.h>
#pragma hdrstop
#include "tinyxml.h"
#include "Unit3NowyProjektWpisu.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
        : TForm(Owner)
{
        KeyApp = this->WindowProc;
        this->WindowProc = GetKeyApp;
}

//---------------------------------------------------------------------------
void __fastcall TForm3::FormCreate(TObject *Sender)
{
        Memo1->Clear();
        Memo2->Clear();
        LabeledEdit3->Text = "http://";
}
//---------------------------------------------------------------------------
void __fastcall TForm3::FormClose(TObject *Sender, TCloseAction &Action)
{
        Action = caFree;
}

void __fastcall TForm3::GetKeyApp(TMessage &Msg)
{
        if(Msg.Msg == WM_KEYDOWN)
        {
                ShowMessage((String)Msg.WParam);
        }
        KeyApp(Msg);
}
 

Wywołanie:
KOD cpp:     UKRYJ  
        TForm3 *Form3 = new TForm3(this);
        Form3->ShowModal();

I w tamtym programie co robię to nie działa:(

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: poniedziałek, 22 listopada 2010, 12:47
przez Cyfrowy Baron
Niestety nic mi to nie mówi. Przytoczony kod jest prawidłowy i działa, co sam stwierdziłeś. W tamtym programie umieściłeś jakiś kod, który wywołuje konflikt. Szukaj, nie masz innego wyjścia.

Re: Tworzenie nowych okien - formularzy

Nowy postNapisane: środa, 4 maja 2011, 20:16
przez Cyfrowy Baron
Odnośnie TMessage i komunikatu WM_KEYDOWN. Zauważyłem, że u mnie też nie zawsze to działa. Stworzyłem taki kod:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:        // User declarations
      TWndMethod KeyApp;
      void __fastcall GetKeyApp(TMessage &Msg);


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 KeyApp = this->WindowProc;
 this->WindowProc = GetKeyApp;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::GetKeyApp(TMessage &Msg)
{
 if(Msg.Msg == WM_KEYDOWN)
 {
   Caption = "Down";
   if(GetKeyState(VK_CONTROL) < 0 && Msg.WParam == 'A')
   {
    ShowMessage("Wciśnięto kombinację klawiszy CTRL + A");
   }
 }

 KeyApp(Msg);
}


Nagle okazało się, że przechwytywanie wciśnięcia klawisza nie działa, ale przechwytywanie innych komunikatów działa.
Stworzyłem nową aplikację testową i wkleiłem ten sam kod. Ku mojemu wielkiemu zdziwieniu okazało się, że działa prawidłowo. Nie wiem czym to może być spowodowane, gdyż nie zmieniałem niczego w ustawieniach projektu.