/* * Hide the window to make it and its children invisible on the screen. * This is a recursive routine which increments the unmapcount values for * this window and all of its children, and causes exposure events for * windows which are newly uncovered. */ void MwHideWindow(HWND hwnd,BOOL bChangeFocus, BOOL bSendMsg) { HWND wp = hwnd; HWND pwp; /* parent window */ HWND sibwp; /* sibling window */ HWND childwp; /* child window */ if (wp == rootwp) return; ++mwpaintNC; /* experimental NC paint handling*/ /* send hide message if currently visible*/ if(bSendMsg && wp->unmapcount == 0) SendMessage(wp, WM_SHOWWINDOW, FALSE, 0L); wp->unmapcount++; for (childwp = wp->children; childwp; childwp = childwp->siblings) MwHideWindow(childwp, bChangeFocus, bSendMsg); if (wp == mousewp) { MwCheckMouseWindow(); MwCheckCursor(); } if (bChangeFocus && wp == focuswp) SetFocus(rootwp->children? rootwp->children: rootwp); /* * If the parent window is still unmapped, then we are all done. */ if (wp->parent->unmapcount) return; /* * Clear the area in the parent for this window, causing an * exposure event for it. */ pwp = wp->parent; MwClearWindow(pwp, wp->winrect.left - pwp->winrect.left, wp->winrect.top - pwp->winrect.top, wp->winrect.right - wp->winrect.left, wp->winrect.bottom - wp->winrect.top, TRUE); /* * Finally clear and redraw all parts of our lower sibling * windows that were covered by this window. */ sibwp = wp; while (sibwp->siblings) { sibwp = sibwp->siblings; MwExposeArea(sibwp, wp->winrect.left, wp->winrect.top, wp->winrect.right - wp->winrect.left, wp->winrect.bottom - wp->winrect.top); } }
BOOL WINAPI ShowWindow(HWND hwnd, int nCmdShow) { if(!hwnd) return FALSE; /* fix: send show msg*/ switch(nCmdShow) { case SW_HIDE: if (!(hwnd->style & WS_VISIBLE)) return FALSE; MwHideWindow(hwnd, TRUE, TRUE); hwnd->style &= ~WS_VISIBLE; return TRUE; case SW_MAXIMIZE: if (!(hwnd->style & WS_MAXIMIZE)) { RECT rc; hwnd->restorerc = hwnd->winrect; SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0); MoveWindow(hwnd, rc.top, rc.left, rc.right - rc.left, rc.bottom - rc.top, TRUE); hwnd->style |= WS_MAXIMIZE; } break; case SW_RESTORE: case SW_SHOWDEFAULT: if(hwnd->style & WS_MAXIMIZE) { RECT rc = hwnd->restorerc; MoveWindow(hwnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE); hwnd->style &= ~WS_MAXIMIZE; } break; default: if (hwnd->style & WS_VISIBLE) return FALSE; } hwnd->style |= WS_VISIBLE; MwShowWindow(hwnd, TRUE); return TRUE; }
BOOL WINAPI ShowWindow(HWND hwnd, int nCmdShow) { if(!hwnd) return FALSE; /* fix: send show msg*/ switch(nCmdShow) { case SW_HIDE: if (!(hwnd->style & WS_VISIBLE)) return FALSE; MwHideWindow(hwnd, TRUE, TRUE); hwnd->style &= ~WS_VISIBLE; break; default: if (hwnd->style & WS_VISIBLE) return FALSE; hwnd->style |= WS_VISIBLE; MwShowWindow(hwnd, TRUE); } return TRUE; }
/* * Destroy the specified window, and all of its children. * This is a recursive routine. */ void MwDestroyWindow(HWND hwnd,BOOL bSendMsg) { HWND wp = hwnd; HWND prevwp; PMWLIST p; PMSG pmsg; if (wp == rootwp || !IsWindow (hwnd)) return; /* * Unmap the window. */ if (wp->unmapcount == 0) MwHideWindow(wp, FALSE, FALSE); if(bSendMsg) SendMessage(hwnd, WM_DESTROY, 0, 0L); /* * Remove from timers */ MwRemoveWndFromTimers(hwnd); /* * Remove hotkeys */ MwRemoveWndFromHotkeys(hwnd); /* * Disable all sendmessages to this window. */ wp->lpfnWndProc = NULL; /* * Destroy all children, sending WM_DESTROY messages. */ while (wp->children) MwDestroyWindow(wp->children, bSendMsg); wp->pClass = NULL; /* * Free any cursor associated with the window. */ if (wp->cursor->usecount-- == 1) { free(wp->cursor); wp->cursor = NULL; } /* * Remove this window from the child list of its parent. */ prevwp = wp->parent->children; if (prevwp == wp) wp->parent->children = wp->siblings; else { while (prevwp && prevwp->siblings != wp) prevwp = prevwp->siblings; if (prevwp) prevwp->siblings = wp->siblings; } wp->siblings = NULL; /* * Remove this window from the complete list of windows. */ prevwp = listwp; if (prevwp == wp) listwp = wp->next; else { while (prevwp->next && prevwp->next != wp) prevwp = prevwp->next; prevwp->next = wp->next; } wp->next = NULL; /* * Forget various information related to this window. * Then finally free the structure. */ /* Remove all messages from msg queue for this window*/ for(p=mwMsgHead.head; p; ) { pmsg = GdItemAddr(p, MSG, link); if(pmsg->hwnd == wp) { p = p->next; GdListRemove(&mwMsgHead, &pmsg->link); GdItemFree(pmsg); } else p = p->next; } /* * Remove all properties from this window. */ for(p=hwnd->props.head; p; ) { MWPROP *pProp = GdItemAddr(p, MWPROP, link); p = p->next; GdListRemove (&hwnd->props, &pProp->link); GdItemFree (pProp); } /* FIXME: destroy hdc's relating to window?*/ if (wp == capturewp) { capturewp = NULL; MwCheckMouseWindow(); } if (wp == MwGetTopWindow(focuswp)) SetFocus(rootwp->children? rootwp->children: rootwp); /* destroy private DC*/ if(wp->owndc) { HDC hdc = wp->owndc; wp->owndc = NULL; /* force destroy with ReleaseDC*/ ReleaseDC(wp, hdc); } if (wp->szTitle) { free(wp->szTitle); wp->szTitle = NULL; } #if UPDATEREGIONS if (wp->update) { GdDestroyRegion(wp->update); wp->update = NULL; } #endif GdItemFree(wp); }
BOOL SetWindowPos(HWND hwnd, HWND hwndInsertAfter, int x, int y, int cx, int cy, UINT fuFlags) { int hidden; BOOL bMove, bSize, bZorder; MWCOORD offx = 0, offy = 0; /* = 0 for bad gcc warning*/ WINDOWPOS winpos; if(!hwnd || hwnd == rootwp || cx < 0 || cy < 0) return FALSE; /* FIXME SWP_NOACTIVATE*/ if((fuFlags & SWP_SHOWWINDOW)) return ShowWindow(hwnd, SW_SHOW); if((fuFlags & SWP_HIDEWINDOW)) return ShowWindow(hwnd, SW_HIDE); /* move is relative to parent's client rect for child windows*/ if(hwnd->style & WS_CHILD) { x += hwnd->parent->clirect.left; y += hwnd->parent->clirect.top; } else { x += hwnd->parent->winrect.left; y += hwnd->parent->winrect.top; } bMove = !(fuFlags & SWP_NOMOVE) && (hwnd->winrect.left != x || hwnd->winrect.top != y); bSize = !(fuFlags & SWP_NOSIZE) && ((hwnd->winrect.right - hwnd->winrect.left) != cx || (hwnd->winrect.bottom - hwnd->winrect.top) != cy); bZorder = !(fuFlags & SWP_NOZORDER); if(!bMove && !bSize && !bZorder) return TRUE; /* could optimize to not require redraw when possible*/ hidden = hwnd->unmapcount || (fuFlags & SWP_NOREDRAW); if(bZorder) { switch((int)hwndInsertAfter) { case (int)HWND_TOP: MwRaiseWindow(hwnd); break; case (int)HWND_BOTTOM: MwLowerWindow(hwnd); break; default: /* FIXME for non top/bottom zorder*/ break; } } else { if(!hidden) MwHideWindow(hwnd, FALSE, FALSE); } if(bMove) { offx = x - hwnd->winrect.left; offy = y - hwnd->winrect.top; } if(bMove || bSize) { hwnd->winrect.left = x; hwnd->winrect.top = y; hwnd->winrect.right = x + cx; hwnd->winrect.bottom = y + cy; } if(bMove) MwOffsetChildren(hwnd, offx, offy); if(bMove || bSize) { MwCalcClientRect(hwnd); /* send windowposchanged message*/ /* FIXME: move WM_MOVE, WM_SIZE to defwndproc*/ winpos.hwnd = hwnd; winpos.hwndInsertAfter = hwndInsertAfter; winpos.x = x; winpos.y = y; winpos.cx = cx; winpos.cy = cy; winpos.flags = fuFlags; SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos); MwSendSizeMove(hwnd, bSize, bMove); } ++mwpaintSerial; /* increment paint serial # for alphablending*/ ++mwpaintNC; /* increment paint serial # for NC painting*/ hwnd->nEraseBkGnd++; if(!bZorder && !hidden) MwShowWindow(hwnd, FALSE); return TRUE; }