Creates a skin for a window, and uses it.
Bare bones stuff (for example, no error checking, files not compressed, etc, etc).
Creating a "kwikskin":
Code: Select all
; Dare2
; CreateKwikSkin
; PureBasic 4.00
;
; I looked at some code in the archive at PureArea.net
; This borrows from code by: Mischa.
; Many thanks to Mischa.
;
; Note: Anything crap was introduced by me.
;
#imgNum = 1
#fileNum = 1
Structure UDT_ks_info ; Basic info for skin
imgWide.l ; Width of image
imgHigh.l ; Height of image
maskSize.l ; Size of mask (bytes)
picSize.l ; Size of image (bytes)
EndStructure
UsePNGImageEncoder() ; So we can use BMP and PNG
UsePNGImageDecoder() ; jpg is not recommended, but your call
; srcFile is the image to use as the skin
; destFile is the file create and containing skin information
; transCol is the RGB(r,g,b) of the transparent colour
Procedure CreateMask(srcFile.s,destFile.s,transCol)
Define skin.UDT_ks_info
Define bmpInfo.BITMAPINFOHEADER
image=LoadImage(#imgNum,srcFile) ; Get the image
wide = ImageWidth(#imgNum) ; Get width and height
high = ImageHeight(#imgNum)
mem = AllocateMemory(wide*high*4) ; Allocate some space
hDC = StartDrawing(ImageOutput(#imgNum)) ; Need a DC, get via StartDrawing
hMask = CreateRectRgn_(0,0,0,0) ; Create an empty mask
bmpInfo\biSize = SizeOf(BITMAPINFOHEADER) ; Set up the bmp header info
bmpInfo\biWidth = wide
bmpInfo\biHeight = high
bmpInfo\biPlanes = 1
bmpInfo\biBitCount = 32
bmpInfo\biCompression = #BI_RGB
; Make a DIB from the bitmap
GetDIBits_(hDC,ImageID(#imgNum), 1, high-1, mem, bmpInfo, #DIB_RGB_COLORS)
ptr=mem ; Scan through the image ignoring the
For vert = 0 To high-1 ; transCol pixels and create tiny
For horz = 0 To wide-1 ; regions then ORing these with the
If PeekL(ptr) <> transCol ; initial mask region
tmpRgn = CreateRectRgn_(horz, high-vert-1, horz+1, high-vert-2)
CombineRgn_(hMask, hMask, tmpRgn, #RGN_OR)
DeleteObject_(tmpRgn) ; Get rid of the temporary region
EndIf
ptr+4 ; Next pixel, please.
Next
Next
StopDrawing() ; Done.
skin\imgWide = wide ; Store our basic information (should have done
skin\imgHigh = high ; this directly rather than via wide/high vars)
skin\maskSize = GetRegionData_(hMask,0,0)
skin\picSize = FileSize(srcFile)
pic = AllocateMemory(skin\picSize) ; Load the image file
OpenFile(#fileNum, srcFile)
ReadData(#fileNum, pic,skin\picSize)
CloseFile(#fileNum)
skn=AllocateMemory(skin\maskSize) ; Copy the mask information
GetRegionData_(hMask, skin\maskSize, skn)
CreateFile(#fileNum, destFile) ; Make our (uncompressed) skin file
WriteData(#fileNum, @skin, SizeOf(UDT_ks_info))
WriteData(#fileNum, skn, skin\maskSize)
WriteData(#fileNum, pic, skin\picSize)
CloseFile(#fileNum)
FreeMemory(skn) ; Clean up
FreeMemory(pic)
DeleteObject_(hMask)
EndProcedure
; Note - depending on the size and complexity of your file, this can have a noticable pause.
srcFile.s = "C:\path\to\your\bmp\or\png\image"
wk.s = GetExtensionPart(srcFile)
destFile.s = Left(srcFile,Len(srcFile)-Len(wk)) + "skn"
CreateMask(srcFile, destFile, RGB(255,0,255)) ; Source,Destination and the transparent color
EndCode: Select all
; Dare2.
; KwikSkin
;
; PureBasic 4
;
; Two parts:
; First part is a simple window skinner.
; Second part is an example of skinning.
;
; No error checking, etc, just some basic stuff and a loose end.
;
; You need your own image and to have created the skin file.
;
; Right click on the window to exit.
;
; All my own work, I can't blame anyone else :(
; Any similarity to any other code is purely co-incidental
; however for those who demand credit for perceived similarities:
; --> Put your name here <--
;
Structure UDT_ks_info ; Basic skin info (stored in file)
imgWide.l ; How wide
imgHigh.l ; How high
maskSize.l ; Bytes used for mask
picSize.l ; Bytes used for image
EndStructure
Structure UDT_ks_plus ; Extended skin info, used in app
kwik.UDT_ks_info ; The basic info
maskAddress.l ; Memory address of mask
picAddress.l ; Memory address of image
maskHandle.l ; handle of mask
winPBnumber.l ; Window number (pb number)
imgHandle.l ; Image handle
EndStructure
UsePNGImageEncoder() ; So we can use PNG
UsePNGImageDecoder()
; Draws the image onto the window.
; Example of what should be called whenever window needs refreshing/repainting.
; The parameter passed in is the value retrieved from ks_LoadSkin
Procedure ks_DrawWindow(*kwikSkin.UDT_ks_plus)
StartDrawing(WindowOutput(*kwikSkin\winPBnumber))
DrawImage(ImageID(*kwikSkin\imgHandle), 0, 0)
StopDrawing()
EndProcedure
; Loads a kwikskin file and prepares for use.
; Must call ks_ReleaseSkin for each skin loaded.
Procedure ks_LoadSkin(srcFile.s)
Define *kwikSkin.UDT_ks_plus
Define kwikMem.l
Define hFile.l
kwikMem=AllocateMemory(SizeOf(UDT_ks_info))
*kwikSkin=kwikMem
hFile=OpenFile(#PB_Any,srcFile)
ReadData(hFile,kwikMem,SizeOf(UDT_ks_info))
*kwikSkin\maskAddress=AllocateMemory(*kwikSkin\kwik\maskSize)
*kwikSkin\picAddress=AllocateMemory(*kwikSkin\kwik\picSize)
ReadData(hFile,*kwikSkin\maskAddress,*kwikSkin\kwik\maskSize)
ReadData(hFile,*kwikSkin\picAddress,*kwikSkin\kwik\picSize)
CloseFile(hFile)
ProcedureReturn kwikMem
EndProcedure
; Releases a skin and associated resources
; The parameter passed in is the value retrieved from ks_LoadSkin
Procedure ks_ReleaseSkin(*kwikSkin.UDT_ks_plus)
DeleteObject_(*kwikSkin\maskHandle)
FreeMemory(*kwikSkin\maskAddress)
FreeMemory(*kwikSkin\picAddress)
EndProcedure
; Skins the window
; The winNumber parameter is the PureBasic number (not the internal or OS value) of the window.
; The skinPtr parameter passed in is the value retrieved from ks_LoadSkin
; (For some reason it will not accept *kwikSkin.UDT_ks_plus as an arg instead of skinPtr)
Procedure ks_SkinWindow(winNumber,skinPtr)
Define *kwikSkin.UDT_ks_plus
*kwikSkin=skinPtr
*kwikSkin\maskHandle=ExtCreateRegion_(0,*kwikSkin\kwik\maskSize,*kwikSkin\maskAddress)
SetWindowRgn_(WindowID(winNumber),*kwikSkin\maskHandle,#True)
*kwikSkin\winPBnumber=winNumber
*kwikSkin\imgHandle = CatchImage(#PB_Any,*kwikSkin\picAddress)
Debug *kwikSkin\picAddress
Debug *kwikSkin\kwik\picSize
Debug *kwikSkin\imgHandle
ks_DrawWindow(skinPtr)
EndProcedure
; Retrieves the width of the skin
; The parameter passed in is the value retrieved from ks_LoadSkin
Procedure ks_GetSkinWidth(*kwikSkin.UDT_ks_plus)
ProcedureReturn *kwikSkin\kwik\imgWide
EndProcedure
; Retrieves the height of the skin
; The parameter passed in is the value retrieved from ks_LoadSkin
Procedure ks_GetSkinHeight(*kwikSkin.UDT_ks_plus)
ProcedureReturn *kwikSkin\kwik\imgHigh
EndProcedure
;-----------------------------------
; The above being the include file
;-----------------------------------
; The below being an example of use
;-----------------------------------
Global kSkin.l ; This is a loose end. Needed as global for the callback proc.
; Callback proc
Procedure WindowCallBack(WindowId, Message, lParam, wParam)
If Message = #WM_PAINT
ks_DrawWindow(kSkin)
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
file.s="C:\path\to\your\skin\file"
kSkin = ks_LoadSkin(file) ; Load the skin
w = ks_GetSkinWidth(kSkin) ; Retrieve width (just because we can) :)
h = ks_GetSkinHeight(kSkin) ; Retrieve height.
; Our window must be borderless otherwise strange things happen!
hWnd = OpenWindow(0, 10,10, w,h, "Test", #PB_Window_Invisible|#PB_Window_BorderLess)
SetWindowCallback(@WindowCallback()) ; Set our callback
SmartWindowRefresh(0,#True) ; Not sure if this helps but it doesn't seem to hurt.
ks_SkinWindow(0,kSkin) ; Apply our loaded skin
HideWindow(0,#False) ; Unhide the window
Repeat ; Hang around until the RIGHT mouse button is clicked.
Select WaitWindowEvent()
Case #WM_LBUTTONDOWN
SendMessage_(hwnd,#WM_NCLBUTTONDOWN, #HTCAPTION,0)
Case #WM_RBUTTONDOWN
Quit=1
EndSelect
Until Quit=1
ks_ReleaseSkin(kSkin) ; Release the skin
End

