How to get size and position of window caption buttons (minimise, restore, close)

9.7k Views Asked by At

Is there an API call to determine the size and position of window caption buttons? I'm trying to draw vista-style caption buttons onto an owner drawn window. I'm dealing with c/c++/mfc.

Edit: Does anyone have a code example to draw the close button?

4

There are 4 best solutions below

0
On BEST ANSWER

I've found the function required to get the position of the buttons in vista: WM_GETTITLEBARINFOEX

This link also shows the system metrics required to get all the spacing correct (shame it's not a full dialog picture though). This works perfectly in Vista, and mostly in XP (in XP there is slightly too much of a gap between the buttons).

From http://shellrevealed.com/photos/blog_images/images/4538/original.aspx

2
On

GetSystemMetrics gives all these informations. To draw within the window decoration, use GetWindowDC.

0
On

GetSystemMetrics function should help you with a size (SM_CYSIZE and SM_CXSIZE parameters).

EDIT

I'm not sure you can find positions with this function but you might take a look at emule source code, they've managed to add a button to a window caption.

1
On

The following code is adapted from the "Global Titlebar Hook" example I found at http://www.catch22.net/content/snippets. I modified the example to make it MFC-friendly. It returns the X-coordinate of the leftmost titlebar button but it could easily be modified to find the position of any of the buttons.

#define B_EDGE 2

int CMyWindow::CalcRightEdge()
{
 if(GetStyle() & WS_THICKFRAME)
  return GetSystemMetrics(SM_CXSIZEFRAME);
 else
  return GetSystemMetrics(SM_CXFIXEDFRAME);
}


int CMyWindow::findNewButtonPosition()
{
 int   nButSize  = 0;
 DWORD dwStyle   = GetStyle();
 DWORD dwExStyle = GetExStyle();

 if(dwExStyle & WS_EX_TOOLWINDOW)
 {
  int nSysButSize = GetSystemMetrics(SM_CXSMSIZE) - B_EDGE;

  if(GetStyle() & WS_SYSMENU) 
   nButSize += nSysButSize + B_EDGE;

  return nButSize + CalcRightEdge();
 }
 else
 {
  int nSysButSize = GetSystemMetrics(SM_CXSIZE) - B_EDGE;

 // Window has Close [X] button. This button has a 2-pixel
 // border on either size
  if(dwStyle & WS_SYSMENU) 
   nButSize += nSysButSize + B_EDGE;

 // If either of the minimize or maximize buttons are shown,
 // Then both will appear (but may be disabled)
 // This button pair has a 2 pixel border on the left
  if(dwStyle & (WS_MINIMIZEBOX | WS_MAXIMIZEBOX) )
   nButSize += B_EDGE + nSysButSize * 2;

 // A window can have a question-mark button, but only
 // if it doesn't have any min/max buttons
  else if(dwExStyle & WS_EX_CONTEXTHELP)
   nButSize += B_EDGE + nSysButSize;

 // Now calculate the size of the border...aggghh!
  return nButSize + CalcRightEdge();
 }
}