1. GUSTAVO MARCELINO
  2. PowerBuilder
  3. Sunday, 7 June 2020 04:36 AM UTC

Hello,

I am struggling with an apparently simple process.

Need to pass a String from one application in Powerbuilder to another Application in Powerbuilder.

As I'm doing:

APP1: "Send (gl_handle, 1024, 0, 'Hello World')"

APP2: event pbm_custom01

string ls_info = String (lparam, "address")

But the variable ls_info is coming empty. And when u do a test with the same "Send" from APP2 to APP2 (same application) is working. Only when I try to send a String through different applications it comes empty. What am I doing wrong?

Thanks in advance.

John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 27 July 2022 15:27 PM UTC
  2. PowerBuilder
  3. # 1

Berka - 

The SourceForge user interface can be misleading...

Did you click on the link I have highlighted in red in the image below?

Regards, John

Comment
There are no comments made yet.
Ricardo Jasso Accepted Answer Pending Moderation
  1. Tuesday, 9 June 2020 19:34 PM UTC
  2. PowerBuilder
  3. # 2

Gustavo,

You can use DDE (Dynamic Data Exchange) to pass data between two PowerBuilder applications within the same machine and the same operating system environment.

I've built a small proof of concept example that passes a string from a DDE server to a DDE client (see attached image and pbls for both the client and the server). The example uses the cold link approach which sends a single command to a DDE server application. This technique should be enough for your requirement.

Regards,

Ricardo

 

Attachments (3)
Comment
There are no comments made yet.
Olan Knight Accepted Answer Pending Moderation
  1. Monday, 8 June 2020 14:45 PM UTC
  2. PowerBuilder
  3. # 3

The guaranteed, sure-fire way to to this is to use an intermediary. This technique will NOT work for real-time interfacing with users.

1. The Database
   Have a table that is used for inter-application communication.
   Program A populates row X, and a column in row X indicates the target application, perhaps Program B.

   Program B reads the table on a timed basis, say every 3 minutes, looking for targeted entries.
   Program B extracts  row X, processthe string, then either saves the string and sets a STATUS flag to READ -
   or simply deletes the row. Depends on your needs.


2. Text File
   Have a specified folder used for inter-application communications.
   Name the text file such that the target program can identify that it is the target of the file.
   Open the text file, read and process the contents.
   Close the text file and either delete it, save it in a different folder, or save it in the same folder with a different name that indicates the file has been processed.


Good Luck,

Olan

 

Comment
There are no comments made yet.
Brad Wery Accepted Answer Pending Moderation
  1. Monday, 8 June 2020 14:18 PM UTC
  2. PowerBuilder
  3. # 4

Hello Gustavo,

 

Can you do something like this?

//Declare local external function:

FUNCTION long lstrcpy (ULong Destination, string Source) library "kernel32.dll" alias for "lstrcpyW"
FUNCTION Ulong LocalAlloc (long Flags, long Bytes) library "kernel32.dll"
FUNCTION long LocalFree (ULongMemHandle) library "kernel32.dll"

//Create pointer and copy string

Int li_length
ULong ll_pointer

li_length = (Len("Hello World") + 1) * 2

ll_pointer = LocalAlloc( 0, li_length)
lStrCpy(ll_pointer, "Hello World" )

Send(gl_handle,1024,0,ll_pointer)

 

//You need to free the pointer at some point... But you'll need to wait for gl_handle to be done with it

LocalFree( ll_pointer )

 

I've had limited success using the pbm_Custom** events to communicate between applications. What I do is use the RegisterWindowMessage Win API function with the HWND_BROADCAST message. I have a registry key that I use to pass data. 

Comment
  1. Andrew Barnes
  2. Monday, 8 June 2020 22:35 PM UTC
I don't think that solution works for Gustavo's problem. The memory allocated by LocalAlloc called from one application will not be seen by another application. To test I created a simple window to send some text using your code above. When launching two instances of the test window from within the same PowerBuilder IDE, it worked fine, however, when launching an instance of the test window from two separate PowerBuilder IDEs, the string sent by the one application was not seen by the other.



Just for fun, I substituted CoTaskMemAlloc and CoTaskMemFree with the hope that CoTaskMem memory allocations could be shared between applications in a way that Local memory allocations cannot, but unfortunately that did not work any better.
  1. Helpful 1
  1. Brad Wery
  2. Tuesday, 9 June 2020 13:54 PM UTC
I didn't try it but he mentioned that using Marshal.StringToHGlobalUni worked in .Net. That method uses LocalAlloc. The code I provided was a PB interpretation of what .Net is doing in Marshal.StringToHGlobalUni (expect they use a different method to copy data into the allocated memory). Maybe the part that's not working is lStrCpy? .
  1. Helpful
  1. Andrew Barnes
  2. Tuesday, 9 June 2020 15:33 PM UTC
No the lstrcpy worked like a champ. It is a handy function I never knew about before. I've always used Read and WriteProcessMemory to do such operations previously.



And as I said, my test windows when called from the same application worked perfectly using your code. The only tweak I did was to send the string length as the WParm, that way the receiving side could reverse the process, i.e. allocate a PowerBuilder string to the correct length and then use another overload of lstrcpy that has a destination parm defined as a REF String. It worked as advertised, until the windows are launched from different application.







  1. Helpful 1
There are no comments made yet.
Roland Smith Accepted Answer Pending Moderation
  1. Monday, 8 June 2020 02:25 AM UTC
  2. PowerBuilder
  3. # 5

Why not use Winsock?

I have a pure PB Winsock example here:

https://www.topwizprogramming.com/freecode_winsock.html

I also have a Winsock PBNI example here:

https://www.topwizprogramming.com/tools.html

 

Comment
  1. Chris Pollach @Appeon
  2. Monday, 25 July 2022 13:50 PM UTC
Hi Berka;

Using TCP/IP socket programming you can send any type of data between any type of PB App on a local or remote machine ...

FYI: http://chrispollach.blogspot.com/2019/12/socket.html

In the above example, I send entire binary data streams (DataWindows) back & forth!

HTH

Regards ... Chris
  1. Helpful 1
  1. Berka Frenfert
  2. Wednesday, 27 July 2022 05:03 AM UTC
Hi Chris,

I clicked where it says "STD Framework's website by clicking 'here' ".



The sourceforge page when clicked on 'Here'

https://sourceforge.net/projects/stdfndclass/files/Applications/PowerBuilder/Socket



I am a bit confused about the downloaded sample which shows me OCR example.

But page explains all about Socket. Also the video is about Socket. I guess the url is not correct.

Could you please check that for me. Thank you.



True regards,

Berka



  1. Helpful
  1. Chris Pollach @Appeon
  2. Wednesday, 27 July 2022 13:17 PM UTC
Hi Berka;

The links are correct. The download is for the use of TCP/IP to communicate between PB Apps. This feature is much more robust than using the Send() or SendMessage() methods.

I just checked the link again & the download is correct on my latest test. If you are getting something else, I would suggest that you clear your web browser's cache & then try again.

Regards ... Chris
  1. Helpful
There are no comments made yet.
GUSTAVO MARCELINO Accepted Answer Pending Moderation
  1. Sunday, 7 June 2020 14:48 PM UTC
  2. PowerBuilder
  3. # 6

When I send an application in C # it works very well, it just doesn't work when it's PB to PB.

 

//C#

public static extern int SendMessageW(IntPtr hWnd, uint Msg, uint wParam, IntPtr lParam);

IntPtr ptr = Marshal.StringToHGlobalUni("Hello World teste123");
uint WM_USER = 0x0400; //1024

SendMessageW(handle, WM_USER, 0, ptr);

Comment
There are no comments made yet.
Michael Kramer Accepted Answer Pending Moderation
  1. Sunday, 7 June 2020 12:41 PM UTC
  2. PowerBuilder
  3. # 7

Your PB app's "address" pointer has to reference memory inside your PB VM's memory space. Address pointer from different app is basically pointer inside different VM process. It takes some low level mem-copy to copy string content into your process' memory space.

Hopefully others can reply with link to a code example of doing such string based app-to-app dialog.

HTH /Michael

Comment
  1. GUSTAVO MARCELINO
  2. Sunday, 7 June 2020 15:10 PM UTC
I really don't know how to do it. I've tried it in several ways and I can't. Can you help me how to do? I thought it would be a simple process
  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.