Topic: Issue appgrafics

When closing the created app I don't want the user to make use of the standard close button (red cross right corner window)
To enable this I did set "closeflag" to ".false." when initiallising the window.
This has always been working, but now I suddenly noticed that it is not working anymore!
I don't know with which version of SF this still was working.
I now receive an error if I click the red right corner window-button and the app chrashes!
The following message I get:

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0xffffffff
#1  0xffffffff
#2  0xffffffff
#3  0xffffffff
#4  0xffffffff
#5  0xffffffff
#6  0xffffffff
#7  0xffffffff
#8  0xffffffff
#9  0xffffffff
#10  0xffffffff
#11  0xffffffff
#12  0xffffffff
#13  0xffffffff
#14  0xffffffff
#15  0xffffffff
#16  0xffffffff
#17  0xffffffff
When setting the "closeflag" to ".true." then this works fine!!
Could you have a look at this because this issue can corrupt my data!!

Re: Issue appgrafics

John,

I can't replicate this behavior.  Do you have a simple code sample that causes this crash?

Jeff Armstrong
Approximatrix, LLC

Re: Issue appgrafics

Sorry Jeff,
I stated that "dbflag" is not working but I mend "closeflag"

Re: Issue appgrafics

I will set up a source and send it to you!

Re: Issue appgrafics

Hi Jeff,
As promised I send you a simple source. When running the executable the app creates a window and waits for a key to be pressed.
When the key is pressed the app will close without any issue.
When closing the app by hitting the red close-button of the window I get the mentioned error!

      Program test
!
      use appgraphics
!
      implicit none
!
      INTEGER ipixxx, ipixyy, maxpx, maxpy, winx, winy, iiwin, ic
      INTEGER*2 port, imode, ipixelx, ipixely
      CHARACTER*6 mnubuf
      logical keypressed
!
      maxpy = getmaxheight()
      maxpx = getmaxwidth()
      port = 38
      imode = 180
      if (maxpx .gt. 1500) then
         ipixely = ((int2(maxpy)-int2(150)) / port) * port
         ipixelx = ((int2(maxpx)-int2(50)) / imode) * imode
      else
         ipixely = ((int2(maxpy)-int2(30)) / port) * port
         ipixelx = ((int2(maxpx)-int2(5)) / imode) * imode
      end if
!
      winx = (maxpx - ipixelx) / 2
      winy = (maxpy - ipixely) / 3
      ipixxx = ipixelx
      ipixyy = ipixely
!     
      mnubuf = 'Dynrel'
      iiwin = initwindow(ipixxx,ipixyy,mnubuf,winx,winy,dbflag=.false.,
     +        closeflag=.FALSE.)
!
450   Keypressed = .FALSE.
      Keypressed = kbhit()
      IF (Keypressed) then
         Ic = getch()
      end if
      IF (Ic .LE. 0) GOTO 450
!
      stop
!
      END program test

Re: Issue appgrafics

The issue in the example is that you're checking for keys pressed after the window is closed.  The keyboard routines are tied to an AppGraphics window.  The call to kbhit after the window closes causes an exception because a non-existent window keyboard queue is queried.

It probably shouldn't outright crash, though it might be hard to modify the library to avoid that.  However, the fix would simply cause kbhit to return .FALSE., leaving this example in an infinite loop.

Basically, if all the AppGraphics windows are closed, it is extremely dangerous to continue making calls to the library.

Jeff Armstrong
Approximatrix, LLC

Re: Issue appgrafics

Jeff, I think I don't understand what you are saying.
In a previous version of SF, when I clicked the red window cross, nothing happened, and that is exactly what I want!
So, I don't want the window to be closed! Again, in a previous version it worked that way.
I have created an "escape"-button in my app, that the user must use, or click the "escape"-key to close the app and not the windows cross-button.
So, I am wondering way this doesn't work any more.

Re: Issue appgrafics

John,

I see what you're asking now.  You want to disable the Windows "close" button?  If that ever did work in AppGraphics, it was a bug.  The closeflag only means that the program won't terminate, not that the window won't close.  If you click the close button, the window and its resources will be destroyed, but the program will keep running.

Overriding Windows' WM_CLOSE is going to be messy.  I would have to add a new API to block it.  The better way to handle this would be to assign a callback using setwindowclosecallback that will trigger safe shutdown in the main thread.  I'll see about cancelling the WM_CLOSE message, though.  It will take a bit of time to add.

Jeff Armstrong
Approximatrix, LLC

Re: Issue appgrafics

Hi Jeff,
Thanks for your reply. If you could add a API to block it I would be very happy.
I think it was in SF version 2 that it worked the way I described.
Again, thanks very much for your support!!

Re: Issue appgrafics

Hi Jeff,
First of all thanks for the new update version 3.19
I'm trying to use the new "setwindowsystemclosecallback" routine
As described in the documentation, I created a callback-Function and after creating a window, I added the following line to my fortran source:       call setwindowsystemclosecallback( noclosewin() )
Noclosewin() is the function I created and compiles without any errors!
When I then try to compile the main-source I get an error at the line with the call to the new subroutine as mentioned above:
    Error: Expected a procedure for argument 'f' at (1)

I defined noclosewin as "integer"
Am I doing something wrong?

Re: Issue appgrafics

You need to pass the function itself, not call the function.  You actually want to write:

              call setwindowsystemclosecallback( noclosewin )

By removing the parentheses, you're passing the function itself, not the result of calling the function, which is what your original code was doing.

Does that make sense?

Jeff Armstrong
Approximatrix, LLC

Re: Issue appgrafics

Hi Jeff,
If I remove the parentheses as you mention I get the same error when trying to compile the source!
I enabled the visibility of warnings in the editor. And the editor already shows the mentioned error before I even can start the compiler.

Re: Issue appgrafics

What does the function noclosewin look like?  Can you post it?  It should be something like:

    function noclosewin ()
    implicit none
    integer::noclosewin 
    
        noclosewin = 0
        Print *, "I blocked it"
        
    end function noclosewin 

I tried the above on my system with the latest build, and it seemed to work.

Jeff Armstrong
Approximatrix, LLC

Re: Issue appgrafics

To do a simple test I kept it simple and created almost exactly the same function as You did! Only the "print" statement is not in there.
      function noclosewin()
!
      implicit none
!
!      procedure als window wordt geclosed
!
!
      INTEGER::noclosewin
!
      noclosewin = 0
!
      return
!
      END function noclosewin

But I don't think the function is the issue.
The main source holding the call to the new subroutine gives the error!

The following lines are amongst others in my mainsource:

      subroutine GRAF()
.
      use appgraphics
      implicit none
.
.
      integer:: noclosewin, ipixxx, ipixyy, winx, winy, iiwin
      character::(20) mnubuf
.
.
.
      iiwin = initwindow(ipixxx,ipixyy,mnubuf,winx,winy,dbflag=.false.,closeflag=.false.)
.
.
      call setwindowsystemclosecallback(noclosewin)
(here the editor presents the error-message!!!)
.
.
      end subroutine GRAF

Re: Issue appgrafics

The problem is that you need to define a true interface to your noclosewin function.  I see that you have it on the integer declaration line, but that isn't sufficient.  If you're using Fortran 90 modules, it would be easy to scope, but I suspect you are not.

A solution that might seem ugly now is to change your calling function to be:

      subroutine GRAF()
.
      use appgraphics
      implicit none
.
.
      integer:: ipixxx, ipixyy, winx, winy, iiwin
      character::(20) mnubuf

      interface
            function noclosewin()
            integer::noclosewin
            end function noclosewin
      end interface

.
.
.
      iiwin = initwindow(ipixxx,ipixyy,mnubuf,winx,winy,dbflag=.false.,closeflag=.false.)
.
.
      call setwindowsystemclosecallback(noclosewin)
.
.
      end subroutine GRAF

The above should now make it clear to the compiler that noclosewin, wherever it is in your code, is a function returning an integer.

Jeff Armstrong
Approximatrix, LLC

Re: Issue appgrafics

Hi Jeff,
It works great now. Thank you very much!!
I must say this compiler is great! I had a look at several Fortran compilers, but this one is for me the best there is!!

I would like to show you what I created with this compiler, but unfortunately this is not possible.

Thanks again for your great support!!!