ObjReader Community
Tips & Tricks => Take the control of your window => Topic started by: Patrice Terrier on February 09, 2020, 04:58:56 pm
-
Get same Blur and Crystal appearance on both VISTA and XP
This screen shot shows you both "Moonraker" and "PhotoComposer" (GDImage) using the new Skin Engine!
As you can see you can create stunning interface with it...
(http://www.zapsolution.com/pictures/sdk/zskinphoto.jpg)
This is the result of many days of brain storming trying to understand DWM, and to work around all the bugs VISTA causes to existing advanced graphic application.
In short, it doesn't respect own Microsoft rules to perform compositing!
and there are many situations where DWM would cause indeed much flickering than on XP, if you are not aware of it.
This is the reason why this new version uses its own way to perform compositing on VISTA.
Note: if you are using Dual monitor with VISTA, there is a problem if you move the skinned window to the second monitor (see the next post for the solution).
Now about this new VISTA version, it allows you to do easily things that are very hard to perform even with VS2005 and WPF.
The new DWM code section:
%S_OK = 0
%WM_DWMCOMPOSITIONCHANGED = &H031E
%DWM_BB_ENABLE = &H00000001
%DWM_BB_BLURREGION = &H00000002
%DWM_BB_TRANSITIONONMAXIMIZED = &H00000004
%DWM_EC_ENABLECOMPOSITION = 1
%DWM_EC_DISABLECOMPOSITION = 0
TYPE DWM_BLURBEHIND
dwFlags AS DWORD
fEnable AS LONG
hRgnBlur AS DWORD
fTransitionOnMaximized AS LONG
END TYPE
TYPE MARGINS
cxLeftWidth AS LONG
cxRightWidth AS LONG
cyTopHeight AS LONG
cyBottomHeight AS LONG
END TYPE
FUNCTION LoadDWM () AS LONG
STATIC hLib AS DWORD, nChecked AS LONG
IF nChecked = 0 THEN nChecked = -1: hLib = LoadLibrary ("dwmapi.dll")
FUNCTION = hLib
END FUNCTION
DECLARE FUNCTION DwmEnableComposition (BYVAL uCompositionAction AS LONG) AS LONG
SUB zDwmEnableComposition (BYVAL uCompositionAction AS LONG)
LOCAL nRet AS LONG, hLib AS DWORD
STATIC hProc AS DWORD
hLib = LoadDWM()
IF hLib THEN
IF hProc = 0 THEN hProc = GetProcAddress(hLib, "DwmEnableComposition")
IF hProc THEN
CALL DWORD hProc USING DwmEnableComposition(uCompositionAction) TO nRet
END IF
END IF
END SUB
DECLARE FUNCTION DwmIsCompositionEnabled () AS LONG
FUNCTION zDwmIsCompositionEnabled () AS LONG
LOCAL nRet AS LONG, hLib AS DWORD
STATIC hProc AS DWORD
hLib = LoadDWM()
IF hLib THEN
IF hProc = 0 THEN hProc = GetProcAddress(hLib, "DwmIsCompositionEnabled")
IF hProc THEN
CALL DWORD hProc USING DwmIsCompositionEnabled() TO nRet
IF nRet THEN FUNCTION = -1
END IF
END IF
END FUNCTION
DECLARE FUNCTION DwmEnableBlurBehindWindow (BYVAL LONG, pBlurBehind AS DWM_BLURBEHIND) AS LONG
SUB zSetBlurBehindMode(BYVAl hWnd AS LONG, BYVAL nBOOL AS LONG, BYVAL hRgnBlur AS LONG)
LOCAL bb AS DWM_BLURBEHIND
LOCAL hLib AS DWORD, nRet AS LONG
STATIC hProc AS DWORD
hLib = LoadDWM ()
IF hLIB THEN
IF zDwmIsCompositionEnabled() THEN
IF hProc = 0 THEN hProc = GetProcAddress(hLib, "DwmEnableBlurBehindWindow")
IF hProc THEN
nRet = %S_OK
' // Create and populate the BlurBehind structure.
' // Set Blur Behind and Blur Region.
bb.fEnable = nBOOL
bb.dwFlags = %DWM_BB_ENABLE OR %DWM_BB_BLURREGION
bb.hRgnBlur = hRgnBlur
' // Set Blur Behind mode.
CALL DWORD hProc USING DwmEnableBlurBehindWindow(hWnd, bb) TO nRet
END IF
END IF
END IF
END SUB
SUB zSetCrystalBehindMode(BYVAl hWnd AS LONG, BYVAL nBOOL AS LONG)
LOCAL bb AS DWM_BLURBEHIND
LOCAL hLib AS DWORD, nRet, hRgnBlur AS LONG
STATIC hProc AS DWORD
hLib = LoadDWM ()
IF hLIB THEN
IF zDwmIsCompositionEnabled() THEN
IF hProc = 0 THEN hProc = GetProcAddress(hLib, "DwmEnableBlurBehindWindow")
IF hProc THEN
nRet = %S_OK
' // Create and populate the BlurBehind structure.
' // Set Blur Behind and Blur Region.
bb.dwFlags = %DWM_BB_ENABLE OR %DWM_BB_BLURREGION
bb.fEnable = nBOOL
bb.fTransitionOnMaximized = 0
' // Fool VISTA with a fake region
hRgnBlur = CreateRectRgn(-1, -1, 0, 0)
bb.hRgnBlur = hRgnBlur
' // Set Blur Behind mode.
CALL DWORD hProc USING DwmEnableBlurBehindWindow(hWnd, bb) TO nRet
END IF
END IF
END IF
END SUB
The complete project is in the attached zskin13.zip
And now that all the hard stuff is done, we will be able to play the fun... using GDImage. 8)
-
Note: if you are using Dual monitor with VISTA, there is a problem if you move the skinned window to the second monitor.
To fix the Dual monitor mouse location problem, replace in the source code all reference to
LOWRD(lParam), HIWRD(lParam)
with
LO(INTEGER, lParam), HI(INTEGER, lParam)
to get a signed value instead of the unsigned WORD.
'// Monitor Windows DEF PROC to take over HITTEST detection
FUNCTION zDefWindowProc(BYVAL hWnd AS LONG, BYVAL Msg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
LOCAL nRet, HITTEST AS LONG
LOCAL rc AS RECT
nRet = DefWindowProc(hWnd, Msg, wParam, lParam)
IF Msg = %WM_NCHITTEST THEN
LOCAL p AS POINTAPI
LOCAL CaptionHeight AS LONG
CALL zGetImageSize(zGetProperty(hWnd, %FORM_TopMid), 0, CaptionHeight)
p.X = LO(INTEGER, lParam): p.Y = HI(INTEGER, lParam)
CALL ScreenToClient(hWnd, p)
IF IsZoomed(hWnd) = 0 THEN
IF nRet = %HTCLIENT THEN
HITTEST = %HTCAPTION
IF SK_DRAG_BACKGROUND() = 0 THEN
IF p.Y > CaptionHeight AND CaptionHeight > 0 THEN
HITTEST = %HTNOWHERE
IF hWnd <> GetForegroundWindow THEN CALL SetFocus(hWnd)
END IF
END IF