[Win11] Custom window title color

Windows specific forum
nicoh
User
User
Posts: 26
Joined: Thu Sep 19, 2019 10:44 am

[Win11] Custom window title color

Post by nicoh »

Hi,

I found a way how to color the title bar of windows in Windows 11.

Code: Select all

EnableExplicit

; https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
; The documented enumeration values are not correct !!
; I played around with the values and found the following:
Enumeration DWMWINDOWATTRIBUTE
  #DWMWA_USE_IMMERSIVE_DARK_MODE = 20
  #DWMWA_BORDER_COLOR = 34
  #DWMWA_CAPTION_COLOR = 35
  #DWMWA_TEXT_COLOR = 36
EndEnumeration

; https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
PrototypeC.i DwmSetWindowAttribute(hwnd.i, dwAttribute.l, *pvAttribute, cbAttribute.l)

Define.DwmSetWindowAttribute DwmSetWindowAttribute  
Define.l CaptionColor, TextColor, BorderColor
Define.i UseDarkMode

OpenWindow(0, 50, 50, 600, 400, "Colored Window", #PB_Window_SystemMenu)
OpenWindow(1, 700, 50, 600, 400, "DarkMode Window", #PB_Window_SystemMenu)

CaptionColor = #Green
TextColor = #Blue
BorderColor = #Red
UseDarkMode = #True

If OpenLibrary(0, "dwmapi")  
  DwmSetWindowAttribute = GetFunction(0, "DwmSetWindowAttribute")  
  DwmSetWindowAttribute(WindowID(0), #DWMWA_CAPTION_COLOR, @CaptionColor, SizeOf(CaptionColor))
  DwmSetWindowAttribute(WindowID(0), #DWMWA_TEXT_COLOR, @TextColor, SizeOf(TextColor))
  DwmSetWindowAttribute(WindowID(0), #DWMWA_BORDER_COLOR,  @BorderColor, SizeOf(BorderColor))  
  DwmSetWindowAttribute(WindowID(1), #DWMWA_USE_IMMERSIVE_DARK_MODE, @UseDarkMode, SizeOf(UseDarkMode))
  CloseLibrary(0)
EndIf

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Image

Unfortunately the DWMWINDOWATTRIBUTE enumeration is not documented correctly by Microsoft.
https://docs.microsoft.com/en-us/window ... wattribute
I found out the correct values by trial and error.

Also, this code only works on Windows 11.

Does anyone have an idea if and how this could be done on Windows 10?
BarryG
Addict
Addict
Posts: 3318
Joined: Thu Apr 18, 2019 8:17 am

Re: [Win11] Custom window title color

Post by BarryG »

I don't know about Win 10, but thanks for sharing this Win 11 code.
User avatar
ChrisR
Addict
Addict
Posts: 1150
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: [Win11] Custom window title color

Post by ChrisR »

The example does not work on windows10, the constants used only work on windows 11 and above.
But nice to have for Windows 11 :)

nicoh wrote: Tue Feb 22, 2022 9:32 pm Unfortunately the DWMWINDOWATTRIBUTE enumeration is not documented correctly by Microsoft.
https://docs.microsoft.com/en-us/window ... wattribute
I found out the correct values by trial and error.
I found this with the same values: Flags used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [Win11] Custom window title color

Post by netmaestro »

I did something related around 11 years ago, I think I was on win7 then. Not exactly what you're looking for but it's fun to hack around with. It's a window with no caption and a custom colored sizeable border. Anyway it gives an idea how to custom-paint a frame.

Code: Select all

; Sizeable window with custom-colored border
; Window controls accessible via right-click menu
; netmaestro circa 2010 or 2011 (I think)
; I don't think it leaks

Structure NCCALCSIZE_PARAMS2
  rgrc.RECT[3]
  *lppos.WINDOWPOS
EndStructure

Global gFrameW = GetSystemMetrics_(#SM_CXSIZEFRAME), gCaptionH = GetSystemMetrics_(#SM_CYSIZEFRAME)

Procedure winproc(hwnd, msg, wParam, lParam)

  Select msg
    Case #WM_NCCALCSIZE
      *np.NCCALCSIZE_PARAMS2 = lparam
      SetRect_(*np\rgrc[0],
               *np\lppos\x+gFrameW,
               *np\lppos\y+gCaptionH,
               *np\lppos\x+*np\lppos\cx-gFrameW,
               *np\lppos\y+*np\lppos\cy-gCaptionH)
      ProcedureReturn #WVR_VALIDRECTS | #WVR_REDRAW 
      
    Case #WM_NCPAINT, #WM_NCACTIVATE
      If msg = #WM_NCACTIVATE And wparam = #False
        ProcedureReturn #True
      EndIf
      GetWindowRect_(hwnd, wr.RECT)
      hdcDest = GetWindowDC_(hwnd) 
      hdcSrc = CreateCompatibleDC_(hdc)
      hrgn = CreateRectRgn_(0,0,wr\right-wr\left, wr\bottom-wr\top) 
      hrgn2 = CreateRectRgn_(gFrameW,gCaptionH,wr\right-wr\left-gFrameW,wr\bottom-wr\top-gCaptionH) 
      CombineRgn_(hrgn, hrgn, hrgn2, #RGN_XOR) 
      SelectClipRgn_(hdcDest, hrgn) 
      hBrush = CreateSolidBrush_(#Red)
      SelectObject_(hdcDest, hBrush)
      SelectObject_(hdcDest, GetStockObject_(#NULL_PEN))
      Rectangle_(hdcDest,0,0,wr\right-wr\left+1,wr\bottom-wr\top+1)
      DeleteDC_(hdcSrc)
      DeleteObject_(hBrush)
      ReleaseDC_(hwnd, hdcDest) 
      DeleteObject_(hrgn)
      DeleteObject_(hrgn2)
      ProcedureReturn #False
      
    Case #WM_LBUTTONDOWN
      SendMessage_(hwnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
      
    Case #WM_RBUTTONUP
      DisplayPopupMenu(0, WindowID(0))
      
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
  
EndProcedure

OpenWindow(0,0,0,512,512,"",#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
TextGadget(0,0,0,200,20,"Right-click for menu")
CreatePopupMenu(0)
MenuItem(9, "Exit")

SetWindowLongPtr_(WindowID(0), #GWL_STYLE,GetWindowLongPtr_(WindowID(0), #GWL_STYLE) &~ #WS_SYSMENU)
SetWindowCallback(@winproc(), 0)
SetWindowPos_(WindowID(0),0,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED) ; Trigger WM_NCPAINT

Repeat
  ev=WaitWindowEvent()
  
  Select ev
    Case #PB_Event_Menu
      Select EventMenu()
        Case 9
          End
      EndSelect
      
  EndSelect
  
Until ev=#PB_Event_CloseWindow
BERESHEIT
nicoh
User
User
Posts: 26
Joined: Thu Sep 19, 2019 10:44 am

Re: [Win11] Custom window title color

Post by nicoh »

ChrisR wrote: Wed Feb 23, 2022 2:24 am The example does not work on windows10, the constants used only work on windows 11 and above.

I found this with the same values: Flags used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions
Hi, thanks for the link.

According to this documentation, the DWMWA_USE_IMMERSIVE_DARK_MODE was also added in Win11.
But this code for setting a window to dark mode works on Win10:

Code: Select all

EnableExplicit

; https://pub.dev/documentation/win32/latest/win32/DWMWINDOWATTRIBUTE-class.html
Enumeration DWMWINDOWATTRIBUTE
  #DWMWA_USE_IMMERSIVE_DARK_MODE = 20
EndEnumeration

; https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
PrototypeC.i DwmSetWindowAttribute(hwnd.i, dwAttribute.l, *pvAttribute, cbAttribute.l)

Define.DwmSetWindowAttribute DwmSetWindowAttribute  
Define.i UseDarkMode

OpenWindow(0, 50, 50, 600, 400, "DarkMode Window", #PB_Window_SystemMenu | #PB_Window_Invisible)

UseDarkMode = #True

If OpenLibrary(0, "dwmapi")  
  DwmSetWindowAttribute = GetFunction(0, "DwmSetWindowAttribute")  
  DwmSetWindowAttribute(WindowID(0), #DWMWA_USE_IMMERSIVE_DARK_MODE, @UseDarkMode, SizeOf(UseDarkMode))
  CloseLibrary(0)
EndIf

HideWindow(0, #False)

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Post Reply