2015-05-14 08:43:25 -05:00
// 14 may 2015
# include "uipriv_windows.h"
2015-05-14 09:08:49 -05:00
static struct ptrArray * resizes ;
void initResizes ( void )
{
resizes = newPtrArray ( ) ;
}
void uninitResizes ( void )
{
while ( resizes - > len ! = 0 )
ptrArrayDelete ( resizes , 0 ) ;
ptrArrayDestroy ( resizes ) ;
}
2015-09-01 06:33:13 -05:00
void uiWindowsControlQueueRelayout ( uiWindowsControl * c )
2015-05-18 11:04:52 -05:00
{
2015-09-01 12:51:25 -05:00
uiControl * cc ;
2015-05-18 11:04:52 -05:00
uintmax_t i ;
2015-09-01 06:33:13 -05:00
uiWindowsControl * d ;
2015-05-18 11:04:52 -05:00
// resizing a control requires us to reocmpute the sizes of everything in the top-level window
2015-09-01 12:51:25 -05:00
cc = toplevelOwning ( uiControl ( c ) ) ;
if ( cc = = NULL )
2015-05-18 11:04:52 -05:00
return ;
2015-09-01 12:51:25 -05:00
c = uiWindowsControl ( cc ) ;
2015-05-16 19:06:03 -05:00
// make sure we're only queued once
for ( i = 0 ; i < resizes - > len ; i + + ) {
2015-09-01 06:33:13 -05:00
d = ptrArrayIndex ( resizes , uiWindowsControl * , i ) ;
2015-05-16 19:06:03 -05:00
if ( c = = d )
return ;
}
2015-05-14 09:08:49 -05:00
ptrArrayAppend ( resizes , c ) ;
}
void doResizes ( void )
{
2015-08-31 14:14:02 -05:00
uiWindowsControl * w ;
2015-05-16 00:55:34 -05:00
HWND hwnd ;
2015-08-31 14:14:02 -05:00
RECT r ;
2015-05-14 09:08:49 -05:00
while ( resizes - > len ! = 0 ) {
2015-08-31 14:14:02 -05:00
w = ptrArrayIndex ( resizes , uiWindowsControl * , 0 ) ;
2015-05-14 09:08:49 -05:00
ptrArrayDelete ( resizes , 0 ) ;
2015-09-02 15:26:54 -05:00
// don't clip content if content dynamically changed (tab page changed, etc.)
ensureMinimumWindowSize ( uiWindow ( w ) ) ;
2015-05-17 20:15:39 -05:00
hwnd = ( HWND ) uiControlHandle ( uiControl ( w ) ) ;
2015-08-31 14:14:02 -05:00
if ( GetClientRect ( hwnd , & r ) = = 0 )
2015-09-01 12:51:25 -05:00
logLastError ( " error getting uiWindow client rect in doResizes() " ) ;
2015-08-31 14:14:02 -05:00
( * ( w - > Relayout ) ) ( w , r . left , r . top , r . right - r . left , r . bottom - r . top ) ;
2015-05-14 09:08:49 -05:00
// we used SWP_NOREDRAW; we need to queue a redraw ourselves
2015-06-04 15:36:28 -05:00
// force all controls to be redrawn; this fixes things like the date-time picker's up-down not showing up until hovered over (and bypasses complications caused by WS_CLIPCHILDREN and WS_CLIPSIBLINGS, which we don't use but other controls might)
if ( RedrawWindow ( hwnd , NULL , NULL , RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN ) = = 0 )
2015-05-14 09:08:49 -05:00
logLastError ( " error redrawing controls after a resize in doResizes() " ) ;
}
}
2015-09-01 06:33:13 -05:00
void uiWindowsEnsureMoveWindow ( HWND hwnd , intmax_t x , intmax_t y , intmax_t width , intmax_t height )
2015-05-14 09:08:49 -05:00
{
2015-05-18 11:04:52 -05:00
RECT r ;
r . left = x ;
r . top = y ;
r . right = x + width ;
r . bottom = y + height ;
2015-06-04 15:42:19 -05:00
if ( SetWindowPos ( hwnd , NULL , r . left , r . top , r . right - r . left , r . bottom - r . top , SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOZORDER ) = = 0 )
2015-05-14 09:08:49 -05:00
logLastError ( " error moving window in moveWindow() " ) ;
}
2015-05-30 02:40:14 -05:00
void setWindowInsertAfter ( HWND hwnd , HWND insertAfter )
2015-05-14 09:08:49 -05:00
{
2015-06-04 15:42:19 -05:00
if ( SetWindowPos ( hwnd , insertAfter , 0 , 0 , 0 , 0 , SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE ) = = 0 )
2015-05-30 02:40:14 -05:00
logLastError ( " error reordering window in setWindowInsertAfter() " ) ;
2015-05-14 09:08:49 -05:00
}
2015-05-15 15:04:10 -05:00
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing and https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
// this X value is really only for buttons but I don't see a better one :/
# define winXPadding 4
# define winYPadding 4
2015-08-31 14:14:02 -05:00
uiWindowsSizing * uiWindowsNewSizing ( HWND hwnd )
2015-05-15 15:04:10 -05:00
{
2015-08-31 16:50:23 -05:00
uiWindowsSizing * d ;
2015-05-15 15:04:10 -05:00
HDC dc ;
HFONT prevfont ;
TEXTMETRICW tm ;
SIZE size ;
2015-08-31 14:14:02 -05:00
d = uiNew ( uiWindowsSizing ) ;
2015-05-15 15:04:10 -05:00
2015-05-16 00:55:34 -05:00
dc = GetDC ( hwnd ) ;
2015-05-15 15:04:10 -05:00
if ( dc = = NULL )
2015-08-31 14:14:02 -05:00
logLastError ( " error getting DC in uiWindowsNewSizing() " ) ;
2015-05-15 15:04:10 -05:00
prevfont = ( HFONT ) SelectObject ( dc , hMessageFont ) ;
if ( prevfont = = NULL )
2015-08-31 14:14:02 -05:00
logLastError ( " error loading control font into device context in uiWindowsNewSizing() " ) ;
2015-05-15 15:04:10 -05:00
ZeroMemory ( & tm , sizeof ( TEXTMETRICW ) ) ;
if ( GetTextMetricsW ( dc , & tm ) = = 0 )
2015-08-31 14:14:02 -05:00
logLastError ( " error getting text metrics in uiWindowsNewSizing() " ) ;
2015-05-15 15:04:10 -05:00
if ( GetTextExtentPoint32W ( dc , L " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " , 52 , & size ) = = 0 )
2015-08-31 14:14:02 -05:00
logLastError ( " error getting text extent point in uiWindowsNewSizing() " ) ;
2015-05-15 15:04:10 -05:00
2015-08-31 14:14:02 -05:00
d - > BaseX = ( int ) ( ( size . cx / 26 + 1 ) / 2 ) ;
d - > BaseY = ( int ) tm . tmHeight ;
d - > InternalLeading = tm . tmInternalLeading ;
2015-05-15 15:04:10 -05:00
if ( SelectObject ( dc , prevfont ) ! = hMessageFont )
2015-05-18 10:46:50 -05:00
logLastError ( " error restoring previous font into device context in uiWindowsSizing() " ) ;
2015-05-16 00:55:34 -05:00
if ( ReleaseDC ( hwnd , dc ) = = 0 )
2015-05-18 10:46:50 -05:00
logLastError ( " error releasing DC in uiWindowsSizing() " ) ;
2015-05-15 15:04:10 -05:00
2015-08-31 14:14:02 -05:00
d - > XPadding = uiWindowsDlgUnitsToX ( winXPadding , d - > BaseX ) ;
d - > YPadding = uiWindowsDlgUnitsToY ( winYPadding , d - > BaseY ) ;
2015-05-18 11:04:52 -05:00
return d ;
2015-05-15 15:04:10 -05:00
}
2015-05-18 10:46:50 -05:00
2015-08-31 14:14:02 -05:00
void uiWindowsFreeSizing ( uiWindowsSizing * d )
2015-05-18 10:46:50 -05:00
{
uiFree ( d ) ;
}