Thread overview
SendMessageTimeoutW requires casting string to uint?
Jul 09, 2019
BoQsc
Jul 09, 2019
Dejan Lekic
Jul 09, 2019
Dejan Lekic
Jul 09, 2019
Dejan Lekic
Jul 09, 2019
BoQsc
Jul 09, 2019
a11e99z
Jul 09, 2019
BoQsc
Mar 05, 2022
BoQsc
July 09, 2019
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();
>     }
>  }


July 09, 2019
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.
July 09, 2019
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!?
July 09, 2019
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
July 09, 2019
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."]



July 09, 2019
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");
July 09, 2019
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();
    }
  }
March 05, 2022
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