HWND uFindParentPopup(HWND wnd_child) { HWND wnd_temp = _GetParent(wnd_child); while (wnd_temp && (GetWindowLong(wnd_temp, GWL_EXSTYLE) & WS_EX_CONTROLPARENT)) { if (GetWindowLong(wnd_temp, GWL_STYLE) & WS_POPUP) break; else wnd_temp = _GetParent(wnd_temp); } return wnd_temp; }
/*****************************************************************************\ * GetAncestor() * * This gets one of: * * The _real_ parent. This does NOT include the owner, unlike * GetParent(). Stops at a top level window unless we start with * the desktop. In which case, we return the desktop. * * The _real_ root, caused by walking up the chain getting the * ancestor. * * The _real_ owned root, caused by GetParent()ing up. \*****************************************************************************/ PWND WINAPI _GetAncestor(PWND pwnd, UINT gaFlags) { PWND pwndParent; /* * If we start with the desktop return NULL. */ if (pwnd == PWNDDESKTOP(pwnd)) return NULL; switch (gaFlags) { case GA_PARENT: pwnd = pwnd->spwndParent; break; case GA_ROOT: while ((pwnd->spwndParent != PWNDDESKTOP(pwnd)) && (pwnd->spwndParent != PWNDMESSAGE(pwnd))) { pwnd = pwnd->spwndParent; } break; case GA_ROOTOWNER: while (pwndParent = _GetParent(pwnd)) { pwnd = pwndParent; } break; } return pwnd; }
//----移动窗口------------------------------------------------------------------ //描述: 移动一个窗口位置,包括子窗口.该函数为内部调用.非线程安全. //参数:hwnd:窗口句柄. // x,y: 相对于父窗口客户区坐标位置. //返回:无. //------------------------------------------------------------------------------ static void _MoveWindow(HWND hwnd,int x,int y) { HWND hParent; POINT pt; if(hwnd == HWND_Desktop) {//桌面不允许移动 return; } pt.x =x; pt.y =y; hParent =_GetParent(hwnd); if(NULL!=hParent) { _ClientToScreen(hParent,&pt,1); } x = pt.x - hwnd->WinRect.left; y = pt.y - hwnd->WinRect.top; _OffsetWindow(hwnd,x,y); }
void CScrollButtonWindow::_OnTimer() { POINT pt = {0, 0}; CScrollBarWindow* pParent = (CScrollBarWindow*)_GetParent(); // more secure w/ dynamic_cast if (pParent == nullptr) { return; } // start another faster timer _StartTimer(_GetScrollSpeed()); GetCursorPos(&pt); MapWindowPoints(HWND_DESKTOP, pParent->_GetWnd(), &pt, 1); RECT rc = {0, 0, 0, 0}; _GetClientRect(&rc); if (PtInRect(&rc, pt)) { switch (subTypeOfControl) { case DFCS_SCROLLDOWN: _NotifyCommand(WM_VSCROLL, SB_LINEDOWN, 0); pParent->_ShiftLine(+1, FALSE); break; case DFCS_SCROLLUP: _NotifyCommand(WM_VSCROLL, SB_LINEUP, 0); pParent->_ShiftLine(-1, FALSE); break; } } }
//----获得父窗口----------------------------------------------------------------- //描述: 略 //参数:hwnd:窗口句柄 //返回:父窗口句柄. //------------------------------------------------------------------------------ HWND GetParent(HWND hwnd) { HWND wnd=NULL; if(HWND_Lock(hwnd)) { wnd= _GetParent(hwnd); HWND_Unlock(hwnd); } return wnd; }
void CScrollBarWindow::_AdjustWindowPos() { if (!IsWindow(_GetWnd())) { return; } RECT rc = {0, 0, 0, 0}; CBaseWindow* pParent = _GetParent(); if (pParent == nullptr) { return; } GetWindowRect(pParent->_GetWnd(), &rc); SetWindowPos(_GetWnd(), pParent->_GetWnd(), rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOOWNERZORDER | SWP_NOACTIVATE); }
void CScrollButtonWindow::_OnLButtonDown(POINT pt) { CButtonWindow::_OnLButtonDown(pt); CScrollBarWindow* pParent = (CScrollBarWindow*)_GetParent(); // more secure w/ dynamic_cast if (pParent == nullptr) { return; } switch (subTypeOfControl) { case DFCS_SCROLLDOWN: _NotifyCommand(WM_VSCROLL, SB_LINEDOWN, 0); pParent->_ShiftLine(+1, FALSE); break; case DFCS_SCROLLUP: _NotifyCommand(WM_VSCROLL, SB_LINEUP, 0); pParent->_ShiftLine(-1, FALSE); break; } _StartTimer(_GetScrollDelay()); }
/* * Modal loop for when the user has selected the help icon from the titlebar * */ VOID xxxHelpLoop(PWND pwnd) { HWND hwndChild; PWND pwndChild; PWND pwndControl; MSG msg; RECT rc; int cBorders; PTHREADINFO ptiCurrent = PtiCurrent(); DLGENUMDATA DlgEnumData; TL tlpwndChild; CheckLock(pwnd); UserAssert(IsWinEventNotifyDeferredOK()); if (FWINABLE()) { xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPSTART, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0); } zzzSetCursor(SYSCUR(HELP)); xxxCapture(ptiCurrent, pwnd, SCREEN_CAPTURE); cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); CopyInflateRect(&rc, &pwnd->rcWindow, -cBorders * SYSMET(CXBORDER), -cBorders * SYSMET(CYBORDER)); while (ptiCurrent->pq->spwndCapture == pwnd) { if (!xxxPeekMessage(&msg, NULL, 0, 0, PM_NOYIELD | PM_NOREMOVE)) { xxxWaitMessage(); continue; } if (msg.message == WM_NCLBUTTONDOWN) { break; } else if (msg.message == WM_LBUTTONDOWN) { /* * If user clicked outside of window client, bail out now. */ if (!PtInRect(&rc, msg.pt)) break; /* * WindowHitTest() won't return a static control's handle */ hwndChild = xxxWindowHitTest(pwnd, msg.pt, NULL, 0); pwndChild = ValidateHwnd( hwndChild ); ThreadLock(pwndChild, &tlpwndChild); if (pwndChild && FIsParentDude(pwndChild)) { /* * If this is a dialog class, then one of three things has * happened: * * o This is a static text control * o This is the background of the dialog box. * * What we do is enumerate the child windows and see if * any of them contain the current cursor point. If they do, * change our window handle and continue on. Otherwise, * return doing nothing -- we don't want context-sensitive * help for a dialog background. * * If this is a group box, then we might have clicked on a * disabled control, so we enumerate child windows to see * if we get another control. */ /* * We're enumerating a dialog's children. So, if we don't * find any matches, hwndChild will be NULL and the check * below will drop out. */ DlgEnumData.pwndDialog = pwndChild; DlgEnumData.pwndControl = NULL; DlgEnumData.ptCurHelp = msg.pt; xxxInternalEnumWindow(pwndChild, EnumPwndDlgChildProc, (LPARAM)&DlgEnumData, BWL_ENUMCHILDREN); pwndControl = DlgEnumData.pwndControl; } else { pwndControl = pwndChild; } /* * If we click on nothing, just exit. */ if (pwndControl == pwnd) { pwndControl = NULL; } /* * HACK ALERT (Visual Basic 4.0) - they have their own non-window * based controls that draw directly on the main dialog. In order * to provide help for these controls, we pass along the WM_HELP * message iff the main dialog has a context id assigned. * * If the top level window has its own context help ID, * then pass it in the context help message. */ if (!pwndControl) { if (_GetProp(pwnd, MAKEINTATOM(gpsi->atomContextHelpIdProp), TRUE)) pwndControl = pwnd; } if (pwndControl) { PWND pwndSend; int id; TL tlpwndSend; TL tlpwndControl; ThreadLockAlways(pwndControl, &tlpwndControl); zzzSetCursor(SYSCUR(ARROW)); xxxReleaseCapture(); xxxRedrawTitle(pwnd, DC_BUTTONS); ClrWF(pwnd, WFHELPBUTTONDOWN); xxxGetMessage(&msg, NULL, 0, 0); if (FWINABLE()) { xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, INDEX_TITLEBAR_HELPBUTTON, FALSE); xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, FALSE); } /* * Determine the ID of the control * We used to always sign extend, but Win98 doesn't do that * so we only sign extend 0xffff. MCostea #218711 */ if (TestwndChild(pwndControl)) { id = PTR_TO_ID(pwndControl->spmenu); if (id == 0xffff) { id = -1; } } else { id = -1; } /* * Disabled controls and static controls won't pass this * on to their parent, so instead, we send the message to * their parent. */ if (TestWF(pwndControl, WFDISABLED)) { PWND pwndParent = _GetParent(pwndControl); if (!pwndParent) { ThreadUnlock( &tlpwndControl ); ThreadUnlock( &tlpwndChild ); return; } pwndSend = pwndParent; } else { pwndSend = pwndControl; } ThreadLockAlways(pwndSend, &tlpwndSend); xxxSendHelpMessage( pwndSend, HELPINFO_WINDOW, id, (HANDLE)HWq(pwndControl), GetContextHelpId(pwndControl)); ThreadUnlock(&tlpwndSend); ThreadUnlock(&tlpwndControl); ThreadUnlock(&tlpwndChild); return; } ThreadUnlock(&tlpwndChild); break; } else if ((msg.message == WM_RBUTTONDOWN) || (msg.message == WM_MBUTTONDOWN) || (msg.message == WM_XBUTTONDOWN)) { /* * fix bug 29852; break the loop for right and middle buttons * and pass along the messages to the control */ break; } else if (msg.message == WM_MOUSEMOVE) { if (PtInRect(&rc, msg.pt)) zzzSetCursor(SYSCUR(HELP)); else zzzSetCursor(SYSCUR(ARROW)); } else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) { xxxGetMessage( &msg, NULL, 0, 0 ); break; } xxxGetMessage(&msg, NULL, 0, 0); xxxTranslateMessage(&msg, 0); xxxDispatchMessage(&msg); } xxxReleaseCapture(); zzzSetCursor(SYSCUR(ARROW)); xxxRedrawTitle(pwnd, DC_BUTTONS); ClrWF(pwnd, WFHELPBUTTONDOWN); if (FWINABLE()) { xxxWindowEvent(EVENT_OBJECT_STATECHANGE, pwnd, OBJID_TITLEBAR, INDEX_TITLEBAR_HELPBUTTON, 0); xxxWindowEvent(EVENT_SYSTEM_CONTEXTHELPEND, pwnd, OBJID_WINDOW, INDEXID_CONTAINER, 0); } }