1. Riccardo Pasqualetti
  2. PowerBuilder
  3. Wednesday, 14 February 2024 14:02 PM UTC

Hi everyone,

I have my application that works into SAP BusinessOne

To open my windows into SAP MDI I get SAP MDI handle's and set this as parent to my windows using windows api SetParent

I don't know why but some windows open without issue others don't show, powerbuilder function Open works but window is not visible.

I'm using PowerBuilder 2022 R3 3289 on Windows 2019 Server 64bit, 64bit environment

If I use my application builded with PowerBuilder R2 build 2819 I don't have this issue.

Any suggestions?

Thanks

-----------------------------------------------------------------------------------------------------------

Window open event 

long ll_rc
long ll_hPBWindow
long ll_parent_handle

ll_parent_handle = wf_get_handle_sap(string(gole_sbo_application.Desktop.Title))
ll_hPBWindow = handle(This)

ll_rc = SetParent( ll_hPBWindow, ll_parent_handle)

-----------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------

Function to get SAP MDI handle's wf_get_handle_sap(string as_windowname)

Constant long GW_HWNDFIRST = 0
Constant long GW_HWNDLAST = 1
Constant long GW_HWNDNEXT = 2
Constant long GW_HWNDPREV = 3
Constant long GW_OWNER = 4
Constant long GW_CHILD = 5
Constant long GW_MAX = 5
Constant long MAX_WIDTH = 1255

long ll_hFrameWindow
long ll_hParentWindow
long ll_Desktop
long ll_Child

String ls_WindowName
String ls_ClassName
String ls_ieopened

SetNull( ls_WindowName )

ll_hFrameWindow = FindWindowA( 'TMFrameClass', as_windowname)

ll_Child = GetWindow( ll_hFrameWindow, GW_CHILD )

DO WHILE (ll_Child > 0)
ls_ClassName = Space(MAX_WIDTH)
ls_WindowName = Space(MAX_WIDTH)

GetClassNameW( ll_Child, ls_ClassName, MAX_WIDTH )
GetWindowTextW( ll_Child, ls_WindowName, MAX_WIDTH )

IF ls_classname = 'TMMDIClientClass' and IsWindowVisible(ll_Child) THEN
Return ll_Child
END IF

ll_Child = GetWindow( ll_Child, GW_HWNDNEXT )
LOOP

Return ll_Child

------------------------------------------------------------------------------------------------------------

Riccardo Pasqualetti Accepted Answer Pending Moderation
  1. Thursday, 15 February 2024 10:31 AM UTC
  2. PowerBuilder
  3. # 1

I have refactored my code but doesn't works

I don't have errors but my window is not visibile

----------------------------------------------------------------------------------------------------------------

API declaration

FUNCTION BOOLEAN IsWindowVisible( longptr hWnd ) LIBRARY "user32"
FUNCTION long SetParent (longptr hwndchild, longptr hwndnewparent) LIBRARY "user32"
FUNCTION longptr FindWindow (string lpclassname,string lpwindowname) LIBRARY "user32" ALIAS FOR "FindWindowA;Ansi"
FUNCTION longptr GetWindow( longptr hWnd, long uCmd ) LIBRARY "user32"
FUNCTION long GetClassNameW ( longptr hWnd, Ref String lpClassName, long nMaxCount ) LIBRARY "user32"
FUNCTION long GetWindowTextW ( longptr hWnd, Ref String lpString, long nMaxCount ) LIBRARY "user32"

---------------------------------------------------------------------------------------------------------------

Function wf_get_handle_sap(string as_windowname)

Constant long GW_HWNDFIRST = 0
Constant long GW_HWNDLAST = 1
Constant long GW_HWNDNEXT = 2
Constant long GW_HWNDPREV = 3
Constant long GW_OWNER = 4
Constant long GW_CHILD = 5
Constant long GW_MAX = 5
Constant long MAX_WIDTH = 1255

longptr ll_hFrameWindow
longptr ll_hParentWindow
longptr ll_Desktop
longptr ll_Child

String ls_WindowName
String ls_ClassName
String ls_ieopened

SetNull( ls_WindowName )

ll_hFrameWindow = FindWindow( 'TMFrameClass', as_windowname)
ll_Child = GetWindow( ll_hFrameWindow, GW_CHILD )

DO WHILE (ll_Child > 0)
ls_ClassName = Space(MAX_WIDTH)
ls_WindowName = Space(MAX_WIDTH)

GetClassNameW( ll_Child, ls_ClassName, MAX_WIDTH )
GetWindowTextW( ll_Child, ls_WindowName, MAX_WIDTH )

IF ls_classname = 'TMMDIClientClass' and IsWindowVisible(ll_Child) THEN
Return ll_Child
END IF

ll_Child = GetWindow( ll_Child, GW_HWNDNEXT )
LOOP

Return ll_Child

---------------------------------------------------------------------------------------------------------------

Window open event

longptr ll_rc
longptr ll_hPBWindow
longptr ll_parent_handle

ll_parent_handle = wf_get_handle_sap(string(gole_sbo_application.Desktop.Title))
ll_hPBWindow = handle(Parent)

ll_rc = SetParent( ll_hPBWindow, ll_parent_handle)

---------------------------------------------------------------------------------------------------------------

 

 

Comment
  1. Marc Wietscher
  2. Friday, 16 February 2024 07:21 AM UTC
Hi Riccardo,

since your script is in open event of your window, what does Handle(parent) return? Try Handle(this) to get the handle of your current window. Did you move this code from some other control on your window (eg. commandbutton) to the open event?



Best regards

Marc
  1. Helpful
  1. Riccardo Pasqualetti
  2. Friday, 16 February 2024 08:28 AM UTC
Hi Marc,

It's my fault, I have moved script from open event in commandbutton clicked event.
  1. Helpful
There are no comments made yet.
Riccardo Pasqualetti Accepted Answer Pending Moderation
  1. Wednesday, 14 February 2024 15:13 PM UTC
  2. PowerBuilder
  3. # 2

API Windows declaration

FUNCTION longptr GetClassNameW ( longptr hWnd, Ref String lpClassName, long nMaxCount ) LIBRARY "user32"
FUNCTION longptr GetWindowTextW ( longptr hWnd, Ref String lpString, long nMaxCount ) LIBRARY "user32"
FUNCTION longptr SetParent (longptr hwndchild, longptr hwndnewparent) LIBRARY "user32"
FUNCTION longptr FindWindow (string lpclassname,string lpwindowname) LIBRARY "user32" ALIAS FOR "FindWindowA;Ansi"
FUNCTION longptr GetWindow( longptr hWnd, long uCmd ) LIBRARY "user32"

In script I have changed variables long into longptr type but doesn't work, my windows is not visible.

Comment
  1. Chris Pollach @Appeon
  2. Wednesday, 14 February 2024 20:17 PM UTC
No, I meant NULL - LOL!

Here is what I use in my STD framework ....

------------------------------------------------------------

String ls_class

LongPtr lp_handle

SetNull (ls_class)

lp_handle = THIS.FindWindow ( ls_class, as_title ) // Try to locate it!
  1. Helpful 1
  1. John Fauss
  2. Thursday, 15 February 2024 01:23 AM UTC
I would never have thought that would work, Chris. Amazing! The PB virtual machine must recognize when a variable is (PB) null, and dynamically substitute the (C/C++) null/zero value.
  1. Helpful
  1. Chris Pollach @Appeon
  2. Thursday, 15 February 2024 15:54 PM UTC
Yes PB does that. Been that way since the PowerSoft days. ;-)
  1. Helpful
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 14 February 2024 14:21 PM UTC
  2. PowerBuilder
  3. # 3

Handles in 64-bit apps are 64 bits, not 32. I suggest you try using a Longptr data type instead of Long. You'll need to update the external function declaration(s) in addition to your code.

Comment
  1. Riccardo Pasqualetti
  2. Wednesday, 14 February 2024 14:33 PM UTC
Thanks John but I don't understand why in PowerBuilder R2 works fine, same scripts and 64bit environment
  1. Helpful
  1. John Fauss
  2. Wednesday, 14 February 2024 19:02 PM UTC
I don't know. Someone from Appeon Engineering would have to answer that. However, I've seen statements in the Q&A forum that the newer versions of Visual Studio which are used to produce the more recent version(s) of PB are more stringent as to what is allowed, but I cannot say for sure that is the cause.

What's important right now is that the existing code does not work. Does the code check for error conditions from the various API functions? Doing so may help you discover why the code is not working.

Calling a DLL function from PB is a very low-level operation, where a lot of factors all need to be correct in order for the DLL interface to work correctly. The rules for 64-bit apps are a little different because the size/length of memory addresses (pointers) and Windows handles are 64-bit. These changes can affect structures, as well (not in your case, thankfully, since the API functions you are calling do not pass any structures).
  1. Helpful 1
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.