Что нового

[Элементы GUI] PNG изображение на layered окне

Fever

Скриптер
Сообщения
308
Репутация
112
Всем здарасте :bye:

Такая проблемка, у меня есть окно, фон которого - png изображение. Все работает на ура, пока не появляется потребность отрисовать на нем другое png изображение, оно элементарно не отображается, прошу у вас совета :-\

Это что-то вроде изображения-кнопки, тогда наверное нужно рисовать динамически? :-\

Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#Include <WinAPIEx.au3>

Global _
	$_sTitle = "", _
	$hImage[6][2], $hBitmap[6][2]

$hImage[1][0] = "3.png"
$hImage[2][0] = "Play.png"

_GDIPlus_Startup()
$hBitmap[1][0] = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\" & $hImage[1][0])
$hBitmap[1][1] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap[1][0])
_GDIPlus_BitmapDispose($hBitmap[1][0])

$hForm = GUICreate($_sTitle, 175, 40, -1, -1, -1, $WS_EX_LAYERED)

$hBitmap[2][0] = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\Play.png")
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap[2][0])

_WinAPI_UpdateLayeredWindowEx($hForm, -1, -1, $hBitmap[1][1], 255)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap[2][0], 10, 10, 16, 16)

_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BitmapDispose($hBitmap[2][0])

GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")

GUISetState(@SW_SHOW, $hForm)

While 1
	_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap[2][0], 10, 10, 16, 16)
	_WinAPI_UpdateLayeredWindowEx($hForm, -1, -1, $hBitmap[1][1], 225)

	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			_GDIPlus_Shutdown()
			Exit
	EndSwitch
WEnd

Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    Switch $hWnd
        Case $hForm
            Switch $iMsg
                Case $WM_NCHITTEST
                    Return $HTCAPTION
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NCHITTEST

OffTopic:
Подобная тема уже была (и я был её автором), но совет "разобрать калькулятор Yashied'a" увы ни к чему не привел, код для меня слишком сложен и непонятен :'(
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
С помощью GDIPlus склеиваете два PNG в один битмап и вставляете в окно.
 
Автор
F

Fever

Скриптер
Сообщения
308
Репутация
112
Yashied [?]
можно пример реализации?

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

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Fever,
Посмотрите здесь. Пример GUICtrlSetOnHover & Icons UDFs Demonstration.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Fever

У тебя есть два пути:

  • Использовать только одно Layered окно. В этом случае придется полностью перерисовывать все его "элементы" при любых изменениях во внешнем виде. Например, у тебя есть подложка и кнопка (три состояния). По умолчанию, на подложке стоит кнопка в нормальном состоянии (отжата). При наведении мышки на кнопку, она должна изменить свой внешний вид. Следовательно, нужно взять чистую подложку (без кнопки) и нарисовать на ней соответствующий вид кнопки, а затем вставить полученное изображение в Layered окно. Если курсор вышел за пределы кнопки, то снова берем чистую подложку, рисуем на ней теперь уже отжатую кнопку и снова обновляем окно. Таким образом, окно реально не содержит никаких элементов, только одно общее изображение, но эффект оправдывает ожидания. Именно по этой схеме и работает тот самый калькулятор. Здесь можно использовать PNG для кнопок в чистом виде без каких-либо танцев с бубном, т.к. перерисовкой (формированием общего изображения) будет заниматься GDI+. Я не могу привести более-менее простой пример для этого метода, т.к. основной алгоритм жестко встроен в код калькулятора, а выдерать его оттуда и оформлять в удобоваримом виде у меня сейчас нет желания.

  • Использовать Layered окно + одно или более дополнительных окон для размещения на них всех необходимых элементов. Для чего нужны дополнительные окна? Как ты сам уже убедился, в Layered окне ничего, кроме битмапа, нельзя создать, даже дочернее окно не будет работать. Поэтому создаем дополнительное окно (WS_POPUP) и уже на нем размещаем все необходимые элементы. Также необходимо синхронизировать перемещение всех этих окон относительно Layered окна с помощью WM_MOVE. Здесь уже нельзя использовать PNG для кнопок, но что нам мешает склеить изображение кнопки с куском подложки в том месте, где она (кнопка) будет располагаться и сохранить это в BMP? Если честно, то я уже раз 10 давал примеры на нашем форуме по этой теме. Напишу еще раз, специально для твоего случая, см. в аттаче. Кстати, здесь я использовал Skin UDF (недокументированный), который, надеюсь, сильно облегчит тебе жизнь. Эта небольшая библиотека позволяет создавать скиновые кнопки для не Layered окон и содержит обработчик событий.

    post_img_082.png
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied,
У меня, как всегда, на XP проблема. :(
Установлен Visual Task Tips v3.4 и, при наведении мыши на окно на панели задач, получаю следующее. У меня это лечится только добавлением расширенного стиля $WS_EX_TOOLWINDOW.
 
Автор
F

Fever

Скриптер
Сообщения
308
Репутация
112
Yashied [?]
перерисовывать все его "элементы"
ага, по-немногу доходит..это все одна картинка, изумительно :scratch:

За пример 2 способа огромнейшее спасибо, работает шикарно, моей благодарности Вам нет конца :thanks:
 
Верх