In my WndProc I receive a WM_SETTINGCHANGE message, and I want to see what category the caller sent in the LParam field of the incoming message. Try as I might (and after searching everywhere), I cannot find anything that shows how to get the original string into C# where I can see it. The best I got was the code below, but it causes a system access violation attempting to read protected memory at the GetLParam call.
I get the feeling that the method for accessing LParam varies with every different WM_* message type.
var mystr = new COPYDATASTRUCT();
var mytype = mystr.GetType();
mystr = (COPYDATASTRUCT) wMsg.GetLParam(mytype)!; // sys access violation here
var textReceived = mystr.lpData;
// System.AccessViolationException: 'Attempted to read or write protected memory
How can I dereference or copy the LParam so that I can see what category the WM_SETTINGCHANGE is referring to? Thank you.
UPDATE: Here is the solution that I was looking for, thanks to @Remy below.
case WM_SETTINGCHANGE:
// this arrives TWICE on a user dark mode change
var text = Marshal.PtrToStringAuto(wMsg.LParam);
var msg = @$"WM_SETTINGCHANGE received: W:{wMsg.WParam}" + $" - L: {text}";
MessageBox.Show(msg);
Yes, it does. So, you have to read the documentation for each individual message. For instance:
Per the
WM_COPYDATA
documentation:Per the
WM_SETTINGCHANGE
documentation:In C#, you can use
PtrToStringAnsi()
,PtrToStringUni()
, orPtrToStringAuto()
function (depending on how you are creating your window) to access the string value from thelParam
ofWM_SETTINGCHANGE
.