Как используя BitBlt сделать скриншот отдельного окна

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Как используя BitBlt сделать скриншот отдельного окна

Сообщение Vova_2581 » 18.11.2012 (Вс) 19:58

Собственно вопрос в заголовке...
Использую код вида...
Код: Выделить всё
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Const SRCCOPY = &HCC0020
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub Form_Load()
   Me.Show
   Dim A1 As Long
   Dim hHost As Long
   hHost = FindWindow("TfrmClock", vbNullString)
   A1 = GetDC(hHost)
   Picture1.AutoRedraw = True
   BitBlt Picture1.hDC, 0, 0, Screen.Width, Screen.Height, A1, 0, 0, SRCCOPY
End Sub

Но почему-то все время получаю скриншот текущего экрана. В чем тут моя ошибка? Подскажите, если не трудно.

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Debugger » 18.11.2012 (Вс) 20:12

Во-первых:
Код: Выделить всё
Screen.Width, Screen.Height

Тебя это не смущает? :) это наверняка больше, чем размер формы.

Во-вторых: посмотри внимательно, что возвращает твой FindWindow. Он ищет окна с именем класса "TfrmClick" среди окон верхнего уровня, не просматривая детишек. Убедись, что имя класса формы у тебя правильно введено. Почему-то у меня насчет этого сомнения.
Открой "Блокнот" и замени
FindWindow("TfrmClock", vbNullString)

на
Код: Выделить всё
FindWindow(vbNullString, "Безымянный - Блокнот")

Всё замечательно работает.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Хакер » 18.11.2012 (Вс) 21:12

Цирк. Я думал, речь идёт о том, чтобы сделать скриншот натурально определённой формы. Например треугольной формы или круглой.
А тут мы опять имеем типичную глупость. Есть вообще две разновидности этой глупости. Лёгкая: это когда экземпляры VB-шных форм называются не экземлярами VB-шных форм, а формами. Тяжёлая: когда любые окна в системе называют формами.


Во-вторых, для того, чтобы снимать скриншот всего окна, а не только его содержимого, надо получать хендл DC всей области окна (а не только клиентской). То есть использовать GetWindowDC.

И не забывать про ReleaseDC.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Vova_2581 » 18.11.2012 (Вс) 21:42

Debugger
У этой формы (окна, экземпляра и т.д.) нет дочерних – это одна форма (окно, экземпляр). Ну вот найти блокнот у меня не получилось. Может покажешь свой код?

Хакер
Ты мне напомнил анекдот. Один гражданин спрашивает другого:
- Скажите который час?
Второй отвечает:
- Во-первых, что значит час? Правильно спрашивать: время?.. Во-вторых, что значит «который»?.. Правильно спрашивать «сколько»...
Не цепляйся к мелочам и не смеши меня, будь проще! :)

А насчет GetWindowDC – это уже по делу! спасибо за подсказку, поработаю...

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Debugger » 18.11.2012 (Вс) 22:00

Код: Выделить всё
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub Form_Load()
    Shell "notepad"
    Debug.Print FindWindow(vbNullString, "Безымянный - Блокнот")
End Sub

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Vova_2581 » 18.11.2012 (Вс) 22:13

Ха!!! Получилось! :)
Спасибо всем!
Debugger
Отдельная благодарность за подсказку насчет
Код: Выделить всё
Screen.Width, Screen.Height
- в них то все и дело!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Хакер » 18.11.2012 (Вс) 23:42

Vova_2581 писал(а):У этой формы (окна, экземпляра и т.д.) нет дочерних – это одна форма (окно, экземпляр).

Тест на сообразительность не пройден. Важна не слова, которые всего лишь оболочка, а понимание смысла. А понимания смысла как не было, так и нет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение ger_kar » 20.11.2012 (Вт) 18:11

Ну вообще понятие форма употребляется в разных смыслах. И в зависимости от контекста, смысл и так вполне бывает понятен. Конечно между формой как классом (шаблоном) и ее экземпляром как объектом этого класса разница есть. И если например речь бы шла о сути понятий, которые используются в технологии COM разница может быть бы и была. Но тут в принципе и так было понятно, что имелось ввиду. гораздо проще написать Форма, чем экземпляр формы, когда и без этого уточнения понятно что имелось ввиду. Как говориться пишем форма, а в уме экземпляр :)
Бороться и искать, найти и перепрятать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Хакер » 20.11.2012 (Вт) 19:27

Здесь не имеется в виду ни форма, ни экземпляр формы. Так что как ни крути — неправильное понятие. К тому же всё усугубляется ещё и тем, что возникает неоднозначность: то ли имелась в виду форма или экземпляр формы, то ли геометрическая форма скриншота.

Ни у кого не хватает дальновидности думать не только о том, как тему поймут при обсуждении, но и о том, каково потом будет другим людям через пару лет при поиске по ключевым словам.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 20.11.2012 (Вт) 19:57

Я, кстати, тоже сначала подумал, что нужно сделать скриншот окна, имеющего непрямоугольную форму...

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как используя BitBlt сделать скриншот определенной формы

Сообщение Vova_2581 » 21.11.2012 (Ср) 8:58

Ладно, ладно... Ну, извините за неточную формулировку в теме. Что же мне теперь повеситься что-ли?! Тогда у меня просьба к модератору: измените название темы должным образом, и тогда снимем все дальнейшие споры.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 21.11.2012 (Ср) 16:04

Vova_2581 писал(а):Тогда у меня просьба к модератору: измените название темы должным образом, и тогда снимем все дальнейшие споры.

Почему бы самому не изменить? Правильный вариант - "окна", если ещё не понял.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот, SemrushBot и гости: 41

    TopList