Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre à l'essai Avatar de wxMiDub
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mars 2018
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mars 2018
    Messages : 9
    Points : 14
    Points
    14

    Par défaut [wxWidgets-3.1.1] [Code::Blocks 17.12] Utilisation de la fonction DC->Blit()

    Bonjour,

    J'ai suivi les vidéos


    Cet exercice permet de mettre en oeuvre les wxWidgets suivants : -wxFrame -wxMenuBar -wxDialog -wxButton -wxFileDialog -wxClientDC -wxMemoryDC -wxPanel -wxMenu -wxToolBar -wxBitmap -wxTheClipboard.

    J'ai refait tout le code en partant de zéro, mais j'ai un petit problème avec la fonction DC->Blit() et ses paramètres

    Voici le résultat que j'obtiens :
    Nom : CopyMon.PNG
Affichages : 96
Taille : 76,9 Ko

    La copie ne donne que le cadre du wxPanel qui est tout noir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void MonPanelFrame::OnCopyClick(wxCommandEvent& event)
    {
        wxBitmap mon_bitmap_tmp(Panel1->GetSize(),wxBITMAP_SCREEN_DEPTH);
        mon_wxmemorydc->SelectObject(mon_bitmap_tmp);
        mon_wxmemorydc->Blit(wxPoint(0,0),Panel1->GetSize(),mon_wxclientdc,wxPoint(-1,-1),wxCOPY, true, wxDefaultPosition);
     
        if (wxTheClipboard->Open())
        {
            wxTheClipboard->SetData(new wxBitmapDataObject(mon_bitmap_tmp));
            wxTheClipboard->Close();
        }
    }
    Dans les liens de la vidéo en question, on trouve le source du projet et un exécutable.

    J'ai téléchargé le source puis je l'ai adapté à ma version, et cela donne le même résultat
    Nom : CopySource.PNG
Affichages : 102
Taille : 56,3 Ko
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void My_ImageFrame::OnCopyClick(wxCommandEvent& event)
    {
        wxBitmap my_bitmap_tmp(Panel1->GetSize(),wxBITMAP_SCREEN_DEPTH);
        my_wxmemorydc->SelectObject(my_bitmap_tmp);
        my_wxmemorydc->Blit(wxPoint(0,0), Panel1->GetSize(), my_wxclientdc, wxPoint(-1,-1), wxCOPY, true, wxDefaultPosition);
     
        if (wxTheClipboard->Open())
            {
                 wxTheClipboard->SetData(new wxBitmapDataObject(my_bitmap_tmp));
                 wxTheClipboard->Close();
            }
    }
    Puis j'ai téléchargé l'exécutable qui lui fonctionne comme dans la vidéo
    Nom : CopyExe.PNG
Affichages : 96
Taille : 59,1 Ko

    Je cherche donc des précisions sur les 3 derniers paramètres de la fonction Blit()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    bool wxDC::Blit 	( 	wxCoord  	xdest,
    		wxCoord  	ydest,
    		wxCoord  	width,
    		wxCoord  	height,
    		wxDC *  	source,
    		wxCoord  	xsrc,
    		wxCoord  	ysrc,
    		wxRasterOperationMode  	logicalFunc = wxCOPY,
    		bool  	useMask = false,
    		wxCoord  	xsrcMask = wxDefaultCoord,
    		wxCoord  	ysrcMask = wxDefaultCoord 
    	)
    Certains pourrons me répondre que je devrais poser ma question dans les commentaires de la vidéo, mais j'ai qq difficultés à poser une question compréhensible en grand-breton

    Ensuite, j'aurai une autre question, pour une second problème qui ne marche pas dans aucuns des 3 cas ci-dessus (donc aussi avec l'exécutable fourni), mais ce n'est peut être pas le sujet de l'exercice.
    Le wxPanel, n'est pas sauvegardé, donc si une autre fenêtre vient le recouvrir, quand la fenêtre revient en premier plan, le wxPanel est blanc

  2. #2
    Membre averti Avatar de wxXav
    Homme Profil pro
    Développeur amateur
    Inscrit en
    décembre 2008
    Messages
    196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur amateur

    Informations forums :
    Inscription : décembre 2008
    Messages : 196
    Points : 322
    Points
    322

    Par défaut

    Salut.

    J'ai téléchargé les sources concernées, et j'ai failli avoir une syncope

    C'est une horreur ce code.
    Et je n'ose même pas penser à ce que ça donnerait si on le passait au détecteur de fuites mémoires.

    Bref : ce code fonctionne jusqu'à la version 3.0.x de wxWidgets.
    Mais pas avec la version 3.1.1 (comme il semblerait que c'est ce que tu utilises).

    En fait, quand tu utilises une classe dérivée de wxDC, il ne faut pas la stocker et l'utiliser tout au long de la durée de vie de l'application.

    Tu crées la variable quand tu en as besoin, et tu la détruis (ou tu fais en sorte qu'elle se détruise toute seule) quand tu n'en a plus besoin.
    D'ailleurs, c'est bien indiqué dans l'aide officielle, par exemple sur la page relative à wxClientDC

    Citation Envoyé par wxWidgets help
    Detailed Description
    A wxClientDC must be constructed if an application wishes to paint on the client area of a window from outside an EVT_PAINT() handler.

    This should normally be constructed as a temporary stack object; don't store a wxClientDC object.

    To draw on a window from within an EVT_PAINT() handler, construct a wxPaintDC object instead.

    To draw on the whole window including decorations, construct a wxWindowDC object (Windows only).

    A wxClientDC object is initialized to use the same font and colours as the window it is associated with.
    Donc la première code à faire dans le code téléchargé est de virer les lignes 114 et 116 du fichier "My_ImageMain.h" (celles relatives aux 2 wxDC).
    Ensuite tu vires les lignes 115 et 116 du fichier cpp correspondant (celles qui créent les 2 DC).
    Et après, chaque fois que ces variables étaient utilisées, tu adaptes le code en créant le(s) dc dont tu as besoin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void My_ImageFrame::OnClearClick(wxCommandEvent& event)
    {
        wxClientDC dc(Panel1); // Pas de fuite mémoire car la variable est automatiquement supprimée
        dc.Clear();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void My_ImageFrame::OnLoadClick(wxCommandEvent& event)
    {
        int dlg=FileDialog1->ShowModal();
            if(dlg==wxID_OK)
            {
                my_bitmap.LoadFile(FileDialog1->GetPath(),wxBITMAP_TYPE_ANY);
                wxClientDC dc(Panel1);
                dc.DrawBitmap(my_bitmap,0,0,false);
            }
    }
    void My_ImageFrame::OnDrawTextClick(wxCommandEvent& event)
    {
        wxClientDC dc(Panel1);
        dc.DrawText(wxT("wxWidgets logo"),100,200);
    }
     
    void My_ImageFrame::OnDrawCircleClick(wxCommandEvent& event)
    {
        wxClientDC dc(Panel1);
        dc.DrawCircle(20,20,10);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void My_ImageFrame::OnCopyClick(wxCommandEvent& event)
    {
        wxBitmap my_bitmap_tmp(Panel1->GetSize(),wxBITMAP_SCREEN_DEPTH);
        wxMemoryDC mdc(my_bitmap_tmp);
     
        wxClientDC dc(Panel1);
        mdc.Blit(wxPoint(0,0),Panel1->GetSize(),&dc,wxPoint(-1,-1),wxCOPY,true,wxDefaultPosition);
        // il faut toujours désélectionner le bitmap avant de pouvoir l'utiliser
        mdc.SelectObject(wxNullBitmap);
     
            if (wxTheClipboard->Open())
                {
                    wxTheClipboard->SetData(new wxBitmapDataObject(my_bitmap_tmp));
                    wxTheClipboard->Close();
                }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    void My_ImageFrame::OnSaveAsClick(wxCommandEvent& event)
    {
        wxBitmap my_bitmap_tmp(Panel1->GetSize(),wxBITMAP_SCREEN_DEPTH);
        wxMemoryDC mdc(my_bitmap_tmp);
        wxClientDC dc(Panel1);
        mdc.Blit(wxPoint(0,0),Panel1->GetSize(),&dc,wxPoint(-1,-1),wxCOPY,true,wxDefaultPosition);
        // Même remarque que précédemment
        mdc.SelectObject(wxNullBitmap);
     
            int dlg=FileDialog2->ShowModal();
            if(dlg==wxID_OK)
            {
                wxFileName my_file(FileDialog2->GetPath());
                wxString my_file_ext=my_file.GetExt().Lower();
     
                if(my_file_ext==wxT("xpm"))my_bitmap_tmp.SaveFile(FileDialog2->GetPath(),wxBITMAP_TYPE_XPM,NULL);
                else if(my_file_ext==wxT("jpeg"))my_bitmap_tmp.SaveFile(FileDialog2->GetPath(),wxBITMAP_TYPE_JPEG,NULL);
                else if(my_file_ext==wxT("bmp"))my_bitmap_tmp.SaveFile(FileDialog2->GetPath(),wxBITMAP_TYPE_BMP,NULL);
     
                else wxMessageBox(wxT("Extension ERROR"),wxT("ERROR"));
            }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void My_ImageFrame::OnDrawRotatedTextClick(wxCommandEvent& event)
    {
        RotatedText tmp_dlg(this);
            int dlg=tmp_dlg.ShowModal();
            if(dlg==wxID_OK)
            {
                wxClientDC dc(Panel1);
                dc.DrawRotatedText(tmp_dlg.Text->GetValue(),tmp_dlg.X->GetValue(),tmp_dlg.Y->GetValue(),tmp_dlg.Angle->GetValue());
            }
    }
    Avec ces modifs, ça marche sans problème

    Et je n'ai pas regardé tout le code en détail, mais il y a d'autres trucs qui seraient à modifier dans le même style (par exemple les wxFileDialog).

    @+
    Xav'

  3. #3
    Membre à l'essai Avatar de wxMiDub
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mars 2018
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mars 2018
    Messages : 9
    Points : 14
    Points
    14

    Par défaut

    Bonsoir,

    Merci très bcp

    Citation Envoyé par wxXav Voir le message
    J'ai téléchargé les sources concernées, et j'ai failli avoir une syncope

    C'est une horreur ce code.
    Et je n'ose même pas penser à ce que ça donnerait si on le passait au détecteur de fuites mémoires.


    Citation Envoyé par wxXav Voir le message
    Avec ces modifs, ça marche sans problème
    Nom : CopyOk.PNG
Affichages : 90
Taille : 687,1 Ko
    Effectivement tout marche bien avec les modifs que tu m'as indiquées

    Merci encore.
    @+ Michel

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 17/03/2018, 14h35
  2. Installation wxWidgets 3.02 sous Code::Blocks 13.12
    Par jcmic dans le forum Code::Blocks
    Réponses: 2
    Dernier message: 09/11/2014, 13h40
  3. [WxWidgets] installation code:blocks
    Par maminova77 dans le forum Code::Blocks
    Réponses: 16
    Dernier message: 25/01/2011, 09h15
  4. [code::blocks] Créer une dll avec des fonctions en C
    Par dewey01 dans le forum Code::Blocks
    Réponses: 0
    Dernier message: 29/09/2008, 15h24
  5. code::blocks et wxWidget 2.8
    Par johnbob_72 dans le forum Code::Blocks
    Réponses: 10
    Dernier message: 27/02/2007, 15h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo