2015-04-24 13:09:48 -05:00
// 6 april 2015
2016-04-23 20:38:51 -05:00
# include "uipriv_windows.hpp"
2015-04-24 13:09:48 -05:00
// this is a helper function that takes the logic of determining window classes and puts it all in one place
// there are a number of places where we need to know what window class an arbitrary handle has
// theoretically we could use the class atom to avoid a _wcsicmp()
// however, raymond chen advises against this - http://blogs.msdn.com/b/oldnewthing/archive/2004/10/11/240744.aspx (and we're not in control of the Tab class, before you say anything)
// usage: windowClassOf(hwnd, L"class 1", L"class 2", ..., NULL)
int windowClassOf ( HWND hwnd , . . . )
{
// MSDN says 256 is the maximum length of a class name; add a few characters just to be safe (because it doesn't say whether this includes the terminating null character)
# define maxClassName 260
WCHAR classname [ maxClassName + 1 ] ;
va_list ap ;
WCHAR * curname ;
int i ;
2016-04-21 22:05:10 -05:00
if ( GetClassNameW ( hwnd , classname , maxClassName ) = = 0 ) {
logLastError ( L " error getting name of window class " ) ;
// assume no match on error, just to be safe
return - 1 ;
}
2015-04-24 13:09:48 -05:00
va_start ( ap , hwnd ) ;
i = 0 ;
for ( ; ; ) {
curname = va_arg ( ap , WCHAR * ) ;
if ( curname = = NULL )
break ;
if ( _wcsicmp ( classname , curname ) = = 0 ) {
va_end ( ap ) ;
return i ;
}
i + + ;
}
// no match
va_end ( ap ) ;
return - 1 ;
}
2015-05-05 12:12:48 -05:00
// wrapper around MapWindowRect() that handles the complex error handling
void mapWindowRect ( HWND from , HWND to , RECT * r )
{
2016-04-21 22:05:10 -05:00
RECT prevr ;
2015-05-05 12:12:48 -05:00
DWORD le ;
2016-04-21 22:05:10 -05:00
prevr = * r ;
2015-05-05 12:12:48 -05:00
SetLastError ( 0 ) ;
if ( MapWindowRect ( from , to , r ) = = 0 ) {
le = GetLastError ( ) ;
SetLastError ( le ) ; // just to be safe
2016-04-21 22:05:10 -05:00
if ( le ! = 0 ) {
logLastError ( L " error calling MapWindowRect() " ) ;
// restore original rect on error, just in case
* r = prevr ;
}
2015-05-05 12:12:48 -05:00
}
}
2015-05-06 17:05:07 -05:00
DWORD getStyle ( HWND hwnd )
{
return ( DWORD ) GetWindowLongPtrW ( hwnd , GWL_STYLE ) ;
}
void setStyle ( HWND hwnd , DWORD style )
{
SetWindowLongPtrW ( hwnd , GWL_STYLE , ( LONG_PTR ) style ) ;
}
DWORD getExStyle ( HWND hwnd )
{
return ( DWORD ) GetWindowLongPtrW ( hwnd , GWL_EXSTYLE ) ;
}
void setExStyle ( HWND hwnd , DWORD exstyle )
{
SetWindowLongPtrW ( hwnd , GWL_EXSTYLE , ( LONG_PTR ) exstyle ) ;
}
2015-09-01 06:33:13 -05:00
2015-09-02 15:02:06 -05:00
// see http://blogs.msdn.com/b/oldnewthing/archive/2003/09/11/54885.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/09/13/54917.aspx
void clientSizeToWindowSize ( HWND hwnd , intmax_t * width , intmax_t * height , BOOL hasMenubar )
{
RECT window ;
window . left = 0 ;
window . top = 0 ;
window . right = * width ;
window . bottom = * height ;
2016-04-21 22:05:10 -05:00
if ( AdjustWindowRectEx ( & window , getStyle ( hwnd ) , hasMenubar , getExStyle ( hwnd ) ) = = 0 ) {
2016-04-23 23:33:42 -05:00
logLastError ( L " error getting adjusted window rect " ) ;
2016-04-21 22:05:10 -05:00
// on error, don't give up; the window will be smaller but whatever
window . left = 0 ;
window . top = 0 ;
window . right = * width ;
window . bottom = * height ;
}
2015-09-02 15:02:06 -05:00
if ( hasMenubar ) {
RECT temp ;
temp = window ;
temp . bottom = 0x7FFF ; // infinite height
SendMessageW ( hwnd , WM_NCCALCSIZE , ( WPARAM ) FALSE , ( LPARAM ) ( & temp ) ) ;
window . bottom + = temp . top ;
}
* width = window . right - window . left ;
* height = window . bottom - window . top ;
}
2016-04-21 22:05:10 -05:00
HWND parentOf ( HWND child )
{
return GetAncestor ( child , GA_PARENT ) ;
}
HWND parentToplevel ( HWND child )
{
return GetAncestor ( child , GA_ROOT ) ;
}
2016-04-22 18:51:33 -05:00
void setWindowInsertAfter ( HWND hwnd , HWND insertAfter )
{
if ( SetWindowPos ( hwnd , insertAfter , 0 , 0 , 0 , 0 , SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE ) = = 0 )
logLastError ( L " error reordering window " ) ;
}
2016-05-16 18:28:30 -05:00
HWND getDlgItem ( HWND hwnd , int id )
{
HWND out ;
out = GetDlgItem ( hwnd , id ) ;
if ( out = = NULL )
logLastError ( L " error getting dialog item handle " ) ;
return out ;
}
2016-05-17 11:41:41 -05:00
void invalidateRect ( HWND hwnd , RECT * r , BOOL erase )
{
if ( InvalidateRect ( hwnd , r , erase ) = = 0 )
logLastError ( L " error invalidating window rect " ) ;
}
2016-06-05 15:07:40 -05:00
// that damn ABI bug is never going to escape me is it
D2D1_SIZE_F realGetSize ( ID2D1RenderTarget * rt )
{
# ifdef _MSC_VER
return rt - > GetSize ( ) ;
# else
D2D1_SIZE_F size ;
typedef D2D1_SIZE_F * ( __stdcall ID2D1RenderTarget : : * GetSizeF ) ( D2D1_SIZE_F * ) ;
GetSizeF gs ;
gs = ( GetSizeF ) ( & ( rt - > GetSize ) ) ;
( rt - > * gs ) ( & size ) ;
return size ;
# endif
}