Приветствую сообщество!
Возникал тема получить BMP из текущего окна (Handle понятно дело известен) путем собственного кода без всяких ImageEx . Изучен пример Grabber - если окно свернуто или на него положено другое то не получить его BMP корректно.
За основу пример из Delphi.
____________-
hSrcWnd := FindWindow(nil, PChAR('Test')); // "*********" - имя нужного окна
GetWindowRect(hSrcWnd, rcSrc);
Это опускаем так как эти параметры известны
hSrcWnd - хэндл окна
hDC1:= GetDC(hSrcWnd);
hSrcDC:=CreateCompatibleDC(hDC1);
hBmp := CreateCompatibleBitmap(hDC1, rcSrc.right - rcSrc.left, rcSrc.bottom - rcSrc.top);
SelectObject(hSrcDC, hBmp);
PrintWindow(hSrcWnd, hSrcDC, 0);
BitBlt(
hDC1,
0,
0,
rcSrc.right - rcSrc.left,
rcSrc.bottom - rcSrc.top,
hSrcDC,
0,
0,
SRCCOPY);
Здесь сохранение в файл
DeleteObject(hBmp);
DeleteDC(hSrcDC);
ReleaseDC(hSrcWnd, hDC1);
___________
У нас это примерно так с учетом примера Grabber
hDC1 = GetDC(hSrcWnd)
hdcCompatible = CreateCompatibleDC(hDC1)
hbmScreen = CreateCompatibleBitmap(hDC1,Rec.Right,Rec.Bottom)
IF NOT hbmScreen
RETURN 1
END
IF NOT SelectObject(hdcCompatible, hbmScreen)
RETURN 1
END
PrintWindow(hSrcWnd, hdcCompatible, 0)
IF NOT BitBlt(hDC1,0,0,Rec.Right,Rec.Bottom,hdcCompatible,Rec.Left,Rec.Top,SRCCOPY)
RETURN 1
END
Далее все освобождаем!
Собственно вопрос:
Проблема в объявлении PrintWindow никак не линкуется (в user32.dll точно есть такая функция )
PrintWindow(HWND, HDC, DWORD),BOOL,PASCAL,PROC или прототип не верен?
Снимок окна оп его Handle
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
- Дед Пахом
- Старичок
- Сообщения: 3289
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
- Контактная информация:
Re: Снимок окна оп его Handle
А LIB-файл с этой функцией в проект включён? В стандартных либах её нет.
С уважением, ДП
- WadimZapara
- Активист
- Сообщения: 181
- Зарегистрирован: 11 Июнь 2008, 12:11
- Откуда: Тамбов
Re: Снимок окна оп его Handle
Или вариант: найти адрес этой функции и использовать по назначению:
MSDN грит, что не во всех операционках есть эта самая функция (Minimum supported client - Windows XP).
Поэтому предложенный вариант с небольшими изменениями (диагностикой) будет работать везде.
А если прилинковать либу с объявлением - будет работать в той среде, где скомпилил, и более новых ОС,
а на стареньких тачках с Windows 98/NT/2000 - приложение просто не запустится, обругав, что не найдена функция в библиотеке.
Код: Выделить всё
PrintWindow ULONG,Static,Name('MePrintWindow')
MAP
MODULE ('')
PrintWindow (UnSigned, UnSigned, ULong), BOOL, PASCAL, PROC, Name('MePrintWindow')
END
MODULE ('Windows.dll')
LoadLibrary(*CString NameLibrary), UnSigned,RAW,Pascal,DLL(TRUE),Name('LoadLibraryA')
GetProcAddress(UnSigned handle, *CString NameFunction), ULong,Raw,Pascal,DLL(TRUE)
FreeLibrary(UnSigned handle),BOOL, RAW,Pascal,DLL(TRUE)
END
END
hLib unsigned
cs CString('User32.dll<0>{50}')
CODE
! Загрузка User32.dll
hLib = LoadLibrary(cs);
IF ~hLib Then MESSAGE('Не найдена User32.dll')
ELSE
! Получение адреса функции PrintWindow
cs = 'PrintWindow'
PrintWindow = GetProcAddress(hLib, cs)
If ~PrintWindow Then MESSAGE('В User32.dll не найдена функция PrintWindow').
END
IF PrintWindow THEN
! ЗДЕСЬ ИСПОЛЬЗУЕШЬ СВОЙ ТЕКСТ
! . . .
! ЗАВЕРШАЕШЬ ТАК (чисто хороший тон освобождать более ненужные ресурсы):
FreeLibrary(hLib)
END
RETURN
Поэтому предложенный вариант с небольшими изменениями (диагностикой) будет работать везде.
А если прилинковать либу с объявлением - будет работать в той среде, где скомпилил, и более новых ОС,
а на стареньких тачках с Windows 98/NT/2000 - приложение просто не запустится, обругав, что не найдена функция в библиотеке.
Компьютер имеет то преимущество перед мозгом, что им пользуются...
Re: Снимок окна оп его Handle
Наивно полагал что это функция API посему lib не подключал. В Win 98 ее нет. При таком раскладе подгрузка через LoadLibrary оптимальна.
Использование GetWindowDC привело к тому что теперь скринится именно заданное по хэндлу окно а не весь десктоп. При этом работает без PrintWindow. Использование PrintWindow приводит к вылету сразу причина пока не ясна. Насколько я понял именно эта функция может дать скрин окна если оно будет свернуто. Без нее имеем просто черный скрин, посему ушел в google.
hDC1 = GetWindowDC(hSrcWnd)
hdcCompatible = CreateCompatibleDC(hDC1)
hbmScreen = CreateCompatibleBitmap(hDC1,recright, recbottom)
RetObject = SelectObject(hdcCompatible, hbmScreen)
PrintWindow(hSrcWnd, hdcCompatible, 0)
Использование GetWindowDC привело к тому что теперь скринится именно заданное по хэндлу окно а не весь десктоп. При этом работает без PrintWindow. Использование PrintWindow приводит к вылету сразу причина пока не ясна. Насколько я понял именно эта функция может дать скрин окна если оно будет свернуто. Без нее имеем просто черный скрин, посему ушел в google.
hDC1 = GetWindowDC(hSrcWnd)
hdcCompatible = CreateCompatibleDC(hDC1)
hbmScreen = CreateCompatibleBitmap(hDC1,recright, recbottom)
RetObject = SelectObject(hdcCompatible, hbmScreen)
PrintWindow(hSrcWnd, hdcCompatible, 0)
Re: Снимок окна оп его Handle
Если окно развёрнуто, можно получить его положение по GetWindowRect и грабберу передать именно этот прямоугольник.
При необходимости временно развернуть окно и вытащить его на передний план несложно.
Всё вроде работает, но у меня на сграбленной картинке содержатся закрытые к настоящему моменту окна
.
После танцев с бубном остался вариант с открытием (и сразу же закрытием) окошка 1x1 пиксел в сторонке, тогда грабится правильно
При необходимости временно развернуть окно и вытащить его на передний план несложно.
Всё вроде работает, но у меня на сграбленной картинке содержатся закрытые к настоящему моменту окна

После танцев с бубном остался вариант с открытием (и сразу же закрытием) окошка 1x1 пиксел в сторонке, тогда грабится правильно