[Win32]GetTextExtentPoint32 ne me donne pas la bonne largeur de chaîne

GetTextExtentPoint32 ne me donne pas la bonne largeur de chaîne [Win32] - C++ - Programmation

Marsh Posté le 19-03-2007 à 17:05:59    

Salut,
 
Pour info, je tourne sous Windows XP SP2.
 
En faisant quelques tests de formattage de chaîne de caractères en utilisant la fonction GetTextExtentPoint32 qui est censée calculer la largeur de'une chaîne de caractère en utilisant la police dans le DC en cours, je me suis rendu compte que dans certains cas, cette fonction ne retournait pas la bonne valeur, en particulier lorsque ma chaîne finit par le caractère "f".
 
En isolant le problème, voici un bout de code (gestionnaire de messages Win32) qui permet facilement de voir le problème. Ce bout de code se contente de sélectionner du Arial d'une taille particulière, à écrire "f" à l'écran, et à côté d'indiquer la largeur retournée par GetTextExtentPoint32. (j'utilise un fond noir pour facilement mesurer la largeur réelle du caractère):
 

Code :
  1. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3. HDC hdc;
  4. PAINTSTRUCT ps;
  5. HFONT hfont;
  6. LOGFONT lf = {-48};
  7. SIZE sz;
  8. TCHAR tmp[30];
  9. TCHAR* szTest = TEXT("f" );
  10. RECT rcClient;
  11. switch (message)
  12. {
  13. case WM_PAINT:{
  14.   GetClientRect(hwnd, &rcClient);
  15.   hdc = BeginPaint(hwnd, &ps);
  16.   FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(BLACK_BRUSH));
  17.   lstrcpy(lf.lfFaceName, TEXT("Arial" ));
  18.   hfont = CreateFontIndirect(&lf);
  19.   SelectObject(hdc, hfont);
  20.   TextOut(hdc, 5, 5, szTest, lstrlen(szTest));
  21.   GetTextExtentPoint32(hdc, szTest, lstrlen(szTest), &sz);
  22.   wsprintf(tmp, TEXT("Width: %d" ), sz.cx);
  23.   TextOut(hdc, 15 + sz.cx, 5, tmp, lstrlen(tmp));
  24.   SelectObject(hdc, GetStockObject(SYSTEM_FONT));
  25.   DeleteObject(hfont);
  26.   EndPaint(hwnd, &ps);
  27.   return 0;}
  28.  case WM_DESTROY:
  29.   PostQuitMessage (0) ;
  30.   return 0 ;
  31. }
  32. return DefWindowProc (hwnd, message, wParam, lParam) ;
  33. }


 
Si vous essayez le code suivant, vous verrez que l'appel à GetTextExtentPoint32 retourne 13 alors que la largeur réelle est de 15 pixels.
 
Voici une image pour illustrer le tout:
 
http://img180.imageshack.us/img180/2959/drawingfonts190307wr2.jpg
 
Donc, ma question: comment faire pour avoir la largeur exacte prise par ma chaîne de caractères?


Message édité par Yoyo@ le 19-03-2007 à 17:06:38
Reply

Marsh Posté le 19-03-2007 à 17:05:59   

Reply

Marsh Posté le 19-03-2007 à 22:59:58    

Il est clairement dit dans la doc :

Citation :

Because some devices kern characters, the sum of the extents of the characters in a string does not always equal to the extent of the string.

Celà vient peut-être de là.

Reply

Marsh Posté le 20-03-2007 à 00:17:39    

Oui, j'ai bien vu ça dans la doc, mais ça ne me concerne pas.
 
Ici, ce qui est dit dans la doc, c'est que Extent("A" ) + Extent("B" ) + Extent("C" ) == Extent("ABC" ) n'est pas tout le temps vrai.
 
Enfin, il me semble...(?)
 
J'imagine qu'il existe un moyen fiable de connaître la taille que prend une chaîne de caractères, non?
 

Reply

Sujets relatifs:

Leave a Replay

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