www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - SendMessageTimeoutW requires casting string to uint?

reply BoQsc <vaidas.boqsc gmail.com> writes:
I'm quite new to the programming, and I'm getting unsure how to 
make SendMessageTimeoutW to work with D lang.

Most of my attention right now resides around the Argument of the 
SendMessageTimeoutW function:
 "Environment",
It seems that SendMessageTimeoutW accepts only uint type, and string can't be directly used. I think that I have to convert string characters to "C-style 0 terminated string". And everything should work? But I'm unsure how to do that. All I know that there was toString16z function from tango project, that made it all work. http://www.dsource.org/projects/tango/docs/stable/tango.stdc.stringz.html#toString32z
 cast(LPARAM)(settingName.toString16z())
Here is how the method was before my modifications:
 void broadcastSettingChange (string settingName, uint timeout=1)
 {
     auto result = SendMessageTimeoutW(
         HWND_BROADCAST,
         WM_SETTINGCHANGE,
         0,
         cast(LPARAM)(settingName.toString16z(),
         SMTO_ABORTIFHUNG,
         timeout,
         null
     );
And finally, here is myVersion.d that throws an error (that I use incorrect variable type for the argument) myVersion.d
 import core.sys.windows.windows : SendMessageTimeoutW;
 import core.sys.windows.windows : GetLastError;
 import core.sys.windows.windows : ERROR_SUCCESS;
 import core.sys.windows.windows : SMTO_ABORTIFHUNG;
 import core.sys.windows.windows : LPARAM;
 import core.sys.windows.windows : HWND_BROADCAST;
 import core.sys.windows.windows : WM_SETTINGCHANGE;


 void main(){
 	broadcastSettingChange();
 
 }

 void broadcastSettingChange (uint timeout=1)
 {
     auto result = SendMessageTimeoutW(
         HWND_BROADCAST,
         WM_SETTINGCHANGE,
         0,
         "Environment",
         SMTO_ABORTIFHUNG,
         timeout,
         null
     );
 
     if(result == 0)
     {
         auto errCode = GetLastError();
     }
  }
Jul 09 2019
next sibling parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
On Tuesday, 9 July 2019 at 10:34:54 UTC, BoQsc wrote:
 I'm quite new to the programming, and I'm getting unsure how to 
 make SendMessageTimeoutW to work with D lang.

 Most of my attention right now resides around the Argument of 
 the SendMessageTimeoutW function:
 "Environment",
It seems that SendMessageTimeoutW accepts only uint type, and string can't be directly used. I think that I have to convert string characters to "C-style 0 terminated string". And everything should work? But I'm unsure how to do that. All I know that there was toString16z function from tango project, that made it all work.
std.utf module has all encoding/decoding you need (in this case UTF-16). I guess You need to convert your string using toUTF16 ( https://dlang.org/phobos/std_utf.html#toUTF16 ). I do not do Windows programming so I am not 100% sure whether this will work or not. Give it a try.
Jul 09 2019
parent Dejan Lekic <dejan.lekic gmail.com> writes:
On Tuesday, 9 July 2019 at 11:06:54 UTC, Dejan Lekic wrote:
 std.utf module has all encoding/decoding you need (in this case 
 UTF-16). I guess You need to convert your string using toUTF16 
 ( https://dlang.org/phobos/std_utf.html#toUTF16 ). I do not do 
 Windows programming so I am not 100% sure whether this will 
 work or not. Give it a try.
Maybe even the straightforward to!wchar will work!?
Jul 09 2019
prev sibling parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
On Tuesday, 9 July 2019 at 10:34:54 UTC, BoQsc wrote:
 All I know that there was toString16z function from tango 
 project, that made it all work.
 
Now that I browsed the std.utf more, I realised what fits your need best is the https://dlang.org/phobos/std_utf.html#toUTF16z
Jul 09 2019
parent reply BoQsc <vaidas.boqsc gmail.com> writes:
On Tuesday, 9 July 2019 at 11:11:53 UTC, Dejan Lekic wrote:
 Now that I browsed the std.utf more, I realised what fits your 
 need best is the https://dlang.org/phobos/std_utf.html#toUTF16z
So far, this is what I have: Filename: myVersion.d import core.sys.windows.windows : SendMessageTimeoutW; import core.sys.windows.windows : GetLastError; import core.sys.windows.windows : ERROR_SUCCESS; import core.sys.windows.windows : SMTO_ABORTIFHUNG; import core.sys.windows.windows : LPARAM; import core.sys.windows.windows : HWND_BROADCAST; import core.sys.windows.windows : WM_SETTINGCHANGE; import std.utf; void main(){ broadcastSettingChange(); } void broadcastSettingChange (string envi="Environment", uint timeout=1) { auto result = SendMessageTimeoutW( HWND_BROADCAST, WM_SETTINGCHANGE, 0, envi.toUTF16z, SMTO_ABORTIFHUNG, timeout, null ); if(result == 0) { auto errCode = GetLastError(); } } The dmd output:
 C:\Users\User\Desktop>rdmd ref.d
 ref.d(19): Error: function 
 `core.sys.windows.winuser.SendMessageTimeoutW(void*, uint, 
 uint, int, uint, uint, uint*)` is not callable using argument 
 types `(void*, int, int, const(wchar)*, int, uint, 
 typeof(null))`
 ref.d(19):        cannot pass argument 
 `toUTF16z(cast(const(char)[])envi)` of type `const(wchar)*` to 
 parameter `int`
 Failed: ["C:\\D\\dmd2\\windows\\bin\\dmd.exe", "-v", "-o-", 
 "ref.d", "-I."]
Jul 09 2019
parent reply a11e99z <black80 bk.ru> writes:
On Tuesday, 9 July 2019 at 12:14:38 UTC, BoQsc wrote:
 On Tuesday, 9 July 2019 at 11:11:53 UTC, Dejan Lekic wrote:
     auto result = SendMessageTimeoutW(
         HWND_BROADCAST,
         WM_SETTINGCHANGE,
         0,
         envi.toUTF16z,
         SMTO_ABORTIFHUNG,
         timeout,
         null
     );
 C:\Users\User\Desktop>rdmd ref.d
 ref.d(19): Error: function 
 `core.sys.windows.winuser.SendMessageTimeoutW(void*, uint, 
 uint, int, uint, uint, uint*)` is not callable using argument 
 types `(void*, int, int, const(wchar)*, int, uint, 
 typeof(null))`
 ref.d(19):        cannot pass argument 
 `toUTF16z(cast(const(char)[])envi)` of type `const(wchar)*` to 
 parameter `int`
 Failed: ["C:\\D\\dmd2\\windows\\bin\\dmd.exe", "-v", "-o-", 
 "ref.d", "-I."]
// add cast to LPARAM for SendMessageTimeoutW cast( LPARAM )envi.toUTF16z, // import lib too somewhere out of main() or in command line version(Windows) pragma(lib, "user32.lib");
Jul 09 2019
parent reply BoQsc <vaidas.boqsc gmail.com> writes:
On Tuesday, 9 July 2019 at 13:10:57 UTC, a11e99z wrote:
 On Tuesday, 9 July 2019 at 12:14:38 UTC, BoQsc wrote:
 On Tuesday, 9 July 2019 at 11:11:53 UTC, Dejan Lekic wrote:
     auto result = SendMessageTimeoutW(
         HWND_BROADCAST,
         WM_SETTINGCHANGE,
         0,
         envi.toUTF16z,
         SMTO_ABORTIFHUNG,
         timeout,
         null
     );
 C:\Users\User\Desktop>rdmd ref.d
 ref.d(19): Error: function 
 `core.sys.windows.winuser.SendMessageTimeoutW(void*, uint, 
 uint, int, uint, uint, uint*)` is not callable using argument 
 types `(void*, int, int, const(wchar)*, int, uint, 
 typeof(null))`
 ref.d(19):        cannot pass argument 
 `toUTF16z(cast(const(char)[])envi)` of type `const(wchar)*` 
 to parameter `int`
 Failed: ["C:\\D\\dmd2\\windows\\bin\\dmd.exe", "-v", "-o-", 
 "ref.d", "-I."]
// add cast to LPARAM for SendMessageTimeoutW cast( LPARAM )envi.toUTF16z, // import lib too somewhere out of main() or in command line version(Windows) pragma(lib, "user32.lib");
You are absolutely right. Here is a working example code on how to broadcast environment variables changes from D language to Windows XP, 7, 8, 10 systems, if anyone searches for it. To launch the code:
 rdmd broadcastSignal.d
broadcastSignal.d import std.utf; version(Windows) pragma(lib, "user32.lib"); import core.sys.windows.windows : SendMessageTimeoutW; import core.sys.windows.windows : GetLastError; import core.sys.windows.windows : ERROR_SUCCESS; import core.sys.windows.windows : SMTO_ABORTIFHUNG; import core.sys.windows.windows : LPARAM; import core.sys.windows.windows : HWND_BROADCAST; import core.sys.windows.windows : WM_SETTINGCHANGE; void main(){ broadcastSettingChange(); } /** Broadcasts a signal to update All Environment variables On Windows XP, 7, 8, 10 systems. Mostly used update changes to Path environment variable. After broadcast of this signal, reopen applications, for changes to be visible. Date: 07/09/2019 License: use freely for any purpose Params: addressBroadcast = "Policy" When the system sends this message as a result of a change in policy settings, this parameter points to this string. "intl" When the system sends this message as a result of a change in locale settings, this parameter points to this string. "Environment" To effect a change in the environment variables for the system or the user, broadcast this message with lParam set to this string Returns: does not return See_Also: https://docs.microsoft.com/lt-lt/windows/win32/api/winuser/nf-winuser-sendmessagetimeouta https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange */ void broadcastSettingChange (string addressBroadcast="Environment", uint timeout=1) { void* hWnd = HWND_BROADCAST; uint Msg = WM_SETTINGCHANGE; uint wParam = 0; int lParam = cast( LPARAM )addressBroadcast.toUTF16z; uint fuFlags = SMTO_ABORTIFHUNG; uint uTimeout = timeout; uint* lpdwResult = null; int result = SendMessageTimeoutW( hWnd, Msg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, lpdwResult ); if(result == 0) { auto errCode = GetLastError(); } }
Jul 09 2019
parent BoQsc <vaidas.boqsc gmail.com> writes:
Update: 2022-03-04
ChangeLog:
     * Fixed Typos
     * Added Switch Statement for Command Line Interface Arguments
     * Added Switch Statement for Policy, intl, Environment
     * Added Switch Statement for Error handling: Exit status, 
Error level
     * Increased window "timeout" from 1 to 1000
https://github.com/vaido-world/WM_SETTINGCHANGE
Mar 05 2022