Page 1 of 3

DWM for windows Vista and PB

Posted: Sun Jan 28, 2007 3:21 pm
by SFSxOI
Finally got the new Vista Desktop Window Manager (DWM) to work in PureBasic. I know a lot of you might not have Vista right now, but some of you will soon. So...heres a working example for DWM in Vista and PureBasic. It enables the Vista Glass effect for a window;

(This only works on Vista)

Code: Select all

#DWM_BB_ENABLE = 1
#DWM_BB_BLURREGION = 2
#DWM_BB_TRANSITIONONMAXIMIZED = 4

Structure DWM_BLURBEHIND
dwFlags.l
fEnable.b
hRgnBlur.l
fTransitionOnMaximized.b
EndStructure

Procedure EnableBlurBehindWindow(hWnd.l, enable.b = #True, region.l = 0, transitionOnMaximized.b = #False)

blurBehind.DWM_BLURBEHIND 
blurBehind\dwFlags = #DWM_BB_ENABLE | #DWM_BB_TRANSITIONONMAXIMIZED
;blurBehind\dwFlags = #DWM_BB_ENABLE 
blurBehind\fEnable = enable
blurBehind\fTransitionOnMaximized = transitionOnMaximized

Lib = LoadLibrary_("dwmapi.dll") ; load the library

  If Lib
    If (enable And 0) <> region
      blurBehind\dwFlags = #DWM_BB_BLURREGION
      blurBehind\hRgnBlur = region
    EndIf
        *pAfunc = GetProcAddress_(Lib, "DwmEnableBlurBehindWindow") ; get pointer to function
        CallFunctionFast(*pAfunc, hWnd, @blurBehind) ; call the function
        MessageRequester("Information", "Blur Behind is enabled", #PB_MessageRequester_Ok)
        FreeLibrary_(Lib) ; free up the library
  EndIf
  
ProcedureReturn ; returns 1 if function called sucessfully

EndProcedure

hWnd.l = OpenWindow(0,100,100,300,300, "Test_V_DWM", #PB_Window_SystemMenu)
Color = RGB(000, 000, 000)
SetWindowColor(0, Color) 
;will not see DWM blur glass effect in PB windows unless we
;change the client area color to something less 'white' (opaque).
;We need to paint our own color for windows here. don't use white
;(255,255,255) or similar as will not see blur effect very well
;some colors look a whole lot better. Vista DWM uses ARGB
;I just do a simple quick set window color here for demo purposes

EnableBlurBehindWindow(hWnd.l)

Repeat 
    Event = WindowEvent() 

    If Event    ; event in queue then process 
    Else  
      Delay(1)  ; No queue event, CPU time for something else 
    EndIf 
  Until Event = #PB_Event_CloseWindow

Re: DWM for windows Vista and PB

Posted: Sun Jan 28, 2007 3:50 pm
by Num3
SFSxOI wrote:I know a lot of you might not have Vista right now, but some of you will soon.
Naaaaaaaaaaaaaaaaaaaaaaaa :twisted: :twisted: :twisted:

Re: DWM for windows Vista and PB

Posted: Sun Jan 28, 2007 3:55 pm
by SFSxOI
Num3 wrote:
SFSxOI wrote:I know a lot of you might not have Vista right now, but some of you will soon.
Naaaaaaaaaaaaaaaaaaaaaaaa :twisted: :twisted: :twisted:
Well...I did say "some of you will soon" - your just not in the "some" category :)

Posted: Sun Jan 28, 2007 5:30 pm
by Kaeru Gaman

Code: Select all

   |
   |
---o---
   |
   |
   |
   |

Vade Retro, Vistanas!

Posted: Sun Jan 28, 2007 11:09 pm
by SFSxOI
And...here is a version using mostly API for the window and stuff :

Code: Select all

#Style = #WS_VISIBLE | #WS_SYSMENU
#DWM_BB_ENABLE = 1
#DWM_BB_BLURREGION = 2
#DWM_BB_TRANSITIONONMAXIMIZED = 4

Structure DWM_BLURBEHIND
dwFlags.l
fEnable.b
hRgnBlur.l
fTransitionOnMaximized.b
EndStructure

Procedure EnableBlurBehindWindow(hWnd.l, enable.b = #True, region.l = 0, transitionOnMaximized.b = #False)

blurBehind.DWM_BLURBEHIND 
blurBehind\dwFlags = #DWM_BB_ENABLE | #DWM_BB_TRANSITIONONMAXIMIZED
;blurBehind\dwFlags = #DWM_BB_ENABLE 
blurBehind\fEnable = enable
blurBehind\fTransitionOnMaximized = transitionOnMaximized

Lib = LoadLibrary_("dwmapi.dll") ; load the library

  If Lib
    If (enable And 0) <> region
      blurBehind\dwFlags = #DWM_BB_BLURREGION
      blurBehind\hRgnBlur = region
    EndIf
        *pAfunc = GetProcAddress_(Lib, "DwmEnableBlurBehindWindow") ; get pointer to function
        CallFunctionFast(*pAfunc, hWnd, @blurBehind) ; call the function
        MessageRequester("Information", "Blur Behind is enabled", #PB_MessageRequester_Ok)
        FreeLibrary_(Lib) ; free up the library, the API here doesn't cause invalid memory error where a PB CloseLibrary() will.
  EndIf
  
ProcedureReturn ; returns 1 if function called sucessfully

EndProcedure

Procedure WindowCallback(Window, Message, wParam, lParam) 
  Select Message 
    Case #WM_CLOSE 
      If MessageBox_(Window, "You sure?", "EXIT", #MB_YESNO) = #IDYES 
        DestroyWindow_(Window) 
      Else 
        Result  = 0 
      EndIf 
    Case #WM_DESTROY 
      PostQuitMessage_(0) 
      Result = 0 
    Default 
      Result = DefWindowProc_(Window, Message, wParam, lParam) 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

WindowClass.s  = "dwmwclass" 
wc.WNDCLASSEX 
wc\cbSize  = SizeOf(WNDCLASSEX) 
wc\lpfnWndProc  = @WindowCallback() 
wc\hCursor  = LoadCursor_(0, #IDC_ARROW) 
wc\hbrBackground  = #Null ; not #COLOR_WINDOW+1 an application must paint its own background for this example  
wc\lpszClassName  = @WindowClass 
RegisterClassEx_(@wc) 

hWnd.l = CreateWindowEx_(#WS_EX_DLGMODALFRAME, WindowClass, "DWM_Test", #Style, 10, 10, 200, 200, 0, 0, 0, 0) 
;///////////////////////////////////////////////
;to do fully transparent client region use EnableBlurBehindWindow(hWnd.l, #Null)
;///////////////////////////////////////////////
EnableBlurBehindWindow(hWnd.l)

While GetMessage_(msg.MSG, #Null, 0, 0 ) 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
Wend

Posted: Sun Jan 28, 2007 11:50 pm
by SFSxOI
And...just a simple something to determine if composition is enabled. Its dumb because its obvious if composition is enabled or not, but sometimes its needed it turns out:

Code: Select all

; PB_DWM_IsCompositionEnabled
Procedure IsCompositionEnabled()

Lib = LoadLibrary_("dwmapi.dll")

  If Lib
    *pAfunc = GetProcAddress_(Lib, "DwmIsCompositionEnabled") ; get pointer to function
    CallFunctionFast(*pAfunc, *pfEnabled.b) ; call the function
    FreeLibrary_(Lib)
  EndIf

ProcedureReturn ; returns 1 if DWM composition enabled, 0 if not

EndProcedure

Debug IsCompositionEnabled()

Posted: Tue Jan 30, 2007 12:25 am
by SFSxOI
And...another example for Vista's DWM with PB (also with some API). This turns the DWM composition on and off for the entire desktop (read the MSDN about it for its effect)

Code: Select all

#DWM_EC_ENABLECOMPOSITION = 1
#DWM_EC_DISABLECOMPOSITION = 0

Procedure DWMEnableDisable(onoff.b)

Lib = LoadLibrary_("dwmapi.dll")

  If Lib
    If (onoff.b = 1) Or (onoff.b = 0) ; only accept 1 = DWM on, 0 = DWM off
    ;Null = Off or #True or #False if you perfer
    *pAfunc = GetProcAddress_(Lib, "DwmEnableComposition") ; get pointer to function
      If onoff.b = 1 
        CallFunctionFast(*pAfunc, #DWM_EC_ENABLECOMPOSITION) ; call the function to enable DWM composition
      ElseIf onoff.b = 0
        CallFunctionFast(*pAfunc, #DWM_EC_DISABLECOMPOSITION) ; call the function to disable DWM composition
      EndIf
    FreeLibrary_(Lib) ; free up the library
    EndIf 
  EndIf 

EndProcedure

example: DWMEnableDisable(#False)

Posted: Tue Jan 30, 2007 5:36 am
by Edwin Knoppert
Post a screenshot of something nice.
Maybe 'before' and 'after' ??

Posted: Tue Jan 30, 2007 5:58 am
by Brice Manuel
Edwin Knoppert wrote:Post a screenshot of something nice.
Maybe 'before' and 'after' ??
This would probably be a good idea when posting any Vista specific code, as it will probably be a long time before most folks here have it. Even if they don't have it, people still like to drool over eye candy :D

Posted: Tue Jan 30, 2007 12:30 pm
by SFSxOI
OK, here are some pics;

First one is just a reference for the desktop on one of my machines so you'll have some bearings (not very tidy right now):

http://www.jpegup.com/v.php?id=47699desktop_ref1.jpg

The next ones are some pics of various simple screen captures.
http://www.jpegup.com/v.php?id=56700Vis ... B_Test.jpg
http://www.jpegup.com/v.php?id=72628gla ... ehind1.jpg
http://www.jpegup.com/v.php?id=24516Vis ... ample1.jpg

and this last one is fully transparent. You have to use the API to do the window in this one because the PB windows won't do it for DWM, or at least I haven't been able to get a PB window to do it yet with DWM.
http://www.jpegup.com/v.php?id=94415DWM ... parent.jpg

Of course these are just the blurring behind the window client area because thats what i'm playing with right now and its what the above example code will produce, there are other things possible with DWM, especially when you get into the rest of the Presentation Foundation.

BTW, what looks like desktop wallpaper is part of one of the theme's for Aero that comes with Vista, but this one's special, its been turned into a full motion desktop. It doesn't show in the pics but the water ripples and an occaisional fish rises to the surface, there are a couple of trees on the left that sway in the breeze. It looks really realstic, like you were really there. Its a little project that i'm working on for work using the presentation foundation I modified the theme to include those things, still working on it, less then 3% resources used to run it and don't even notice it at all. Full motion desktop is possible in Vista.

Posted: Wed Jan 31, 2007 11:13 pm
by fsw
@SFSxOI
you are using Win32 API, but I thought it's deprecated in Vista. (because it's obsolete)

Besides, GDI and GDI+ are not hardware accelarated anymore.

So if PB is using GDI or GDI+ any drawing will be slower than it was on XP, or not?

Posted: Thu Feb 01, 2007 12:01 am
by SFSxOI
fsw wrote:@SFSxOI
you are using Win32 API, but I thought it's deprecated in Vista. (because it's obsolete)

Besides, GDI and GDI+ are not hardware accelarated anymore.

So if PB is using GDI or GDI+ any drawing will be slower than it was on XP, or not?
The API is alive and well in Vista, however, there are some items that were deprecated the same as always happens over time. In fact there have been new API's added for Vista, especially for file functions. Vista uses GDI+ for a lot of things, Vista renders everything off screen and it uses some GDI+ to do this, so no one needs to worry about porting stuff over the the new Windows Presentation Foundation just yet. there is more DirectX used in DWM then anything else however. Honestly, Vista probably, in a general minimum respect, means a vid card upgrade for some people and maybe an investment in more memory. I'm using an ATI 800 Pro series card and it supports Vista just fine. I haven't noticed any slow downs. GDI+ in Vista seems to work well, in fact some of the GDI examples posted in the forums are faster in Vista with DWM enabled then they ever were in XP (for me). Also, i'm working in the Aero Theme, so there are things used in the Aero theme that might not be used if i switched to the classic theme, and the DWM effects and API's are mostly used in the Aero theme even tho they can be used at any time. The Aero Glass theme was designed to speed up screen rendering, and it works great. You can read more about the new API's added with Vista, or changes in the API for Vista, in the MSDN at:
http://msdn2.microsoft.com/en-us/library/aa383874.aspx

Since you mention that i'm using API, heres another DWM example for the DwmExtendFrameIntoClientArea function. I'm using API, especially in this example, because there are some areas where PureBasic functions will not work in Vista with DWM. While this is an example of one of them i'm sure that PureBasic will offer more Vista support within a few years just like it has with other versions of windows. Read the comments in the code to find out why I used API here.

Code: Select all

#Style = #WS_VISIBLE | #WS_SYSMENU

Structure MARGINS
cxLeftWidth.l
cxRightWidth.l
cyTopHeight.l
cyBottomHeight.l
EndStructure

Procedure ExtendFrame(hWnd.l)
; the margin structure do -1 as shown below
; for sheet glass effect for whole window
pMargin.MARGINS
pMargin\cxLeftWidth = -1
pMargin\cxRightWidth = -1
pMargin\cyTopHeight = -1
pMargin\cyBottomHeight = -1

Lib = LoadLibrary_("dwmapi.dll") ; load the library

    If Lib
        *pAfunc = GetProcAddress_(Lib, "DwmExtendFrameIntoClientArea") ; get pointer to function
        CallFunctionFast(*pAfunc, hWnd, pMargin) ; call the function
        MessageRequester("Information", "Frame extended into window!", #PB_MessageRequester_Ok)
        FreeLibrary_(Lib) ; free up the library
    EndIf

EndProcedure

Procedure WindowCallback(Window, Message, wParam, lParam) 
  Select Message 
    Case #WM_CLOSE 
      If MessageBox_(Window, "You sure?", "EXIT", #MB_YESNO) = #IDYES 
        DestroyWindow_(Window) 
      Else 
        Result  = 0 
      EndIf 
    Case #WM_DESTROY 
      PostQuitMessage_(0) 
      Result = 0 
    Default 
      Result = DefWindowProc_(Window, Message, wParam, lParam) 
  EndSelect 
  ProcedureReturn Result 
EndProcedure 

WindowClass.s  = "dwmwclass" 
wc.WNDCLASSEX 
wc\cbSize  = SizeOf(WNDCLASSEX) 
wc\lpfnWndProc  = @WindowCallback() 
wc\hCursor  = LoadCursor_(0, #IDC_ARROW) 
wc\hbrBackground  = #Null ; not #COLOR_WINDOW+1 an application must paint its own background for this example  
wc\lpszClassName  = @WindowClass 
RegisterClassEx_(@wc) 

hWnd.l = CreateWindowEx_(#WS_EX_DLGMODALFRAME, WindowClass, "DWM_Test", #Style, 10, 10, 200, 200, 0, 0, 0, 0)
ExtendFrame(hWnd.l)

; The "DwmExtendFrameIntoClientArea" DWM function
; does not work for windows produced by
; PureBasic commands.
; will work with windows produced by API as above

While GetMessage_(msg.MSG, #Null, 0, 0 ) 
  TranslateMessage_(msg) 
  DispatchMessage_(msg) 
Wend
You'll notice the window has no borders (frame), actually it does but the code above extends them into the window producing what is called the 'sheet glass' effect. After you do this you can draw on the surface, put gadgets, etc, and get a really neat looking GUI going, looks really 3D because the gadgets apear to be actually floating over the 'sheet glass' background.

Here's a pic showing the effect of extending the frame from the code above:

http://www.123pichosting.com/viewer.php ... tended.JPG

And...heres another pic showing the same extended frame window (over the Purebasic IDE, this very code in fact) but to point out something that DWM adds by default, a shadow effect around a window. The pic also shows a faint lighter band diagonally on the window, this is the reflective effect of the DWM Glass.

http://www.123pichosting.com/viewer.php ... nded_2.JPG


(These were captured from the screen with the built in 'screen capture' tool in Vista called the Snipping Tool.)

Posted: Tue Feb 06, 2007 11:29 pm
by SFSxOI
And....if anyone wants it, i'm using the include file below, with two of the helper functions in it. It contains all the constants and structures for DWM. I built a library also but its not right yet. Here is the working test .pbi i'm using for testing, any suggestions welcome for the .pbi.

Code: Select all

;////////////test V_dwm_inc_a.pbi////////////
;for Windows Vista DWM

;////////////parameters////////////////////////////////////////////////////////////////////
;hWnd = A window handle
;pMargin = A pointer to the MARGINS structure
;enable = Either #True or #False (or 1 or 0)
;hRgnBlur = A handle to a region to blur or 0 otherwise (0 blurs the entire client window)
;transitionOnMaximized = Basically tells the window title bar to use the blur at max or not
;onoff.b = Turn something on or off with 1 or 0 or #true/#false, Null = off
;//////////////////////////////////////////////////////////////////////////////////////////
; Vista DWM include file

;Constants
#DWM_BB_ENABLE = 1
#DWM_BB_BLURREGION = 2
#DWM_BB_TRANSITIONONMAXIMIZED = 4
#DWM_EC_DISABLECOMPOSITION = 0
#DWM_EC_ENABLECOMPOSITION = 1
#DWM_TNP_RECTDESTINATION = $00000001
#DWM_TNP_RECTSOURCE = $00000002
#DWM_TNP_OPACITY = $00000004
#DWM_TNP_VISIBLE = $00000008
#DWM_TNP_SOURCECLIENTAREAONLY = $00000010

Enumeration ;DWM_SOURCE_FRAME_SAMPLING
  #DWM_SOURCE_FRAME_SAMPLING_POINT = 1
  #DWM_SOURCE_FRAME_SAMPLING_COVERAGE
  #DWM_SOURCE_FRAME_SAMPLING_LAST
EndEnumeration

Enumeration ;DWMFLIP3DWINDOWPOLICY
  #DWMFLIP3D_DEFAULT
  #DWMFLIP3D_EXCLUDEBELOW
  #DWMFLIP3D_EXCLUDEABOVE
EndEnumeration

Enumeration ;DWMNCRENDERINGPOLICY
  #DWMNCRP_USEWINDOWSTYLE
  #DWMNCRP_DISABLED
  #DWMNCRP_ENABLED
  #DWMNCRP_LAST
EndEnumeration

Enumeration ;DWMWINDOWATTRIBUTE
#DWMWA_NCRENDERING_ENABLED = 1
#DWMWA_NCRENDERING_POLICY
#DWMWA_TRANSITIONS_FORCEDISABLED
#DWMWA_ALLOW_NCPAINT
#DWMWA_CAPTION_BUTTON_BOUNDS
#DWMWA_NONCLIENT_RTL_LAYOUT
#DWMWA_FORCE_ICONIC_REPRESENTATION
#DWMWA_FLIP3D_POLICY
#DWMWA_EXTENDED_FRAME_BOUNDS
#DWMWA_LAST
EndEnumeration

;Structures
Structure DWM_BLURBEHIND
  dwFlags.l
  fEnable.b
  hRgnBlur.l
  fTransitionOnMaximized.b
EndStructure

Structure MARGINS
  cxLeftWidth.l
  cxRightWidth.l
  cyTopHeight.l
  cyBottomHeight.l
EndStructure

Structure DWM_PRESENT_PARAMETERS
    cbSize.l
    fQueue.l
    cRefreshStart.q
    cBuffer.l
    fUseSourceRate.q
    rateSource.l
    cRefreshesPerFrame.l
    eSampling.l
EndStructure

Structure DWM_THUMBNAIL_PROPERTIES
  dwFlags.l
  rcDestination.l
  rcSource.l
  opacity.b
  fVisible.b
  fSourceClientAreaOnly.b
EndStructure

;DWM_TIMING_INFO structure corrected 8/10/2009 courtesy of Rescator
; http://www.purebasic.fr/english/viewtopic.php?p=295163#295163
Structure DWM_TIMING_INFO 
 cbSize.l 
 rateRefresh.UNSIGNED_RATIO 
 qpcRefreshPeriod.q 
 rateCompose.UNSIGNED_RATIO 
 qpcVBlank.q 
 cRefresh.q 
 cDXRefresh.l 
 qpcCompose.q 
 cFrame.q 
 cDXPresent.l 
 cRefreshFrame.q 
 cFrameSubmitted.q 
 cDXPresentSubmitted.l 
 cFrameConfirmed.q 
 cDXPresentConfirmed.l 
 cRefreshConfirmed.q 
 cDXRefreshConfirmed.l 
 cFramesLate.q 
 cFramesOutstanding.l 
 cFrameDisplayed.q 
 qpcFrameDisplayed.q 
 cRefreshFrameDisplayed.q 
 cFrameComplete.q 
 qpcFrameComplete.q 
 cFramePending.q 
 qpcFramePending.q 
 cFramesDisplayed.q 
 cFramesComplete.q 
 cFramesPending.q 
 cFramesAvailable.q 
 cFramesDropped.q 
 cFramesMissed.q 
 cRefreshNextDisplayed.q 
 cRefreshNextPresented.q 
 cRefreshesDisplayed.q 
 cRefreshesPresented.q 
 cRefreshStarted.q 
 cPixelsReceived.q 
 cPixelsDrawn.q 
 cBuffersEmpty.q 
EndStructure 

Structure UNSIGNED_RATIO
  uiNumerator.l
  uiDenominator.l
EndStructure

ProcedureDLL.l V_DWMExtendFrameIntoClientArea(hWnd.l, pMargin)

Libef = OpenLibrary(#PB_Any, "dwmapi.dll")

    If Libef
        *pAEFfunc = GetFunction(Libef, "DwmExtendFrameIntoClientArea")
        CallFunctionFast(*pAEFfunc, hWnd, pMargin)
        CloseLibrary(Libef)
    EndIf
    
    ProcedureReturn 

EndProcedure

ProcedureDLL.l V_DWMEnableBlurBehindWindow(hWnd.l, enable.b, hRgnBlur.l, transitionOnMaximized.b)

blurBehind.DWM_BLURBEHIND 
blurBehind\dwFlags = #DWM_BB_ENABLE | #DWM_BB_TRANSITIONONMAXIMIZED
blurBehind\fEnable = enable
blurBehind\fTransitionOnMaximized = transitionOnMaximized

Libbb = OpenLibrary(#PB_Any, "dwmapi.dll")

  If Libbb
    If (enable And 0) <> region
      blurBehind\dwFlags = #DWM_BB_BLURREGION
      blurBehind\hRgnBlur = region
    EndIf
        *pABBfunc = GetFunction(Libbb, "DwmEnableBlurBehindWindow")
        CallFunctionFast(*pABBfunc, hWnd, @blurBehind)
        CloseLibrary(Libbb)
  EndIf
  
  ProcedureReturn 
  
EndProcedure


ProcedureDLL.l V_DWMEnableComposition(onoff.b)

Libed = OpenLibrary(#PB_Any, "dwmapi.dll")

  If Libed
    If (onoff.b = 1) Or (onoff.b = 0)
    *pAEDfunc = GetFunction(Libed, "DwmEnableComposition")
      If onoff.b = 1 
        CallFunctionFast(*pAEDfunc, #DWM_EC_ENABLECOMPOSITION)
      ElseIf onoff.b = 0
        CallFunctionFast(*pAEDfunc, #DWM_EC_DISABLECOMPOSITION)
      EndIf
    CloseLibrary(Libed)
    EndIf 
  EndIf 

  ProcedureReturn

EndProcedure


ProcedureDLL.l V_DWMIsCompositionEnabled()

Libce = OpenLibrary(#PB_Any, "dwmapi.dll")

  If Libce
    pAICfunc = GetFunction(Libce, "DwmIsCompositionEnabled")
    pfEnabled.b = #False
    If CallFunctionFast(*pAICfunc, @pfEnabled.b)
    enabled.b = #True
    EndIf 
    CloseLibrary(Libce)
  EndIf
  
  ProcedureReturn enabled
  
EndProcedure

Posted: Tue Feb 06, 2007 11:29 pm
by SFSxOI
if anyone wants to play with a library version let me know.

Posted: Sun Feb 11, 2007 11:39 pm
by DoubleDutch
SFSxOI: I've just installed Vista. Your demos are great!

I would like to use a library.

I think that a useful function would be to enable blur on the background region of a PureBasic gadget.

Eg:

Code: Select all

BlurGadgetBGnd(#Gadget,flag) ; flag would be true to enable blur, false to disable
-Anthony