[Haskell-cafe] How do I marshall a pointer over SendMessage LPARAM or WPARAM?

Simon Peter Nicholls simon at mintsource.org
Sun Jul 22 12:09:35 CEST 2012

Sorry Yuras, I missed this.

It turns out that I made a mistake when trying to pinpoint my problem.
I had started out using WM_COPY_DATA and COPYDATASTRUCT, but upon
facing issues, tried simple sending of a C string and a WM_APP
message. However, that simplifying resulted in me losing the memory
mapping needed for copying data.

(for anyone facing similar woes)

The use of WM_COPY_DATA and COPYDATASTRUCT in combination are
essential, since Windows performs memory mapping to ensure the data
being "copied" is available to the receiving process:

WM_COPY_DATA message is received by Windows.
It's handled as a special case, and COPYDATASTRUCT is inspected.
cbData worth of bytes are memory mapped for the lpData content.
A WM_COPY_DATA message will be received in your wndProc function, with
an appropriate COPYDATASTRUCT for the memory mapped content.

It's fine to use withTString (and similar) in combination with
sendMessage, since the IO will be syncronous.

cbData for a TString can be calculated by string length * size of a
System.Win32.Types.TCHAR, accounting for end of string sentinel.

withTStringLen can also be used, but be aware that the zero terminator
will not be present, and I'm not sure if the "Len" given by that
function is string length, or byte count. I wanted a regular
terminated c string, and so haven't tried it.

On Wed, Jul 18, 2012 at 7:29 PM, Yuras Shumovich <shumovichy at gmail.com> wrote:
> On Wed, 2012-07-18 at 18:22 +0200, Simon Peter Nicholls wrote:
>> Some "sending" code:
>>             Foreign.C.String.withCWString "frustrator" $ \s -> do
>>                 let wParam = System.Win32.Types.castPtrToUINT s ::
>> System.Win32.Types.WPARAM
>>                 Graphics.Win32.sendMessage wnd Graphics.Win32.wM_APP wParam 0
>> wndProc "receiving" code:
>>     | wmsg == Graphics.Win32.wM_APP = do
>>         s <- peekCWString $ System.Win32.Types.castUINTToPtr wParam
>>         putStrLn s
>>         return 0
> From the docs
> ( http://hackage.haskell.org/packages/archive/base/ ):
>> the memory is freed when the subcomputation terminates (either
> normally or via an exception), so the pointer to the temporary storage
> must not be used after this
> I'm noy a windows guru, but I assume that `sendMessage` just puts the
> message into a queue and exits. So, you receive a pointer to already
> deallocated memory.

More information about the Haskell-Cafe mailing list