Windows clipboard et DROPFILE structure

Windows clipboard et DROPFILE structure - C++ - Programmation

Marsh Posté le 30-07-2010 à 22:44:43    

Bonjour a tous !  
 
Tout d'abord excusez moi pour les accents absent mais j'ai un clavier qwerty :(
 
J'ecris ici car je suis en train de me prendre la tete depuis un moment sur la structure DROPFILE et le presse papier windows.
Voila deja le morceau de code dont je parle :

Code :
  1. /***structure DROPFILES***/
  2. typedef struct _DROPFILES {
  3.     DWORD pFiles;                   // Offset of file list
  4.     POINT pt;                       // Drop coordinates
  5.     BOOL fNC;                       // Client or nonclient area
  6.     BOOL fWide;                     // ANSI or Unicode text
  7. } DROPFILES, FAR * LPDROPFILES;
  8. /***ma fonction : ***/
  9.     OpenClipboard(0);
  10.     EmptyClipboard();
  11. LPCTSTR path1 = (LPCTSTR)"C:\\example.emf";
  12. LPCTSTR path2 = (LPCTSTR)"C:\\Copy.emf";
  13. UINT           uBuffSize = 0;
  14. uBuffSize = lstrlen ((LPCTSTR) path1 )+ lstrlen ( (LPCTSTR)path2 ) + 2; //+2 pour les deux \0, un pour chaque chaine
  15. uBuffSize = sizeof(DROPFILES) + sizeof(TCHAR) * (uBuffSize + 1); //=1 pour un dernier \0 a la toute fin
  16.         HGLOBAL hData = ::GlobalAlloc (GHND | GMEM_SHARE, uBuffSize);
  17.         DROPFILES* pDropFiles = (DROPFILES*) ::GlobalLock (hData);
  18.         pDropFiles->pFiles = sizeof (DROPFILES);
  19.         pDropFiles->fWide = FALSE; //la variable UNICODE est definie et pourtant lorsque je met TRUE, Word lis des caractere chinois :/
  20.         TCHAR *pData = (TCHAR*)((LPBYTE) pDropFiles + sizeof (DROPFILES));
  21.         lstrcpy ( pData, (LPCTSTR) path1 ); //premiere chaine apres la structure DROPFILES (offset indique dans pFiles)
  22.         pData = 1+wcschr ( pData, (wchar_t )'\0' ); //placement apres l'\0
  23.         lstrcpy ( pData, (LPCTSTR) path2 ); //2e chaine
  24.         pData = 1 + wcschr ( pData, (wchar_t )'\0' );
  25.         lstrcpy ( pData, (LPCTSTR) '\0'); //rajout du dernier \0
  26.     ::GlobalUnlock (hData);
  27.     ::SetClipboardData (CF_HDROP, hData);
  28.     ::CloseClipboard ();


 
Alors voila le truc : Mon but est de copier 2 fichiers (voire plus) de meme format (.emf (enhanced metafile pour les connaisseurs)) dans le presse papier. Pour ca j'utilise donc le meme systeme que celui utilise pour le drag & drop et j'utilise la structure DROPFILE dans laquelle je ne met que les chemins d'accees aux fichiers (path1 et path2).
Lorsque je fais, apres l'execution de ma fonction, un ctrl+V sous Microsoft Word, ce dernier ne lit que le 1er nom de fichier et le colle bien mais il oublie le 2e (les 2 sont bien l'une a la suite de l'autre dans pData, j'ai verifie).
Dans mon presse papier, mes chaines de caracteres sont disposees comme ca :  
"C:\example.emf\0C:\Copy.emf\0\0"
 
Si j'intervertis les 2 et que je met d'abord Copy.emf et ensuite example.emf, ca sera Copy.emf qui sera bien copie dans Word et l'autre qui sera oublie.
 
A mon avis c'est l'\0 a la fin de la 1ere chaine de caractere qui fait ca mais pourtant sur les sites ou j'ai trouver la "methode", il est indique de faire ainsi au niveau de la syntaxe de pDropFile (pointeur sur la structure DROPFILE).
Voici ma principale source : http://www.codeproject.com/KB/shel [...] gdrop.aspx dans la partie "Initiating a drag and drop"
 
J'ai essaye d'enlever l'\0 entre les 2 et word me dit ERREUR fichier C:\example.emfC:\Copy.emf introuvable (logique !)
 
Est ce que qqun saurait comment faire pour que WORD voit bien tous mes fichiers ? Je ne connais que tres peu de chose a la programmation sous windows donc si la question est debile, excusez moi d'avance :)
 
Merci pour votre precieuse aide ! moi je craque :(
 
Lambou


Message édité par lambou le 30-07-2010 à 22:46:16
Reply

Marsh Posté le 30-07-2010 à 22:44:43   

Reply

Marsh Posté le 30-07-2010 à 22:56:47    

Hmm, ton code à l'air correct, juste un petit détail :

Code :
  1. LPCTSTR path1 = (LPCTSTR)"C:\\example.emf";
  2. LPCTSTR path2 = (LPCTSTR)"C:\\Copy.emf";


 
Je ne sais pas quel compilateur tu utilises, mais je doute que même avec Visual Studio que tu aies des chaines de "wchar_t *". Or plus loin dans ton code, tu utilises des fonctions qui prennent des wchar_t * en paramètres :
 

Code :
  1. pData = 1+wcschr ( pData, (wchar_t )'\0' );


 
Mouais, je ne suis pas vraiment sûr que ça soit le problème, car je doute que le C++ autorise un mélange aussi barbare, déjà qu'en C le compilo gueulerait de tous les cotés. M'enfin à vérifier tout de même.
 
Petit test à la con vite fait: copie deux fichiers via l'explorer et colles les dans Word. Ça donne quoi ?
 
edit: arf, je n'avais pas vu ton commentaire dans le code. Ouais, tu mélanges ANSI et Unicode. Il déjà initialiser tes chaines de la sorte :
 

Code :
  1. LPCTSTR path1 = L"C:\\example.emf";
  2. LPCTSTR path2 = L"C:\\Copy.emf";


 
Et wcslen au lieu de strlen, wcscpy au lieu de strcpy, ...

Message cité 1 fois
Message édité par tpierron le 30-07-2010 à 23:01:34
Reply

Marsh Posté le 30-07-2010 à 23:09:16    

tpierron a écrit :

Hmm, ton code à l'air correct, juste un petit détail :

Code :
  1. LPCTSTR path1 = (LPCTSTR)"C:\\example.emf";
  2. LPCTSTR path2 = (LPCTSTR)"C:\\Copy.emf";


 
Je ne sais pas quel compilateur tu utilises, mais je doute que même avec Visual Studio que tu aies des chaines de "wchar_t *". Or plus loin dans ton code, tu utilises des fonctions qui prennent des wchar_t * en paramètres :
 

Code :
  1. pData = 1+wcschr ( pData, (wchar_t )'\0' );


 
Mouais, je ne suis pas vraiment sûr que ça soit le problème, car je doute que le C++ autorise un mélange aussi barbare, déjà qu'en C le compilo gueulerait de tous les cotés. M'enfin à vérifier tout de même.
 
Petit test à la con vite fait: copie deux fichiers via l'explorer et colles les dans Word. Ça donne quoi ?
 
edit: arf, je n'avais pas vu ton commentaire dans le code. Ouais, tu mélanges ANSI et Unicode. Il déjà initialiser tes chaines de la sorte :
 

Code :
  1. LPCTSTR path1 = L"C:\\example.emf";
  2. LPCTSTR path2 = L"C:\\Copy.emf";


 
Et wcslen au lieu de strlen, wcscpy au lieu de strcpy, ...


 
Pour le wchar_t j'ai juste essaye de caster pour voir si ca fonctionnait un peu mieux. Quand je les enleve ca ne change rien :(
J'ai modifier les lstrcpy et lstrlen en wcscpy et wcslen. Le resultat est le meme. Je vois vraiment pas ou est le probleme. Ma syntaxe de pDropFile est peut etre pas bonne, pourtant les differents sites ou je suis alle indique bien cette syntaxe la.
 
Merci pour ta reponse ultra rapide, je continue a cherche :)

Reply

Marsh Posté le 30-07-2010 à 23:29:17    

Je ne sais pas ce que tu as modifié exactement, mais à l'arrache, sans tester, c'est ce que je ferais (il ne doit pas y avoir le moindre warning) :
 

Code :
  1. /***structure DROPFILES***/
  2. typedef struct _DROPFILES {
  3.    DWORD pFiles;                   // Offset of file list
  4.    POINT pt;                       // Drop coordinates
  5.    BOOL fNC;                       // Client or nonclient area
  6.    BOOL fWide;                     // ANSI or Unicode text
  7. } DROPFILES, FAR * LPDROPFILES;
  8. /***ma fonction : ***/
  9.     OpenClipboard(0);
  10.     EmptyClipboard();
  11.  
  12.     LPCTSTR path1 = L"C:\\example.emf";
  13.     LPCTSTR path2 = L"C:\\Copy.emf";
  14.     UINT    uBuffSize = 0;
  15.  
  16.     uBuffSize = wcslen (path1) + wcslen(path2) + 2; //+2 pour les deux \0, un pour chaque chaine
  17.     uBuffSize = sizeof(DROPFILES) + sizeof(TCHAR) * (uBuffSize + 1); //=1 pour un dernier \0 a la toute fin
  18.  
  19.     HGLOBAL hData = ::GlobalAlloc (GHND | GMEM_SHARE, uBuffSize);
  20.     DROPFILES* pDropFiles = (DROPFILES*) ::GlobalLock (hData);
  21.     pDropFiles->pFiles = sizeof (DROPFILES);
  22.     pDropFiles->fWide = TRUE; //la variable UNICODE est definie
  23.  
  24.     TCHAR *pData = (TCHAR*)((LPBYTE) pDropFiles + sizeof (DROPFILES));
  25.     wcscpy(pData, path1); //premiere chaine apres la structure DROPFILES (offset indique dans pFiles)
  26.     pData = 1+wcschr(pData, 0); //placement apres l'\0
  27.     wcscpy(pData, path2); //2e chaine
  28.     pData = 1+wcschr(pData, 0);
  29.     pData[1] = 0
  30.     ::GlobalUnlock (hData);
  31.     ::SetClipboardData (CF_HDROP, hData);
  32.     ::CloseClipboard ();


 

Reply

Marsh Posté le 30-07-2010 à 23:44:10    

Alors tout ce que j'ai a dire c'est MERCIIIIIIIIIIIIIIIIIIIIIIIIIIIII
Donc visiblement le probleme c'etait bel et bien au niveau de la declaration de mes variables. Lorsque je les declarais je castais mes char * en LPCTSTR et visiblement ca lui plaisait pas !
Du coup j'ai fait ce que tu as dis : J'ai mis le L devant les char* et j'ai passer le fWide a TRUE et ca a fonctionner.
J'ai encore bcp de mal a comprendre ces differents LPCTSTR, LPCWSTR, le L avant la declaration de char*. Va falloir que je me penche sur la question !
Merci encore pour ton aide, j'y aurai passer encore bcp de temps sinon :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed