PWND xxxSetCapture( PWND pwnd) { PQ pq; PWND pwndCaptureOld; HWND hwndCaptureOld; pq = (PQ)PtiCurrent()->pq; /* * Don't allow the app to set capture to a window * from another queue. */ if ((pwnd != NULL) && GETPTI(pwnd)->pq != pq) return NULL; /* * If full screen capture don't allow any other capture */ if (gspwndScreenCapture) return NULL; pwndCaptureOld = pq->spwndCapture; hwndCaptureOld = HW(pwndCaptureOld); xxxCapture(PtiCurrent(), pwnd, CLIENT_CAPTURE); if (hwndCaptureOld != NULL) { if (RevalidateHwnd(hwndCaptureOld)) return pwndCaptureOld; } return NULL; }
/***************************************************************************\ * xxxMessageEvent * * Description: Called when a hooked DDE message is sent or posted. flags * specifies the applicable MF_ flag. This is called in the server side * context of the sender or poster which may or may not be a DDEML process. * pdmhd contains DDE data extracted and copied from the client side. * * History: * 12-1-91 sanfords Created. \***************************************************************************/ VOID xxxMessageEvent( PWND pwndTo, UINT message, WPARAM wParam, LPARAM lParam, DWORD flag, PDDEML_MSG_HOOK_DATA pdmhd) { PEVENT_PACKET pep; PWND pwndFrom; TL tlpep; PTHREADINFO pti; CheckCritIn(); pep = (PEVENT_PACKET)UserAllocPoolWithQuota(sizeof(EVENT_PACKET) - sizeof(DWORD) + sizeof(MONMSGSTRUCT), TAG_DDE8); if (pep == NULL) { return; } pep->EventType = flag; pep->fSense = TRUE; pep->cbEventData = sizeof(MONMSGSTRUCT); #define pmsgs ((MONMSGSTRUCT *)&pep->Data) pmsgs->cb = sizeof(MONMSGSTRUCT); pmsgs->hwndTo = PtoH(pwndTo); pmsgs->dwTime = NtGetTickCount(); pwndFrom = RevalidateHwnd((HWND)wParam); if (pwndFrom != NULL) { pmsgs->hTask = GETPTI(pwndFrom)->pEThread->Cid.UniqueThread; } else { pmsgs->hTask = 0; } pmsgs->wMsg = message; pmsgs->wParam = wParam; pmsgs->lParam = lParam; if (pdmhd != NULL) { pmsgs->dmhd = *pdmhd; } #undef pmsgs pti = PtiCurrent(); ThreadLockPool(pti, pep, &tlpep); xxxCsEvent(pep, sizeof(MONMSGSTRUCT)); ThreadUnlockAndFreePool(pti, &tlpep); }
LONG SfnINLBOXSTRING( PWND pwnd, UINT msg, DWORD wParam, LONG lParam, DWORD xParam, PROC xpfn, DWORD dwSCMSFlags, PSMS psms) { DWORD dw; /* * See if the control is ownerdraw and does not have the LBS_HASSTRINGS * style. If so, treat lParam as a DWORD. */ if (!RevalidateHwnd(HW(pwnd))) { return 0L; } dw = pwnd->style; if (!(dw & LBS_HASSTRINGS) && (dw & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))) { /* * Treat lParam as a dword. */ return SfnDWORD(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms); } /* * Treat as a string pointer. Some messages allowed or had certain * error codes for NULL so send them through the NULL allowed thunk. * Ventura Publisher does this */ switch (msg) { default: return SfnINSTRING(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms); break; case LB_FINDSTRING: return SfnINSTRINGNULL(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms); break; } }
LONG SfnOUTLBOXSTRING( PWND pwnd, UINT msg, DWORD wParam, LONG lParam, DWORD xParam, PROC xpfn, DWORD dwSCMSFlags, PSMS psms) { DWORD dw; BOOL bNotString; DWORD dwRet; TL tlpwnd; /* * See if the control is ownerdraw and does not have the LBS_HASSTRINGS * style. If so, treat lParam as a DWORD. */ if (!RevalidateHwnd(HW(pwnd))) { return 0L; } dw = pwnd->style; /* * See if the control is ownerdraw and does not have the LBS_HASSTRINGS * style. If so, treat lParam as a DWORD. */ bNotString = (!(dw & LBS_HASSTRINGS) && (dw & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))); /* * Make this special call which'll know how to copy this string. */ ThreadLock(pwnd, &tlpwnd); dwRet = ClientGetListboxString(pwnd, msg, wParam, (PLARGE_UNICODE_STRING)lParam, xParam, xpfn, dwSCMSFlags, bNotString, psms); ThreadUnlock(&tlpwnd); return dwRet; }
void xxxShowOwnedWindows( PWND pwndOwner, UINT cmdShow) { BOOL fShow; int cmdZoom; HWND *phwnd; PBWL pbwl; PWND pwnd, pwndTopOwner; TL tlpwnd; CheckLock(pwndOwner); /* * Not interested in child windows */ if (TestwndChild(pwndOwner)) return; if ((pbwl = BuildHwndList(PWNDDESKTOP(pwndOwner)->spwndChild, BWL_ENUMLIST, NULL)) == NULL) return; /* * NOTE: The following code assumes the values of SW_* are 1, 2, 3, and 4 */ fShow = (cmdShow >= SW_PARENTOPENING); cmdZoom = 0; if (cmdShow == SW_OTHERZOOM) cmdZoom = SIZEZOOMHIDE; if (cmdShow == SW_OTHERUNZOOM) cmdZoom = SIZEZOOMSHOW; /* * If zoom/unzoom, then open/close all popups owned by all other * windows. Otherwise, open/close popups owned by pwndOwner. */ for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { /* * Lock the window before we play with it. * If the window handle is invalid, skip it */ if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) continue; /* * Kanji windows can't be owned, so skip it. */ if (TestCF(pwnd, CFKANJIWINDOW)) continue; /* * If same as window passed in, skip it. */ if (pwnd == pwndOwner) continue; /* * Find ultimate owner of popup, but only go up as far as pwndOwner. */ if ((pwndTopOwner = pwnd->spwndOwner) != NULL) { /* * The TestwndHI is needed since if it has an icon, pwndOwner * is invalid. */ while (!TestwndHI(pwndTopOwner) && pwndTopOwner != pwndOwner && pwndTopOwner->spwndOwner != NULL) pwndTopOwner = pwndTopOwner->spwndOwner; } /* * Zoom/Unzoom case. */ if (cmdZoom != 0) { /* * If no parent, or parents are the same, skip. */ if (pwndTopOwner == NULL || pwndTopOwner == pwndOwner) continue; /* * If owner is iconic, then this window should stay hidden, * UNLESS the minimized window is disabled, in which case we'd * better show the window. */ if ( cmdShow == SW_OTHERUNZOOM && pwndTopOwner != NULL && TestWF(pwndTopOwner, WFMINIMIZED) && !TestWF(pwndTopOwner, WFDISABLED) ) continue; } else { /* * Hide/Iconize/Show/Open case. */ /* * If parents aren't the same, skip. */ if (pwndTopOwner != pwndOwner) continue; } /* * Hide or show if: * Showing & this is a hidden popup * OR * Hiding & this is a visible window */ if ((fShow && TestWF(pwnd, WFHIDDENPOPUP)) || (!fShow && TestWF(pwnd, WFVISIBLE))) { ThreadLockAlways(pwnd, &tlpwnd); xxxSendMessage(pwnd, WM_SHOWWINDOW, fShow, (LONG)cmdShow); ThreadUnlock(&tlpwnd); } } /* * Free the window list. */ FreeHwndList(pbwl); }
VOID xxxInternalDoSyncPaint( PWND pwnd, DWORD flags) { CheckLock(pwnd); /* * Do the paint for this window. */ xxxSimpleDoSyncPaint(pwnd); /* * Normally we like to enumerate all of this window's children and have * them erase their backgrounds synchronously. However, this is a bad * thing to do if the window is NOT CLIPCHLIDREN. Here's the scenario * we want to to avoid: * * 1) Window 'A' is invalidated * 2) 'A' erases itself (or not, doesn't matter) * 3) 'A's children are enumerated and they erase themselves. * 4) 'A' paints over its children (remember, 'A' isn't CLIPCHILDREN) * 5) 'A's children paint but their backgrounds aren't their ERASEBKND * color (because 'A' painted over them) and everything looks like * dirt. */ if ((flags & DSP_ALLCHILDREN) || ((flags & DSP_ENUMCLIPPEDCHILDREN) && TestWF(pwnd, WFCLIPCHILDREN))) { TL tlpwnd; PBWL pbwl; HWND *phwnd; if (pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL)) { PTHREADINFO ptiCurrent = PtiCurrent(); HWND hwnd; /* * If the client dies during a callback, the hwnd list * will be freed in xxxDestroyThreadInfo. */ for (phwnd = pbwl->rghwnd; (hwnd = *phwnd) != (HWND)1; phwnd++) { if (hwnd == NULL) continue; if ((pwnd = (PWND)RevalidateHwnd(hwnd)) == NULL) continue; /* * Note: testing if a window is a child automatically * excludes the desktop window. */ if (TestWF(pwnd, WFCHILD) && (ptiCurrent != GETPTI(pwnd))) { /* * Don't cause any more intertask sendmessages cause it * does bad things to cbt's windowproc hooks. (Due to * SetParent allowing child windows in the topwindow * hierarchy. */ continue; } /* * Note that we pass only certain bits down as we recurse: * the other bits pertain to the current window only. */ ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); xxxInternalDoSyncPaint(pwnd, flags); ThreadUnlock(&tlpwnd); } FreeHwndList(pbwl); } } }
BOOL xxxClientShutdown2( PBWL pbwl, UINT msg, DWORD wParam) { HWND *phwnd; PWND pwnd; TL tlpwnd; BOOL fEnd; PTHREADINFO ptiCurrent; BOOL fDestroyTimers; LPARAM lParam; ptiCurrent = PtiCurrent(); /* * Make sure we don't send this window any more WM_TIMER * messages if the session is ending. This was causing * AfterDark to fault when it freed some memory on the * WM_ENDSESSION and then tried to reference it on the * WM_TIMER. * LATER GerardoB: Do we still need to do this?? * Do this horrible thing only if the process is in the * context being logged off. * Perhaps someday we should post a WM_CLOSE so the app * gets a better chance to clean up (if this process is in * the context being logged off, winsrv is going to call * TerminateProcess soon after this). */ fDestroyTimers = (wParam & WMCS_EXIT) && (wParam & WMCS_CONTEXTLOGOFF); /* * fLogOff and fEndSession parameters (WM_ENDSESSION only) */ lParam = wParam & ENDSESSION_LOGOFF; wParam &= WMCS_EXIT; /* * Now enumerate these windows and send the WM_QUERYENDSESSION or * WM_ENDSESSION messages. */ for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) continue; ThreadLockAlways(pwnd, &tlpwnd); /* * Send the message. */ switch (msg) { case WM_QUERYENDSESSION: /* * Windows does not send the WM_QUERYENDSESSION to the app * that called ExitWindows */ if (ptiCurrent == gptiShutdownNotify) { fEnd = TRUE; } else { fEnd = xxxSendMessage(pwnd, WM_QUERYENDSESSION, FALSE, lParam); } break; case WM_ENDSESSION: xxxSendMessage(pwnd, WM_ENDSESSION, wParam, lParam); fEnd = TRUE; if (fDestroyTimers) { DestroyWindowsTimers(pwnd); } break; } ThreadUnlock(&tlpwnd); if (!fEnd) return FALSE; } return TRUE; }
UINT xxxArrangeIconicWindows( PWND pwnd) { PBWL pbwl; PSMWP psmwp; PWND pwndTest, pwndSort, pwndSwitch; HWND *phwnd, *phwndSort; CHECKPOINT *pcp, *pcpSort; POINT ptSort, ptSrc; WORD nIcons = 0; RECT rc; POINT ptMin; int xOrg, yOrg; int dx, dy; int dxSlot, dySlot; int cIconsPerPass, iIconPass; BOOL fHorizontal, fBreak; TL tlpwndTest; BOOL fHideMe; CheckLock(pwnd); /* * Create a window list of all children of pwnd */ if ((pbwl = BuildHwndList(pwnd->spwndChild, BWL_ENUMLIST, NULL)) == NULL) return 0; fHideMe = IsTrayWindow(pwnd->spwndChild); // // Put these into local vars for efficiency (see ParkIcon()) // dxSlot = SYSMET(CXMINSPACING); dySlot = SYSMET(CYMINSPACING); // // We need to adjust the client rectangle if the parent has scrollbars. // GetRealClientRect(pwnd, &rc, GRC_SCROLLS); /* * find all icons */ pwndSwitch = RevalidateHwnd(ghwndSwitch); for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { if (((pwndTest = RevalidateHwnd(*phwnd)) == NULL) || !TestWF(pwndTest , WFVISIBLE) || pwndTest == pwndSwitch || (pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT, PROPF_INTERNAL)) == NULL) { *phwnd = NULL; continue; } if (!TestWF(pwndTest, WFMINIMIZED)) { pcp->fMinInitialized = FALSE; pcp->ptMin.x = pcp->ptMin.y = -1; *phwnd = NULL; continue; } /* * inc count of icons */ nIcons++; /* * we will park in default position again... */ pcp->fDragged = FALSE; /* * ensure the original position is up to date */ pcp->ptMin.x = pwndTest->rcWindow.left - pwnd->rcClient.left; pcp->ptMin.y = pwndTest->rcWindow.top - pwnd->rcClient.top; // Slide into the nearest row or column switch (SYSMET(ARRANGE) & ~ARW_HIDE) { case ARW_TOPLEFT | ARW_RIGHT: case ARW_TOPRIGHT | ARW_LEFT: // Slide into top row pcp->ptMin.y += dySlot / 2; pcp->ptMin.y -= pcp->ptMin.y % dySlot; break; case ARW_TOPLEFT | ARW_DOWN: case ARW_BOTTOMLEFT | ARW_UP: // Slide into left column pcp->ptMin.x += dxSlot / 2; pcp->ptMin.x -= pcp->ptMin.x % dxSlot; break; case ARW_BOTTOMLEFT | ARW_RIGHT: case ARW_BOTTOMRIGHT | ARW_LEFT: // Slide into bottom row pcp->ptMin.y = rc.bottom - pcp->ptMin.y; pcp->ptMin.y += dySlot / 2; pcp->ptMin.y -= pcp->ptMin.y % dySlot; pcp->ptMin.y = rc.bottom - pcp->ptMin.y; break; case ARW_BOTTOMRIGHT | ARW_UP: case ARW_TOPRIGHT | ARW_DOWN: // Slide into right column pcp->ptMin.x = rc.right - pcp->ptMin.x; pcp->ptMin.x += dxSlot / 2; pcp->ptMin.x -= pcp->ptMin.x % dxSlot; pcp->ptMin.x = rc.right - pcp->ptMin.x; break; } } if (nIcons == 0) { /* * no icons were found... break out */ FreeHwndList(pbwl); return 0; } if (fHideMe) { ptMin.x = WHERE_NOONE_CAN_SEE_ME; ptMin.y = WHERE_NOONE_CAN_SEE_ME; goto JustParkEm; } // // Get gravity && move vars // if (SYSMET(ARRANGE) & ARW_STARTRIGHT) { // Starting on right side ptMin.x = xOrg = rc.right - dxSlot; dx = -dxSlot; } else { // Starting on left ptMin.x = xOrg = rc.left + DX_GAP; dx = dxSlot; } if (SYSMET(ARRANGE) & ARW_STARTTOP) { // Starting on top ptMin.y = yOrg = rc.top + DY_GAP; dy = dySlot; } else { // Starting on bottom ptMin.y = yOrg = rc.bottom - dySlot; dy = -dySlot; } // // Get arrange dir // fHorizontal = ( (SYSMET(ARRANGE) & ARW_DOWN) ? FALSE : TRUE ); iIconPass = fHorizontal ? (rc.right / dxSlot) : (rc.bottom / dySlot); cIconsPerPass = iIconPass = max(1, iIconPass); /* * insertion sort of windows by y, and by x within a row. */ for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { /* * Check for 0 (window was not icon) and * Check for invalid HWND (window has been destroyed) */ if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL) continue; pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT, PROPF_INTERNAL); ptSrc = pcp->ptMin; fBreak = FALSE; for (phwndSort = pbwl->rghwnd; phwndSort < phwnd; phwndSort++) { if (*phwndSort == NULL || (pwndSort = RevalidateHwnd(*phwndSort)) == NULL) continue; pcpSort = (CHECKPOINT*)_GetProp(pwndSort, PROP_CHECKPOINT, PROPF_INTERNAL); ptSort = pcpSort->ptMin; // // Is this the position in which to sort this min window? // switch (SYSMET(ARRANGE) & ~ARW_HIDE) { case ARW_BOTTOMLEFT | ARW_RIGHT: // Lower left, moving horizontally if (((ptSort.y == ptSrc.y) && (ptSort.x > ptSrc.x)) || (ptSort.y < ptSrc.y)) fBreak = TRUE; break; case ARW_BOTTOMLEFT | ARW_UP: // Lower left, moving vertically if (((ptSort.x == ptSrc.x) && (ptSort.y < ptSrc.y)) || (ptSort.x > ptSrc.x)) fBreak = TRUE; break; case ARW_BOTTOMRIGHT | ARW_LEFT: // Lower right, moving horizontally if (((ptSort.y == ptSrc.y) && (ptSort.x < ptSrc.x)) || (ptSort.y < ptSrc.y)) fBreak = TRUE; break; case ARW_BOTTOMRIGHT | ARW_UP: // Lower right, moving vertically if (((ptSort.x == ptSrc.x) && (ptSort.y < ptSrc.y)) || (ptSort.x < ptSrc.x)) fBreak = TRUE; break; case ARW_TOPLEFT | ARW_RIGHT: // Top left, moving horizontally if (((ptSort.y == ptSrc.y) && (ptSort.x > ptSrc.x)) || (ptSort.y > ptSrc.y)) fBreak = TRUE; break; case ARW_TOPLEFT | ARW_DOWN: // Top left, moving vertically if (((ptSort.x == ptSrc.x) && (ptSort.y > ptSrc.y)) || (ptSort.x > ptSrc.x)) fBreak = TRUE; break; case ARW_TOPRIGHT | ARW_LEFT: // Top right, moving horizontally if (((ptSort.y == ptSrc.y) && (ptSort.x < ptSrc.x)) || (ptSort.y > ptSrc.y)) fBreak = TRUE; break; case ARW_TOPRIGHT | ARW_DOWN: // Top right, moving vertically if (((ptSort.x == ptSrc.x) && (ptSort.y > ptSrc.y)) || (ptSort.x < ptSrc.x)) fBreak = TRUE; break; } if (fBreak) break; } /* * insert the window at this position by sliding the rest up. * LATER IanJa, use hwnd intermediate variables, avoid PW() & HW() */ while (phwndSort < phwnd) { pwndSort = PW(*phwndSort); *phwndSort = HW(pwndTest); pwndTest = pwndSort; phwndSort++; } /* * replace the window handle in the original position */ *phwnd = HW(pwndTest); } // // Now park the icons. // JustParkEm: for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL) continue; if (fHideMe) { pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT, PROPF_INTERNAL); if (pcp != NULL) { pcp->fMinInitialized = TRUE; pcp->ptMin.x = ptMin.x; pcp->ptMin.y = ptMin.y; } continue; } pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT, PROPF_INTERNAL); if (pcp != NULL) { pcp->fMinInitialized = TRUE; pcp->ptMin.x = ptMin.x; pcp->ptMin.y = ptMin.y; } // Setup to process the next position if (--iIconPass <= 0) { // Need to setup next pass iIconPass = cIconsPerPass; if (fHorizontal) { ptMin.x = xOrg; ptMin.y += dy; } else { ptMin.x += dx; ptMin.y = yOrg; } } else { // Same pass if (fHorizontal) ptMin.x += dx; else ptMin.y += dy; } } psmwp = _BeginDeferWindowPos(2 * nIcons); if (psmwp == NULL) goto ParkExit; for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { /* * Check for a NULL (window has gone away) */ if (*phwnd == NULL || (pwndTest = RevalidateHwnd(*phwnd)) == NULL) continue; pcp = (CHECKPOINT *)_GetProp(pwndTest, PROP_CHECKPOINT, PROPF_INTERNAL); ThreadLockAlways(pwndTest, &tlpwndTest); psmwp = _DeferWindowPos(psmwp, pwndTest, NULL, pcp->ptMin.x, pcp->ptMin.y, rgptMinMaxWnd[MMI_MINSIZE].x, rgptMinMaxWnd[MMI_MINSIZE].y, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS); ThreadUnlock(&tlpwndTest); if (psmwp == NULL) break; } if (psmwp != NULL) { /* * Make the swp async so we don't hang waiting for hung apps. */ xxxEndDeferWindowPosEx(psmwp, TRUE); } ParkExit: FreeHwndList(pbwl); return nIcons; }