Скриншот в Vista
Создаю поток :
в func, в цикле с определенным таймаутом работает такой код:
const char * filePath = "c:\\temp.jpg";
HDC screenDC = NULL;
screenDC = GetDC( pDesctop );
HDC bufferDC = CreateCompatibleDC(screenDC);
DWORD nWidth = GetDeviceCaps( screenDC, HORZRES );
DWORD nHeight = GetDeviceCaps( screenDC, VERTRES );
HBITMAP pDestPicture = ::CreateCompatibleBitmap(screenDC, nWidth, nHeight);
::SelectObject(bufferDC, pDestPicture);
BitBlt( bufferDC, 0, 0, nWidth, nHeight, screenDC, 0, 0, SRCCOPY | CAPTUREBLT);
CImage img;
img.Attach(pDestPicture);
img.Save( filePath, ImageFormatJPEG );
ReleaseDC( NULL, screenDC );
DeleteDC(bufferDC);
Все работает в XP, однако в Viste и Win 7 в файле сохраняется просто черный цвет.
Если код запустить вне потока - все отлично.
Есть мысль что это как то связано с ACL. Помогите.
т.е. не обязательно вызывать GetDesktopWindow
и еще вот что. не знаю как насчет потоков, но логически рассуждая CImage.Attach вполне может пытаться делать SelectObject для pDestPicture, который уже выбран на bufferDC, что приводит к такому результату. хотя в таком случае и вне доп. потока не должен этот код работать. в общем проверьте. если так, то DeleteDC(bufferDC) можно переместить сразу после BitBlt
//added
и, кстати, DeleteObject я тут не увидел, а надо бы. и если GetDC( pDesctop ), то корректнее ReleaseDC( pDesctop, screenDC ). вполне может статься, что в потоке "глюк" связан именно с чем то этим, неправильным освобожением ресурсов. ну как вариант. и еще может лучше в try-finally блоки засунуть код
и нашел кое что о GetDC и в дополнение к предыдущему абзацу:
направление мыслей улавливаете?
Собственно поток запускается процессом, а процесс после висты, похоже не имеет доступа к рабочему столу пользователя.
И вот кусок документации:
Services have always run in session 0. Before Windows Vista, the first user to log on was also assigned to session 0. Now, session 0 is reserved exclusively for services and other applications not associated with an interactive user session. (The first user to log on is connected to session 1, the second user to log on is connected to session 2, and so on.) Session 0 does not support processes that interact with the user.
This change means that a service cannot post or send a message to an application and an application cannot send or post a message to a service. In addition, services cannot display a user interface item such as a dialog box directly. A service can use the WTSSendMessage function to display a dialog box in another session.
Т.е, как я понимаю все работает нормально, просто сервис получает свой собственный рабочий стол.
SetProcessWindowStation();
SetThreadDesktop();
SwitchDesktop(),
которые, по идее как раз и должны менять рабочий стол потока...
Однако у меня этого не вышло ни в коем разе.
Возможно ли в Vista и Win7, сделать скриншот экрана из сервиса?
И если возможно, удавалось ли кому то?