1. Scott Gorke
  2. PowerBuilder
  3. Friday, 20 September 2019 19:20 PM UTC

Hi,

 

Let's say I have a C# app "A" that makes a command line call to open a Powerbuilder app "B" and automatically open a sheet therein. OK, that's clear to me - I've coded that.

 

But what if app "A" wants to open app "B" and automatically open its sheet, and "B" is already open? How do I code PB to do that (command line again)? Or is this a C# developer's job? Or some of each?

 

Thanks,

Scott

Accepted Answer
Michael Kramer Accepted Answer Pending Moderation
  1. Tuesday, 12 November 2019 22:22 PM UTC
  2. PowerBuilder
  3. # Permalink

Hi Scott, I created new reply so I can add code snippets and a table.

Technique described here by Chris I have used personally form 10+ years in many different apps. It works! Just a couple of pitfalls to avoid:

  1. Sending event to right object
  2. Know how to pick up the vent that was sent.

Passing zero for both 3rd and 4th arguments are perfectly fine. Here is how parameters of Send function match up to PowerScript features. Syntax for Send function call in PowerScript is:

Send ( handle, message#, lowword, long )

 

Send Param PowerScript Equivalent
handle Handle of your window to receive the event - EX:
Handle(w_test)
Handle(w_test.tab_data.tabpage_misc.dw_data)
message# ID-number for the PowerScript event to be triggered
1024 => pbm_custom01
1025 => pbm_custom02
1026 => pbm_custom03 . . .
lowWord PBM_customXX's WParam argument
long PBM_customXX's LParam argument

A word of caution >>>

// Call Send on a WINDOW handle
Send( Handle(W_TEST), 1024, 0, 0)
// Triggers user event on W_TEST mapped to pbm_custom01

// Call Send on any CONTROL handle (DW/Tab/Button/Anything)
Send( Handle(W_TEST.DW_DATA), 1024, 0, 0)
// Triggers OTHER event on W_TEST.DW_DATA
// When OTHER event starts, Message.Number has value 1024 ! ! !

When a window receives the Windows message, it will auto-transfom into the "right" custom user event

When a non-window receives the Windows message, there is no auto-transform. Instead you have to be explicit looking at Message.Number for guidance.

You may be closer to actually solution than you think.

HTH /Michael (PS: I'm also reachable through LinkedIn. Link on my MVP profile page)

Comment
  1. Michael Kramer
  2. Thursday, 14 November 2019 22:14 PM UTC
Godspeed - and luck!

Yeah, two events mapped to same EventID can make any app go quirky.
  1. Helpful
  1. Chris Pollach @Appeon
  2. Thursday, 14 November 2019 23:31 PM UTC
Yep .. LOL!
  1. Helpful
  1. Scott Gorke
  2. Friday, 15 November 2019 19:51 PM UTC
THAT WORKED! Changing to pbm_custom02, and passing 1025 as the 2nd argument into SendMessageW did what I needed it to do.

Thank you both for your invaluable help!
  1. Helpful
There are no comments made yet.
David Peace (Powersoft) Accepted Answer Pending Moderation
  1. Thursday, 14 November 2019 17:00 PM UTC
  2. PowerBuilder
  3. # 1

Many moons ago our PB application used to act as an DDE Server for a 3rd party application to make calls on it and we passed data back. I'm not sure it it's even possible these days. All the stuff is there in the help under DDE.

Event pbm_dderequest is triggered.

Just an idea :)

Cheers

David

Comment
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Friday, 20 September 2019 19:35 PM UTC
  2. PowerBuilder
  3. # 2

Hi Scott;

  I would use ...

1) App "A" locates App "B" handle via a FindWindow SDK call

2) App "A" uses a "Send" SDK call to send "App "B" a message. App "A" can then fire an event on App "B" (use "Custom01" {numeric 1024} through "Custom75" to receive the Send message).

3) Code the "CustomNN" user event on App "B" to open the sheet when the UE fires.

HTH

Regards ... Chris

Comment
  1. Scott Gorke
  2. Friday, 8 November 2019 15:53 PM UTC
Hi Chris,



Sorry to bother but I'm not getting this to work. I'm coding this in PB 12.1 for now, likely to be converted to C# by other programmers later.



I have written a "pbm_custom01" event in my frame. All it should do is this:

- if Window 2 is open in the frame, bring it to top

- else if Window 1 is open in the frame, bring it to top

- else open Window 1



Here is my app launch object's local external function declaration:



FUNCTION long SendMessage (long Hwnd, long Msg, long wParam, long lParam) LIBRARY "USER32.DLL" Alias For "SendMessageW"



Here is the code snippet that I'm running:



<.....>

ls_title = of_generate_title_display() //grab title of frame

f_setplatform(lnv_platform, true)

lb_running = lnv_platform.of_is_app_running(ls_title, lul_handle) //pass title of frame, get frame handle by reference

f_setplatform(lnv_platform, false)

If lb_running Then

if lul_handle > 0 then

int li_Rtn

li_rtn = SendMessage(lul_handle, 1024, 0, 0) //args: handle to frame, 1023 + NN where NN is event "CustomNN", last 2 args not used

<.....>



I do this after compiling:

- start app - open Window 1 - close window 1

- minimize app

- start app a 2nd time



Nothing happens.



I'm sure my syntax is wrong, but how?

The return fro SendMessage is 0, and the app doesn't
  1. Helpful
  1. Chris Pollach @Appeon
  2. Friday, 8 November 2019 16:07 PM UTC
Hi Scott;

Good timing .. I just created an example SendMessage() PB App using my latest framework release. You can download it from SourceForge. It has both Inter-Process and Intra-Process examples of Sending & Receiving messages. Both in 32 and 64 bit compiled Apps. I have not had a chance to post a notice of this new example yet to the LinkedIn and FaceBook PB Groups. I hope to do that this weekend as a formal release notice.

FYI: https://sourceforge.net/projects/stdfndclass/files/Applications/PowerBuilder/SendMessage

HTH

Regards ... Chris
  1. Helpful
  1. Chris Pollach @Appeon
  2. Wednesday, 13 November 2019 19:56 PM UTC
  1. Helpful
There are no comments made yet.
Michael Kramer Accepted Answer Pending Moderation
  1. Friday, 20 September 2019 19:31 PM UTC
  2. PowerBuilder
  3. # 3

Hi, there are Win API calls to search for windows having given title text and given "class" where the class of PB windows depends on window type and PB version.

I don't remember exact names from top of my head, but PFC has such functionality. Others may chime in with details.

Some extra digging. OLD sample (thread dates back to 2003) that shows how a PB app can check for a running window across all running apps: FindWindow

Microsoft docs FindWindowW 

You can also search PFC (PB v. 7.0 or later) for "FindWindow". PFC version is very specific. Like in PFC for PB 2017. That version will ONLY match PB windows running in PB 2017. It is easy to see in window "class names" where you need to change if you run a different PB version.

NOTE: PFC version won't find dockable frames since they use different class names.

PFC version searches for substring in window title.
Say you have an app where MDI frame's title = "My Great App - [User] - [CaseFile-ID]".
Such window is hard to search for unless your code matches only "My Great App - ...".

I believe it is pretty straightforward to get working, albeit new trade tools are better learned in pairs than one craftsman at a time.

/Michael

Comment
  1. Scott Gorke
  2. Tuesday, 12 November 2019 21:21 PM UTC
Thanks Chris, I downloaded your STD FC and also an eval copy of PB 2019 (we're actively pursuing an upgrade to 2019 so this was opportune).



I looked at your SendMessage implementation, and tried to model my code after yours, but it's still not calling my custom event in the frame.



Here is my app launch object's local external function declaration:



FUNCTION Long SendMessage ( Long hwnd, uLong wMsg, uLong wParam, Long lParam ) LIBRARY "USER32.dll" ALIAS FOR "SendMessageW"

FUNCTION Long SendMessage ( uLong hwnd, uLong wMsg, Long wParam, Ref String lParam ) LIBRARY "USER32.dll" ALIAS FOR "SendMessageW"



Here is the call at the moment:



<.....>



ls_title = of_generate_title_display() //grab title of frame

f_setplatform(lnv_platform, true)

lb_running = lnv_platform.of_is_app_running(ls_title, lul_handle) //pass title of frame, get frame handle by reference

f_setplatform(lnv_platform, false)

If lb_running Then

if lul_handle > 0 then

int li_Rtn

uInt lui_msg_no = 1023 + 75

li_rtn = SendMessage(lul_handle, lui_msg_no, 0, 0) //args: handle to frame, 1023 + (76 - NN) where NN is event "CustomNN", zero, ZERO (last 2 args not used)

<.....>



I do this after compiling:

- start app - open Window 1 - close window 1

- start app a 2nd time



Nothing happens. The 1st instance of the app doesn't open window 1.



Maybe I need to pass non-zero values for arguments 3 and 4, but I don't use them in my custom event... ??
  1. Helpful
  1. Chris Pollach @Appeon
  2. Wednesday, 13 November 2019 20:02 PM UTC
Hi Scott;

No, as long as you have the correct "Handle" of the other App that you want to talk to and you send the correct message number that corresponds to the "pbm_customNN" user event, that should do the trick!

Feel free to post a simple PB App example that you are working on so that we can look at your code.

Regards ... Chris
  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.