Потребовалось сделать программку повторяющую функционал кнопки «PrintScreen» - считать битмэп рабочего стола в память. Делалось так (упрощённо): Код (Text): BITMAPINFO bi; ... ... dc = CreateDC ("DISPLAY", NULL, NULL, NULL); // или dc = GetDC(GetDesktopWindow()); mdc = CreateCompatibleDC (dc); X_MAX = GetSystemMetrics (SM_CXSCREEN); Y_MAX = GetSystemMetrics (SM_CYSCREEN); BPP = (unsigned short) GetDeviceCaps (dc, BITSPIXEL); if (BPP == 32) BPP = 24; // экономим память. :) PLS = (unsigned short) GetDeviceCaps (dc, PLANES); BPP *= PLS; i = ((X_MAX * tBPP / 8) * Y_MAX); if (tBPP <= 8) { nColors = (unsigned short) (1 << tBPP); i += (nColors << 2); } hMem = GlobalAlloc (GPTR, i); if (hMem == 0) return; bbuff = GlobalLock (hMem); if (bbuff == 0) return; bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bi.bmiHeader.biWidth = X_MAX; bi.bmiHeader.biHeight = Y_MAX; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = tBPP; bi.bmiHeader.biCompression = BI_RGB; if (tBPP <= 8) { pLogPal = malloc (sizeof (LOGPALETTE) + (nColors * sizeof (PALETTEENTRY))); pLogPal->palVersion = 0x300; pLogPal->palNumEntries = nColors; } hbm = CreateCompatibleBitmap (dc, X_MAX, Y_MAX); if (tBPP == 8) { GetSystemPaletteEntries(dc,0,nColors,pLogPal->palPalEntry); for (p=0;p<(nColors-20);p++) pLogPal->palPalEntry[p+10].peFlags = PC_NOCOLLAPSE; hPal = CreatePalette(pLogPal); SelectPalette(mdc,hPal,FALSE); RealizePalette(mdc); } ohbm = SelectObject (mdc, hbm); BitBlt (mdc, 0, 0, X_MAX, Y_MAX, dc, 0, 0, SRCCOPY); SelectObject (mdc, ohbm); if (GetDIBits(mdc, hbm, 0, Y_MAX, bbuff, (LPBITMAPINFO) & bi,DIB_RGB_COLORS) != Y_MAX) return 0; Пока тестилось на 32/24/16/4/1 бит цвете всё было OK. А в 256-цветах (8 бит) – частично "бились" значения в получаемой палитре (bi.bmiColors) – обычно последние 10 записей и из-за этого картинка искажается. По документации MSDN известно что системная т.е. неизменяемая часть палитры состоит из 20 цветов (записи 0..9, 246..255). Для исправления этой ошибки всем несистемным цветам ставится флаг PC_NOCOLLAPSE. 1) Как реализовать функционал «PrintScreen», если пользователь вышел из cистемы?
И ещё вопросик. Разрешение 720x576x24. Выделяю память на битмэп. 720 * 3 * 30 = 64800 байт (30 строк) Делаю так Код (Text): s = 30; if (GetDIBits(dc,hbm,0,s,buffer,(LPBITMAPINFO)&bi,DIB_RGB_COLORS) != s) MessageBox( thiswnd, "GetDIBits() fails", "", MB_OK ); При s = 30,29,28,27 всё работает но в taskmanager-е видно что происходит page fault. А при s <= 26 всё работает без page fault. Что это за бред и как отловить page fault в т.ч. и в других программах?
Актуально. Т.е. когда юзер выходит из системы, функции GetDIBits() и BitBlt() возвращают ошибки или пустой черный экран. Нужны привилегии системы? Запускать прогу как службу или что-то ещё?
виден другой десктоп, т.е вам нужно переключить тред на другой десктоп (винлогона) и оттуда сделать снимок.