-->

Windows Common Control 6.0 Theme in Property Sheet or run by Rundll32

21 2020
    • Open Sources file in the directory.
    • Add the Library in TARGETLIBS
$(SDK_LIB_PATH)\comctl32.lib \
    • Add C Defines
C_DEFINES=$(C_DEFINES) -DMANIFEST_RESOURCE=$(SXS_MANIFEST_RESOURCE_ID)
#
# Fusionized
#
SXS_ASSEMBLY_NAME=xx.yy.zz
SXS_ASSEMBLY_LANGUAGE_INDEPENDENT=1
SXS_MANIFEST=theme.manifest
SXS_MANIFEST_IN_RESOURCES=1
SXS_MANIFEST_RESOURCE_ID=123
SXS_NO_BINPLACE=1
    • Create a header file and include the function prototypes
    • Create a CPP file and add the following content
#define MAX_LOOP    10

// This indicates to Prefast that this is a usermode driver file.
__user_driver;

// Module's Activation Context from DLLEntry of process.
HANDLE      ghActCtx = INVALID_HANDLE_VALUE;
 
HANDLE GetMyActivationContext(HINSTANCE hInstance)
{
    // Make sure we've created our activation context.
    CreateMyActivationContext(hInstance);

    // Return the global.
    return ghActCtx;
}


BOOL CreateMyActivationContext(HINSTANCE ghInstance)
{
    if(INVALID_HANDLE_VALUE != ghActCtx)
    {
        return TRUE;
    }

    ghActCtx = CreateActivationContextFromResource(ghInstance, MAKEINTRESOURCE(MANIFEST_RESOURCE));

    return (INVALID_HANDLE_VALUE != ghActCtx);
}



HANDLE CreateActivationContextFromResource(HMODULE hModule, LPCTSTR pszResourceName)
{
    DWORD   dwSize          = MAX_PATH;
    DWORD   dwUsed          = 0;
    DWORD   dwLoop;
    PTSTR   pszModuleName   = NULL;
    ACTCTX  act;
    HANDLE  hActCtx         = INVALID_HANDLE_VALUE;

    
    // Get the name for the module that contains the manifest resource
    // to create the Activation Context from.
    dwLoop = 0;
    do 
    {
        // May need to allocate or re-alloc buffer for module name.
        if(NULL != pszModuleName)
        {
            // Need to re-alloc bigger buffer.

            // First, delete old buffer.
            delete[] pszModuleName;

            // Second, increase buffer alloc size.
            dwSize <<= 1; } pszModuleName = new TCHAR[dwSize]; if(NULL == pszModuleName) { goto Exit; } // Try to get the module name. dwUsed = GetModuleFileName(hModule, pszModuleName, dwSize); // Check to see if it failed. if(0 == dwUsed) { goto Exit; } // If dwUsed is equla to dwSize or larger, // the buffer passed in wasn't big enough. } while ( (dwUsed >= dwSize) && (++dwLoop < MAX_LOOP) );

    // Now let's try to create an activation context
    // from manifest resource.
    ::ZeroMemory(&act, sizeof(act));
    act.cbSize          = sizeof(act);
    act.dwFlags         = ACTCTX_FLAG_RESOURCE_NAME_VALID;
    act.lpResourceName  = pszResourceName;
    act.lpSource        = pszModuleName;

    hActCtx = CreateActCtx(&act);


Exit:

    //
    //  Clean up.
    //

    if(NULL != pszModuleName)
    {
        delete[] pszModuleName;
    }

    return hActCtx;
}
    • Create a property sheet with the following code
PROPSHEETPAGE MySheet;
// Init property page.
memset(&MySheet, 0, sizeof(PROPSHEETPAGE));
MySheet.dwSize = sizeof(PROPSHEETPAGE);
MySheet.dwFlags = PSP_DEFAULT;
MySheet.hInstance = ghInstance;
MySheet.pszTemplate = MAKEINTRESOURCE(IDD_DIALOG );
MySheet.pfnDlgProc =  PropPageProc; // Callback Function
MySheet.pszIcon = MAKEINTRESOURCE(IDI_ICON);
MySheet.hActCtx = GetMyActivationContext(ghInstance);

// Set the flag to indicate that our PROPSHEETPAGE
// has an Activation Context.
// The Activation Context indicates with version of
// comctl for Compstui to create our PROPSHEETPAGE
// with. To get Themed UI we need to specify comctl v6.
if ((NULL != MySheet.hActCtx) && (INVALID_HANDLE_VALUE != MySheet.hActCtx))
{
MySheet.dwFlags |= PSP_USEFUSIONCONTEXT;
}
  • Create a Manifest file in the same directory and name it as theme.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
language=SXS_ASSEMBLY_LANGUAGE
version=SXS_ASSEMBLY_VERSION
processorArchitecture="*"
name=SXS_ASSEMBLY_NAME
type="win32"
/>
<description>Local Monitor UI Components</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

Leave a Reply