We send a message to another app using SendMessageTimeout()
, but we have noticed that the last parameter result doesn't return the expected value. Example:
var
ReturnValuePtr: PDWORD_PTR;
begin
ReturnValuePtr := nil;
SendMessageTimeout(OtherAppHandle,
WM_COPYDATA,
0,
LPARAM(@CopyDataStruct),
SMTOFlag,
CTimeout,
ReturnValuePtr);
// Here ReturnValuePtr is still nil when we expect it to be a known value.
end;
But if we change the code to pass @ReturnValuePtr
to SendMessageTimeout()
, like this:
begin
ReturnValuePtr:= nil;
SendMessageTimeout(OtherAppHandle,
WM_COPYDATA,
0,
LPARAM(@CopyDataStruct),
SMTOFlag,
CTimeout,
@ReturnValuePtr); // <- Only change here
// Here ReturnValuePtr returns the known expected value.
end;
This way we get the correct value in ReturnValuePtr
.
This is the main question: Why does this work? Is it still correct?
We were not sure if the above was correct so we ended up implementing this instead:
var
ReturnValue: NativeUInt;
ReturnValuePtr: PDWORD_PTR;
begin
ReturnValue := 0;
ReturnValuePtr := @ReturnValue;
SendMessageTimeout(OtherAppHandle,
WM_COPYDATA,
0,
LPARAM(@CopyDataStruct),
SMTOFlag,
CTimeout,
ReturnValuePtr);
// Here we check ReturnValue and it has the known expected value.
end;
CodePudding user response:
You must provide valid address to the last parameter to allow receiver fill it with some result.
When address is nil, receiver (or Windows messaging system) cannot put data at this address.
Perhaps you did expect that function would change this address, but it cannot (otherwise parameter type should be "pointer to pointer")
So your last variant is correct
CodePudding user response:
The last parameter expects a pointer to a valid DWORD_PTR
variable. The function will dereference the pointer when assigning a value to the variable.
In your 1st case, you are passing a nil
pointer, which is wrong.
You need to do more like your 3rd case, though you don't need an explicit variable for the pointer, eg:
var
ReturnValue: DWORD_PTR;
begin
ReturnValue := 0;
SendMessageTimeout(OtherAppHandle,
WM_COPYDATA,
0,
LPARAM(@CopyDataStruct),
SMTOFlag,
CTimeout,
@ReturnValue);
end;