So far I tried using GetThemePartSize, GetThemeMetric, GetSystemMetrics, WM_GETTITLEBARINFOEX via SendMessage and a couple of other calls, but nothing comes even close to the real dimensions (Windows 7 with themes enabled).
Basically my questions are: How to get the size (and location, ideally even handle) of these buttons and what do the retrieved values from GetThemePartSize even mean? What are they good for?
I already looked at this answer and many others, but they simply don't work.
Thank you
Update
For Hans:
[DllImport("uxtheme", ExactSpelling=true)]
private extern static Int32 GetThemePartSize(IntPtr hTheme, IntPtr hdc, WindowPart part, WindowPartState state, ref RECT pRect, ThemeSize eSize, out SIZE size);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct SIZE
{
public int cx;
public int cy;
}
private const int TS_TRUE = 1;
private const int CBS_NORMAL = 1;
private const int WP_CLOSEBUTTON = 18;
private const string VSCLASS_WINDOW = "WINDOW";
/* inside a method */
var rect = new RECT {left = 0, right = 200, top = 0, bottom = 200};
var size = new SIZE();
var windowHandle = new WindowInteropHelper({MyWindow}).Handle;
var theme = OpenThemeData(windowHandle, VSCLASS_WINDOW);
GetThemePartSize(theme, null, WP_CLOSEBUTTON, CBS_NORMAL, ref rect, TS_TRUE, ref size);
// result on w7 with default theme -> size.cx == 28, size.cy == 17
After browsing the Firefox 17.0.1 source code (namely the files nsNativeThemeWin.cpp and nsUXThemeData.cpp), I was able to come up with a partial solution for desktops apps running on Vista or newer that satisfied my needs:
private const int DWMWA_CAPTION_BUTTON_BOUNDS = 5;
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("dwmapi.dll")]
public static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out RECT pvAttribute, int cbAttribute);
var windowHandle = new WindowInteropHelper(Main.Instance).Handle;
var buttonsRect = new RECT();
var sizeButtonsRect = Marshal.SizeOf(buttonsRect);
DwmGetWindowAttribute(windowHandle, DWMWA_CAPTION_BUTTON_BOUNDS, out buttonsRect, sizeButtonsRect);
The results stored in buttonsRect are somewhat strange: The width difference (right - left == 105) fits the actually bounds exactly, however, the height difference (29px) is 8 pixel larger than the area the buttons are actually occupying.
Since this doesn't really answer any of the questions in full, I will leave this thread open for further responses.
Thanks again Hans for your invaluable and well-thought-out comment. As you can clearly see, it was all about the programming language and the code snippet.
You can use the Microsoft.Windows.Shell.dll in combination with the custom chrome window library to modify or address your window buttons. I am using this in order to create windows 8 ui styled applications
http://www.codeproject.com/Articles/131515/WPF-Custom-Chrome-Library
http://archive.msdn.microsoft.com/WPFShell
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With