Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

snapshot.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: snapshot.c 00003 * 00004 * Screen/Window SnapShotting Routines 00005 * 00006 * Copyright (c) 1985 - 1999, Microsoft Corporation 00007 * 00008 * History: 00009 * 26-Nov-1991 DavidPe Ported from Win 3.1 sources 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 /***************************************************************************\ 00016 * xxxSnapWindow 00017 * 00018 * Effects: Snaps either the desktop hwnd or the active front most window. If 00019 * any other window is specified, we will snap it but it will be clipped. 00020 * 00021 \***************************************************************************/ 00022 00023 BOOL xxxSnapWindow( 00024 PWND pwnd) 00025 { 00026 PTHREADINFO ptiCurrent; 00027 RECT rc; 00028 HDC hdcScr = NULL; 00029 HDC hdcMem = NULL; 00030 BOOL fRet; 00031 HBITMAP hbmOld; 00032 HBITMAP hbm; 00033 HANDLE hPal; 00034 LPLOGPALETTE lppal; 00035 int palsize; 00036 int iFixedPaletteEntries; 00037 BOOL fSuccess; 00038 PWND pwndT; 00039 TL tlpwndT; 00040 PWINDOWSTATION pwinsta; 00041 TL tlpwinsta; 00042 00043 CheckLock(pwnd); 00044 UserAssert(pwnd); 00045 00046 ptiCurrent = PtiCurrent(); 00047 00048 /* 00049 * If this is a thread of winlogon, don't do the snapshot. 00050 */ 00051 if (GetCurrentProcessId() == gpidLogon) 00052 return FALSE; 00053 00054 /* 00055 * Get the affected windowstation 00056 */ 00057 if (!NT_SUCCESS(ReferenceWindowStation( 00058 PsGetCurrentThread(), 00059 NULL, 00060 WINSTA_READSCREEN, 00061 &pwinsta, 00062 TRUE)) || 00063 pwinsta->dwWSF_Flags & WSF_NOIO) { 00064 return FALSE; 00065 } 00066 00067 /* 00068 * If the window is on another windowstation, do nothing 00069 */ 00070 if (pwnd->head.rpdesk->rpwinstaParent != pwinsta) 00071 return FALSE; 00072 00073 /* 00074 * Get the parent of any child windows. 00075 */ 00076 while ((pwnd != NULL) && TestWF(pwnd, WFCHILD)) { 00077 pwnd = pwnd->spwndParent; 00078 } 00079 00080 /* 00081 * Lock the windowstation before we leave the critical section 00082 */ 00083 ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta); 00084 00085 /* 00086 * Open the clipboard and empty it. 00087 * 00088 * pwndDesktop is made the owner of the clipboard, instead of the 00089 * currently active window; -- SANKAR -- 20th July, 1989 -- 00090 */ 00091 pwndT = ptiCurrent->rpdesk->pDeskInfo->spwnd; 00092 ThreadLockWithPti(ptiCurrent, pwndT, &tlpwndT); 00093 fSuccess = xxxOpenClipboard(pwndT, NULL); 00094 ThreadUnlock(&tlpwndT); 00095 00096 if (!fSuccess) { 00097 ThreadUnlockWinSta(ptiCurrent, &tlpwinsta); 00098 return FALSE; 00099 } 00100 00101 xxxEmptyClipboard(pwinsta); 00102 00103 /* 00104 * Use the whole window. 00105 */ 00106 CopyRect(&rc, &pwnd->rcWindow); 00107 00108 /* 00109 * Only snap what is on the screen. 00110 */ 00111 if (!IntersectRect(&rc, &rc, &gpDispInfo->rcScreen)) { 00112 fRet = FALSE; 00113 goto SnapExit; 00114 } 00115 00116 rc.right -= rc.left; 00117 rc.bottom -= rc.top; 00118 00119 /* 00120 * Figure out how far offset from window origin visible part is 00121 */ 00122 if (pwnd != PWNDDESKTOP(pwnd)) { 00123 rc.left -= pwnd->rcWindow.left; 00124 rc.top -= pwnd->rcWindow.top; 00125 } 00126 00127 /* 00128 * Get the entire window's DC. 00129 */ 00130 hdcScr = _GetWindowDC(pwnd); 00131 if (!hdcScr) 00132 goto MemoryError; 00133 00134 /* 00135 * Create the memory DC. 00136 */ 00137 hdcMem = GreCreateCompatibleDC(hdcScr); 00138 if (!hdcMem) 00139 goto MemoryError; 00140 00141 /* 00142 * Create the destination bitmap. If it fails, then attempt 00143 * to create a monochrome bitmap. 00144 * Did we have enough memory? 00145 */ 00146 00147 if (SYSMET(SAMEDISPLAYFORMAT)) { 00148 hbm = GreCreateCompatibleBitmap(hdcScr, rc.right, rc.bottom); 00149 } else { 00150 hbm = GreCreateBitmap(rc.right, rc.bottom, 1, gpDispInfo->BitCountMax, NULL); 00151 } 00152 00153 if (!hbm) { 00154 hbm = GreCreateBitmap(rc.right, rc.bottom, 1, 1, NULL); 00155 if (!hbm) 00156 goto MemoryError; 00157 } 00158 00159 /* 00160 * Select the bitmap into the memory DC. 00161 */ 00162 hbmOld = GreSelectBitmap(hdcMem, hbm); 00163 00164 /* 00165 * Snap!!! 00166 * Check the return value because the process taking the snapshot 00167 * may not have access to read the screen. 00168 */ 00169 fRet = GreBitBlt(hdcMem, 0, 0, rc.right, rc.bottom, hdcScr, rc.left, rc.top, SRCCOPY | CAPTUREBLT, 0); 00170 00171 /* 00172 * Restore the old bitmap into the memory DC. 00173 */ 00174 GreSelectBitmap(hdcMem, hbmOld); 00175 00176 /* 00177 * If the blt failed, leave now. 00178 */ 00179 if (!fRet) 00180 goto SnapExit; 00181 00182 _SetClipboardData(CF_BITMAP, hbm, FALSE, TRUE); 00183 00184 /* 00185 * If this is a palette device, let's throw the current system palette 00186 * into the clipboard also. Useful if the user just snapped a window 00187 * containing palette colors... 00188 */ 00189 if (TEST_PUSIF(PUSIF_PALETTEDISPLAY)) { 00190 00191 int i; 00192 int iPalSize; 00193 00194 palsize = GreGetDeviceCaps(hdcScr, SIZEPALETTE); 00195 00196 /* 00197 * Determine the number of system colors. 00198 */ 00199 if (GreGetSystemPaletteUse(hdcScr) == SYSPAL_STATIC) 00200 iFixedPaletteEntries = GreGetDeviceCaps(hdcScr, NUMRESERVED); 00201 else 00202 iFixedPaletteEntries = 2; 00203 00204 lppal = (LPLOGPALETTE)UserAllocPoolWithQuota( 00205 (LONG)(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * palsize), 00206 TAG_CLIPBOARD); 00207 00208 if (lppal != NULL) { 00209 lppal->palVersion = 0x300; 00210 lppal->palNumEntries = (WORD)palsize; 00211 00212 if (GreGetSystemPaletteEntries(hdcScr, 00213 0, 00214 palsize, 00215 lppal->palPalEntry)) { 00216 00217 iPalSize = palsize - iFixedPaletteEntries / 2; 00218 00219 for (i = iFixedPaletteEntries / 2; i < iPalSize; i++) { 00220 00221 /* 00222 * Any non system palette enteries need to have the NOCOLLAPSE 00223 * flag set otherwise bitmaps containing different palette 00224 * indices but same colors get messed up. 00225 */ 00226 lppal->palPalEntry[i].peFlags = PC_NOCOLLAPSE; 00227 } 00228 00229 if (hPal = GreCreatePalette(lppal)) 00230 _SetClipboardData(CF_PALETTE, hPal, FALSE, TRUE); 00231 } 00232 00233 UserFreePool(lppal); 00234 } 00235 } 00236 PlayEventSound(USER_SOUND_SNAPSHOT); 00237 00238 fRet = TRUE; 00239 00240 SnapExit: 00241 00242 /* 00243 * Release the window/client DC. 00244 */ 00245 if (hdcScr) { 00246 _ReleaseDC(hdcScr); 00247 } 00248 00249 xxxCloseClipboard(pwinsta); 00250 Unlock(&pwinsta->spwndClipOwner); 00251 00252 /* 00253 * Delete the memory DC. 00254 */ 00255 if (hdcMem) { 00256 GreDeleteDC(hdcMem); 00257 } 00258 00259 ThreadUnlockWinSta(ptiCurrent, &tlpwinsta); 00260 00261 return fRet; 00262 00263 MemoryError: 00264 /* 00265 * Display an error message box. 00266 */ 00267 ClientNoMemoryPopup(); 00268 fRet = FALSE; 00269 goto SnapExit; 00270 }

Generated on Sat May 15 19:41:50 2004 for test by doxygen 1.3.7