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