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

2012-07-22 Thread Simon Peter Nicholls
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 shumovi...@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/4.5.1.0/doc/html/Foreign-C-String.html#v:withCWString
  ):

 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.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

2012-07-18 Thread Yuras Shumovich
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/4.5.1.0/doc/html/Foreign-C-String.html#v:withCWString
 ):

 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.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe