• Welcome to PlanetSquires Forums.
 

Window with XP style appearance on Windows 10

Started by José Roca, June 22, 2020, 11:45:25 PM

Previous topic - Next topic

José Roca

Börje Hagsten has posted in the PowerBASIC forum a trick to get a window with an XP appearance on Windows 10. See: https://forum.powerbasic.com/forum/user-to-user-discussions/programming/795791-why-do-my-child-windows-have-a-washed-out-title-bar?p=795889#post795889

Here is an example using CWindow:


' ########################################################################################
' Microsoft Windows
' Contents: CWindow XP style
' Displays the main window using the XP style
' Compiler: FreeBasic 32 & 64 bit
' Copyright (c) 2020 José Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#define UNICODE
#INCLUDE ONCE "Afx/CWindow.inc"
USING Afx

DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                          BYVAL hPrevInstance AS HINSTANCE, _
                          BYVAL szCmdLine AS ZSTRING PTR, _
                          BYVAL nCmdShow AS LONG) AS LONG

   END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)

' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                  BYVAL hPrevInstance AS HINSTANCE, _
                  BYVAL szCmdLine AS ZSTRING PTR, _
                  BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   ' // The recommended way is to use a manifest file
   AfxSetProcessDPIAware

   ' // Creates the main window
   DIM pWindow AS CWindow
   ' -or- DIM pWindow AS CWindow = "MyClassName" (use the name that you wish)
   pWindow.Create(NULL, "CWindow XP style", @WndProc)
   ' // Sizes it by setting the wanted width and height of its client area
   pWindow.SetClientSize(500, 320)
   ' // Centers the window
   pWindow.Center

   ' // Adds a button
   pWindow.AddControl("Button", , IDCANCEL, "&Close", 350, 250, 75, 23)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   STATIC iNcPaint AS LONG

   SELECT CASE uMsg

      CASE WM_CREATE
         ' // No WM_NCPAINT a this stage. Post a message to do it later.
         iNcPaint = 0
         PostMessage hwnd, WM_USER, 0, 0
         EXIT FUNCTION

      CASE WM_USER
         iNcPaint = 1  ' // Now let's do WM_NCPAINT
         PostMessage hwnd, WM_NCACTIVATE, CTRUE, 0

      CASE WM_NCPAINT
         IF iNcPaint = 0 THEN EXIT FUNCTION
         
      CASE WM_COMMAND
         SELECT CASE GET_WM_COMMAND_ID(wParam, lParam)
            CASE IDCANCEL
               ' // If ESC key pressed, close the application by sending an WM_CLOSE message
               IF GET_WM_COMMAND_CMD(wParam, lParam) = BN_CLICKED THEN
                  SendMessageW hwnd, WM_CLOSE, 0, 0
                  EXIT FUNCTION
               END IF
         END SELECT

      CASE WM_SIZE
         ' // Optional resizing code
         IF wParam <> SIZE_MINIMIZED THEN
            ' // Retrieve a pointer to the CWindow class
            DIM pWindow AS CWindow PTR = AfxCWindowPtr(hwnd)
            ' // Move the position of the button
            IF pWindow THEN pWindow->MoveWindow GetDlgItem(hwnd, IDCANCEL), _
               pWindow->ClientWidth - 120, pWindow->ClientHeight - 50, 75, 23, CTRUE
         END IF

    CASE WM_DESTROY
         ' // Ends the application by sending a WM_QUIT message
         PostQuitMessage(0)
         EXIT FUNCTION

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


This is the relevant code:


   STATIC iNcPaint AS LONG

   SELECT CASE uMsg

      CASE WM_CREATE
         ' // No WM_NCPAINT a this stage. Post a message to do it later.
         iNcPaint = 0
         PostMessage hwnd, WM_USER, 0, 0
         EXIT FUNCTION

      CASE WM_USER
         iNcPaint = 1  ' // Now let's do WM_NCPAINT
         PostMessage hwnd, WM_NCACTIVATE, CTRUE, 0

      CASE WM_NCPAINT
         IF iNcPaint = 0 THEN EXIT FUNCTION


Bumblebee

Is this what would be called an undocumented feature?
Failed pollinator.

José Roca


James Fuller

I like it. It works fine with my translators and my ported CWindow. Thanks for posting it here. I overlooked it on the PB site.

James