CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - GDI+, DrawImage i klawisze Alt/Shift/Ctrl
Strona 1 z 1

GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: sobota, 20 lutego 2021, 13:17
przez Mironas
Biblioteka GDI+
Najprostsza możliwa funkcja rysująca obrazek na 'Image1', w pozycji myszki.
Funkcja wywoływana w Image1_OnMouseMove, czyli za każdym razem gdy ruszę myszką na Image1 to obrazek jest rysowany w nowym miejscu.
KOD cpp:     UKRYJ  
void __fastcall TForm1::Image1_OnMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
  Rysowanie(X, Y);
}
//---------------------------------------------------------------------------
void TForm1::Rysowanie(int x, int y)
{
  GGraphics Graf (Image1->Canvas->Handle);
  Graf.Clear(GYellow);

  GRect Rect1 (0, 0, iw, ih);
  GRect Rect2 (x, y, 300, 200);
  Graf.DrawImage(IMAGE, Rect2, Rect1);

  Image1->Repaint();
}
 

Całość działa dość szybko, aż do momentu gdy nacisnę Alt, Shift lub Ctrl. Wtedy nagle zaczyna się niemiłosiernie mulić. Mogę zrobić parę zygzaków myszką a potem, w zwolnionym tempie oglądać jak program odtwarza tę ścieżkę przez kilka następnych sekund. Zaznaczam, że w programie w ogóle nie obsługuję klawiszy Alt/Shift/Ctrl. Zrobiłem specjalny mini-program, który wyłącznie robi to co opisałem, i sytuacja jest dokładnie taka jak powyżej.

Pytania:
1. Dlaczego tak się dzieje?
2. Jak tego uniknąć?

Próba "wyłączenia" klawiszy Shift/Ctrl jak poniżej, przy włączonym KeyPreview, nie daje rezultatu.
KOD cpp:     UKRYJ  
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  if ( Key==VK_SHIFT || Key==VK_CONTROL )
    Key = 0;
}
 

Re: GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: niedziela, 21 lutego 2021, 11:42
przez polymorphism
Przenieś rysowanie do on-paint kontrolki, a w mouse-move daj jedynie komendę odświeżającą okno.

Re: GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: niedziela, 21 lutego 2021, 11:54
przez lukagrom
To chyba nie zależy od tej biblioteki, tylko to jakiś feler "borlandowskiego Canvasa".
Dla odmiany w tradycyjnym ujęciu zrobiłem podobnie:
KOD cpp:     UKRYJ  
void __fastcall TForm1::Rysowanie(int x, int y)
{
  TCanvas *Canv1;
  Canv1=Image1->Canvas;
  Canv1->Brush->Style=bsSolid;
  Canv1->Brush->Color=clRed;
  Canv1->Rectangle(x,y,x+random(x),y+random(y));
}
void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X,
                  int Y)
{
 Rysowanie(X,Y);
}

 

I tak samo wciśnięcie powyższych klawiszy funkcyjnych przerywa rysowanie. Ponowne ich kilkukrotne wciśnięcie rysowanie przywraca.

Re: GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: niedziela, 21 lutego 2021, 12:05
przez lukagrom
Przenieś rysowanie do on-paint kontrolki, a w mouse-move daj jedynie komendę odświeżającą okno.


TImage jest komponentem specyficznym, który nie posiada zdarzenia - on paint, czy podobnych.

Re: GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: niedziela, 21 lutego 2021, 12:12
przez polymorphism
Fakt. Zapomniałem. Ale niech kombinuje w tym kierunku.

Re: GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: wtorek, 23 lutego 2021, 14:33
przez lukagrom
U mnie chyba udało się rozwiązać problem blokowania rysowania przypisując adresy klawiszy funkcyjnych innemu adresowi klawisza, który wciśnięty nie przerywa malunku. Posłużyłem się adresem spacji - ox20.
KOD cpp:     UKRYJ  
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)

{
 if(Key==VK_LSHIFT)
  Key=0x20;
 if(Key==VK_SHIFT)
  Key=0x20;
 if(Key==VK_CONTROL)
  Key=0x20;
 if(Key==VK_MENU)
  Key=0x20;
 }
 

Re: GDI+, DrawImage i klawisze Alt/Shift/Ctrl

Nowy postNapisane: wtorek, 23 lutego 2021, 15:49
przez Mironas
polymorphism napisał(a):Przenieś rysowanie do on-paint kontrolki, a w mouse-move daj jedynie komendę odświeżającą okno.

lukagrom napisał(a):U mnie chyba udało się rozwiązać problem blokowania rysowania przypisując adresy klawiszy funkcyjnych innemu adresowi klawisza

Niestety oba sposoby nie dają rezultatu.

Za to chyba można obejść problem, robiąc 2 rzeczy:
1. Jakaś zmienna za pomocą której pilnuję, aby w OnMouseMove nie wywoływać ponownie rysowania dopóki poprzednie się nie skończyło.
2. Na początku każdego rysowania wykonać Application->ProcessMessages();

Trzeba tylko pilnować, aby ostatnie rysowanie po zakończeniu ruchu myszki się wykonało.