[wxWidgets] rysowanie na na kontrolkach

0

Zrobiłem proste rysowanie na kontrolce - przy drag&drop ma podążać tekst "Przeciągnij i upuść" tekst jest przeciągany ale zamazuje dane w kontrolce. Odświeżanie kontrolki przed rysowanie w ogóle nie wyświetla tekstu

    void OnMouseMove(wxMouseEvent& event)
    {
    if (event.Dragging())
    {
        wxClientDC dc(this);
        //dc.Clear();
        this->Refresh();      //to powoduje, że tekst wykreślany poniżej nie jest widoczny  
        //dc.SetPen(wxNullPen);
        this->SetCursor(wxCursor(wxCURSOR_NO_ENTRY ));
        //dc.DrawLabel("Upusc przenoszona pozycje",wxRect(event.GetX(),event.GetY(),event.GetX()+20,event.GetY()+50));     

        dc.DrawText("Upusc przenoszona pozycje",event.GetX(),event.GetY());        
        return;
    }
   ....

Najprostszym sposobem było by skopiować część ekranu na którym rysuję tekst, wyświetlić tekst, przy kolejnym przesunięciu odzyskać skopiowany kawałem ... i powtórzyć operację

0

Z dokumentacji o Refresh:

Note that repainting doesn't happen immediately but only during the next event loop iteration, if you need to update the window immediately you should use Update instead.

0

bardziej chodziło by mi o kopiowanie wycinka ekranu...

co mogę wyczytać o funkcji refresh?, gdyby nawet się udało, to będę miał 'mruganie' ekranu

0

To możesz wyczytać, że Refresh nie powoduje natychmiastowego odmalowania okna, nastąpi to w następnej iteracji pętli komunikatów. Więc to, co narysujesz wewnątrz OnMouseMove po Refresh, zostanie zamalowane.

Jeśli chodzi o kopiowanie zawartości okna, to według mnie niepotrzebne komplikowanie sprawy. Do sygnalizowania stanu d&d wystarczy kursor.

0

No niestety nie mogę przeskoczyć tego temat,
nie ważne gdzie umieszczę refresh i tak tekst nie jest pokazywany i... kontrolka 'mruga'

0

Po pierwsze, myślałem, że sprawę Refresh mamy już zamkniętą. Po drugie, co to za kontrolka? Własna, czy jakaś systemowa?

0

Też tak myślałem :)

kontrolka własna

class wxListBoxPopup 
    : public wxListBox,
      public wxComboPopup
{
public:
0

Czyli systemowy listbox. Sprawdzałem i u mnie działa. Wprawdzie lekko miga, ale być może dlatego, że odświeżam całą kontrolkę.

--- edit ---

Tu masz wersję z odświeżaniem fragmentu okna, efekt jest zadowalający:

void OnMouseMove(wxMouseEvent& event)
{
	static wxRect repaint_rc;

	wxWindow* wnd = (wxWindow*)event.GetEventObject();

	wnd->Refresh(true,&repaint_rc);
	wnd->Update();

	wxClientDC	dc(wnd);
	wxPoint	pt = e.GetPosition() + wxSize(16,16);

	wxString text(wxT("Upuść przenoszoną pozycję"));
	wxSize s = dc.GetTextExtent(text);
	dc.DrawText(text,pt);

	repaint_rc.SetLeftTop(pt);
	repaint_rc.SetSize(s);
}

repaint_rc dla jasności przekazu jest statyczny, normalnie powinien być składnikiem klasy, zerowanym na początku operacji przeciągania.

0

Super o to chodziło,
ale jak widzę to właściwie odświeżany jest kawałek ekranu pod tekstem, co powoduje, że kontrolka ani drgnie. Dorysowałem linie wstawienia, która podąża za kursorem. Muszę jeszcze zorganizować tak, aby inia 'skakał' pomiędzy rekordy w liście.

user image

0

Z tym możesz mieć problem. Nigdzie nie widzę w dokumentacji, żeby była jakaś metoda zwracająca pozycję i rozmiar elementu listy. Chyba że nie zależy Ci na przenośności, wtedy możesz użyć LB_GETITEMRECT.

0

rzeczywiście może być problem, przyjrzałem się funkcji SendMessage, spróbuję - co do przenośnoci, to nie ma tu problemu - ten programik działa jedynie na MS

0

a to działający kawałek kodu dla potomności, może się komuś przyda:

    if ( event.LeftIsDown() && event.Dragging())
    {  
        static wxRect repaint_rc;

        this->Refresh(true,&repaint_rc);
        this->Update();

        wxClientDC dc(this);
        wxPoint pt = event.GetPosition() + wxSize(16,6);

        this->SetCursor(wxCursor(wxCURSOR_HAND ));
        
        wxString text(wxT("Przenieś nad wskazaną pozycję"));
        wxSize s = dc.GetTextExtent(text);
        dc.DrawText(text,pt);
        
	wxPen pen(*wxGREEN,3); 
        dc.SetPen(pen);
		    
	wxRect lParam;
	bool lResult = ::SendMessage(
		               (HWND)this->GetHandle(),
                               LB_GETITEMRECT,
                               wxListBox::HitTest(event.GetPosition()),
                              (LPARAM)&lParam 
                              );
					   		    
        dc.DrawLine(event.GetX()-10,lParam.y,event.GetX()+40,lParam.y);

        repaint_rc.SetLeftTop(pt-wxSize(50,50));
        repaint_rc.SetSize(s+wxSize(50,50));

        //drag=true;        
        return;
    };

1 użytkowników online, w tym zalogowanych: 0, gości: 1