The size of the WinLIFT64.dll is very small (only 129 Kb)
Version 7.00 is now a (paypal) donate-ware version.
Support is available to registered users on www.objreader.com
WinLIFT has been around since more than 24 years,
the subclassing engine is able to skin on the fly a Windows application with only 2 lines of code:
skInitEngine
skSkinWindow
The DLL is provided with:
WinLIFT64.DLL
WinLIFT64.lib
WinLIFT.h (C++ header)
One default skin theme.
You can get more skin themes, and original image backgrounds when tkey become available,
for an extra (paypal) donate-ware subscription.
Previous skin themes from version 5.00 can also be used
It is up to you to create the corresponding PureBasic import file, or to use directly the LoadLibrary API.
Here is an example of Version 7.00 composited skin theme
http://www.objreader.com/download/images/Rainbow.png
WinLIFT Version 7.00 Skin Engine
-
- User
- Posts: 21
- Joined: Sun Aug 10, 2003 11:45 am
- Location: France
- Contact:
WinLIFT Version 7.00 Skin Engine
Last edited by Patrice Terrier on Thu Feb 15, 2024 8:53 pm, edited 1 time in total.
Patrice Terrier
objreader@gmail.com
http://www.objreader.com
Addon: WinLIFT (Skin Engine), GDImage (Graphic library), ObjReader (3D engine)
objreader@gmail.com
http://www.objreader.com
Addon: WinLIFT (Skin Engine), GDImage (Graphic library), ObjReader (3D engine)
-
- User
- Posts: 21
- Joined: Sun Aug 10, 2003 11:45 am
- Location: France
- Contact:
Re: WinLIFT Version 7.00
Here is an example of WinLIFT 7.00 composited skin using a dark theme.
http://www.objreader.com/download/image ... owDark.png
(The same is available in light theme).
http://www.objreader.com/download/image ... owDark.png
(The same is available in light theme).
Patrice Terrier
objreader@gmail.com
http://www.objreader.com
Addon: WinLIFT (Skin Engine), GDImage (Graphic library), ObjReader (3D engine)
objreader@gmail.com
http://www.objreader.com
Addon: WinLIFT (Skin Engine), GDImage (Graphic library), ObjReader (3D engine)
Re: WinLIFT Version 7.00
Thanks Patrice,
As I got some requests to explain how to use it in PureBasic, here is the long story and a sceleton PB Include for Winlift 32 and 64 bit.
The screenshot Patrice provided (and some other on Patrice's objreader.com forum)
are from a working PureBasic Email Client - so I can confirm, that most things work quite fine and also look good!
As PureBasic executables on Windows are not a pure WinAPI applications, some caveats are to be considered.
Please do not ostracize me for poor coding of the include below - I started using PB a year ago and only on the Weekends
Link to the Download: http://www.objreader.com/download/demo/SkinTheme.7z
Before you start screaming, please read below:
Demo version skins only main screen.
Winlift 7 does not need any special Window styles or WinAPI calls or additional Message Pumps.
Not every single gadget will work - so chose your controls or check if you can use those, which work.
Splitters will not be skinned (or WebGadget or canvas) BUT to show a nice splitter - make your own splitter bars using CanvasGadget and as long as it is less than 15 px wide or less than 15 px in height - it will be considered as splitter!
Background images are rotated by left or right click on the "System Menu" - if they contain transparency (png) and skin is defined as using DWM/Aplha - it will nicely show through desktop/background - don't complain - amount of alpha in your image needs tweaking to get ideal result (readable / transparent)
It works the same on 32 and 64 bit - it will not work on XP, Vista/Win 7 or later is needed.
It will increase RAM for your application (for an app using 10-12 MB RAM it will become 20 - something)
Resizing trees and very complex screens may not be perfectly smooth - just like resizing treegadget in PB itself is not smooth - you can use Winlift sizing instead (proportional, anchored etc.) - this may work or may not work for you, if you have nested containers. Play with your code to see the best option.
Menus are replaced and work well *only* if they have no images (images in menus are not implemented in Winlift)
Not all gadgets are tested with PB, following should work fine: window frame, menu (no images), statusbars, progress bars, String, Tree, Text, ImageList (Report View), ListView, combos boxes, lists, virtual ListView (so secondary subclassing also works), buttons, checkboxes, option boxes and toolbars.
There is a neat function to add multiple PNG sliced images to (Image)ListView in single column, which will adjust their size to row height. Refer to Objreader forum - there is an example of what I'm using and Patrice made it neat.
Multiple windows - no problem.
Hidden windows - if they have menu a click on main window may pass through to the hidden window menu (neither Patrice nor I could figure it out completely) so keep your hidden window off-screen if you must or do not use hidden windows apart from window start-up.
An application must have a main window and main window needs to be skinned first.
If you want to switch skin at runtime: from no skin to skin you need to restart the application and init skin engine properly. From one skin to another: just switch skin with a new path to the skin definition file. From Skin to no skin - restart application and do not init the skin engine.
Do not skin the same window repeatedly, it would work, but will cause memory leaks.
If you do not like the System Menu button to rotate the skin backgrounds - intercept the Windows message and add your own "system" menu
Bitmaps used for the (transparent or not) background are defined in the .sks file.
Always cleanly unload (FreeLibrary) at the end of your application - after all windows are closed, to remove hooks and release resources.
Finally: if you do not like the fancy skin styles from Patrice's distribution, find it odd, outdated or not to your taste - just make your own - it is easy to program (but hard if you are not skilled in graphic design
) : skin definition is in plain text, bitmaps for frame, buttons, check, splitter handles are in the skin folder.
Usage:
Design you main window.
Call wrapper function below: InitSkins(MainWindow.i, SkinName.s) where MainWindow is the Window and Skinname (full) path to the .sks file.
For additional windows (if you have a license): call wrapper "SkinWindow(thewin.i)"
If you want to use message boxes or sizing / anchoring - implement also other functions form WinLift(64).h the same way as you see below
simple include file (remove LIB implementation code if you just use DLL):
You can contact me here for WinLift questions I may have answer to or not regarding PureBasic, for Winlift itself - use Patrice's ObjReader.com forum, CHM file (also Forum)
Cheers!
As I got some requests to explain how to use it in PureBasic, here is the long story and a sceleton PB Include for Winlift 32 and 64 bit.
The screenshot Patrice provided (and some other on Patrice's objreader.com forum)
are from a working PureBasic Email Client - so I can confirm, that most things work quite fine and also look good!
As PureBasic executables on Windows are not a pure WinAPI applications, some caveats are to be considered.
Please do not ostracize me for poor coding of the include below - I started using PB a year ago and only on the Weekends

Link to the Download: http://www.objreader.com/download/demo/SkinTheme.7z
Before you start screaming, please read below:
Demo version skins only main screen.
Winlift 7 does not need any special Window styles or WinAPI calls or additional Message Pumps.
Not every single gadget will work - so chose your controls or check if you can use those, which work.
Splitters will not be skinned (or WebGadget or canvas) BUT to show a nice splitter - make your own splitter bars using CanvasGadget and as long as it is less than 15 px wide or less than 15 px in height - it will be considered as splitter!
Background images are rotated by left or right click on the "System Menu" - if they contain transparency (png) and skin is defined as using DWM/Aplha - it will nicely show through desktop/background - don't complain - amount of alpha in your image needs tweaking to get ideal result (readable / transparent)
It works the same on 32 and 64 bit - it will not work on XP, Vista/Win 7 or later is needed.
It will increase RAM for your application (for an app using 10-12 MB RAM it will become 20 - something)
Resizing trees and very complex screens may not be perfectly smooth - just like resizing treegadget in PB itself is not smooth - you can use Winlift sizing instead (proportional, anchored etc.) - this may work or may not work for you, if you have nested containers. Play with your code to see the best option.
Menus are replaced and work well *only* if they have no images (images in menus are not implemented in Winlift)
Not all gadgets are tested with PB, following should work fine: window frame, menu (no images), statusbars, progress bars, String, Tree, Text, ImageList (Report View), ListView, combos boxes, lists, virtual ListView (so secondary subclassing also works), buttons, checkboxes, option boxes and toolbars.
There is a neat function to add multiple PNG sliced images to (Image)ListView in single column, which will adjust their size to row height. Refer to Objreader forum - there is an example of what I'm using and Patrice made it neat.
Multiple windows - no problem.
Hidden windows - if they have menu a click on main window may pass through to the hidden window menu (neither Patrice nor I could figure it out completely) so keep your hidden window off-screen if you must or do not use hidden windows apart from window start-up.
An application must have a main window and main window needs to be skinned first.
If you want to switch skin at runtime: from no skin to skin you need to restart the application and init skin engine properly. From one skin to another: just switch skin with a new path to the skin definition file. From Skin to no skin - restart application and do not init the skin engine.
Do not skin the same window repeatedly, it would work, but will cause memory leaks.
If you do not like the System Menu button to rotate the skin backgrounds - intercept the Windows message and add your own "system" menu
Bitmaps used for the (transparent or not) background are defined in the .sks file.
Always cleanly unload (FreeLibrary) at the end of your application - after all windows are closed, to remove hooks and release resources.
Finally: if you do not like the fancy skin styles from Patrice's distribution, find it odd, outdated or not to your taste - just make your own - it is easy to program (but hard if you are not skilled in graphic design

Usage:
Design you main window.
Call wrapper function below: InitSkins(MainWindow.i, SkinName.s) where MainWindow is the Window and Skinname (full) path to the .sks file.
For additional windows (if you have a license): call wrapper "SkinWindow(thewin.i)"
If you want to use message boxes or sizing / anchoring - implement also other functions form WinLift(64).h the same way as you see below
simple include file (remove LIB implementation code if you just use DLL):
Code: Select all
EnableExplicit
; you need to free library on the application exit using this handle.
; if libhandle is 0 or 2 - do not call FreeLibrary() if it is any other integer - FreeLibrary at app exit.
Global libhandle
#COMPILE_WINLIFTDLL = 1 ; you can try Lib version if you want
; check the other C contants from Winlift.h if you want to use Winlift Sizing,
; below is not necessary for skinning, just a sample how to translate from C++ header
#SK_CXFRAMERIGHT = 4
#SK_CYFRAMEBOTTOM = 5
#SK_CYFRAMETOP = 0
CompilerIf #COMPILE_WINLIFTDLL = 1 ; use DLL not lib - default
Prototype.l skInitEngine(skinname.p-unicode, userkey.p-unicode)
Prototype skSkinWindow(hwnd.l, tooltips.p-unicode)
Prototype.l skDialogYesNo(Zcaption.p-unicode, zText.p-unicode, zButton.p-unicode)
Prototype skSkinChildCtrl(hwnd.l, Redraw.l)
Prototype skDoNotSkinPopupMenu(yesno.l, rw.l)
Prototype skSkinEnable(hwnd.l)
Prototype skSkinDisable(hwnd.l)
Prototype skSetLabelFont(hctrl.l, zFontName.s, nFontSize.l, ARGBcolor.l, nFontStyle.l, redraw.b = 0)
Prototype skSetListViewImage(FullPathName.s, ReadWriteFlag.l) ;set to 1!
Prototype skGetClientSize(hWnd.l, xClient.l, yClient.l, ClientWidth.l, ClientHeight.l)
Prototype skUseAnchorMode(hWnd.l, UseMode.l)
Prototype skHomotheticResize(hwnd.l, bool.i)
Prototype skAnchorInit(hWnd.l)
Prototype.s skDialogInput(zCaption.s, zMessage.s, zButtons.s);
Prototype.l skGetSystemMetrics(sksize.l)
Prototype.l skARGB(a.i, r.i, g.i, b.i)
Prototype skGetWindowSize(hWnd.l, xClient.l, yClient.l, ClientWidth.l, ClientHeight.l)
Prototype.b skSkinChange(zSkinFile.p-unicode)
Prototype skShowScrollBarEx(hCtrl.l, lParam.b);
CompilerElseIf #COMPILE_WINLIFTDLL =0 ; only if using static LIB, othersise - remove the whole block
;Sample: if using lib and 32 bit, obviously use conditional compilation for each:
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Compiler_32Bit
#Libfile = "WinLIFT32.lib"
ImportC #Libfile
CompilerEndSelect
;End sample, remove
; below works with a static C Lib and 64 bit:
ImportC "WinLIFT64.lib" ; or ImportC "winlift32.lib"
skInitEngine.l(skinname.p-unicode, userkey.p-unicode)
skSkinWindow(hwnd.l, tooltips.p-unicode)
skDialogYesNo.l(Zcaption.p-unicode, zText.p-unicode, zButton.p-unicode)
skSkinChildCtrl(hwnd.l, Redraw.l)
skDoNotSkinPopupMenu(yesno.l, rw.l)
skSkinEnable(hwnd.l)
skSkinDisable(hwnd.l)
skSetLabelFont(hctrl.l, zFontName.s, nFontSize.l, ARGBcolor.l, nFontStyle.l, redraw.b = 0)
skSetListViewImage(FullPathName.s, ReadWriteFlag.l) ;set to 1!
skGetClientSize(hWnd.l, xClient.l, yClient.l, ClientWidth.l, ClientHeight.l)
skUseAnchorMode(hWnd.l, UseMode.l)
skHomotheticResize(hwnd.l, bool.i)
skAnchorInit(hWnd.l)
;skDialogInput.s(zCaption.s, zMessage.s, zButtons.s);
skGetSystemMetrics.l(sksize.l)
skARGB.l(a.i, r.i, g.i, b.i)
skGetWindowSize(hWnd.l, xClient.l, yClient.l, ClientWidth.l, ClientHeight.l)
skSkinChange.b(zSkinFile.p-unicode)
skShowScrollBarEx(hCtrl.l, lParam.b);
EndImport
CompilerEndIf
Procedure InitSkinLib() ; PRIVATE load and init WinLift64/32
Protected appDir.s = ""
If #PB_Compiler_Debugger
appdir = GetCurrentDirectory()
Else
appdir = GetPathPart(ProgramFilename())
EndIf
Define libfile.s
If #PB_Compiler_32Bit = 0
libfile = appDir + "WinLIFT64.DLL"
Else
libfile = appDir + "WinLIFT32.DLL"
EndIf
CompilerIf #COMPILE_WINLIFTDLL ; using DLL, get addresses of functions
libhandle.i = OpenLibrary (#PB_Any,libfile)
Global skInitEngine.skInitEngine = GetFunction(libhandle,"skInitEngine")
Global skSkinWindow.skSkinWindow = GetFunction(libhandle,"skSkinWindow")
Global skDialogYesNo.skDialogYesNo = GetFunction(libhandle,"skDialogYesNo")
Global skSkinDisable.skSkinDisable = GetFunction(libhandle,"skSkinDisable")
Global skSetListViewImage.skSetListViewImage = GetFunction(libhandle,"skSetListViewImage")
Global skSetLabelFont.skSetLabelFont = GetFunction(libhandle,"skSetLabelFont")
Global skGetClientSize.skGetClientSize = GetFunction(libhandle,"skGetClientSize")
Global skHomotheticResize.skHomotheticResize = GetFunction(libhandle,"skHomotheticResize")
Global skAnchorInit.skAnchorInit = GetFunction(libhandle,"skAnchorInit")
Global skUseAnchorMode.skUseAnchorMode = GetFunction(libhandle,"skUseAnchorMode")
Global skDialogInput.skDialogInput = GetFunction(libhandle,"skDialogInput")
Global skARGB.skARGB = GetFunction(libhandle,"skARGB")
Global skGetSystemMetrics.skGetSystemMetrics = GetFunction(libhandle,"skGetSystemMetrics")
Global skGetWindowSize.skGetWindowSize = GetFunction(libhandle,"skGetWindowSize")
Global skSkinChange.skSkinChange = GetFunction(libhandle,"skSkinChange")
Global skShowScrollBarEx.skShowScrollBarEx = GetFunction(libhandle,"skShowScrollBarEx")
CompilerElse
libhandle = 2 ; Libhandle is set to 2 as we use static LIB - there is no FreeLibrary needed. On application end - call FreeLibrary only if libhandle is a valid handle, not 0 or 2
CompilerEndIf
EndProcedure
Procedure SkinWindow(thewin.i) ; PUBLIC This should be used, after Init to skin any subsequent window. Use only once per each window!
If libhandle <> 0
Protected hwnd.l = WindowID(thewin)
skSkinWindow(hwnd , " Dock | Undock | Minimize | Maximize | Restore | Close ")
EndIf
EndProcedure
; shorthand for Init and skin Main window - use this at start of the applicaiton (when window is still hidden) to initialize engine and apply skin.
; As first window becomes main window for WinLift this is better called first.
Procedure.i InitSkins(MainWindow.i, SkinName.s) ; PUBLIC
If libhandle = 0
InitSkinLib()
EndIf
If libhandle
If IsWindow(MainWindow) = 0
ProcedureReturn
EndIf
Protected skinfile.s
If FindString(SkinName, #PS$)
skinfile = SkinName
Else
SetCurrentDirectory(appDir)
skinfile.s = appDir + SkinName
EndIf
If FileSize(skinfile) < =0
MessageRequester("Skin file not present", "Skin not found: " + skinfile)
ProcedureReturn 0 ; but be aware - lib is loaded already and needs to be freed!
EndIf
Protected hwnd.i = WindowID(MainWindow)
Protected isok =0
isok = skInitEngine(skinfile , "") ; add you license key here, or try with single window
If isok
SkinWindow(MainWindow)
EndIf
ProcedureReturn isok
EndIf
EndProcedure
Cheers!
S.T.V.B.E.E.V.
Re: WinLIFT Version 7.00
Very interesting, though I find the forum a bit confusing. But I'll register and try it out. 

Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: WinLIFT Version 7.00
Wow, very oldscool. Such skins had their heyday at the end of the 90s and beginning of the 2000s. It was cool back then. Today, people probably smile about it, as pure control elements are preferred at the moment. I also don't believe that such skins will catch on again. But fond memories of days gone by...
Re: WinLIFT Version 7.00
Yes, but the skin design is not the point of this post.
Quoting myself:
So you can make smooth, rounded, no border elements similar to Win 11, modern MacOS like skin with Alpha channel - this is up to the developer / designer.
The skins are "Old School" if you want to call them that, but the engine is not.
Quoting myself:
The style is what YOU do with it, having a working engine is of much more importance as PB controls look very off on modern Windows."Finally: if you do not like the fancy skin styles from Patrice's distribution, find it odd, outdated or not to your taste - just make your own"
So you can make smooth, rounded, no border elements similar to Win 11, modern MacOS like skin with Alpha channel - this is up to the developer / designer.
The skins are "Old School" if you want to call them that, but the engine is not.
S.T.V.B.E.E.V.
Re: WinLIFT Version 7.00
Obviously it would be great,
If someone from the community with graphic design experience
could design basic Light and Dark "modern" skin for windows 10+ using the engine and share with others.
If someone from the community with graphic design experience
could design basic Light and Dark "modern" skin for windows 10+ using the engine and share with others.
S.T.V.B.E.E.V.
-
- User
- Posts: 21
- Joined: Sun Aug 10, 2003 11:45 am
- Location: France
- Contact:
Re: WinLIFT Version 7.00
>>Very interesting, though I find the forum a bit confusing.
This is because the www.objreader.com private forum was first designed for the ObjReader GDImage/OpenGL 3D engine.
However the forum is great for those wanting to render wavefront 3D models in real time,
using the GDImage/ObjReader specific shader and texture materials.
Here are a few Behance examples of what could be done with it
https://www.behance.net/gallery/1114490 ... NTROL-UNIT
https://www.behance.net/gallery/115233229/Predator
https://www.behance.net/gallery/110660645/PORSCHE-GT3R
There is also a free 64-bit DLL simplified API that is able to render any ObjReader 3D models
http://www.objreader.com/index.php?topic=324.0
It is also a great place for those using directly the core SDK FLAT API to produce small standalone executables.
See also the "Eye Candies" section
http://www.objreader.com/index.php?board=5.0
For those who find the style old fashion,
here are some of the skins that were designed almost 20 years ago for the standard commercial version.
http://www.zapsolution.com/DW/US/skinroom.html
>>Today, people probably smile about it, as pure control elements are preferred at the moment.
One of the greatest WinLIFT feature is that it could work in full DWM composited mode, using varaiable opacity mode.
Here is a video showing what could be done in GDImage/WinLIFT composited mode:
http://www.objreader.com/download/video/Mbox64.webm
This is because the www.objreader.com private forum was first designed for the ObjReader GDImage/OpenGL 3D engine.
However the forum is great for those wanting to render wavefront 3D models in real time,
using the GDImage/ObjReader specific shader and texture materials.
Here are a few Behance examples of what could be done with it
https://www.behance.net/gallery/1114490 ... NTROL-UNIT
https://www.behance.net/gallery/115233229/Predator
https://www.behance.net/gallery/110660645/PORSCHE-GT3R
There is also a free 64-bit DLL simplified API that is able to render any ObjReader 3D models
http://www.objreader.com/index.php?topic=324.0
It is also a great place for those using directly the core SDK FLAT API to produce small standalone executables.
See also the "Eye Candies" section
http://www.objreader.com/index.php?board=5.0
For those who find the style old fashion,
here are some of the skins that were designed almost 20 years ago for the standard commercial version.
http://www.zapsolution.com/DW/US/skinroom.html
>>Today, people probably smile about it, as pure control elements are preferred at the moment.
One of the greatest WinLIFT feature is that it could work in full DWM composited mode, using varaiable opacity mode.
Here is a video showing what could be done in GDImage/WinLIFT composited mode:
http://www.objreader.com/download/video/Mbox64.webm
Patrice Terrier
objreader@gmail.com
http://www.objreader.com
Addon: WinLIFT (Skin Engine), GDImage (Graphic library), ObjReader (3D engine)
objreader@gmail.com
http://www.objreader.com
Addon: WinLIFT (Skin Engine), GDImage (Graphic library), ObjReader (3D engine)