begin process at 2012 02 11 16:07:58
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Au secours

 > 

pb de ClipBoard


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

pb de ClipBoard

vendredi 19 mars 2004 à 18:31:54 | pb de ClipBoard

totodude


Bonjour tout le monde,

je voudrais réaliser une application qui réalise une impression écran et découpe un tableau sur l'image ainsi enregistrée. j'ai déjà jeté un oeil sur les questions du forum en rapport mais je n'y ai pas trouvé mon bonheur.

voici donc ou j'en suis :
1) je réalise mon impression écran

keybd_event(VK_SNAPSHOT,1,0,0);

2) j'ouvre mon clipboard

::OpenClipboard(NULL);

3) je récupère ce qu'il y a dedans
HBITMAP* hClip = (HBITMAP*)GetClipboardData(CF_BITMAP);

4) je découpe l'image
CImage cImage;
cImage.Attach(*hClip);
HDC hImage=NULL;
cImage.Draw(hImage, 100, 100, 100, 100);

5) je remet dans le clipboard
EmptyClipboard();
SetClipboardData(CF_BITMAP, hImage);


6) je referme
CloseClipboard();

mon prog ne marche pas, j'ai beau cherché pourquoi j'y arrive pas.
quelqu'un aurait une solution ou une suggestion pour m'aider ??? merci infiniment

Cheers ;)
tom
vendredi 19 mars 2004 à 21:32:09 | Re : pb de ClipBoard

ymca2003

je croit que c'est au niveau de la récupération du bitmap depuis le clipboard que ça coince. Voila comment récupérer le HBITMAP contenu dedans :


// ouverture du presse-papier
if(!OpenClipboard())
return;

// récupération du contenu du presse-papier (doît être une image)
HGLOBAL hData = GetClipboardData(CF_DIB);

// si la récupération a échoué, on referme le presse-papier
if(!hData)
{
CloseClipboard();
return;
}

int size = GlobalSize(hData);

LPBYTE lpData = (LPBYTE) GlobalLock(hData);

LPBITMAPINFO lpInfo= (LPBITMAPINFO) lpData;
LPBITMAPINFOHEADER lpHeader= &lpInfo->bmiHeader;
LPBYTE lpBits = lpData + sizeof(BITMAPINFOHEADER);


HDC hdc = ::GetDC(NULL);
HBITMAP hBmp = ::CreateDIBitmap(hDC, lpHeader, CBM_INIT, lpBits, lpInfo,DIB_RGB_COLORS);
::ReleaseDC(NULL, hdc);

CloseClipboard();


lundi 22 mars 2004 à 11:26:21 | Re : pb de ClipBoard

totodude

Merci infiniment ymca.
j'arrive maintenant à récupérer l'objet de mon presse papier.

maintenant je voudrais découper l'image ainsi récupérée et la remttre dans le presse papier.

saurais tu quelle méthode utilisée pour ca ?
la méthode Draw de CImage réalise en fait une copie, pas une découpe.
j'arrive pas à trouver une méthode qui marche directement.

je vais donc me lancer dans le recopiage de la partie que je veux pixel par pixel, mais ca m'as l'air un peu bourrin.

la méthode clone de la classe Bitmap à l'air pas mal, mais j'arrive pas a créer un objet bitmap alors que j'inclue bien les librairies qu'il faut (gdiplus.h). J'ai une erreur de compilation comme quoi il connait pas la classe "Bitmap".

si quelqu'un connait une methode plus rapide, merci de me faire signe ;)

Cheers
lundi 22 mars 2004 à 14:37:38 | Re : pb de ClipBoard

totodude

alors voila ou j'en suis :

grace a ymca j'arrive à récupérer l'objet dans mon presse papier.

je pensais avoir fini le prog ensuite, mais j'ai une erreur dans les données sauvegardées dans le presse papier qui n'ont pas l'air d'être au meme format.

j'ai fait :
//définition de mon rectangle à découper
CRect myRect = new CRect(0,0,400,400);
//récupération de l'image
CImage cImage;
cImage.Attach(hBmp);

//découpage de l'image
CImage* myImage = cutImage(cImage,myRect);
HBITMAP myhBmp = myImage->Detach();

EmptyClipboard();
SetClipboardData(CF_BITMAP, myhBmp);
CloseClipboard();

ma fonction de découpe est la suivante :

CImage* cutImage(CImage cImage,CRect myRect)
{
CImage* newImage = new CImage();
newImage->Create(400,400,16,0);
CPoint ptDown,ptUp;
ptDown = myRect.BottomRight();
ptUp = myRect.TopLeft();

for(int x=0;x<((int)newImage->GetWidth());x++)
{
for(int y=0;y<((int)newImage->GetHeight());y++)
{
newImage->SetPixel(x,y,cImage.GetPixel(x,y));
}
}

return newImage;
}


pkoi ca ne marche donc pas ???

merci de votre aide
tom
mardi 23 mars 2004 à 14:41:00 | Re : pb de ClipBoard

ymca2003

de la même façon que tu récupère les données les données du bitmap dans le clipboard, il ne s'agit pas d'un HBITMAP, mais une structure BITMAPINFO suivie des bits(pixels) du bitmap qu'il faut mettre dedans. En fait il s'agit n'y plus ni moins que ce que tu mettrait dans un fichier pour obtenir un *.bmp (hormis l'entête de fichier BITMAPFILEHEADER).

je vais essayer de mettre un bout de code qui fait ça.
mardi 23 mars 2004 à 18:33:41 | Re : pb de ClipBoard

totodude

je pensais qu'il fallait passer un handle en parametre de SetClipboardData.

si je fais
<code>
CImage cImage;
cImage.Attach(hBmp);
HBITMAP myhBmp = cImage.Detach(); //je sais c'est très con

EmptyClipboard();
SetClipboardData(CF_BITMAP, myhBmp);
CloseClipboard();

</code>

ca a l'air de marcher. mais je ne fais alors que remettre la meme image dans le presse papier. c'est pour ca que j'avais l'impression qu'il suffisait de récupérer le HBITMAP de l'image que je voulais mettre avec la méthode CImage::Detach()
mais ca ne marche pas pour une image que j'aurais modifié.

sans vouloir abuser de ta gentillesse et de ton temps, un petit bout de code m'aiderais bien, car j'arrive pas à créer la structure BITMAPINFO à passer en parametre correctement.

merci beaucoup mec.

Cheers ;)
mardi 23 mars 2004 à 23:13:00 | Re : pb de ClipBoard

ymca2003


Tout d'abord, excuse pour les complications que j'ai apportées à ton problème. On peut en effet manipuler directement les HBITMAP avec le presse-papier. Le truc c'est sur la durée de vie de ceux-ci. On effet, quand tu veux récupérer le HBITMAP à partir du presse-papier, celui-ci n'est plus valable une fois que tu as appelé CloseClipboard (le propriétaire, celui qui l'a mis dedans, a peut-être libérer les ressources associées). De la même façon , il ne faut pas détruire le HBITMAP que tu met dans le presse-papier (les objets MFC englobant le GDI détruisent systématiquement les HANDLE associé dans leur destructeur). En passane par les API, c'est plus sur (de toutes façon les MFC sont fait à partir de l'API).

voici 2 fonctions :


BOOL GetClipboardBitmap(HBITMAP* phBmp, SIZE* pSize)
{
// ouverture du presse-papier
if(!OpenClipboard(NULL))
return FALSE;

// vérification du format
if(!IsClipboardFormatAvailable(CF_BITMAP))
{
CloseClipboard();
return FALSE;
}

// récupération bitmap contenu dans le presse-papier
HBITMAP hClipboardBmp = (HBITMAP) GetClipboardData(CF_BITMAP);
if(hClipboardBmp == NULL)
{
CloseClipboard();
return FALSE;
}

// récupération infos sur le bitmap (dont la taille)
BITMAP info;
SIZE size;
GetObject(hClipboardBmp, sizeof(BITMAP), &info);
size.cx = info.bmWidth;
size.cy = info.bmHeight;

// DC de l'écran
HDC hScreenDC = GetDC(NULL);

// création DC et sélection de ce bitmap dedans
HDC hClipboardDC = CreateCompatibleDC(hScreenDC);
HBITMAP hOldClipboardBmp = (HBITMAP) SelectObject(hClipboardDC, hClipboardBmp);

// création DC et bitmap en mémoire
HDC hMemDC = CreateCompatibleDC(hScreenDC);
HBITMAP hMemBmp = CreateCompatibleBitmap(hScreenDC, size.cx, size.cy);
HBITMAP hOldMemBmp = (HBITMAP) SelectObject(hMemDC, hMemBmp);

// recopie inversée
for(int x = 0; x < size.cx; x++)
{
for(int y = 0; y < size.cy; y++)
{
COLORREF color = GetPixel(hClipboardDC, x, y);
SetPixel(hMemDC, size.cx-x-1, y, color);
}
}

// sélection anciens objets et destruction DC
SelectObject(hClipboardDC, hOldClipboardBmp);
SelectObject(hMemDC, hOldMemBmp);
DeleteDC(hClipboardDC);
DeleteDC(hMemDC);
ReleaseDC(NULL, hdc);

// fermeture presse-papier
CloseClipboard();
*phBmp = hMemBmp;
pSize->cx = size.cx;
pSize->cy = size.cy;
return TRUE;
}




void SetClipboardBitmap(HBITMAP hBmp)
{
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBmp);
CloseClipboard();
}


utilisation :


int main(int argc, char* argv[])
{
HBITMAP hBmp;
SIZE size;
GetClipboardBitmap(&hBmp, &size);
SetClipboardBitmap(hBmp);
return 0;
}


le HBITMAP récupérer par la première fonction (qui est une copie inversée de ce qui se trouvait dans le presse-papier) est remis dans le presse-papier. Il n'est pas à détruire par DeleteObject (le système le fera pour nous).
mercredi 24 mars 2004 à 18:54:36 | Re : pb de ClipBoard

totodude


Merci infiniment mec pour cette réponse plus que complete.
maintenant je vais devrais pouvoir m'en sortir.

j'ai toutefois une question supplémentaire pour finir :
j'utilise la fonction
OpenClipboard()
pour ouvrir mon clipboard, et pas OpenClipboard(NULL)
comme dans ton exemple.

je bosse sous windows avec visual studio (mon appli est un activex), et quand j'utilise ::OpenClipboard(NULL) j'ai pas d'erreur d'exécution, mais en fait le prog ne travaille pas sur le bon clip board (je récupère en faisant ctrl+v la meme image non modifiée)

quand j'utilise OpenClipboard(), j'ai une erreur à l'exécution
"Debug Assertion Failed" que j'ignore, et ensuite ca marche bien. mais je voudrais me débarrasser de cette erreur pour avoir un prog vraiment propre.

saurai tu comment corriger ca ?

merci encore pour ton aide précieuse.
bonne soirée
tom
mercredi 24 mars 2004 à 22:03:10 | Re : pb de ClipBoard

ymca2003

la fonction de l'API (avec :: devant) prend comme argument le HWND de la fenêtre qui sera propriétaire du presse-papier (la mainframe en générale). Si j'ai mis NULL dans mon exemple c'est que j'ai simplement testé en mode console sans créer de fenêtre et passer NULL revient à associer le presse-papier à la tâche en cours.

en MFC, il suffit d'appeler OpenCliboard() sans paramètre dans la fenêtre qui gère le presse-papier. Cette fonction appelera ensuite la fonction de l'API en lui passant le membre m_hWnd de l'objet CWnd (ou dérivé).

si tu as un Debug Assertion Failed, pose un point d'arrêt là ou tu appelle OpenClipboard et tarce les appels aux fonctions (vérifie en particulier le mebre m_hWnd de l'objet 'this', il ne doit pas être NULL).
mardi 30 mars 2004 à 18:23:45 | Re : pb de ClipBoard

totodude

et me revoilou !

désolé, j'étais passé à autre chose, et me revoici sur ce prog.

j'ai testé this->m_hWnd et il apparait qu'il est NULL.

j'ai essayé de bidouillé avec la fonction GetClipboardOwner()
en faisant ::OpenClipboard(GetClipboardOwner()->m_hWnd)

mais ca a pas l'air de marcher. Comment je m'en sors maintenant ? qu'est ce que je peux changer ?

ton aide est la bienvenue ;)
merci encore

Cheers ;)
tom

1 2

Cette discussion est classée dans : pb, clipboard, cimage, réalise, himage


Répondre à ce message

Sujets en rapport avec ce message

Les variables globales...... [ par netman ] Bon la j'ai un petit probleme (normal sinon je poserais pas de question ....)Bon je fait un petit programme et la je suis confronte a un pb .....J'uti pb de base de donnee en C [ par tequ13 ] j'aimerais savoir comment faire pour charger des fichiers (*.txt) a l'ouverture d'un programme pour ensuite les comparer et repérer les doublons pour pb avec procedure [ par bidules ] bonjour,voila mon code(simplifier) :void affiche(int numero){cout }void main(){affiche(10);}et un message d'erreur apparait lors de la compilation Pb code source CMphSock [ par xaviou ] Salut.J'ai téléchargé le projet "CMphSock" : Utilisation de Winsock sans MFC.Je l'ai compilé en mode Debug : tout est OKJ'ai essayé en mode Release : petit pb de type string [ par bidules ] D'apres ce que g pu apprendre lorsque l'on veut declarer une variable de type string il faut faire :#include string variable;c bien ca? car qd je fais pb de grille avec visual C++ [ par cedcrow ] Salut,je cherche à rendre éditable les cellules créés dans mon objet de type flexgrid (comme un tableur excel quoi !). Je ne trouve pas la méthode app Pb avec Glut sous Visual C++ [ par Yoann ] Bonjour !Je viens de me mettre à OpenGL avec Glut, mais j'ai un petit problème. En effet, quand je compile un exemple, j'ai l'erreur suivante :TestGlu Pb avec Glut sous VC++ et Dev [ par mederic ] Je ne sais pas si ça vient de mon include ou autre chose. Mais je n'arrive pas executer un exemple simple sur plusieurs compilateurs.Sur VC++, il écri un ti pb sur les tableaux [ par Julius Caesar ] On range dans un tableau 8 entiers générés aléatoirement par l'ordi. coment faire pour être sur que chaque nombre généré soit uniquen c'est à dire qu' pb avec gluLookAt() ! [ par naugondo ] Comment ça marche !!En fait, a quoi correpondent les 3 dernières coordonnées ?


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,292 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales