1
0

childwnd.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #include "main.h"
  2. #include "childwnd.h"
  3. #include "resource.h"
  4. typedef struct _CHILDREMOVERGN
  5. {
  6. HWND hwndParent;
  7. HRGN rgnUpdate;
  8. HRGN rgnChild;
  9. } CHILDREMOVERGN;
  10. static BOOL useDeferWndPos = TRUE;
  11. void childresize_init(HWND hwndDlg, ChildWndResizeItem *list, int num)
  12. {
  13. RECT r;
  14. int x;
  15. useDeferWndPos = (GetVersion() < 0x80000000);
  16. GetClientRect(hwndDlg, &r);
  17. for (x = 0; x < num; x ++)
  18. {
  19. RECT r2;
  20. GetWindowRect(GetDlgItem(hwndDlg,list[x].id), &r2);
  21. MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&r2, 2);
  22. list[x].rinfo.left = (0xF000 & list[x].type) ? (r.right - r2.left) : r2.left;
  23. list[x].rinfo.top = (0x0F00 & list[x].type) ? (r.bottom -r2.top) : r2.top;
  24. list[x].rinfo.right = (0x00F0 & list[x].type) ? (r.right - r2.right) : r2.right;
  25. list[x].rinfo.bottom= (0x000F & list[x].type) ? (r.bottom - r2.bottom) : r2.bottom;
  26. list[x].type |= 0xF0000;
  27. }
  28. }
  29. BOOL CALLBACK childresize_enumRemoveRegion(HWND hwnd, LPARAM lParam)
  30. {
  31. if (IsWindowVisible(hwnd) && GetParent(hwnd) == ((CHILDREMOVERGN*)lParam)->hwndParent)
  32. {
  33. RECT r;
  34. GetWindowRect(hwnd, &r);
  35. MapWindowPoints(HWND_DESKTOP, ((CHILDREMOVERGN*)lParam)->hwndParent, (LPPOINT)&r, 2);
  36. SetRectRgn(((CHILDREMOVERGN*)lParam)->rgnChild, r.left, r.top, r.right, r.bottom);
  37. CombineRgn(((CHILDREMOVERGN*)lParam)->rgnUpdate, ((CHILDREMOVERGN*)lParam)->rgnUpdate, ((CHILDREMOVERGN*)lParam)->rgnChild, RGN_DIFF);
  38. }
  39. return TRUE;
  40. }
  41. void childresize_resize_to_rectlist(HWND hwndDlg, ChildWndResizeItem *list, int num, RECT *rectout)
  42. {
  43. RECT r;
  44. int x;
  45. GetClientRect(hwndDlg,&r);
  46. for (x = 0; x < num; x ++) if (list[x].type&0xf0000)
  47. {
  48. RECT r2;
  49. if (list[x].type&0xF000) r2.left=r.right-list[x].rinfo.left;
  50. else r2.left=list[x].rinfo.left;
  51. if (list[x].type&0x0F00) r2.top=r.bottom-list[x].rinfo.top;
  52. else r2.top=list[x].rinfo.top;
  53. if (list[x].type&0x00F0) r2.right=r.right-list[x].rinfo.right;
  54. else r2.right=list[x].rinfo.right;
  55. if (list[x].type&0x000F) r2.bottom=r.bottom-list[x].rinfo.bottom;
  56. else r2.bottom=list[x].rinfo.bottom;
  57. *rectout = r2;
  58. rectout++;
  59. }
  60. }
  61. void childresize_resize_from_rectlist(HWND hwndDlg, ChildWndResizeItem *list, int num, RECT *rectin)
  62. {
  63. RECT r, *pr;
  64. CHILDREMOVERGN crr;
  65. int x;
  66. HDWP hdwp;
  67. HWND h;
  68. GetClientRect(hwndDlg,&r);
  69. crr.hwndParent = hwndDlg;
  70. crr.rgnUpdate = CreateRectRgnIndirect(&r);
  71. crr.rgnChild = CreateRectRgn(0,0,0,0);
  72. EnumChildWindows(hwndDlg,&childresize_enumRemoveRegion,(LPARAM)&crr);
  73. hdwp = (useDeferWndPos) ? BeginDeferWindowPos(num) : NULL;
  74. for (pr = rectin, x = 0; x < num && hdwp; x ++)
  75. {
  76. if (0xF0000 & list[x].type)
  77. {
  78. h = GetDlgItem(hwndDlg,list[x].id);
  79. if (h && pr) hdwp = DeferWindowPos(hdwp, h, NULL, pr->left, pr->top, pr->right - pr->left, pr->bottom - pr->top, SWP_NOZORDER | SWP_NOACTIVATE);
  80. pr++;
  81. }
  82. }
  83. if (hdwp) EndDeferWindowPos(hdwp);
  84. else
  85. {
  86. for (pr = rectin, x = 0; x < num; x ++)
  87. {
  88. if (0xF0000 & list[x].type)
  89. {
  90. h = GetDlgItem(hwndDlg,list[x].id);
  91. if (h && pr) SetWindowPos(h, NULL, pr->left, pr->top, pr->right - pr->left, pr->bottom - pr->top, SWP_NOZORDER | SWP_NOACTIVATE);
  92. pr++;
  93. }
  94. }
  95. }
  96. EnumChildWindows(hwndDlg,&childresize_enumRemoveRegion,(LPARAM)&crr);
  97. InvalidateRgn(hwndDlg, crr.rgnUpdate, TRUE);
  98. DeleteObject(crr.rgnUpdate);
  99. DeleteObject(crr.rgnChild);
  100. }
  101. void childresize_resize(HWND hwndDlg, ChildWndResizeItem *list, int num)
  102. {
  103. RECT rc, rw;
  104. CHILDREMOVERGN crr;
  105. int x, y, cx, cy;
  106. DWORD flags;
  107. HDWP hdwp;
  108. ChildWndResizeItem *pi;
  109. GetClientRect(hwndDlg,&rc);
  110. crr.hwndParent = hwndDlg;
  111. crr.rgnUpdate = CreateRectRgnIndirect(&rc);
  112. crr.rgnChild = CreateRectRgn(0,0,0,0);
  113. EnumChildWindows(hwndDlg,&childresize_enumRemoveRegion,(LPARAM)&crr);
  114. hdwp = (useDeferWndPos) ? BeginDeferWindowPos(num) : NULL;
  115. for (pi = list + num - 1; pi >= list && (!useDeferWndPos || hdwp); pi--)
  116. {
  117. HWND hwnd = GetDlgItem(hwndDlg, pi->id);
  118. if (hwnd && (0xF0000 & pi->type))
  119. {
  120. x = (0xF000 & pi->type) ? (rc.right - pi->rinfo.left) : pi->rinfo.left;
  121. y = (0x0F00 & pi->type) ? (rc.bottom - pi->rinfo.top) : pi->rinfo.top;
  122. cx = ((0x00F0 & pi->type) ? (rc.right - pi->rinfo.right) : pi->rinfo.right) - x;
  123. cy = ((0x000F & pi->type) ? (rc.bottom - pi->rinfo.bottom) : pi->rinfo.bottom) - y;
  124. flags = SWP_NOZORDER | SWP_NOACTIVATE;
  125. GetWindowRect(hwnd, &rw);
  126. MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rw, 2);
  127. if (rw.left == x && rw.top == y) flags |= SWP_NOMOVE;
  128. if (rw.right == (x + cx) && rw.bottom == (y + cy)) flags |= SWP_NOSIZE;
  129. if ((SWP_NOSIZE | SWP_NOMOVE) != ((SWP_NOSIZE | SWP_NOMOVE) & flags))
  130. {
  131. if (useDeferWndPos) hdwp = DeferWindowPos(hdwp, hwnd, NULL, x, y, cx, cy, flags);
  132. else SetWindowPos( hwnd, NULL, x, y, cx, cy, flags);
  133. }
  134. }
  135. }
  136. if (hdwp) EndDeferWindowPos(hdwp);
  137. EnumChildWindows(hwndDlg,&childresize_enumRemoveRegion,(LPARAM)&crr);
  138. InvalidateRgn(hwndDlg, crr.rgnUpdate, TRUE);
  139. DeleteObject(crr.rgnUpdate);
  140. DeleteObject(crr.rgnChild);
  141. }
  142. void childresize_resize2(HWND hwndDlg, ChildWndResizeItem *list, int num, BOOL fRedraw, HRGN rgnUpdate)
  143. {
  144. RECT rc, rw;
  145. CHILDREMOVERGN crr;
  146. int x, y, cx, cy;
  147. DWORD flags;
  148. HDWP hdwp;
  149. ChildWndResizeItem *pi;
  150. GetClientRect(hwndDlg,&rc);
  151. crr.hwndParent = hwndDlg;
  152. crr.rgnUpdate = CreateRectRgnIndirect(&rc);
  153. crr.rgnChild = CreateRectRgn(0,0,0,0);
  154. // EnumChildWindows(hwndDlg,&childresize_enumRemoveRegion,(LPARAM)&crr);
  155. hdwp = (useDeferWndPos) ? BeginDeferWindowPos(num) : NULL;
  156. for (pi = list + num - 1; pi >= list && (!useDeferWndPos || hdwp); pi--)
  157. {
  158. HWND hwnd = GetDlgItem(hwndDlg, pi->id);
  159. if (hwnd && (0xF0000 & pi->type))
  160. {
  161. x = (0xF000 & pi->type) ? (rc.right - pi->rinfo.left) : pi->rinfo.left;
  162. y = (0x0F00 & pi->type) ? (rc.bottom - pi->rinfo.top) : pi->rinfo.top;
  163. cx = ((0x00F0 & pi->type) ? (rc.right - pi->rinfo.right) : pi->rinfo.right) - x;
  164. cy = ((0x000F & pi->type) ? (rc.bottom - pi->rinfo.bottom) : pi->rinfo.bottom) - y;
  165. flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW;
  166. GetWindowRect(hwnd, &rw);
  167. MapWindowPoints(HWND_DESKTOP, hwndDlg, (LPPOINT)&rw, 2);
  168. if (rw.left == x && rw.top == y) flags |= SWP_NOMOVE;
  169. if (rw.right == (x + cx) && rw.bottom == (y + cy)) flags |= SWP_NOSIZE;
  170. if ((SWP_NOSIZE | SWP_NOMOVE) != ((SWP_NOSIZE | SWP_NOMOVE) & flags))
  171. {
  172. if (useDeferWndPos) hdwp = DeferWindowPos(hdwp, hwnd, NULL, x, y, cx, cy, flags);
  173. else SetWindowPos( hwnd, NULL, x, y, cx, cy, flags);
  174. }
  175. else
  176. {
  177. SetRectRgn(crr.rgnChild, rw.left, rw.top, rw.right, rw.bottom);
  178. CombineRgn(crr.rgnUpdate, crr.rgnUpdate, crr.rgnChild, RGN_DIFF);
  179. }
  180. }
  181. }
  182. if (hdwp) EndDeferWindowPos(hdwp);
  183. // EnumChildWindows(hwndDlg,&childresize_enumRemoveRegion,(LPARAM)&crr);
  184. if (fRedraw)
  185. {
  186. InvalidateRgn(hwndDlg, crr.rgnUpdate, TRUE);
  187. RedrawWindow(hwndDlg, NULL, crr.rgnUpdate, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ERASE | RDW_ALLCHILDREN);
  188. //RedrawWindow(hwndDlg, NULL, crr.rgnUpdate, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_FRAME | RDW_ALLCHILDREN);
  189. }
  190. DeleteObject(crr.rgnUpdate);
  191. DeleteObject(crr.rgnChild);
  192. }