forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   PureBasic (http://forum.boolean.name/forumdisplay.php?f=90)
-   -   Скин с альфа-каналом (UpdateLayeredWindow_) (http://forum.boolean.name/showthread.php?t=15611)

barsunduk 07.10.2011 00:10

Скин с альфа-каналом (UpdateLayeredWindow_)
 
Вложений: 1
появившееся было желание писать на пурике моментально ударилось лицом о несговорчивость некоторых функций API. в частности UpdateLayeredWindow_(), которая должна была преобразовать полупрозрачный рисунок в многослойное окно (т.е. практически в шкурку с альфа-каналом).
в чем может быть дело?
может, дело в win7? тогда, если не затруднит, кто-нибудь гляньте на другой винде и отпишитесь, не высветляется ли левый верхний угол иконки фотошопа?
или, может, дело в чем-то другом?
я понимаю, что есть прекрасная функция WinSkin(), но она не передает полутонов канала прозрачности. при низком разрешении экрана границы картинки выходят несколько угловатыми.
исходники кода и скомпилированные экзешники в аттаче. (заменено на рабочий вариант)



проблема решена, рабочий вариант с комментариями:

Romanzes 07.10.2011 00:15

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Картинка не дает сосредоточиться на решении проблемы

barsunduk 07.10.2011 00:23

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Цитата:

Сообщение от Romanzes (Сообщение 204925)
Картинка не дает сосредоточиться на решении проблемы

:-D
хотя бы экзешник запусти, скажи, как он себя ведет на другой винде. или у тебя тоже семерка?

Romanzes 07.10.2011 00:31

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Вложений: 1
Вот как он себя ведет. У меня семерка.

barsunduk 07.10.2011 00:34

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
походу, дело в семерке. надо API покурить. эээх...
---
нда. там такое... как я понял, png нужно будет разбить на битмап и маску, потом объединить их снова, но как-то по хитрому, и только после этого вызывать построение слоистых окон. короче долго еще думать...

barsunduk 07.10.2011 23:17

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
как бэ ура. победил я эту беду. надо было RGB предварительно с альфа-каналом смешать. винда сама этого делать не умеет почему-то.
одно неудобство - контролы теперь недоступны. нужно свои рисовать. зато шкурки теперь можно полупрозрачные делать.
з.ы.: косячные архивы удаляю. исправленный и дополненный вариант см. в первом посте

Romanzes 07.10.2011 23:26

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
У меня работает отлично

kvitaliy 10.10.2011 23:04

Re: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Эта фраза очень насторожила:
Цитата:

;при использовании многослойных окон обычное PopupMenu не работает
;поэтому удалим/закомментируем его и будем пока закрывать окно по двойному клику :(
Проверил - всё нормально работает, меню вызывается и обрабатывается как надо.



Код:

EnableExplicit

UsePNGImageDecoder()

XIncludeFile("WinSkin2.pb")

Global hWndParent, hWnd
Global hPng, hBmp
Global Quit, Moving
Global dX, dY
Global Event
Define Menu
hWndParent = OpenWindow(#PB_Any, 0, 0, 1, 1, "AlphaSkin", #PB_Window_BorderLess|#PB_Window_Invisible)
hPng = LoadImage(#PB_Any, GetPathPart(ProgramFilename()) + "Icons\back.png")
hBmp = ConvertPNG(hPng)
  hWnd = wndCreateChild(hWndParent, hBmp)
  wndSkin(hWnd, hBmp)
  HideWindow(hWnd, #False)
  Quit = #False
  Moving = #False
  dX = 0
  dY = 0
  Global xy.TPoint
  CreatePopupMenu(0)     
      MenuItem(1, "Open")     
      MenuItem(2, "Save")     
      MenuItem(3, "Save as")
      MenuItem(4, "Quit")
    Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #WM_LBUTTONDOWN
        ;SendMessage_(WindowID(Frm\hWnd), #WM_NCLBUTTONDOWN, #HTCAPTION, 0); передвигать окно мышкой
        ;этот способ вызывает утечку памяти
        Moving = #True
        GetCursorPos_(xy)
        dX = WindowX(hWnd) - xy\x
        dY = WindowY(hWnd) - xy\y
      Case #WM_LBUTTONUP
        If Moving
          GetCursorPos_(xy)
          wndMove(hWnd, xy\x + dX, xy\y + dY)
          Moving = #False
        EndIf

      Case #WM_LBUTTONDBLCLK
        ;Quit = #True
      Case #WM_RBUTTONDOWN
        ; Контекстное меню правым кликом
        DisplayPopupMenu(0, WindowID(hWndParent))
      Case #PB_Event_Menu
        Menu = EventMenu()
        If Menu = 4
          Quit = #True
        EndIf
;
    EndSelect
    If Event = #PB_Event_CloseWindow
      Quit = #True
    EndIf
    If Moving
      GetCursorPos_(xy)
      wndMove(hWnd, xy\x + dX, xy\y + dY)
      Moving = GetAsyncKeyState_(#VK_LBUTTON)
    EndIf
 
    Delay(20)
  Until (Quit)
End


barsunduk 11.10.2011 17:37

Ответ: Re: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Цитата:

Сообщение от kvitaliy (Сообщение 205379)
Код:

...
        DisplayPopupMenu(0, WindowID(hWndParent))
...


да, действительно, тут я сильно зевнул. полноценное невидимое окно есть, а не используется. спс за идею.
(хорошо, что я комментарии свои дурацкие забыл удалить в коде ..)
а если так, то не попрет:
Код:

        DisplayPopupMenu(0, WindowID(hWnd))
так как окно hWnd уже изнасиловано функцией UpdateLayeredWindow()

barsunduk 11.10.2011 17:47

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Цитата:

Сообщение от Romanzes (Сообщение 204925)
Картинка не дает сосредоточиться на решении проблемы

Эти 7 пользователя(ей) сказали Спасибо Romanzes за это полезное сообщение:
barsunduk (11.10.2011), baton4ik (07.10.2011), impersonalis (06.10.2011), L-ee-X (06.10.2011), Nuprahtor (07.10.2011), pax (07.10.2011), Randomize (06.10.2011)

имхо, на булике давно пора переименовать кнопку "Полезно!" в кнопку "Прикольно ..)"
з.ы.: Romanzes, я против вышеописанного ничего не имею, кстати. самому смешно было. тоже плюсанул

barsunduk 17.10.2011 18:52

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

zeronull 10.12.2011 15:07

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Подскажите пожалуйста как добавить на это окно кнопку и вывести текст? Раньше учил VB, сейчас возникла необходимость написать утилиту изпользуя скин, пример хорошо демонстрирует как прикрутить скин, но как реализовать простейшие контролы не понятно. Буду рад любой помощи!

barsunduk 10.12.2011 22:36

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Цитата:

Сообщение от zeronull (Сообщение 213375)
Подскажите пожалуйста как добавить на это окно кнопку и вывести текст? Раньше учил VB, сейчас возникла необходимость написать утилиту изпользуя скин, пример хорошо демонстрирует как прикрутить скин, но как реализовать простейшие контролы не понятно. Буду рад любой помощи!

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

вывод: данный вариант подходит для виджетов и прочей мелочевки. для работы со стандартными контролами - WinSkin.

Paranoia 27.07.2012 13:22

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Очень информативный пример, спасибо.

Только вот перемещение окна как-то странной сделано, более того, окно может "открепиться" от курсора в момент его перетаскивания.

Лучше использовать эту WinAPI:
Код:

SendMessage_(WindowID(hWnd), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)

barsunduk 27.07.2012 16:00

Ответ: Скин с альфа-каналом (UpdateLayeredWindow_)
 
Цитата:

Сообщение от Paranoia (Сообщение 234486)
Лучше использовать эту WinAPI:
Код:

SendMessage_(WindowID(hWnd), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)

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


Часовой пояс GMT +4, время: 18:11.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot