Как правильно создать прозрачный контейнер контрола?

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

Как правильно создать прозрачный контейнер контрола?

Сообщение Адская_Капча » 28.07.2014 (Пн) 20:29

Здравствуйте.

Сабж - cвойство BackStyle = 0 контрола - результата не дает. Результата не дает, если контрол (ocx) вставить в документ Microsoft Word 2003. В результате у вставленного ActiveX объекта (контейнера) будет цвет фона, который был задан изначально у самого контрола. Прозрачности никакой не будет. В Excel 2003 аналогично. В сети информации по этому поводу не нашлось.

Хочется, чтобы контрол нормально работал везде.
На контроле должны присутствовать другие элементы, например, кнопки, метки с текстом.

Если нужно, могу сделать пример.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение The trick » 29.07.2014 (Вт) 10:52

SetWindowRgn не подходит?
UA6527P

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

Сообщение Qwertiy » 29.07.2014 (Вт) 13:01

Прозрачность фона можно (нужно?) разрешить при создании окна (соответстующие флаги в CreateParams). Возможно, потребуется также передать флаги, говорящие, что контрол сам себя отрисовывает. Дальше по необходимости.
Это для случая, если контрол свой, естественно.

Адская_Капча
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 60
Зарегистрирован: 28.07.2014 (Пн) 20:22

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение Адская_Капча » 29.07.2014 (Вт) 14:00

SetWindowRgn работает на VB-шных формах, но в Word/Excel так не получится, прозрачности не будет...

CreateParams - может, это относится к NET? У меня Visual Basic 6. Не совсем понятно, что значит "свой" контрол. Компилирую в OCX и вставляю как элемент управления в Word/Excel (контрол должен быть зарегистрирован).

Удалось найти один пример - через CreateCompatibleBitmap + CreateIPictureDispFromHBITMAP. Он в Word работает, но в Excel - нет. Привести его, или нельзя (на ряде веб-ресурсов выкладывание ссылок запрещено)? И потом не знаю, хороший это способ или плохой...

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

Сообщение Qwertiy » 29.07.2014 (Вт) 14:23

Адская_Капча писал(а):CreateParams - может, это относится к NET? У меня Visual Basic 6.

Эм.. Я немного не точно выразился, точнее использовал .NET'товскую терминологию, однако, в области, непосредственно связаной с winapi.
Надо было от CreateParams добраться до Style и ExStyle, а оттуда до Window Styles и Extended Window Styles.

Адская_Капча писал(а):Не совсем понятно, что значит "свой" контрол. Компилирую в OCX

Собственно это и имелось в виду. Что ты сам компилируешь контрол, а не пытаешься использовать некий готовый контрол, на чей код не можешь влиять.

Адская_Капча
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 60
Зарегистрирован: 28.07.2014 (Пн) 20:22

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение Адская_Капча » 29.07.2014 (Вт) 15:35

Имелось ввиду использование флага WS_EX_TRANSPARENT?
Прозрачность таким образом вообще не получается:
Код: Выделить всё
Private Sub MakeFrameTransparent()
    Call SetWindowLong(UserControl.hwnd, GWL_EXSTYLE, GetWindowLong(UserControl.hwnd, GWL_EXSTYLE) Or WS_EX_TRANSPARENT)
    Call SetBkMode(GetDC(UserControl.hwnd), TRANSPARENT)
    Call SetWindowPos(UserControl.hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_FRAMECHANGED)
    Call InvalidateRectLong(UserControl.hwnd, vbNull, True)
    UserControl.Refresh
End Sub


Контрол - это не top-level окно, поэтому прозрачность у него сделать не получится. И потом, элементы на контроле (хотя бы label и желательно Picturebox) должны быть видны...

Может быть, нужно настроить встроенные свойства UserControl-а каким-то особым образом?
Или без GDI - прозрачности не добиться?

Пример с CreateCompatibleBitmap + CreateIPictureDispFromHBITMAP в Excel не работает (где задействовано живое перетаскивание элементов) - что нужно в нем исправить? Или нужно идти вообще каким-то другим путем?

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

Сообщение Qwertiy » 29.07.2014 (Вт) 15:48

Адская_Капча писал(а):GetWindowLong(UserControl.hwnd, GWL_EXSTYLE) Or WS_EX_TRANSPARENT

Не всё так просто. Там минимум два флага надо выставить.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение The trick » 29.07.2014 (Вт) 15:50

Нужно под собой отрисовывать контролы и родителя, хотя все это делает WS_EX_TRANSPARENT. Насчет регионов я не понял, все должно работать без проблем. Также если система Win8 можно использовать слоеные окна для прозрачности.
UA6527P

Адская_Капча
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 60
Зарегистрирован: 28.07.2014 (Пн) 20:22

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение Адская_Капча » 31.07.2014 (Чт) 16:25

WS_EX_TRANSPARENT - у меня сработало только для VB-шных форм. Или я что-то делаю не так?
Какой еще должен быть флаг? С прозрачностью больше никаких флагов нет, кроме WS_EX_LAYERED, но он не годится, потому что Windows8 - не вариант. Нужно, чтобы работало в Windows 7 и Windows XP.

Пример с CreateCompatibleBitmap + CreateIPictureDispFromHBITMAP оказывается не работает и в Word, если рисовать простой текст на юзерконтроле через GDI.

SetWindowRgn думаю, тоже не подойдет. Нужно определенный цвет на юзерконтроле (его фон) сделать прозрачным.
Ни один из примеров, найденных в сети, не решил проблему.

Попробую объяснить задачу более детально.

1. Создаю UserControl.
2. Он должен содержать пару нарисованных линий и простой текст (с помощью GDI). Где именно рисовать - на самом юзерконтроле или на размещенном в нем PictureBox - не особо важно.
3. Компилирую в OCX, либо добавляю его в соседний проект VB.
4. Добавленный ActiveX контрол должен содержать только нарисованный текст/линии. Остальное (его фон) - должны быть прозрачны.
То есть должны быть видны элементы, которые находятся под этим контролом, а не просто "дыра". Если добавили в Excel например, то должны быть видны ячейки и формулы сквозь него, но не сам написанный на нем текст.
5. Прозрачность должна работать как в Design, так и в User Mode, не пропадать, при изменении размера или положения контрола ничего не должно пропадать или искажаться. Прозрачность должна работать в любой среде, независимо от того, где размещен контрол - в MS Word, Excel, VB, Delphi, PhotoShop и т.д. ОС - нужно, чтобы работало не только в Windows 8, но и в Windows 7 и XP.

Задачу решить не удалось. Одни способы работают в одних случаях, а другие - в других.

В какую сторону копать, ума не приложу. AlphaBlend, BitBlt, TransparentBlt? И какой должен быть сам контрол - Windowless или нет (свойство)?

Насчет встроенного свойства BackStyle: если Transparent - в Excel полностью исчезает вместе с содержимым, а в Word не срабатывает. Остается Opaque.

Адская_Капча
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 60
Зарегистрирован: 28.07.2014 (Пн) 20:22

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение Адская_Капча » 01.08.2014 (Пт) 16:56

Пытаюсь сделать имитацию прозрачности с помощью BitBlt.
Оказывается, MS Office не понимает UserControl.Extender.Container, поэтому приходится делать аналог через API...

При начальном размещении юзерконтрола hwnd родителя почему-то другой, но это ладно. Можно изменить размер для перерисовки - и они будут совпадать со 2 раза.
А вот почему-то VB-шный hDC родителя не совпадает с API-шным (lngSrcDC_1 и lngSrcDC_2) никак.
Результат - ничего не отрисовывается.
Где у меня ошибка? Проект прилагается.

Заранее хочу поблагодарить за консультацию.
Вложения
trnsp_01.rar
(14.63 Кб) Скачиваний: 123

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

Сообщение Qwertiy » 02.08.2014 (Сб) 0:08

Адская_Капча писал(а):Какой еще должен быть флаг?

У меня только код для .NET'а, причём эксперементировал с TextBox'ом, докатился до пользовательской отрисовки и получил косяк с выделением текста...
Выставлял SupportsTransparentBackColor, UserPaint и Opaque. Вроде бы Opaque тут совсем не порсто так и без ненго работать не должно, но уже не помню.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение ALX_2002 » 11.08.2014 (Пн) 19:30

Если я правильно понял, то что-то подобное я очень давно пытался делать в этой теме
http://bbs.vbstreets.ru/viewtopic.php?f=1&t=17000&p=128219&hilit=Screenmate#p128219

Там есть несколько примеров.

Возможно это подойдёт
http://www.pscode.com/vb/scripts/ShowZip.asp?lngWId=1&lngCodeId=57338&strZipAccessCode=tp%2FS573387112

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как правильно создать прозрачный контейнер контрола?

Сообщение The trick » 11.08.2014 (Пн) 19:54

Прозрачные контролы, можно сделать, перехватив отрисовку и отрисовывая сначала родителя под собой (если отрисовывать в буфер, то можно избавится от мерцания).
http://www.cyberforum.ru/post6441097.html
http://www.cyberforum.ru/post5098814.html
http://www.cyberforum.ru/post5104632.html
Прозрачность окон верхнего уровня.
viewtopic.php?f=9&t=45012#p6771433
viewtopic.php?f=15&t=45390
http://www.cyberforum.ru/post5555870.html
UA6527P


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

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

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

    TopList