layout.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include "./layout.h"
  2. #include <windows.h>
  3. BOOL Layout_Initialize( HWND hwnd, const INT *itemList, INT itemCount, LAYOUTITEM *layout )
  4. {
  5. if ( NULL == itemList || NULL == layout )
  6. return FALSE;
  7. LAYOUTITEM *item;
  8. for ( INT i = 0; i < itemCount; i++ )
  9. {
  10. item = &layout[ i ];
  11. item->hwnd = GetDlgItem( hwnd, itemList[ i ] );
  12. if ( item->hwnd == NULL )
  13. continue;
  14. if ( FALSE == GetWindowRect( item->hwnd, &item->rect ) )
  15. SetRectEmpty( &item->rect );
  16. else
  17. MapWindowPoints( HWND_DESKTOP, hwnd, (POINT *)&item->rect, 2 );
  18. item->cx = item->rect.right - item->rect.left;
  19. item->cy = item->rect.bottom - item->rect.top;
  20. item->x = item->rect.left;
  21. item->y = item->rect.top;
  22. item->flags = 0;
  23. }
  24. return TRUE;
  25. }
  26. BOOL Layout_Perform( HWND hwnd, LAYOUTITEM *layout, INT layoutCount, BOOL fRedraw )
  27. {
  28. HDWP hdwp, hdwpTemp;
  29. hdwp = BeginDeferWindowPos( layoutCount );
  30. if ( hdwp == NULL )
  31. return FALSE;
  32. UINT baseFlags = SWP_NOACTIVATE | SWP_NOZORDER;
  33. if ( fRedraw == FALSE )
  34. baseFlags |= ( SWP_NOREDRAW | SWP_NOCOPYBITS );
  35. LAYOUTITEM *item;
  36. for ( INT i = 0; i < layoutCount; i++ )
  37. {
  38. item = &layout[ i ];
  39. if ( item->hwnd == NULL )
  40. continue;
  41. UINT flags = baseFlags | ( item->flags & ~( SWP_HIDEWINDOW | SWP_SHOWWINDOW ) );
  42. if ( item->x == item->rect.left && item->y == item->rect.top )
  43. flags |= SWP_NOMOVE;
  44. if ( item->cx == ( item->rect.right - item->rect.left ) && item->cy == ( item->rect.bottom - item->rect.top ) )
  45. flags |= SWP_NOSIZE;
  46. if ( ( SWP_HIDEWINDOW & item->flags ) != 0 )
  47. {
  48. UINT windowStyle = GetWindowLongPtr( item->hwnd, GWL_STYLE );
  49. if ( ( WS_VISIBLE & windowStyle ) != 0 )
  50. {
  51. SetWindowLongPtr( item->hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE );
  52. if ( FALSE != fRedraw )
  53. {
  54. RedrawWindow( hwnd, &item->rect, NULL, RDW_INVALIDATE | RDW_ERASE );
  55. }
  56. }
  57. }
  58. if ( ( SWP_NOSIZE | SWP_NOMOVE ) != ( ( SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED ) & flags ) )
  59. {
  60. hdwpTemp = DeferWindowPos( hdwp, item->hwnd, NULL, item->x, item->y, item->cx, item->cy, flags );
  61. if ( hdwpTemp == NULL )
  62. break;
  63. hdwp = hdwpTemp;
  64. }
  65. }
  66. BOOL result = ( hdwp != NULL ) ? EndDeferWindowPos( hdwp ) : FALSE;
  67. for ( INT i = 0; i < layoutCount; i++ )
  68. {
  69. item = &layout[ i ];
  70. if ( NULL != item->hwnd && 0 != ( SWP_SHOWWINDOW & item->flags ) )
  71. {
  72. UINT windowStyle = GetWindowLongPtr( item->hwnd, GWL_STYLE );
  73. if ( 0 == ( WS_VISIBLE & windowStyle ) )
  74. {
  75. SetWindowLongPtr( item->hwnd, GWL_STYLE, windowStyle | WS_VISIBLE );
  76. if ( FALSE != fRedraw )
  77. RedrawWindow( item->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
  78. }
  79. }
  80. }
  81. return result;
  82. }
  83. static void Layout_SetItemVisibility( const RECT *rect, LAYOUTITEM *item )
  84. {
  85. if ( NULL == item || NULL == item->hwnd )
  86. return;
  87. BOOL outsider = ( item->cx <= 0 || item->cy <= 0 ||
  88. item->x >= rect->right || item->y >= rect->bottom ||
  89. ( item->x + item->cx ) < rect->left || ( item->y + item->cy ) < rect->top );
  90. UINT windowStyle = GetWindowLongPtr( item->hwnd, GWL_STYLE );
  91. if ( 0 == ( WS_VISIBLE & windowStyle ) )
  92. {
  93. if ( !outsider )
  94. {
  95. item->flags |= SWP_SHOWWINDOW;
  96. }
  97. }
  98. else
  99. {
  100. if ( outsider )
  101. {
  102. item->flags |= SWP_HIDEWINDOW;
  103. }
  104. }
  105. }
  106. BOOL Layout_SetVisibility( const RECT *rect, LAYOUTITEM *layout, INT layoutCount )
  107. {
  108. if ( NULL == rect || NULL == layout )
  109. return FALSE;
  110. for ( INT i = 0; i < layoutCount; i++ )
  111. {
  112. Layout_SetItemVisibility( rect, &layout[ i ] );
  113. }
  114. return TRUE;
  115. }
  116. BOOL Layout_SetVisibilityEx( const RECT *rect, const INT *indexList, INT indexCount, LAYOUTITEM *layout )
  117. {
  118. if ( NULL == rect || NULL == indexList || NULL == layout )
  119. return FALSE;
  120. for ( INT i = 0; i < indexCount; i++ )
  121. {
  122. Layout_SetItemVisibility( rect, &layout[ indexList[ i ] ] );
  123. }
  124. return TRUE;
  125. }
  126. BOOL Layout_GetValidRgn( HRGN validRgn, POINTS parrentOffset, const RECT *validRect, LAYOUTITEM *layout, INT layoutCount )
  127. {
  128. if ( NULL == validRgn )
  129. return FALSE;
  130. SetRectRgn( validRgn, 0, 0, 0, 0 );
  131. if ( NULL == layout )
  132. return FALSE;
  133. HRGN rgn = CreateRectRgn( 0, 0, 0, 0 );
  134. if ( NULL == rgn )
  135. return FALSE;
  136. LAYOUTITEM *item;
  137. LONG l, t, r, b;
  138. for ( INT i = 0; i < layoutCount; i++ )
  139. {
  140. item = &layout[ i ];
  141. if ( NULL != item->hwnd && 0 == ( ( SWP_HIDEWINDOW | SWP_SHOWWINDOW ) & item->flags ) )
  142. {
  143. l = item->x + parrentOffset.x;
  144. t = item->y + parrentOffset.y;
  145. r = l + item->cx;
  146. b = t + item->cy;
  147. if ( 0 != ( SWP_NOREDRAW & item->flags ) || ( l == item->rect.left && t == item->rect.top && r == item->rect.right && b == item->rect.bottom ) )
  148. {
  149. if ( NULL != validRect )
  150. {
  151. if ( l < validRect->left )
  152. l = validRect->left;
  153. if ( t < validRect->top )
  154. t = validRect->top;
  155. if ( r > validRect->right )
  156. r = validRect->right;
  157. if ( b > validRect->bottom )
  158. b = validRect->bottom;
  159. }
  160. if ( l < r && t < b )
  161. {
  162. SetRectRgn( rgn, l, t, r, b );
  163. CombineRgn( validRgn, validRgn, rgn, RGN_OR );
  164. if ( NULLREGION != GetUpdateRgn( item->hwnd, rgn, FALSE ) )
  165. {
  166. OffsetRgn( rgn, parrentOffset.x, parrentOffset.y );
  167. CombineRgn( validRgn, validRgn, rgn, RGN_DIFF );
  168. }
  169. }
  170. }
  171. }
  172. }
  173. DeleteObject( rgn );
  174. return TRUE;
  175. }