2009-01-10 48 views
27
 
     ::GetSystemMetrics (SM_CYBORDER) 

... regresa con 1 y sé que la barra de título es más alto que un píxel:/ancho y alto del borde de la ventana en Win32 - ¿cómo lo obtengo?

También probé:

 
    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); 

Pero frontera w, h volvieron como 0.

en mi manejador WM_SIZE, necesito para asegurarse de que la altura de la ventana cambia en "pasos" para, por ejemplo, una nueva línea de texto podría caber en la ventana sin "espacio adicto parcial de línea" en la parte inferior .

Pero :: MoveWindow necesidades de las dimensiones con el espacio fronterizo añadido en.

alguien debe haber hecho esto antes ... Gracias por cualquier ayuda :)

+0

la documentación para 'dicen AdjustWindowRect', bastante inútil, que no puedes usar 'WS_OVERLAPPED' con él. – JWWalker

+0

@JWWalker: En realidad, eso es bastante útil. Ahora, si también sabe que 'WS_OVERLAPPED' se define como' 0x0', debería ser obvio, por qué, también. – IInspectable

+0

@IInspectable, no, no tengo idea de por qué es relevante que 'WS_OVERLAPPED' sea 0. – JWWalker

Respuesta

38

Las funciones GetWindowRect y GetClientRect se pueden utilizar para calcular el tamaño de todos los bordes de las ventanas.

Suite101 tiene un artículo en resizing a window and the keeping client area at a know size.

Aquí es su código de ejemplo:

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); 
} 
+2

Hay una función WinAPI para cambiar el tamaño de la ventana para tener un tamaño de área de cliente determinado: AdjustWindowRectEx () – MrZebra

+1

Creo que me quedaré con el método GetWindowRect() - GetClientRect(). De esa manera no tengo que meterme con los estilos de ventana de diablos. ¿Cuál es el mismo problema que tendré con GetSystemMetrics (lo que sea) ... Gracias a todos - este lugar rocas :) –

+0

Esta solución no funcionará si la ventana se minimiza debido a los ajustes realizados en el tamaño de ventana –

9

Creo que lo que está buscando es SM_CYCAPTION - esa es la altura de la barra de título. SM_CYBORDER es la altura de los bordes horizontales de una ventana.

+0

Hellow. Como mi [herramienta de captrue de pantalla] (https://i.stack.imgur.com/Ikgeg.jpg), sé que la altura de la barra de título es 28. Pero su 'GetSystemMetrics (SM_CYCAPTION)' acaba de dar '23'. – yode

+0

Esa medición puede incluir otras métricas, como el borde de la ventana. –

+0

¿Sabía que incluye qué componenets? – yode

2

Head Geek da la respuesta detallada: use GetSystemMetrics para sumar los títulos y los bits de borde. También puede hacer una diferencia en ancho/alto entre GetWindowRect y GetClientRect. Esto le dará el total de todos los subtítulos/bordes/etc.

+0

GetSystemMetics en MSDN: http://msdn.microsoft.com/en-us/library/ms724385(VS.85).aspx – stukelly

10
int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); 

de hecho, el resultado anterior es igual a:

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

pero "GetSystemMetrics (SM_CXSIZEFRAME)" es fácil de utilizar.

2

El método sugerido por stukelly funcionará a menos que la ventana se minimice o no se inicialice por completo. Un enfoque alternativo que le dará el tamaño del borde en estas condiciones es usar la función AdjustWindowRectEx. Aquí está un ejemplo:

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(); 
} 

Dependiendo de la aplicación, puede ser necesario combinar este enfoque con la stukelly si el tamaño actual borde visible es necesario:

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(); 
    } 
} 
Cuestiones relacionadas