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 
00050 
00051     
if (
GetCurrentProcessId() == 
gpidLogon)
00052         
return FALSE;
00053 
00054     
00055 
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 
00069 
00070     
if (pwnd->
head.rpdesk->rpwinstaParent != pwinsta)
00071         
return FALSE;
00072 
00073     
00074 
00075 
00076     
while ((pwnd != 
NULL) && 
TestWF(pwnd, WFCHILD)) {
00077         pwnd = pwnd->
spwndParent;
00078     }
00079 
00080     
00081 
00082 
00083     
ThreadLockWinSta(ptiCurrent, pwinsta, &tlpwinsta);
00084 
00085     
00086 
00087 
00088 
00089 
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 
00105 
00106     
CopyRect(&rc, &pwnd->
rcWindow);
00107 
00108     
00109 
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 
00121 
00122     
if (pwnd != 
PWNDDESKTOP(pwnd)) {
00123         rc.left -= pwnd->
rcWindow.left;
00124         rc.top -= pwnd->
rcWindow.top;
00125     }
00126 
00127     
00128 
00129 
00130     hdcScr = 
_GetWindowDC(pwnd);
00131     
if (!hdcScr)
00132         
goto MemoryError;
00133 
00134     
00135 
00136 
00137     hdcMem = GreCreateCompatibleDC(hdcScr);
00138     
if (!hdcMem)
00139         
goto MemoryError;
00140 
00141     
00142 
00143 
00144 
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 
00161 
00162     hbmOld = GreSelectBitmap(hdcMem, hbm);
00163 
00164     
00165 
00166 
00167 
00168 
00169     fRet = GreBitBlt(hdcMem, 0, 0, rc.right, rc.bottom, hdcScr, rc.left, rc.top, SRCCOPY | CAPTUREBLT, 0);
00170 
00171     
00172 
00173 
00174     GreSelectBitmap(hdcMem, hbmOld);
00175 
00176     
00177 
00178 
00179     
if (!fRet)
00180         
goto SnapExit;
00181 
00182     
_SetClipboardData(CF_BITMAP, hbm, FALSE, TRUE);
00183 
00184     
00185 
00186 
00187 
00188 
00189     
if (
TEST_PUSIF(PUSIF_PALETTEDISPLAY)) {
00190 
00191         
int i;
00192         
int iPalSize;
00193 
00194         palsize = GreGetDeviceCaps(hdcScr, SIZEPALETTE);
00195 
00196         
00197 
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 
00223 
00224 
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 
00244 
00245      
if (hdcScr) {
00246          
_ReleaseDC(hdcScr);
00247      }
00248 
00249     
xxxCloseClipboard(pwinsta);
00250     
Unlock(&pwinsta->
spwndClipOwner);
00251 
00252     
00253 
00254 
00255     
if (hdcMem) {
00256         GreDeleteDC(hdcMem);
00257     }
00258 
00259     
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
00260 
00261     
return fRet;
00262 
00263 MemoryError:
00264     
00265 
00266 
00267     
ClientNoMemoryPopup();
00268     fRet = 
FALSE;
00269     
goto SnapExit;
00270 }