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..." |