1 /** 2 * Copyright: Copyright (c) 2011 Nick Sabalausky. 3 * Authors: Nick Sabalausky 4 * Version: Initial created: Jun 1, 2011 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module dvm.util.Windows; 8 9 version (Windows): 10 11 import mambo.core..string; 12 import dvm.dvm.Exceptions; 13 import tango.sys.win32.Types; 14 import tango.sys.win32.UserGdi; 15 import tango.util.Convert; 16 17 // If FORMAT_MESSAGE_ALLOCATE_BUFFER is used, then this is the correct 18 // signature. Otherwise, the signature in tango.sys.win32.UserGdi is corrent. 19 extern (Windows) DWORD FormatMessageW (DWORD, LPCVOID, DWORD, DWORD, LPWSTR*, DWORD, VA_LIST*); 20 21 class WinAPIException : DvmException 22 { 23 LONG code; 24 string windowsMsg; 25 26 this (LONG code, string msg = "", string file = __FILE__, size_t line = __LINE__) 27 { 28 this.code = code; 29 30 if(windowsMsg == "") 31 windowsMsg = getMessage(code); 32 33 super(msg == "" ? windowsMsg : msg, file, line); 34 } 35 36 static string getMessage (DWORD errorCode) 37 { 38 wchar* pMsg; 39 40 auto result = FormatMessageW( 41 FORMAT_MESSAGE_ALLOCATE_BUFFER | 42 FORMAT_MESSAGE_FROM_SYSTEM | 43 FORMAT_MESSAGE_IGNORE_INSERTS, 44 null, errorCode, 0, &pMsg, 0, null 45 ); 46 47 if(result == 0) 48 return "Unknown WinAPI Error"; 49 50 scope (exit) 51 LocalFree(pMsg); 52 53 auto msg = fromString16z(pMsg); 54 return to!(string)(msg); 55 } 56 } 57 58 private alias mambo.core..string.toString16z toString16z; 59 60 immutable(wchar)* toString16z (string str) 61 { 62 return to!(wstring)(str).toString16z(); 63 } 64 65 /// For more info, see: http://msdn.microsoft.com/en-us/library/ms725497(VS.85).aspx 66 void broadcastSettingChange (string settingName, uint timeout=1) 67 { 68 auto result = SendMessageTimeoutW( 69 HWND_BROADCAST, WM_SETTINGCHANGE, 70 0, cast(LPARAM)(settingName.toString16z()), 71 SMTO_ABORTIFHUNG, timeout, null 72 ); 73 74 if(result == 0) 75 { 76 auto errCode = GetLastError(); 77 78 if (errCode != ERROR_SUCCESS) 79 throw new WinAPIException(errCode, "Problem broadcasting WM_SETTINGCHANGE of '" ~ settingName ~ "'", __FILE__, __LINE__); 80 } 81 } 82 83 string expandEnvironmentStrings(string str) 84 { 85 auto wstr = toString16z(str); 86 87 wchar[] result; 88 result.length = 32_000 / wchar.sizeof; 89 90 auto resultLength = ExpandEnvironmentStringsW(wstr, result.ptr, result.length); 91 92 if(resultLength == 0) 93 { 94 auto errCode = GetLastError(); 95 96 if (errCode != ERROR_SUCCESS) 97 throw new WinAPIException(errCode, "Problem expanding environment variables", __FILE__, __LINE__); 98 } 99 100 return to!(string)(result[0..resultLength-1]); 101 }