{ ============================================================================ XP Themed Controls Support (C) Copyright 2007 LOGIX, All Rights Reserved. Changes: Created 12/20/2006 by Mike Ghan Adapted to SwiftForth 3.1 1/11/2008 MAG Quick Demo: Copy the contents of this file to ComCntlsXP.F Copy the file SF.exe.manifest to the same directory as SF.exe. Launch SF INCLUDE ComCntlsXP.F (this file) Note: for a turnkey app, rename SF.exe.manifest to MyApp.exe.manifest and include it with your distribution. Your app must execute INIT-THEME at startup. =========================================================================== } FALSE VALUE THEMED? \ Our App Uses Themes FALSE VALUE THEMED-DLL? \ True = DLL Loaded [OPTIONAL] LIBRARY UXTHEME.DLL [UNDEFINED] LIB-LOADED? [IF] : LIB-LOADED? ( addr cnt -- flag ) DLL-LOADED? ; : CLOSE-LIB ( addr cnt -- ) FREE-DLL ; [THEN] : CLOSE-THEME-DLL ( -- ) FALSE TO THEMED-DLL? S" UXTHEME.DLL" 2DUP LIB-LOADED? NOT IF 2DROP EXIT THEN ( else ) CLOSE-LIB ; :ONSYSLOAD \ Cleanup at Exit FALSE TO THEMED-DLL? ; : LOAD-UXTHEME ( -- ) S" UXTHEME.DLL" LIB-LOADED? TO THEMED-DLL? ; : CLOSE-UXTHEME ( -- ) THEMED-DLL? -EXIT CLOSE-THEME-DLL ; :ONSYSEXIT CLOSE-UXTHEME ; \ Combine bytes in to Word16 : MAKEWORD ( lsw8 msw8 -- word16 ) 8 LSHIFT SWAP $0FF AND OR ; \ **************************************************************************** \ UXTHEME Functions \ **************************************************************************** \ Reports whether the current application's user interface displays using visual styles. [OPTIONAL] Function: IsAppThemed ( -- flag ) \ Tests if a visual style for the current application is active. [OPTIONAL] Function: IsThemeActive ( -- flag ) { --------------------------------------------------------------------------- // OpenThemeData() - Open the theme data for the specified HWND and // semi-colon separated list of class names. // // OpenThemeData() will try each class name, one at // a time, and use the first matching theme info // found. If a match is found, a theme handle // to the data is returned. If no match is found, // a "NULL" handle is returned. // // When the window is destroyed or a WM_THEMECHANGED // msg is received, "CloseThemeData()" should be // called to close the theme handle. // // hwnd - window handle of the control/window to be themed // // pszClassList - class name (or list of names) to match to theme data // section. if the list contains more than one name, // the names are tested one at a time for a match. // If a match is found, OpenThemeData() returns a // theme handle associated with the matching class. // This param is a list (instead of just a single // class name) to provide the class an opportunity // to get the "best" match between the class and // the current theme. For example, a button might // pass L"OkButton, Button" if its ID=ID_OK. If // the current theme has an entry for OkButton, // that will be used. Otherwise, we fall back on // the normal Button entry. //--------------------------------------------------------------------------- } [OPTIONAL] Function: OpenThemeData ( hWnd spClassList -- hTheme ) { --------------------------------------------------------------------------- // CloseThemeData() - closes the theme data handle. This should be done // when the window being themed is destroyed or // whenever a WM_THEMECHANGED msg is received // (followed by an attempt to create a new Theme data // handle). // // hTheme - open theme data handle (returned from prior call // to OpenThemeData() API). //--------------------------------------------------------------------------- } [OPTIONAL] Function: CloseThemeData ( hTheme -- ) { ------------------------------------------------------------------------ // DrawThemeBackground() // - draws the theme-specified border and fill for // the "iPartId" and "iStateId". This could be // based on a bitmap file, a border and fill, or // other image description. // // hTheme - theme data handle // hdc - HDC to draw into // iPartId - part number to draw // iStateId - state number (of the part) to draw // pRect - defines the size/location of the part // pClipRect - optional clipping rect (don't draw outside it) //------------------------------------------------------------------------ } [OPTIONAL] Function: DrawThemeBackground ( hTheme hdc iPartId iStateId pRect pClipRect -- ) { ------------------------------------------------------------------------- // GetThemeBackgroundContentRect() // - gets the size of the content for the theme-defined // background. This is usually the area inside // the borders or Margins. // // hTheme - theme data handle // hdc - (optional) device content to be used for drawing // iPartId - part number to draw // iStateId - state number (of the part) to draw // pBoundingRect - the outer RECT of the part being drawn // pContentRect - RECT to receive the content area //------------------------------------------------------------------------- } [OPTIONAL] Function: GetThemeBackgroundContentRect ( hTheme hdc iPartId iStateId pBoundingRect pContentRect -- ) \ DrawThemeText() flags 1 CONSTANT DTT_GRAYED \ Draw a grayed-out string { ------------------------------------------------------------------------- // DrawThemeText() - draws the text using the theme-specified // color and font for the "iPartId" and // "iStateId". // // hTheme - theme data handle // hdc - HDC to draw into // iPartId - part number to draw // iStateId - state number (of the part) to draw // pszText - actual text to draw // dwCharCount - number of chars to draw (-1 for all) // dwTextFlags - same as DrawText() "uFormat" param // dwTextFlags2 - additional drawing options // pRect - defines the size/location of the part //------------------------------------------------------------------------- } [OPTIONAL] Function: DrawThemeText ( hTheme hdc iPartId iStateId pszText iCharCount dwTextFlags dwTextFlags2 pRect -- ) \ **************************************************************************** \ DLL Version \ **************************************************************************** CLASS DLLVERSIONINFO VARIABLE Size \ Size of the structure, in bytes. This member must be filled in before calling the function. VARIABLE MajorVersion \ Major version of the DLL. If the DLL's version is 4.0.950, this value will be 4. VARIABLE MinorVersion \ Minor version of the DLL. If the DLL's version is 4.0.950, this value will be 0. VARIABLE BuildNumber \ Build number of the DLL. If the DLL's version is 4.0.950, this value will be 950. VARIABLE PlatformID \ Identifies the platform for which the DLL was built. This can be one of the following values. \ DLLVER_PLATFORM_WINDOWS The DLL was built for all Microsoft Windows platforms. \ DLLVER_PLATFORM_NT The DLL was built specifically for Microsoft Windows NT. : CONSTRUCT ( -- ) [ THIS SIZEOF ] LITERAL Size ! ; END-CLASS Function: DllGetVersion ( pDLLVERSIONINFO -- res ) : COMCNTL-THEMED? ( -- flag ) \ Version 6.0 or Greater and manifest present [OBJECTS DLLVERSIONINFO MAKES DVI OBJECTS] DVI CONSTRUCT DVI ADDR DllGetVersion DROP DVI MinorVersion @ DVI MajorVersion @ MAKEWORD $600 ( Version 6.00 ) >= ; \ **************************************************************************** \ Init Theme \ **************************************************************************** \ We first check if DLL Version supports themes (>=6.0). \ Next we verify theme library (DLL) is open. \ Lastly, we test if user has themes turned off. : INIT-THEME ( -- ) FALSE TO THEMED? ( default is No themes ) FALSE TO THEMED-DLL? COMCNTL-THEMED? -EXIT LOAD-UXTHEME THEMED-DLL? ( Loaded ) -EXIT IsAppThemed 0<> TO THEMED? ; CR .( Your App must call INIT-THEME ) \ **************************************************************************** \ "Button" Parts & States \ **************************************************************************** \ PARTS(BUTTON) 1 CONSTANT BP_PUSHBUTTON 2 CONSTANT BP_RADIOBUTTON 3 CONSTANT BP_CHECKBOX 4 CONSTANT BP_GROUPBOX 5 CONSTANT BP_USERBUTTON \ STATES(PUSHBUTTON) 1 CONSTANT PBS_NORMAL 2 CONSTANT PBS_HOT 3 CONSTANT PBS_PRESSED 4 CONSTANT PBS_DISABLED 5 CONSTANT PBS_DEFAULTED \ STATES(RADIOBUTTON) 1 CONSTANT RBS_UNCHECKEDNORMAL 2 CONSTANT RBS_UNCHECKEDHOT 3 CONSTANT RBS_UNCHECKEDPRESSED 4 CONSTANT RBS_UNCHECKEDDISABLED 5 CONSTANT RBS_CHECKEDNORMAL 6 CONSTANT RBS_CHECKEDHOT 7 CONSTANT RBS_CHECKEDPRESSED 8 CONSTANT RBS_CHECKEDDISABLED \ STATES(CHECKBOX) 1 CONSTANT CBS_UNCHECKEDNORMAL 2 CONSTANT CBS_UNCHECKEDHOT 3 CONSTANT CBS_UNCHECKEDPRESSED 4 CONSTANT CBS_UNCHECKEDDISABLED 5 CONSTANT CBS_CHECKEDNORMAL 6 CONSTANT CBS_CHECKEDHOT 7 CONSTANT CBS_CHECKEDPRESSED 8 CONSTANT CBS_CHECKEDDISABLED 9 CONSTANT CBS_MIXEDNORMAL 10 CONSTANT CBS_MIXEDHOT 11 CONSTANT CBS_MIXEDPRESSED 12 CONSTANT CBS_MIXEDDISABLED $1600 CONSTANT BCM_FIRST \ Button control messages BCM_FIRST $0001 + CONSTANT BCM_GETIDEALSIZE BCM_FIRST $0002 + CONSTANT BCM_SETIMAGELIST BCM_FIRST $0003 + CONSTANT BCM_GETIMAGELIST BCM_FIRST $0004 + CONSTANT BCM_SETTEXTMARGIN BCM_FIRST $0005 + CONSTANT BCM_GETTEXTMARGIN -1250 CONSTANT BCN_FIRST BCN_FIRST $0001 + CONSTANT BCN_HOTITEMCHANGE \ **************************************************************************** \ Status Parts and States \ **************************************************************************** \ PARTS(STATUS) 1 CONSTANT SP_PANE 2 CONSTANT SP_GRIPPERPANE 3 CONSTANT SP_GRIPPER \ **************************************************************************** \ Demo \ **************************************************************************** INIT-THEME \ Simple Message Box with Yes & No Button & Question Icon, Default = Yes : MESSAGE-BOX-YES/NO? ( z_message z_title -- flag ) \ True = Yes HWND -ROT MB_ICONQUESTION MB_YESNO OR MessageBox IDYES = ; : DEMO ( -- ) Z" Will it Rain Today?" Z" Demo of XP Themes" MESSAGE-BOX-YES/NO? . ; CR .( Type demo to test a themed message box)