xuioswndhost.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include <precomp.h>
  2. #include "xuioswndhost.h"
  3. #include <api/wnd/notifmsg.h>
  4. #include <bfc/parse/paramparser.h>
  5. #include <tataki/region/region.h>
  6. #include <api/wndmgr/layout.h>
  7. // -----------------------------------------------------------------------
  8. const wchar_t OSWndHostXuiObjectStr[] = L"OSWndHost"; // This is the xml tag
  9. char OSWndHostXuiSvcName[] = "OSWndHost xui object";
  10. XMLParamPair XuiOSWndHost::params[] = {
  11. {XUIOSWNDHOST_SETHWND, L"HWND"},
  12. {XUIOSWNDHOST_SETOFFSETS, L"OFFSETS"},
  13. };
  14. // -----------------------------------------------------------------------
  15. XuiOSWndHost::XuiOSWndHost() {
  16. hosted=false;
  17. setStartHidden(1);
  18. setVisible(0);
  19. visible_start_state=1;
  20. setVirtual(0); // we are a real window, with an hwnd and shit
  21. hasregionrect = 0;
  22. myxuihandle = newXuiHandle();
  23. CreateXMLParameters(myxuihandle);
  24. ScriptObject *o = getGuiObject()->guiobject_getScriptObject();
  25. o->vcpu_setInterface(osWndHostGuid, static_cast<OSWndHost *>(this));
  26. }
  27. void XuiOSWndHost::CreateXMLParameters(int master_handle)
  28. {
  29. //XUIOSWNDHOST_PARENT::CreateXMLParameters(master_handle);
  30. int numParams = sizeof(params) / sizeof(params[0]);
  31. hintNumberOfParams(myxuihandle, numParams);
  32. for (int i = 0;i < numParams;i++)
  33. addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
  34. }
  35. // -----------------------------------------------------------------------
  36. XuiOSWndHost::~XuiOSWndHost() {
  37. }
  38. void XuiOSWndHost::onSetVisible(int show)
  39. {
  40. visible_start_state = show;
  41. XUIOSWNDHOST_PARENT::onSetVisible(show);
  42. }
  43. // -----------------------------------------------------------------------
  44. int XuiOSWndHost::onPaint(Canvas *c) {
  45. XUIOSWNDHOST_PARENT::onPaint(c);
  46. RECT r;
  47. getClientRect(&r);
  48. c->fillRect(&r, 0);
  49. return 1;
  50. }
  51. // -----------------------------------------------------------------------
  52. int XuiOSWndHost::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
  53. if (xuihandle != myxuihandle)
  54. return XUIOSWNDHOST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
  55. switch (xmlattributeid) {
  56. case XUIOSWNDHOST_SETHWND: {
  57. #ifdef _WIN64
  58. HWND wnd = (HWND)_wtoi64(value);
  59. #else
  60. HWND wnd = (HWND)WTOI(value);
  61. #endif
  62. if (IsWindow(wnd))
  63. oswndhost_host(wnd);
  64. break;
  65. }
  66. case XUIOSWNDHOST_SETOFFSETS: {
  67. ParamParser pp(value, L",");
  68. RECT r={0,0,0,0};
  69. if (pp.getNumItems() > 0)
  70. r.left = WTOI(pp.enumItem(0));
  71. if (pp.getNumItems() > 1)
  72. r.top = WTOI(pp.enumItem(1));
  73. if (pp.getNumItems() > 2)
  74. r.right = WTOI(pp.enumItem(2));
  75. if (pp.getNumItems() > 3)
  76. r.bottom = WTOI(pp.enumItem(3));
  77. oswndhost_setRegionOffsets(&r);
  78. break;
  79. }
  80. default:
  81. return 0;
  82. }
  83. return 1;
  84. }
  85. // -----------------------------------------------------------------------
  86. void XuiOSWndHost::oswndhost_setRegionOffsets(RECT *r) {
  87. if (r == NULL) {
  88. hasregionrect = 0;
  89. if (wnd != NULL && isPostOnInit()) {
  90. SetWindowRgn(wnd, NULL, 0);
  91. onResize();
  92. }
  93. return;
  94. }
  95. regionrect = *r;
  96. hasregionrect = 1;
  97. //if (isPostOnInit())
  98. //onResize();
  99. }
  100. void XuiOSWndHost::doOnResize()
  101. {
  102. if (wnd != NULL)
  103. {
  104. RECT r;
  105. getClientRect(&r);
  106. if (renderRatioActive())
  107. {
  108. //CUT: double ra = getRenderRatio();
  109. multRatio(&r);
  110. }
  111. if (hasregionrect) {
  112. r.left -= regionrect.left;
  113. r.top -= regionrect.top;
  114. r.right += regionrect.right;
  115. r.bottom += regionrect.bottom;
  116. }
  117. SetWindowPos(wnd, NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE/*|SWP_NOCOPYBITS|SWP_NOREDRAW*/);
  118. if (hasregionrect) {
  119. RECT cr={0,0,r.right-r.left,r.bottom-r.top};
  120. RECT wndr={cr.left+regionrect.left, cr.top+regionrect.top, cr.right-regionrect.right, cr.bottom-regionrect.bottom};
  121. RegionI reg(&wndr);
  122. SetWindowRgn(wnd, reg.makeWindowRegion(), TRUE);
  123. //InvalidateRgn(wnd, reg.getOSHandle(), FALSE);
  124. }
  125. //else
  126. //InvalidateRect(wnd, NULL, TRUE);
  127. //UpdateWindow(wnd);
  128. //repaint();
  129. }
  130. }
  131. int XuiOSWndHost::onAfterResize()
  132. {
  133. if (!XUIOSWNDHOST_PARENT::onAfterResize()) return 0;
  134. doHost();
  135. doOnResize();
  136. return 1;
  137. }
  138. // -----------------------------------------------------------------------
  139. #define STYLE_FILTER (WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW | WS_DLGFRAME | WS_CHILD)
  140. #define EXSTYLE_FILTER (WS_EX_OVERLAPPEDWINDOW | WS_EX_PALETTEWINDOW | WS_EX_CONTROLPARENT)
  141. void XuiOSWndHost::doHost()
  142. {
  143. if (wnd && !hosted)
  144. {
  145. onBeforeReparent(1);
  146. oldparent = GetAncestor(wnd, GA_PARENT);
  147. /*
  148. bool blah=false;
  149. RECT r;
  150. if (IsWindowVisible(wnd))
  151. {
  152. GetWindowRect(wnd, &r);
  153. MapWindowPoints(HWND_DESKTOP, oldparent, (LPPOINT)&r, 2);
  154. blah=true;
  155. }
  156. */
  157. // remember if WS_POPUP or WS_CHILD was set so we can reset it when we unhost
  158. DWORD style;
  159. style = GetWindowLongPtrW(wnd, GWL_STYLE);
  160. savedStyle = (style & STYLE_FILTER);
  161. SetWindowLongPtrW(wnd, GWL_STYLE, (style & ~(STYLE_FILTER)) | WS_CHILD);
  162. style = GetWindowLongPtrW(wnd, GWL_EXSTYLE);
  163. savedExStyle = (style & EXSTYLE_FILTER);
  164. SetWindowLongPtrW(wnd, GWL_EXSTYLE, (style & ~(EXSTYLE_FILTER)) | WS_EX_CONTROLPARENT);
  165. GetWindowRect(wnd, &oldrect);
  166. SetParent(wnd, gethWnd());
  167. //if (blah)
  168. //InvalidateRect(oldparent, &r, FALSE);
  169. //UpdateWindow(oldparent);
  170. SendMessageW(gethWnd(), 0x0127, MAKEWPARAM(3/*UIS_INITIALIZE*/, 3/*UISF_HIDEACCEL | UISF_HIDEFOCUS*/), 0L);
  171. onAfterReparent(1);
  172. dropVirtualCanvas(); // we don't need a canvas anymore, save the memory!
  173. hosted=true;
  174. doOnResize();
  175. setVisible(visible_start_state);
  176. }
  177. }
  178. // -----------------------------------------------------------------------
  179. void XuiOSWndHost::oswndhost_host(HWND oswnd)
  180. {
  181. ASSERT(IsWindow(oswnd));
  182. wnd = oswnd;
  183. if (isPostOnInit())
  184. doHost();
  185. }
  186. // -----------------------------------------------------------------------
  187. void XuiOSWndHost::oswndhost_unhost() {
  188. if (wnd == NULL) return;
  189. onBeforeReparent(0);
  190. if (IsWindow(wnd)) {
  191. // set back the old flags
  192. DWORD style;
  193. style = GetWindowLongPtrW(wnd, GWL_STYLE);
  194. SetWindowLongPtrW(wnd, GWL_STYLE, ((style & ~STYLE_FILTER) | savedStyle));
  195. style = GetWindowLongPtrW(wnd, GWL_EXSTYLE);
  196. SetWindowLongPtrW(wnd, GWL_EXSTYLE, ((style & ~EXSTYLE_FILTER) | savedExStyle));
  197. int config_aot = ((GetWindowLong(WASABI_API_WND->main_getRootWnd()->gethWnd(), GWL_EXSTYLE) & WS_EX_TOPMOST) != 0);
  198. SetWindowPos(wnd, config_aot ? HWND_TOPMOST : HWND_NOTOPMOST,
  199. oldrect.left, oldrect.top, oldrect.right-oldrect.left, oldrect.bottom-oldrect.top,
  200. SWP_NOZORDER | (( 0 == config_aot) ? SWP_NOACTIVATE : 0));
  201. SetParent(wnd, oldparent);
  202. if (hasregionrect) SetWindowRgn(wnd, NULL, 0);
  203. // InvalidateRect(wnd, NULL, TRUE);
  204. hosted=false;
  205. }
  206. onAfterReparent(0);
  207. hasregionrect = 0;
  208. wnd = NULL;
  209. }
  210. int XuiOSWndHost::onUserMessage(int msg, int w, int l, int *r) {
  211. switch (msg) {
  212. case OSWNDHOST_REQUEST_IDEAL_SIZE:
  213. onDeferredCallback/*postDeferredCallback*/(DCB_OSWNDHOST_REQUEST_IDEAL_SIZE, (intptr_t)(new DCBIdealSize(w, l)));
  214. *r = 1;
  215. return 1;
  216. }
  217. return XUIOSWNDHOST_PARENT::onUserMessage(msg, w, l, r); // do default handling
  218. }
  219. int XuiOSWndHost::onDeferredCallback(intptr_t p1, intptr_t p2) {
  220. switch (p1) {
  221. case DCB_OSWNDHOST_REQUEST_IDEAL_SIZE:
  222. {
  223. DCBIdealSize *ideal = (DCBIdealSize *)p2;
  224. if (ideal == NULL) break;
  225. ifc_window *p=getDesktopParent(); // Gets the group/layout at the base of the wnd tree, the desktop hwnd
  226. if (p == NULL) {
  227. delete ideal;
  228. break;
  229. }
  230. Layout *l = static_cast<Layout *>(p->getInterface(layoutGuid));
  231. if (l)
  232. l->beginResize();
  233. RECT r,r2;
  234. getClientRect(&r); // the size of this wnd
  235. if (renderRatioActive()) multRatio(&r);
  236. p->getWindowRect(&r2); // the size of the desktop parent
  237. // take borders into account
  238. int neww = ideal->m_idealwidth+((r2.right-r2.left)-(r.right-r.left));
  239. int newh = ideal->m_idealheight+((r2.bottom-r2.top)-(r.bottom-r.top));
  240. // take layout min/max values into account
  241. int min_w = p->getPreferences(MINIMUM_W);
  242. int min_h = p->getPreferences(MINIMUM_H);
  243. int max_w = p->getPreferences(MAXIMUM_W);
  244. int max_h = p->getPreferences(MAXIMUM_H);
  245. if (min_w != AUTOWH) neww = MAX(min_w, neww);
  246. if (min_h != AUTOWH) newh = MAX(min_h, newh);
  247. if (max_w != AUTOWH) neww = MIN(max_w, neww);
  248. if (max_h != AUTOWH) newh = MIN(max_h, newh);
  249. //CUT: RECT res={r2.left,r2.top,neww,newh};
  250. p->resize(r2.left, r2.top, neww, newh);
  251. if (l)
  252. l->endResize();
  253. delete ideal;
  254. return 1;
  255. }
  256. }
  257. return XUIOSWNDHOST_PARENT::onDeferredCallback(p1, p2);
  258. }
  259. void XuiOSWndHost::onBeforeReparent(int i) {
  260. }
  261. void XuiOSWndHost::onAfterReparent(int i) {
  262. }