See the question and my original answer on StackOverflow

One solution is to use the AdjustWindowRectEx function which also computes other window borders width, and allows for window style variations:

RECT rcFrame = { 0 };
AdjustWindowRectEx(&rcFrame, WS_OVERLAPPEDWINDOW, FALSE, 0);
// abs(rcFrame.top) will contain the caption bar height

And for modern Windows (10+), there is the DPI-aware version:

// get DPI from somewhere, for example from the GetDpiForWindow function
const UINT dpi = GetDpiForWindow(myHwnd);
...
RECT rcFrame = { 0 };
AdjustWindowRectExForDpi(&rcFrame, WS_OVERLAPPEDWINDOW, FALSE, 0, dpi);
// abs(rcFrame.top) will contain the caption bar height