1. Bjarne Anker
  2. PowerBuilder
  3. Thursday, 25 January 2018 20:09 PM UTC

Hi.

 

Has anyone successfully managed to receive string data sent from a C# application using SendMessage?

We have a small starter program written in C# which is triggered from a website.

This starter program will do some small work and pass a string (perhaps XML) to a running PowerBuilder 2017 application (32-bit).

This is the C# code:

[DllImport("user32.dll", SetLastError = true, EntryPoint = "SendMessageA", CharSet = CharSet.Ansi)]
internal static extern Int32 SendMessageAnsiPtr(IntPtr hWnd, uint Msg, Int32 wParam, IntPtr lParam);

ptr = Marshal.StringToHGlobalAnsi("Hello World");
SendMessageAnsiPtr(proc.MainWindowHandle, 0x429, 11, ptr); //11 is the length of the string hardcoded for testing

Marshal.FreeHGlobal(ptr); //freee the memory to avoid memory leak

This triggers an event in PB mapped to the pbm_custom42 eventhandler.

It receives a pointer to the string, and I've tried this:

string ls_result

ls_result = space(wparam)
ls_Result = String(lParam, "address")
 
Sometimes I get som rubbish, and sometimes Powerbuilder crashes.
 
Am I on the right track?
Is there any other way to "decode" the pointer into a string in PowerBuilder?
Or is there another solution?
 
Regards,
 
Bjarne Anker
Michael Kramer Accepted Answer Pending Moderation
  1. Friday, 26 January 2018 11:15 AM UTC
  2. PowerBuilder
  3. # 1

Hi Bjarne,

String(lParam, "address") is the right way to convert a string pointer into an actual string. You can skip Space(WParam) since that empty string is never used.

ANSI vs. Unicode is a "usual suspect" when integration goes sour. Your C# code calls the ANSI version (SendMessageA) but PB is Unicode internally since PB 10.

HTH  /Michael

Comment
  1. Bjarne Anker
  2. Friday, 26 January 2018 13:38 PM UTC
Hi Michael.



 



I tried these changes to my C# and PB code, but still I sometimes receive rubbish and every now and then PB crashes.



I've been thinking about using the WM_COPYDATA in SendMessage(), but I cannot seem to trap the message in any event i PB.



I've tried to listen to Message.Number = 74 in the "other" (pbm_other) event, but it never fires.



So it looks like we have to use another approach, like the registry.



 



Thanks,



 



Bjarne

  1. Helpful
  1. Michael Kramer
  2. Friday, 26 January 2018 15:13 PM UTC
Hi Bjarne,



The PBM_Custom01 ... PBM_Custom75 are the right events to use. They match WM_User ... (WM_User + 74) where WM_User = 1024 as I recall.



"Sometimes rubbish" worries me. To me it sounds like PB is trying to read from memory outside the PBVM which means it is inherently volatile and unsafe.



 



An idea: Is it possible to create a "dialogue" between the two components?





C# calls SendMessage( ) to notify PB.

PB calls a GetMyGreatData( ) function exposed by your C# component  which returns the string of interest.





If the string is the function's return datatype PB should allocate it in PBVM's realm. Instead, if string is a pass-by-ref parameter, then you need to preallocate in PB before calling the function. This is where Space(wParam) to allocate a string of specific length is important.



 



HTH /Michael



 

  1. Helpful
  1. Bjarne Anker
  2. Monday, 29 January 2018 09:52 AM UTC
Hi Michael.



 



That is a good idea.



However, the application which uses "Sendmessage" is just a small console application, started from a protocol handler located in the registry.



It starts when the user clicks on a link on a webpage (just like with ex. iTunes).



So I don't think I can expose a public function in a console application, but I will try.



 



Regards,



 



Bjarne

  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.
We use cookies which are necessary for the proper functioning of our websites. We also use cookies to analyze our traffic, improve your experience and provide social media features. If you continue to use this site, you consent to our use of cookies.