Как скопировать содержимое окна

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

Как скопировать содержимое окна

Сообщение ANDLL » 04.09.2004 (Сб) 19:19

Извините, еще один вопрос.

Всем привет.

У меня есть hDC и hWnd. У окна(hWnd) есть дочерние окна, и у этих окон тоже могут быть дочерние окна... hDC прикреплен к bitmap'у.
Вопрос: как скопировать изображение с окна в hDC. Естественно со всеми окнами. Надо как-бы сделать его скриншот.

Я пробовал:
Код: Выделить всё
BitBlt hDC, 0, 0, Width, Height, getdc(hWnd), 0, 0, vbSrcCopy


В полном варианте, естественно вызваеться ReleaseDC для hWnd. Кроме того я пробовал вместо hwnd писать GetWindow(hwnd,GW_OWNER)
Почему-то не получаеться. В hDC постоянно присутствует чернота...

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.09.2004 (Сб) 19:25

Ты MDI пытаешься брать? Хм...
Ну попробуй findwindowex(hwnd, "MDIClient", ...) А потом уже с него, с клиента.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 04.09.2004 (Сб) 19:28

Попробуй послать окну WM_PRINT со своим hDC
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.09.2004 (Сб) 19:34

2GSerg: Нет. Обычное окно с дочерними окнами. Окно создаеться с помощью CreateWindowEx
2tyomitch:Спасибо, щас попробую
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 04.09.2004 (Сб) 19:35

Ещё, плз, покажи полный код - может, у тебя с самим рисованием какие-то проблемы, например битмап в DC чёрно-белый :-)
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.09.2004 (Сб) 19:48

2tiomitch:
Битмап у меня совместимый с GetDC(hWnd). Т.е. цветной. Полный код без надобноти показывать не хочу, т.к. там слишком много намешано и разобраться будет сложно. Но если понадобиться я отчищу и выставлю его.

Код: Выделить всё
SendMessage hWnd, WM_PRINT, hDC, ByVal CLng(PRF_OWNED Or PRF_CHILDREN Or PRF_CLIENT)


Не рвботает. Он ресует только контуры окон(белым). Остальное - черное.
Но ведь, что бы сделать скриншот экрана достаточно сделать то, что сделал я для GetDesktopWindow(). Почему тут не работает?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 04.09.2004 (Сб) 20:41

добавь PRF_NONCLIENT и PRF_ERASEBKGND, может заработает :-)

Ещё раз, если в DC попадают только чёрные и белые линии, очень большая вероятность, что битмап в нём чёрно-белый. Проверь наверняка.
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 04.09.2004 (Сб) 21:09

debug.print GetDeviceCaps(ret.hdc, BITSPIXEL) пишет - 32. Константы не работает. Правда, на кол-во цветов пишет - -1.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 04.09.2004 (Сб) 21:29

ты не понял :-)
не DC чёрно-белый, а битмап в нём.
проверяется вызовом GetDIBits

давай всё-таки код :-)
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.09.2004 (Вс) 8:27

Код: Выделить всё
Public Type DrawWindowInfo
    hWnd As Long
    hDC As Long
    hBitmap As Long
    Width As Long
    Height As Long
End Type
'...
Dim nRect As Rect, ret As DrawWindowInfo
GetClientRect nParent, nRect
ret.Width = nRect.Right - nRect.Left
ret.Height = nRect.Bottom - nRect.Top
ret.hwnd = CreateWindowEx(0, DRAW_WINDOW_CLASS32, "draw_wnd", WS_VISIBLE, 0, 0, ret.Width, ret.Height, nParent, 0, App.hInstance, ByVal 0&)
Dim nTempDC As Long ', nTempWnd As Long
'nTempWnd = GetWindow_api(nParent, GW_OWNER)
nTempDC = GetDC(nParent)
ret.hDC = CreateCompatibleDC(nTempDC)
ret.hBitmap = CreateCompatibleBitmap(ret.hDC, ret.Width, ret.Height)
SelectObject ret.hDC, ret.hBitmap
Debug.Print GetDeviceCaps(ret.hDC, NUMCOLORS)
SendMessage nParent, WM_PRINT, ret.hDC, ByVal CLng(PRF_OWNED Or PRF_CHILDREN Or PRF_NONCLIENT Or PRF_CLIENT Or PRF_ERASEBKGND)
'BitBlt ret.hDC, 0, 0, ret.Width, ret.Height, nTempDC, 0, 0, vbSrcCopy
ReleaseDC nParent, nTempDC
'И где-то далеко... mWindow=ret
        hDC = GetDC(mWindow.hwnd)
        BitBlt hDC, 0, 0, mWindow.Width, mWindow.Height, mWindow.hDC, 0, 0, vbSrcCopy
        ReleaseDC mWindow.hwnd, hDC

Щас, может пострараюсь сбросить демонстрационный исходник...
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.09.2004 (Вс) 12:17

Я знал, я знал!!!
ANDLL писал(а):
Код: Выделить всё
ret.hDC = CreateCompatibleDC(nTempDC)
ret.hBitmap = CreateCompatibleBitmap(ret.hDC, ret.Width, ret.Height)

замени на
Код: Выделить всё
ret.hDC = CreateCompatibleDC(nTempDC)
ret.hBitmap = CreateCompatibleBitmap(nTempDC, ret.Width, ret.Height)
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.09.2004 (Вс) 13:32

Caption у окна действительно рисуеться... Но не все остальное... Это просто жуть! Щас, подожди выставлю тестовый проект.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.09.2004 (Вс) 17:44

Вот пример. Надо скопировать содержимое этого окна на другое окно.
Вложения
CopyWindow.zip
Копирование окна
(4.42 Кб) Скачиваний: 43

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 05.09.2004 (Вс) 18:10

Во-первых, что это за класс DRAW_WINDOW_CLASS32? У меня на XP такого нет. Возвращается, ессно, 0, и потому рисование идёт на десктоп.
Во-вторых, если ты хочешь таскать форму за любое место, то скажи - это делается ровно двумя строчками кода :)
В-третьих, попробуй копировать не с form.hdc, а с getdc(getdesktopwindow), указывая экранные координаты формы.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.09.2004 (Вс) 18:54

1. Простите, в официальном варианте есть еще RegisterClass...
2. нет
3. Пожалуй, это единственный выход. Очень печально, но лучше чем ничего.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.09.2004 (Вс) 19:06

3. подожди, не делай, дай я сейчас посмотрю :-)
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 05.09.2004 (Вс) 19:38

Жду.
Кстати кнопочка добавилась "Цитировать последнее сообщ."
Раньше ее не было.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.09.2004 (Вс) 20:01

Неправда, сколько я здесь ошиваюсь (с 1 августа) - она всё время тут.

Комментарий:
- Начнём с того, что RegisterDrawWindowClass и UnregisterDrawWindowClass нигде в коде не вызываются... Ладно.

- В Form_MouseUp неправильное условие - надо "If Button = 1 Then"

- "mDragWindow = CreateDrawWindow(hwnd)" в Form_MouseMove лишнее

- WM_PRINT, действительно, рисует только неклиентскую область. Но зато если его закомментировать и раскомментировать "BitBlt ret.hDC, 0, 0, ret.Width, ret.Height, nTempDC, 0, 0, vbSrcCopy" - всё работает.
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 06.09.2004 (Пн) 9:18

Возмутительно. Кажеться я опрохвостился. Дааа правильное решение под носом, а я его не вижу...

А в чем отличия:
Код: Выделить всё
ret.hDC = CreateCompatibleDC(nTempDC)
ret.hBitmap = CreateCompatibleBitmap(ret.hDC, ret.Width, ret.Height)

и
Код: Выделить всё
ret.hDC = CreateCompatibleDC(nTempDC)
ret.hBitmap = CreateCompatibleBitmap(nTempDC, ret.Width, ret.Height)

По логике, это одно и тоже
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 06.09.2004 (Пн) 12:56

В memory DC по умолчанию выбран чёрно-белый битмап 1х1 пиксел. Если ты создаёшь совместимый именно с ним битмап, то создаётся чёрно-белый.

Видишь, если бы ты сразу меня послушал, решение было бы у тебя на день или два раньше :-)
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 06.09.2004 (Пн) 13:21

GSerg писал(а):Во-вторых, если ты хочешь таскать форму за любое место, то скажи - это делается ровно двумя строчками кода :)

Кстати, ты видел мою вариацию на эту тему?
http://vbrussian.com/examples.asp?ID=95
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 06.09.2004 (Пн) 13:55

А я и так сразу тебя послушал. Сначала послушал про WM_PRINT - сделал. А потом послушал про CreateCompatibleBitmap... И сделал...
А сделат я хочу следующее: у окна есть дочерние окна, которые WS_BORDER, но состоят из двух частей. В верху - заголовок, который я сам рисую, а внизу - еще одно окно, чаще всего это VB-форма. Надо таскать дочернюю форму за эту надпись. Т.е. Я хватаю за надпись. Тяну. В этот момент поверх "снятой" картинки рисуеться серый прямоугольник. Если я приблежаюсь к краю родительского окна, рамка становиться красной, и прилипает к этому краю. Нечто подобное(т.е. тоже самое) можно наблюдать во многих аппах, в VB6, к примеру. Исходник на эту тему я видел только на сайте vbAccelerator, правдо силно я не искал. Хотелось бы сделать по-порядку и по возможности самому. Учитывая, что тул-окон может быть весьма много они могут выстариваться весьма интересно:
Код: Выделить всё
   *********************************
   *     |                    |    *
   *-----|                    |    *
   *     |                    |    *
   *     |                    |    *
   *-------------------------------*
   *           клиентская          *
   *             область           *
   *                               *
   *-------------------------------*
   *-------------------------------*
   *      |                |       *
   *********************************

Ну основа примерно такая. Пожалуй все-таки расскажу. Есть родительское окно. VB-форма, обсабкласеная VB-классом.
Есть интерфейс IDocked. Родительское окно расчерчено примерно так:
Код: Выделить всё
   *********************************
   *               top             *
   *                               *
   *-------------------------------*
   * l |                       | r *
   * e |                       | i *
   * f |                       | g *
   * t |                       | h *
   *   |                       | t *
   * ------------------------------*
   *                               *
   *            bottom             *
   *********************************

Два класса, ToolWidnow и Edge реализуют IDocked. Соотвтественно у MainWindow есть четыре предопредленных Edge - (top, bottom и т.п.). Каждый Edge представляет собой контейнер для других IDocked элементов - или ToolWindow или другой Edge. В каждом Edge элементы выстраиваються либо по вертикали, либо по горизонтали. Для программы это легко и понятно. Для пользователя это не применимо. Т.е. пользователь должен собирать набор из тул-окон как конструктор лего. Потянул сюда - приклеилось сюда. Потянул в другое место, значит в другое. Вот как это реализовать, вопрос другой. Может вы знаете, какую идею по этому поводу. Именно идею. Исходник меня не интересует - все что я могу сделать сам я хочу так и сделать, но не хотелось бы идти по заведеомо ложному пути. Может существует какая-то простая деталь которую я упустил.

Кстати, "Цитировать..." я раньше не замечал. К сожалению, в кэше старых страниц не осталось - они там вообще как-то странно сохраняються, так что верю наслово. Но все равно я ее заметил только позавчера.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 07.09.2004 (Вт) 22:16

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

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 08.09.2004 (Ср) 4:49

tyomitch писал(а):В общем, подумал я над твоей проблемой, и вот что решил. Оставь как есть :-)


Пршу прощения за оффтоп, но навеяло анекдот:
Папа-программист написал программу. Всё отлажено, но вот он обнаружил маленькую неточность в несущественном в общем-то месте. Полез исправлять и... программа перестала работать. И что программист ни делает, не может разобраться в причине (:) анекдот, наверное, ламеры про программистов придумали :))... короче, сидит в полутрансе...
в этот момент к нему сын подходит и спрашивает
- пап, а, пап,
- чего сынок (в полузабытьи отвечает отец)
- пап, а почему Солнце всегда восходит на востоке?
- ты всё проверял, всегда на востоке?
- да.
- точно?
- да, папа
- да, и плюнь, сынок, пускай оно встаёт на востоке, ничего не меняй...
С уважением, Approximator.


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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28

    TopList