1. Daniel Vivier
  2. PowerBuilder
  3. Friday, 1 March 2019 22:06 PM UTC

This is in PB 2017 R3. I'm having a weird problem where some code I'm using to try to determine whether an instance of my app is already running is somewhat randomly crashing the compiled program (or PB if I run from there or use the debugger).

I have an external function declaration as follows:

FUNCTION long GetWindowText(ulong handle, ref string wintext, long length) Library "user32.dll" alias for "GetWindowTextW"

The I call it as follows (having determined the ULong handle value ulHwnd somehow):

String lsTitle, lsTitleStart = "text to search for"
lsTitle = String(200)
if gnv_environment.GetWindowText(ulHwnd, REF lsTitle, 200) > 0 then
    if Pos(lsTitle, lsTitleStart) = 0 then
        ....

I have seen in the debugger where the GetWindowText succeeds (I see a value for lsTitle) but then PB crashes on the next line, looking for lsTitleStart in lsTitle. Other times it crashes other places in the larger function containing this (or sometimes doesn't crash if I put enough debugging messageboxes into the code at various places).

So my intuition is that the GetWindowText is somehow screwing things up in PB's internal memory. But I don't know how. And oddly enough, another function that calls GetWindowText seems to always work. But I'm pretty sure it's what is causing the problem in this function, because if I eliminate that call, it never crashes (so far!).

Any thoughts, or other similar experience? Thanks.

Accepted Answer
Roland Smith Accepted Answer Pending Moderation
  1. Friday, 1 March 2019 23:55 PM UTC
  2. PowerBuilder
  3. # Permalink

You need:

lsTitle = Space(200)

Instead of:

lsTitle = String(200)

 

Comment
  1. Daniel Vivier
  2. Saturday, 2 March 2019 00:00 AM UTC
Oh my. That is almost certainly the right answer. Feeling really dumb. :(
  1. Helpful
There are no comments made yet.
Roland Smith Accepted Answer Pending Moderation
  1. Friday, 1 March 2019 23:57 PM UTC
  2. PowerBuilder
  3. # 1

Maybe instead you should use a Mutex to prevent multiple copies. It isn't dependent on the window title which could change.

http://www.topwizprogramming.com/freecode_mutex.html

 

Comment
  1. Daniel Vivier
  2. Saturday, 2 March 2019 00:04 AM UTC
I was also using the mutex - I was only showing the part of the code with the problem. But then I have to find the previous instance app to try to activate it, or in some cases send a message to it.
  1. Helpful
  1. Roland Smith
  2. Saturday, 2 March 2019 00:58 AM UTC
That is how PBSearch does it, a GetWindow loop that calls GetWindowText.
  1. Helpful
There are no comments made yet.
Olan Knight Accepted Answer Pending Moderation
  1. Friday, 1 March 2019 23:53 PM UTC
  2. PowerBuilder
  3. # 2


We make the same check on a process that we kick off using this:

string          ls_exe_title
uint            val

ls_exe_title =
val             = FindWindowW(0, ls_exe_title)

IF (val = 0) THEN
   ...the exe is not currently running
END IF

 

In another utility, we also use this trick:

// In the OPEN event of the application
// ---------------------------------------------------
IF Handle( This, TRUE ) <> 0 THEN
    MessageBox( "Application Error", this.DisplayName + " is already running.", StopSign! )
    Return
END IF

 

Maybe one of those will accomplish what you need.


Good Luck,

Olan

Comment
  1. Daniel Vivier
  2. Friday, 1 March 2019 23:59 PM UTC
We can't do such a simple FindWindow because the title bar varies depending on the user's data.



And the current docs says if the 2nd arg to Handle is TRUE, it always returns 0.



So I'm not sure either of these suggestions would work for me.
  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.