HWND WINAPI SetFocus(HWND hwnd) { HWND oldfocus; HWND top, top2; /* if NULL or hidden, set focus to desktop*/ if(!hwnd || hwnd->unmapcount) hwnd = rootwp; if(hwnd == focuswp) return focuswp; oldfocus = focuswp; top = MwGetTopWindow(oldfocus); top2 = MwGetTopWindow(hwnd); SendMessage(oldfocus, WM_KILLFOCUS, (WPARAM)hwnd, 0L); /* send deactivate. Note: should be sent before changing the focuswp var*/ if(top2 != top) SendMessage(top, WM_ACTIVATE, (WPARAM)MAKELONG(WA_INACTIVE, 0), (LPARAM)top2); focuswp = hwnd; SendMessage(focuswp, WM_SETFOCUS, (WPARAM)oldfocus, 0L); /* FIXME SetActiveWindow() here?*/ if(top2 != top) { /* repaint captions*/ MwPaintNCArea(top); #if 0 /* Make sure that caption area is fully invalidated, * as repaint will be in active color. * FIXME: this doesn't work; breaks terminal emulator * on focus out/in */ MwUnionUpdateRegion(top2, 0, 0, top2->winrect.right-top2->winrect.left, mwSYSMETRICS_CYCAPTION+4, TRUE); #endif /* send activate*/ SendMessage(top2, WM_ACTIVATE, (WPARAM)MAKELONG(WA_ACTIVE, 0), (LPARAM)top); MwPaintNCArea(top2); } return oldfocus; }
/* setting the foreground window sets focus and moves window to top*/ BOOL WINAPI SetForegroundWindow(HWND hwnd) { /* activate (set focus to) specified window*/ SetFocus(hwnd); /* raise top level parent to top of z order*/ SetWindowPos(MwGetTopWindow(hwnd), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); return TRUE; }
void MwDeliverMouseEvent(int buttons, int changebuttons, MWKEYMOD modifiers) { HWND hwnd, top; int hittest; UINT msg; mwCurrentModifiers = modifiers; hwnd = GetCapture(); if(!hwnd) hwnd = mousewp; /* if wnd is disabled, or window is child and parent disabled, do nothing*/ if( hwnd == NULL || !IsWindowEnabled(hwnd) ) return; top = MwGetTopWindow(hwnd); if( top != NULL && !IsWindowEnabled(top) ) return; hittest = SendMessage(hwnd, WM_NCHITTEST, 0, MAKELONG(cursorx,cursory)); if(!changebuttons) MwTranslateMouseMessage(hwnd, WM_MOUSEMOVE, hittest, buttons); if(changebuttons & MWBUTTON_L) { msg = (buttons&MWBUTTON_L)? WM_LBUTTONDOWN: WM_LBUTTONUP; MwTranslateMouseMessage(hwnd, msg, hittest, buttons); } if(changebuttons & MWBUTTON_M) { msg = (buttons&MWBUTTON_M)? WM_MBUTTONDOWN: WM_MBUTTONUP; MwTranslateMouseMessage(hwnd, msg, hittest, buttons); } if(changebuttons & MWBUTTON_R) { msg = (buttons&MWBUTTON_R)? WM_RBUTTONDOWN: WM_RBUTTONUP; MwTranslateMouseMessage(hwnd, msg, hittest, buttons); } }
/* The active window is the first non-child ancestor of focus window*/ HWND WINAPI GetActiveWindow(VOID) { return MwGetTopWindow(focuswp); }
/* * 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); }