How to make non rectangular windows
BlitzMax Forums/MaxGUI Module/How to make non rectangular windows
| ||
| First, I would like to say : I am aware that this topic has been discussed before, however the solution offered doesn't seem to work anymore with the new versions of Max Gui A non rectangular window would be a window that not only doesn't have a border, but also has a shape defined by an image with alpha channel or mask color. The former solution was based on the functions : Extern "Win32" Function SetWindowRgn(hWnd, hRgn, bRedraw) Function CreateRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect) Function CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, fnCombineMode) End Extern However when I use the sample :
Import MaxGui.Drivers
Strict
Const HTCAPTION = 2
Const RGN_XOR = 3
Extern "Win32"
Function SetWindowRgn(hWnd, hRgn, bRedraw)
Function CreateRectRgn(nLeftRect, nTopRect, nRightRect, nBottomRect)
Function CombineRgn(hrgnDest, hrgnSrc1, hrgnSrc2, fnCombineMode)
End Extern
Local skinPmap:TPixmap = LockImage(LoadImage("Background.png"))
If skinPmap = Null Then RuntimeError "Oi...Where's me picture?"
Local window:TGadget = CreateWindow("", 100, 100, skinPmap.width, skinPmap.height, Null,0)
SkinWindow(window, skinPmap)
'SetGadgetShape(Window,100,100,100,500)
ShowGadget(window)
Local canvas:TGadget = CreateCanvas(0, 0, ClientWidth(window), ClientHeight(window), window)
Local hWnd = QueryGadget(window, QUERY_HWND)
SetGraphics CanvasGraphics(canvas)
SetBlend ALPHABLEND
DrawPixmap skinPmap, 0, 0
Flip
Repeat
Select WaitEvent()
Case EVENT_MOUSEDOWN
ReleaseCapture()
SendMessageA(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, Null)
Case EVENT_KEYDOWN
If CurrentEvent.data = 27 Then End
Case EVENT_GADGETPAINT
SetGraphics CanvasGraphics(canvas)
DrawPixmap skinPmap, 0, 0
Flip
End Select
Forever
End
Function SkinWindow(window:TGadget, skin:TPixmap)
Local rectRgn = CreateRectRgn(0, 0, GadgetWidth(window), GadgetHeight(window))
Local hWnd = QueryGadget(window, QUERY_HWND_CLIENT)
For Local pixY=0 Until skin.height
Local startFlag = 0
Local startX = 0
Local maskLine, pixX
For pixX=0 Until skin.width
Local argb = ReadPixel(skin, pixX, pixY)
If argb & $ff000000 = 0
If startFlag = 0
startFlag = 1
startX = pixX
EndIf
Else
If startFlag
startFlag = 0
maskLine = CreateRectRgn(startX, pixY, pixX, pixY + 1)
CombineRgn(rectrgn, rectrgn, maskLine, RGN_XOR)
DeleteObject(maskLine)
EndIf
EndIf
Next
If startFlag
maskLine = CreateRectRgn(startX, pixY, pixX, pixY + 1)
CombineRgn(rectrgn, rectrgn, maskLine, RGN_XOR)
DeleteObject(maskLine)
EndIf
Next
SetWindowRgn(hWnd, rectrgn, True)
End Function
I end up with a rectangular gray area around the window any ideas? |
| ||
| there are three errors in your code 1. QUERY_HWND_CLIENT is the wrong handle 2. your start pixel finder is not working 3. the XOR is the wrong combination see this to continue: Function SkinWindow(window:TGadget, skin:TPixmap) Local rectRgn = CreateRectRgn(0, 0, GadgetWidth(window), GadgetHeight(window)/2) Local hWnd = QueryGadget(window, QUERY_HWND) Local maskLine, pixX maskLine = CreateRectRgn(0, 0, GadgetWidth(window)/2, GadgetHeight(window)) CombineRgn(rectrgn, rectrgn, maskLine, 2) SetWindowRgn(hWnd, rectrgn, True) end function |
| ||
| thanks, I got it working after replacing QUERY_HWND_CLIENT by QUERY_HWND, the rest is working though, start pixel and XOR is correct (try it?) |
| ||
here is my solution:Function SkinWindowII(Window:TGadget , Skin:TPixmap) Const NOTHING=-1 Local RectRgn = CreateRectRgn(0, 0, 0,0) Local hWnd = QueryGadget(Window , QUERY_HWND) Local X% , Y% , StartX% , argb:Long For Y=0 Until Skin.Height For X=0 Until Skin.Width argb = ReadPixel(skin, X, Y) If (argb <> NOTHING) If StartX = -1 StartX = X EndIf Else If StartX > -1 Local MaskLine MaskLine = CreateRectRgn( StartX , Y , X , Y+1 ) CombineRgn ( RectRgn , RectRgn, MaskLine , 2 ) DeleteObject MaskLine StartX = -1 EndIf EndIf Next If StartX > -1 Local MaskLine MaskLine = CreateRectRgn( StartX , Y, X , Y+1 ) CombineRgn ( RectRgn , RectRgn , MaskLine, 2 ) DeleteObject MaskLine StartX = -1 EndIf Next SetWindowRgn ( hWnd , RectRgn , True) End Function My first rectangle is empty, with futher rectangles I do an "AND"-combination. I don't know why, but I have to take argb=-1 to detect an empty pixel, the $FF000000 seems not to work correct with my 8bit-PNG-Picture on my computer. Last edited 2011 Last edited 2011 |
| ||
| Found the problem on my start position finder, also you have a slight mistake : For Y=0 Until Skin.Height For X=0 To Skin.Width should be : For Y=0 Until Skin.Height For X=0 Until Skin.Width thanks for the help |
| ||
| thanks too! this is very strange: when I published the code in the morning it worked perfectly with a "For X=0 TO...". Now my girlfriend came home. I wanted to demonstrate it, but now I got an error and changed it to "For X= 0 UNTIL..." |