web-dev-qa-db-fra.com

largeur et hauteur de bordure de fenêtre dans Win32 - comment l'obtenir?

 :: GetSystemMetrics (SM_CYBORDER) 

... revient avec 1 et je sais que la barre de titre est plus haute que UN pixel: /

J'ai aussi essayé:

 RECT r; 
 R.left = r.top = 0; r.right = r.bottom = 400; 
 :: AdjustWindowRect (& r, WS_OVERLAPPED, FALSE); 
 _bdW = (uword) (r.right - r.left - 400); 
 _bdH = (uword) (r.bottom - r.top - 400); 

Mais la frontière w, h est revenue à 0.

Dans mon gestionnaire WM_SIZE, je dois m'assurer que la hauteur de la fenêtre change en "étapes" afin, par exemple, qu'une toute nouvelle ligne de texte puisse tenir dans la fenêtre sans "espace de ligne partielle junky" en bas.

Mais :: MoveWindow a besoin des dimensions AVEC l'espace de bordure ajouté.

QUELQU'UN doit avoir fait ça avant ... Merci pour toute aide :)

27
Stephen Hazel

Les fonctions GetWindowRect et GetClientRect peuvent être utilisées pour calculer la taille de toutes les bordures de fenêtre.

Suite101 a un article sur redimensionnement d'une fenêtre et maintien de la zone client à une taille connue .

Voici leur exemple de code:

void ClientResize(HWND hWnd, int nWidth, int nHeight)
{
  RECT rcClient, rcWind;
  POINT ptDiff;
  GetClientRect(hWnd, &rcClient);
  GetWindowRect(hWnd, &rcWind);
  ptDiff.x = (rcWind.right - rcWind.left) - rcClient.right;
  ptDiff.y = (rcWind.bottom - rcWind.top) - rcClient.bottom;
  MoveWindow(hWnd,rcWind.left, rcWind.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
}
39
stukelly
int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);

En fait, le résultat ci-dessus pourrait être égal à:

GetClientRect(hWnd, &rcClient); 
GetWindowRect(hWnd, &rcWind); 
int border_thickness = ((rcWind.right - rcWind.left) - rcClient.right) / 2; 

mais GetSystemMetrics(SM_CXSIZEFRAME) est plus facile à utiliser.

12
Tody.Lu

Je pense que ce que vous cherchez c'est SM_CYCAPTION - c'est la hauteur de la barre de titre. SM_CYBORDER est la hauteur des bords horizontaux d'une fenêtre.

11
Head Geek

La méthode suggérée par stukelly fonctionnera à moins que la fenêtre ne soit minimisée ou pas complètement initialisée. Une autre approche qui vous donnera la taille de la bordure dans ces conditions est d'utiliser la fonction AdjustWindowRectEx. Voici un exemple:

CSize GetBorderSize(const CWnd& window)
{
   // Determine the border size by asking windows to calculate the window rect
   // required for a client rect with a width and height of 0
   CRect rect;
   AdjustWindowRectEx(&rect, window.GetStyle(), FALSE, window.GetExStyle());
   return rect.Size();
}

Selon l'application, il peut être nécessaire de combiner cette approche avec celle de stukelly si la taille de bordure visible actuelle est nécessaire:

CSize GetBorderSize(const CWnd& window)
{
   if (window.IsZoomed())
   {
      // The total border size is found by subtracting the size of the client rect
      // from the size of the window rect. Note that when the window is zoomed, the
      // borders are hidden, but the title bar is not.
      CRect wndRect, clientRect;
      window.GetWindowRect(&wndRect);
      window.GetClientRect(&clientRect);
      return wndRect.Size() - clientRect.Size();
   }
   else
   {
      // Determine the border size by asking windows to calculate the window rect
      // required for a client rect with a width and height of 0. This method will
      // work before the window is fully initialized and when the window is minimized.
      CRect rect;
      AdjustWindowRectEx(&rect, window.GetStyle(), FALSE, window.GetExStyle());
      return rect.Size();
   }
}
3
Thomas M

Head Geek donne la réponse détaillée: utilisez GetSystemMetrics pour additionner les bits de légende et de bordure. Vous pouvez également faire une différence de largeur/hauteur entre GetWindowRect et GetClientRect. Cela vous donnera le total de toutes les légendes/bordures/etc.

2
CodeGuy

Vous avez une autre solution ... Vous pouvez pré-calculer la frontière en appelant une fonction dédiée dans les messages WM_CREATE et WM_INITDIALOG. Et actualisez les valeurs lorsque vous modifiez le style de votre fenêtre ou lorsque le menu est divisé en deux lignes.

RECT cRect, wRect, oRect;
GetWindowRect(hWnd, &wRect);
GetClientRect(hWnd, &cRect);
MapWindowPoints(hWnd, NULL, (LPPOINT)&cRect, 2);

oRect.left = cRect.left - wRect.left;
oRect.top = cRect.top - wRect.top;
oRect.right = wRect.right - cRect.right;
oRect.bottom = wRect.bottom - cRect.bottom;
0
user11109368