Снимок окна оп его Handle

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
seawolf
Старожил
Сообщения: 217
Зарегистрирован: 08 Июль 2005, 11:23
Откуда: St. Petersburg

Снимок окна оп его Handle

Сообщение seawolf »

Приветствую сообщество!
Возникал тема получить 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 или прототип не верен?
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3289
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 49 раз
Контактная информация:

Re: Снимок окна оп его Handle

Сообщение Дед Пахом »

А LIB-файл с этой функцией в проект включён? В стандартных либах её нет.
С уважением, ДП
Аватара пользователя
WadimZapara
Активист
Сообщения: 181
Зарегистрирован: 11 Июнь 2008, 12:11
Откуда: Тамбов

Re: Снимок окна оп его Handle

Сообщение WadimZapara »

Или вариант: найти адрес этой функции и использовать по назначению:

Код: Выделить всё

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
MSDN грит, что не во всех операционках есть эта самая функция (Minimum supported client - Windows XP).
Поэтому предложенный вариант с небольшими изменениями (диагностикой) будет работать везде.

А если прилинковать либу с объявлением - будет работать в той среде, где скомпилил, и более новых ОС,
а на стареньких тачках с Windows 98/NT/2000 - приложение просто не запустится, обругав, что не найдена функция в библиотеке.
Компьютер имеет то преимущество перед мозгом, что им пользуются...
seawolf
Старожил
Сообщения: 217
Зарегистрирован: 08 Июль 2005, 11:23
Откуда: St. Petersburg

Re: Снимок окна оп его Handle

Сообщение seawolf »

Наивно полагал что это функция 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)
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Re: Снимок окна оп его Handle

Сообщение Yufil »

Если окно развёрнуто, можно получить его положение по GetWindowRect и грабберу передать именно этот прямоугольник.
При необходимости временно развернуть окно и вытащить его на передний план несложно.
Всё вроде работает, но у меня на сграбленной картинке содержатся закрытые к настоящему моменту окна :( .
После танцев с бубном остался вариант с открытием (и сразу же закрытием) окошка 1x1 пиксел в сторонке, тогда грабится правильно
Ответить