1

Changing this code was straightforward:

This:

S_COPY_PACKET* pCopyPacket = (S_COPY_PACKET*)(pCopyDataStruct->lpData);

Becomes:

S_COPY_PACKET* pCopyPacket = static_cast<S_COPY_PACKET*>(pCopyDataStruct->lpData);

But what about this line:

if (SendMessageTimeout(hOtherInstance, WM_COPYDATA,
                NULL, (LPARAM)(LPVOID)&cds, SMTO_BLOCK, 2000, &dwResult) != 0)

We are passing in a (LPARAM)(LPVOID)&cds. So what is the newer concept (inline with static_cast) for this?

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164

1 Answers1

3

In your first code snippet, the lpData member of the COPYDATASTRUCT is a void* type, so you can static_cast it to a pointer to (almost) any other data type. However, you cannot use static_cast to convert between a pointer (&cds) and non-pointer (LPARAM) type. You need reinterpret_cast (but only one):

if (SendMessageTimeout(hOtherInstance, WM_COPYDATA,
                NULL, reinterpret_cast<LPARAM>(&cds), SMTO_BLOCK, 2000, &dwResult) != 0)

Although such casts are frequently frowned-upon by 'purist' C++ programmers, there is really no other way to avoid them, other than the even nastier 'C-style' cast(s) that your 'old' code already has. This derives from the fact that the WinAPI was written as a C interface, so its use in more modern, C++ code will inevitably have some such 'inconsistencies'.

(The problem becomes even trickier when using WinAPI calls that involve function pointers, as I pondered here: What’s the best way to cast a function pointer from one type to another?.)

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 2
    The `reinterpret_cast(&)` will be found frequently in WinAPI calls that involve Windows messages, where the `lParam` argument is (of necessity) a pointer to something. – Adrian Mole May 11 '20 at 15:32