Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Transfert d'un buffer dans le presse-papier et réciproquement

5 réponses
Avatar
Cirus Minor
Bonjour,

Je débute en programmation sous Windows.
Pour commencer, je veux faire une appli qui fait des transformations sur
du texte du presse-papier.
J'ai un bouton "Coller", qui colle le texte du presse-papier dans ma
fenêtre :

/* Bouton Coller */
case IDC_Coller:

/* S'il n'y a pas de texte dans le presse-papier */
if (!IsClipboardFormatAvailable(CF_TEXT))
/* Retour Maison */
return 0;
/* Si on peut ouvrir le presse-papier */
if (OpenClipboard (Dlg))
{
/* Alors on copie son contenu dans le buffer */
strcpy(buf,(char *) GetClipboardData (CF_TEXT) );
/* on ferme le presse-papier */
CloseClipboard () ;
/* Et on met le contenu du buffer dans la fenêtre texte */
SetDlgItemText(Dlg,IDC_TEXT,buf);
}
/* Fin du traitement */
return 0;

Jusque là, ça va. Mon bouton colle bien dans ma fenêtre le contenu du
presse-papier. Maintenant, pour passer de ma fenêtre au presse-papier,
j'ai un bouton "Copier" :

/* Copie du contenu de la fenêtre dans le presse-papier */
case IDC_Copier :
/* Récupération du contenu de la fenêtre texte */
GetDlgItemText(Dlg, IDC_TEXT, buf, TAILLE_TEXTE);
/* Si on peut ouvrir le presse-papier */
if (OpenClipboard (Dlg))
{
/* On commence par le vider */
EmptyClipboard();
/* Création d'un Handle */
HANDLE hC = GlobalAlloc(GMEM_MOVEABLE, TAILLE_TEXTE);
char* c=(char*) GlobalLock(hC);
/* Copie du buffer dans le handle */
strcpy(c, buf);
/* Copie du Handle dans le presse-papier */
SetClipboardData (CF_TEXT,hC);
/* On ferme le presse-papier */
CloseClipboard () ;
/* Opération réussie */
SetDlgItemText(Dlg,IDC_Message_du_bas,"Le message est copié
dans le presse-papier.");
}
return 0 ;
/* Fin du traitement */

Ca marche aussi : je tapes du blabla dans ma fenêtre, je cliques sur mon
bouton "Copier", je fais un Ctrl+V dans le bloc-note : le blabla y est.

Mais si, après avoir copié mon blabla dans le presse-papier via mon
bouton "Copier", je veux recoller ce blabla dans ma fenêtre via mon
bouton "Coller", ça ne marche plus ! J'ai à la place du blabla trois
caractères genre : h8|
Si je recopie du texte dans le presse-papier via une autre appli, celui-
ci est bien collé via mon bouton "Coller". J'ai du louper un truc dans ma
copie, mais quoi ???

Merci de votre aide


--
Cirus

5 réponses

Avatar
Christian ASTOR
Cirus Minor a écrit:

if (OpenClipboard (Dlg))
{
/* Alors on copie son contenu dans le buffer */
strcpy(buf,(char *) GetClipboardData (CF_TEXT) );



Manque GlobalLock(), puis GlobalUnlock() (et GlobalFree()) ds les 2 cas
Avatar
Cirus Minor
Christian ASTOR a pris son petit clavier pour
y tapoter ceci :

Cirus Minor a écrit:

if (OpenClipboard (Dlg))
{
/* Alors on copie son contenu dans le buffer */
strcpy(buf,(char *) GetClipboardData (CF_TEXT) );



Manque GlobalLock(), puis GlobalUnlock() (et GlobalFree()) ds les 2 cas





Ra, merci pour la piste.

Mais j'ai beau chercher comment on s'en sert et faire des essais, ça ne
marche pas mieux. Pour le coller, j'ai maintenant ça :

/* On récupère */
hC = GlobalAlloc(GMEM_MOVEABLE, TAILLE_TEXTE);
hC = GetClipboardData (CF_TEXT) ;
tmp = GlobalLock(hC);
/* On copie son contenu dans le buffer */
strcpy(buf, (char *) tmp );
/* On ferme le presse-papier */
CloseClipboard () ;
GlobalUnlock (hC) ;
GlobalFree (hC) ;

Pour le copier, ça a un poil changé (clarification) :

EmptyClipboard();
hC = GlobalAlloc(GMEM_MOVEABLE, TAILLE_TEXTE);
char* c=(char*) GlobalLock(hC);
/* Copie du buffer dans le handle */
strcpy(c, buf);
/* Copie du Handle dans le presse-papier */
SetClipboardData (CF_TEXT,hC);
/* Fermeture du Presse-papier */
CloseClipboard () ;
GlobalUnlock(hC);
GlobalFree (hC) ;

J'ai du me gourrer quelque part, mais où ? Comment ça marche ces
Globalxxxx, à quoi ça sert ?

Pouvez-vous m'aider à les remettre en ordre ?



--
Cirus
Avatar
Cirus Minor
Cirus Minor a pris son petit clavier pour y
tapoter ceci :

J'ai du me gourrer quelque part, mais où ? Comment ça marche ces
Globalxxxx, à quoi ça sert ?




J'ai trouvé mon erreur Ce sont les GlobalFree qui foutaient la m...e.
Mais par contre, je ne libère nulle part la mémoire que j'alloue (arg).
Comment le faire sans nuire au presse-papier et à mon appli ?

Voici le code qui marche bien :
Pour le "Coller" :

/* S'il n'y a pas de texte dans le presse-papier */
if (!IsClipboardFormatAvailable(CF_TEXT))
/* Retour Maison */
return 0;
/* Si on peut ouvrir le presse-papier */
if (OpenClipboard (Dlg))
{
/* On récupère l'adresse */
hC = GetClipboardData (CF_TEXT) ;
/* On verouille son accès */
tmp = GlobalLock(hC);
/* On copie son contenu dans le buffer */
strcpy(buf, (char *) tmp );
/* On déverouille le presse-papier */
GlobalUnlock (hC) ;
/* On ferme le presse-papier */
CloseClipboard () ;
/* Et on met le contenu du buffer dans la fenêtre texte */
SetDlgItemText(Dlg,IDC_TEXT,buf);
}

Pour le "Copier"

/* Récupération du contenu de la fenêtre texte */
GetDlgItemText(Dlg, IDC_TEXT, buf, TAILLE_TEXTE);
/* Si on peut ouvrir le presse-papier */
if (OpenClipboard (Dlg))
{
/* On commence par le vider */
EmptyClipboard();
/* Allocation d'une zone mémoire protégée */
hC = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, TAILLE_TEXTE+1);
/* Qu'on verouille */
c=(char*) GlobalLock(hC);
/* Copie du buffer dans le handle */
strcpy(c, buf);
/* Copie du Handle dans le presse-papier */
SetClipboardData (CF_TEXT,hC);
/* Fermeture du Presse-papier */
CloseClipboard () ;
/* Déverouillage de la zone mémoire pour les autres applis */
GlobalUnlock(hC);

/* OK, c'est Bon, ça marche ! */
SetDlgItemText(Dlg,IDC_Message_du_bas,"Le message est copié dans le
presse-papier.");
}


--
Cirus Minor
Avatar
Christian ASTOR
Cirus Minor a écrit:


J'ai trouvé mon erreur Ce sont les GlobalFree qui foutaient la m...e.
Mais par contre, je ne libère nulle part la mémoire que j'alloue (arg).
Comment le faire sans nuire au presse-papier et à mon appli ?



Pour le "Coller", on fait GlobalAlloc() au début et le GlobalFree() une
fois qu'on a fait le SetDlgItemText()
Il y a des ex ds MSDN, notamment ds la PSDK (ClipText.c), qui fait à peu
près comme ça (bien qu'il mette le hText en global) =>

case IDC_Coller:
{
HANDLE hText = NULL;
HANDLE hClipData = NULL;
LPTSTR lpszText = NULL;
LPTSTR lpClipData = NULL;
if (!IsClipboardFormatAvailable(CF_TEXT))
return 0;
if (OpenClipboard(hWnd))
{
if (!(hClipData = GetClipboardData(CF_TEXT)))
{
CloseClipboard();
break;
}
if (!(hText = GlobalAlloc(GMEM_MOVEABLE, GlobalSize(hClipData))))
{
CloseClipboard();
break;
}
if (!(lpClipData = (LPTSTR)GlobalLock(hClipData)))
{
CloseClipboard();
break;
}
if (!(lpszText = (LPTSTR)GlobalLock(hText)))
{
CloseClipboard();
break;
}
lstrcpyn(lpszText, lpClipData, (int)GlobalSize(hClipData));
GlobalUnlock(hClipData);
CloseClipboard();
GlobalUnlock(hText);
SetDlgItemText(hWnd, IDC_TEXT, lpszText);
GlobalFree(hText);
}
}
break;
Avatar
Cirus Minor
Christian ASTOR a pris son petit clavier
pour y tapoter ceci :

Pour le "Coller", on fait GlobalAlloc() au début et le GlobalFree()
une fois qu'on a fait le SetDlgItemText()



Je vais reprendre mon code dans les jours qui viennent pour rendre tout ça
propre.

Il y a des ex ds MSDN, notamment ds la PSDK (ClipText.c), qui fait à
peu près comme ça (bien qu'il mette le hText en global) =>



Le problème d'msdn, c'est que ce n'est pas toujours très compréhensible,
surtout pour les grands débutants en programmation Ouinedoze comme moi...

case IDC_Coller:
{....



Article -> Print -> Confirm -> Yes

Voilà, comme ça je suis sûr de l'avoir sous la main au bon moment. Merci de
votre aide.



--
Cirus