# HG changeset patch # User Frank Benoit # Date 1205537599 -3600 # Node ID 03f179597782b343cad71277612b07a22bde42fb # Parent bcdc37794717bfdb77ed4e8355242753993f822c Make WinXP themes work with windows resources diff -r bcdc37794717 -r 03f179597782 README.txt --- a/README.txt Mon Mar 10 17:08:22 2008 +0100 +++ b/README.txt Sat Mar 15 00:33:19 2008 +0100 @@ -40,6 +40,27 @@ -L/SUBSYSTEM:windows:5 Without this option, DWT renderes some controls not correctly. Eg. table headers are not shown. + +WinXP Theming and Controls +========================== +With WinXP it is required to make windows use a manifest. +There are several ways to make this manifest available. +1.) Place the manifest file in the same directory where the .exe is. + E.g. + application.exe + application.exe.manifest +2.) Link the content of the manifest to the application as a windows resource. +3.) Have another program that uses resource injection to put the manifest into the application +4.) Let the application write the manifest to a an external file and load it. + This had problems in the past, some applications on some machines did not load images. + +1. .. 3.) Seems to work reliable. + + * Using 2. + compile the dwt.rc/dwt.exe.manifest files with rcc.exe from the digitalmars to create the dwt.res. + rcc dwt.rc + link the resulting dwt.res with the -L/rc:dwt.res + Changes/Additions to SWT ======================== o MessageBox can be instantiated without parent. Use the Ctor "this( int style )", diff -r bcdc37794717 -r 03f179597782 dwt.exe.manifest --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt.exe.manifest Sat Mar 15 00:33:19 2008 +0100 @@ -0,0 +1,1 @@ +D Widget Toolkit diff -r bcdc37794717 -r 03f179597782 dwt.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt.rc Sat Mar 15 00:33:19 2008 +0100 @@ -0,0 +1,3 @@ + +2 24 "dwt.exe.manifest" + diff -r bcdc37794717 -r 03f179597782 dwt.res Binary file dwt.res has changed diff -r bcdc37794717 -r 03f179597782 dwt/internal/win32/OS.d --- a/dwt/internal/win32/OS.d Mon Mar 10 17:08:22 2008 +0100 +++ b/dwt/internal/win32/OS.d Sat Mar 15 00:33:19 2008 +0100 @@ -19,6 +19,7 @@ import dwt.internal.C; import dwt.internal.Library; import tango.sys.SharedLib : SharedLib; +import tango.sys.Common : SysError; static import tango.stdc.stdlib; import tango.stdc.string : memset; @@ -167,9 +168,11 @@ /* Forward references */ public static const int HEAP_ZERO_MEMORY = 0x8; - public static const int ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x00000008; - public static const int ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x00000010; - public static const int MANIFEST_RESOURCE_ID = 2; + public static const int ACTCTX_FLAG_RESOURCE_NAME_VALID = 0x00000008; + public static const int ACTCTX_FLAG_SET_PROCESS_DEFAULT = 0x00000010; + public static const int ACTCTX_FLAG_APPLICATION_NAME_VALID = 0x00000020; + public static const int ACTCTX_FLAG_OVERRIDEMANIFEST_VALID = 0x00000100; + public static const TCHAR* MANIFEST_RESOURCE_ID = cast(TCHAR*)2; public static const int SM_DBCSENABLED = 0x2A; public static const int SM_IMMENABLED = 0x52; public static const int LANG_KOREAN = 0x12; @@ -248,6 +251,16 @@ WIN32_MINOR = info.dwMinorVersion; WIN32_VERSION = VERSION (WIN32_MAJOR, WIN32_MINOR); + if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) { + loadLib( Symbols_Kernel32, `Kernel32.dll` ); + } + + //PORTING_CHANGE: made by version + //IsUnicode = !IsWin32s && !IsWin95; + + /* Load the manifest to force the XP Theme */ + enableVisualStyles(); + // when to load uxtheme if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) { loadLib( Symbols_UxTheme, `UxTheme.dll` ); @@ -261,16 +274,6 @@ if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (4, 0)) { loadLib( Symbols_Imm32, `Imm32.dll` ); } - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) { - loadLib( Symbols_Kernel32, `Kernel32.dll` ); - } - - //PORTING_CHANGE: made by version - //IsUnicode = !IsWin32s && !IsWin95; - - /* Load the manifest to force the XP Theme */ - - enableVisualStyles(); /* Make the process DPI aware for Windows Vista */ if (OS.WIN32_VERSION >= OS.VERSION (6, 0)) OS.SetProcessDPIAware (); @@ -346,95 +349,66 @@ SHELL32_MINOR = dvi.dwMinorVersion; SHELL32_VERSION = VERSION (SHELL32_MAJOR, SHELL32_MINOR); } - + /************************************************************************** - + **************************************************************************/ - - public static void enableVisualStyles() - { - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (5, 1)) { - const char[] manifest = - ` - - - D Widget Toolkit - - - - - - `; - - scope temp = new tango.io.TempFile.TempFile(tango.io.TempFile.TempFile.Permanent); - temp.write(manifest); - temp.detach(); - - ACTCTX actctx; - actctx.cbSize = actctx.sizeof; - actctx.dwFlags = 0; - actctx.lpSource = StrToTCHARz( 0, temp.toString ); - - // Create the activation context - HANDLE hActCtx = OS.CreateActCtx(&actctx); - - // Did we fail creating the activation context? - if (hActCtx is INVALID_HANDLE_VALUE){ - Trace.formatln("The Activation Context could not be created"); - } else { - // Activate the context and make use of it - ULONG_PTR ulpActivationCookie; - if (!OS.ActivateActCtx(hActCtx, &ulpActivationCookie)){ - Trace.formatln("The Activation Context failed to load"); - } + + public static void enableVisualStyles() { + void printError( char[] msg ){ + char[] winMsg = SysError.lastMsg(); + char[2000] buf; + Trace.formatln("{}: {}", msg, CodePage.from( winMsg, buf ) ); + } + TCHAR[] buffer = new TCHAR[ MAX_PATH ]; + buffer[] = 0; + HANDLE hModule = OS.GetLibraryHandle (); + while (OS.GetModuleFileName (hModule, buffer.ptr, buffer.length ) is buffer.length ) { + buffer.length = buffer.length + MAX_PATH; + buffer[] = 0; + } + auto hHeap = OS.GetProcessHeap (); + int byteCount = buffer.length * TCHAR.sizeof; + TCHAR* pszText = cast(TCHAR*) OS.HeapAlloc (hHeap, HEAP_ZERO_MEMORY, byteCount); + OS.MoveMemory (pszText, buffer.ptr, byteCount); + + ACTCTX pActCtx; + pActCtx.cbSize = ACTCTX.sizeof; + pActCtx.dwFlags = 0 + | ACTCTX_FLAG_RESOURCE_NAME_VALID + | ACTCTX_FLAG_SET_PROCESS_DEFAULT + ; + pActCtx.lpSource = pszText; + pActCtx.lpApplicationName = pszText; + pActCtx.lpResourceName = MANIFEST_RESOURCE_ID; + HANDLE hActCtx = OS.CreateActCtx (&pActCtx); + if (hActCtx is INVALID_HANDLE_VALUE){ + printError("CreateActCtx failed" ); + } + else{ + ULONG_PTR ulpActivationCookie; + if (!OS.ActivateActCtx(hActCtx, &ulpActivationCookie)){ + printError("ActivateActCtx failed" ); } - - temp.path.remove(); - -/+ - //if (System.getProperty (NO_MANIFEST) is null) { - TCHAR[] buffer = new TCHAR[ MAX_PATH ]; - HANDLE hModule = OS.GetLibraryHandle (); - while (OS.GetModuleFileName (hModule, buffer.ptr, buffer.length ) is buffer.length ) { - buffer.length = buffer.length + MAX_PATH; - } - auto hHeap = OS.GetProcessHeap (); - int byteCount = buffer.length * TCHAR.sizeof; - TCHAR* pszText = cast(TCHAR*) OS.HeapAlloc (hHeap, HEAP_ZERO_MEMORY, byteCount); - OS.MoveMemory (pszText, buffer.ptr, byteCount); - ACTCTX pActCtx; - pActCtx.cbSize = ACTCTX.sizeof; - pActCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_SET_PROCESS_DEFAULT; - pActCtx.lpSource = pszText; - pActCtx.lpResourceName = cast(TCHAR*)MANIFEST_RESOURCE_ID; - HANDLE hActCtx = OS.CreateActCtx (&pActCtx); - if (pszText !is null) OS.HeapFree (hHeap, 0, pszText); - uint lpCookie; - OS.ActivateActCtx (hActCtx, &lpCookie); - /* - * NOTE: A single activation context is created and activated - * for the entire lifetime of the program. It is deactivated - * and released by Windows when the program exits. - */ - //} -+/ + } + + if (pszText !is null){ + OS.HeapFree (hHeap, 0, pszText); } + + /* + * NOTE: A single activation context is created and activated + * for the entire lifetime of the program. It is deactivated + * and released by Windows when the program exits. + */ } - + /************************************************************************** - + **************************************************************************/ - + /* Flag used on WinCE */ - + static const int SYS_COLOR_INDEX_FLAG = OS.IsWinCE ? 0x40000000 : 0x0; /*