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