Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

Vous n'avez pas encore de compte Developpez.com ? L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Developpez.com

C++

Choisissez la catégorie, puis la rubrique :

logo
Sommaire > GDI > Press-Papiers
        Comment copier un bitmap dans le presse-papiers ?
        Comment récupérer une image dans le presse-papiers ?
        Comment copier du texte dans le presse-papiers ?



Comment copier un bitmap dans le presse-papiers ?
auteur : Farscape

bool CopyBitmapToClipBoard(CBitmap *pBitmap) 
{ 
    if(!AfxGetMainWnd()->OpenClipboard()) return false; 
     if(!EmptyClipboard()) return false; 

     bool bret=(SetClipboardData(CF_BITMAP, pBitmap->m_hObject)!=NULL); 
     bret=(CloseClipboard()==TRUE); 
    return bret; 
} 
CBitmap *pBmp=CopyWindowToBitmap(this,true); 
CopyBitmapToClipBoard(pBmp);
Les autres fonctions sont issues de la faq: Comment imprimer une boite de dialogue ?


Comment récupérer une image dans le presse-papiers ?
auteur : Farscape
L'exemple ci-dessus suppose que le presse-papiers contient une image.

Le scénario est le suivant :
Récupération de l'image au format DIB en effectuant une copie.
Création d'un bitmap au format DDB.
Impression du bitmap avec la fonction PrintBmp voir faq :Comment imprimer une boîte de dialogue ?
Effacement du presse-papiers et insertion de la copie de l'image DIB à nouveau dans le presse-papiers.

// Zafir Anjum : http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1757/
HBITMAP DIBToDDB( HANDLE hDIB )
{
    LPBITMAPINFOHEADERlpbi;
    HBITMAP hbm;
    CPalettepal;
    CPalette*pOldPal;
    CClientDCdc(NULL);
    
    if (hDIB == NULL)
        return NULL;
    
    lpbi = (LPBITMAPINFOHEADER)hDIB;
    
    int nColors = lpbi->biClrUsed ? lpbi->biClrUsed : 
    1 << lpbi->biBitCount;
    
    BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
    LPVOID lpDIBBits;
    if( bmInfo.bmiHeader.biBitCount > 8 )
        lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + 
        bmInfo.bmiHeader.biClrUsed) + 
        ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
    else
        lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
    
    // Create and select a logical palette if needed
    if( nColors <= 256 && dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
    {
        UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
        LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
        
        pLP->palVersion = 0x300;
        pLP->palNumEntries = nColors;
        
        for( int i=0; i < nColors; i++)
        {
            pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
            pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
            pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
            pLP->palPalEntry[i].peFlags = 0;
        }
        
        pal.CreatePalette( pLP );
        
        delete[] pLP;
        
        // Select and realize the palette
        pOldPal = dc.SelectPalette( &pal, FALSE );
        dc.RealizePalette();
    }
    
    
    hbm = CreateDIBitmap(dc.GetSafeHdc(),// handle to device context
        (LPBITMAPINFOHEADER)lpbi,// pointer to bitmap info header 
        (LONG)CBM_INIT,// initialization flag
        lpDIBBits,// pointer to initialization data 
        (LPBITMAPINFO)lpbi,// pointer to bitmap info
        DIB_RGB_COLORS );// color-data usage 
    
    if (pal.GetSafeHandle())
        dc.SelectPalette(pOldPal,FALSE);
    
    return hbm;

}

HGLOBAL WINAPI CopyHandle (HGLOBAL h)
{
   if (h == NULL) return NULL;
   DWORD dwLen = ::GlobalSize((HGLOBAL) h);
   HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
   if (hCopy != NULL)
   {
        void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
        void* lp     = ::GlobalLock((HGLOBAL) h);
        memcpy(lpCopy, lp, dwLen);
        ::GlobalUnlock(hCopy);
        ::GlobalUnlock(h);
   }
   return hCopy;
}
// le test est fait dans une CFormView
void CTestSDIView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();
    GetParentFrame()->RecalcLayout();
    ResizeParentToFit();
    
    HANDLE hNewDIB = NULL;
    
    // une image est disponible ?
    if(!::IsClipboardFormatAvailable(CF_DIB)) return;
    
    // ouverture du presse papier
    if (!OpenClipboard()) return;
    
    // copie l'image du presse papier.
    hNewDIB = CopyHandle(::GetClipboardData(CF_DIB));
    
    // fermeture presse papier
    CloseClipboard();        
    
    // lock l'espace memoire alloué au dib.
    HGLOBAL h=::GlobalLock((HGLOBAL)hNewDIB);
    
    CBitmap Bitmap;
    // fabrique un bitmap DDB
    Bitmap.Attach(DIBToDDB(h));
    
    // edition du bitmap.
    PrintBmp(&Bitmap);
    
    // unlock 
    ::GlobalUnlock((HGLOBAL)hNewDIB);
    
    // remet l'image dans le presse papier
    OpenClipboard() ;
    EmptyClipboard() ; // vide au préalable
    SetClipboardData(CF_DIB,hNewDIB);
    CloseClipboard () ;  
    
    // liberation du handle hNewDIB
    ::GlobalFree(hNewDIB);        
}

Comment copier du texte dans le presse-papiers ?
auteur : nico-pyright(c)
En utilisant les fonctions de l'API pour le presse-papiers .
Le principe est le suivant :

  1. allouer de la mémoire pour ce qu'on doit copier ;
  2. bloquer la zone mémoire pour permettre de la remplir avec la valeur à copier dans le presse-papiers ;
  3. libérer la zone mémoire ;
  4. ouvrir le presse-papiers ;
  5. ( vider le presse-papiers ) ;
  6. copier les données dans le presse-papiers ;
  7. fermer le presse-papiers.
L'exemple qui suit permet de copier dans le presse-papiers le nom de l'éxecutable en cours :

DWORD len;
HGLOBAL hgbl;
char temp[MAX_PATH];
char *pmem;

len = GetModuleFileName(NULL,temp,MAX_PATH);
if (!len) return 0;
hgbl = GlobalAlloc(GHND, len + 1);
if(!hgbl) return 0;
pmem = (char*)GlobalLock(hgbl);
strcpy(pmem,temp);
GlobalUnlock(hgbl);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, hgbl);
CloseClipboard();
Remarques :
- il faut connaitre la longueur à copier pour pouvoir allouer la mémoire avec GlobalAlloc (ici, GetModuleFileName renvoie la longueur de la chaîne)
- On utilise OpenClipboard avec un handle égal à NULL pour ouvrir le presse-papiers associé à la tâche courante. Si on veut récupérer le presse-papiers d'une autre fenêtre, il suffit de lui passer son handle en paramètre.



Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web