Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

SetConsoleCrtlHandler

reneeculver
Beginner
4,756 Views
Ian has been a remarkable help to me and I want to thank him.

Rather than have a special source for exiting, in that it was an example of a real program as opposed to the real thing, I have moved the code back to the sources. In doing that, I now have an accvio.

I guess I better explain what this does. First there's a handler that's setup. When a number event occurs the handler is called. Parsing for the argument occurs. The code "does the right thing" based on an argument on what event is occurring.

Part of the reason why I am having trouble debugging is that I'm used to a debbuger that uses addresses which MS doesn't. The handler does generate an address but it's not the correct one and because addresses are not used I can't tell how far off I am.

The code is:

SUBROUTINE SetupExit

USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE

INTEGER(BOOL) :: ff

ff = SetConsoleCtrlHandler(LOC(CloseWindow), TRUE)

END SUBROUTINE SetupExit

FUNCTION CloseWindow(number)

USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE

INTEGER(DWORD), INTENT(IN) :: number

INTEGER(BOOL) :: CloseWindow

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

SELECT CASE (number)

CASE (0) ! Ctrl c

PRINT "('Oi!! Stop pressing Ctrl-C!')"

CloseWindow = TRUE

CASE (1) ! Ctrl break

PRINT "('Ouch!! That Ctrl-Break hurt!')"

CloseWindow = TRUE

CASE (2) ! Console Window close

PRINT "('Wait a tick - I don''t want to go away!')"

CloseWindow = TRUE

CASE DEFAULT ! 5 for log off, 6 for shutdown -

PRINT "('Bye bye!!')"

CloseWindow = FALSE

END SELECT

END FUNCTION CloseWindow

I haven't altered the code yet. It's still Ians.

The first accvio I get is:

Unhandled exception at 0x002ab537 in Adventure.exe: 0xC0000005: Access violation writing location 0x0000000000000000. It occurs when I try to close the window with the X that occurs at the top right of all windows.

Renee

0 Kudos
1 Solution
IDZ_A_Intel
Employee
4,745 Views
Hello reneeculver,

I tested your code with a test program and it seems fine. My code is:

[fortran]module my_setconsole

contains

    SUBROUTINE SetupExit

        USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE
        INTEGER(BOOL) :: ff
        ff = SetConsoleCtrlHandler(loc(CloseWindow), TRUE)
        continue
    END SUBROUTINE SetupExit

    INTEGER(BOOL) FUNCTION CloseWindow(number)
    !DEC$ ATTRIBUTES STDCALL :: CloseWindow

        USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE

        INTEGER(DWORD) :: number

        SELECT CASE (number)
            CASE (0) ! Ctrl c
                PRINT "('Oi!! Stop pressing Ctrl-C!')"
                CloseWindow = TRUE
            CASE (1) ! Ctrl break
                PRINT "('Ouch!! That Ctrl-Break hurt!')"
                CloseWindow = TRUE
            CASE (2) ! Console Window close
                PRINT "('Wait a tick - I don''t want to go away!')"
                CloseWindow = TRUE
            CASE DEFAULT ! 5 for log off, 6 for shutdown -
                PRINT "('Bye bye!!')"
                CloseWindow = FALSE
        END SELECT
    END FUNCTION CloseWindow 
end module my_setconsole

program close_handle
    USE IFCORE
    USE my_setconsole
    implicit none

    ! Variables
    logical :: pressed=.false.
    ! Body of close_handle
    Call SetupExit
    print *, 'Hello World'
    DO WHILE (.NOT. pressed)   
        pressed = PEEKCHARQQ ( )
        CALL SLEEPQQ (200) 
    END DO

end program close_handle[/fortran]

I've just inserted the subroutines inside a module and I've created a test program. Please try it and tell me if it works for you.

Pedro

View solution in original post

0 Kudos
41 Replies
IDZ_A_Intel
Employee
4,746 Views
Hello reneeculver,

I tested your code with a test program and it seems fine. My code is:

[fortran]module my_setconsole

contains

    SUBROUTINE SetupExit

        USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE
        INTEGER(BOOL) :: ff
        ff = SetConsoleCtrlHandler(loc(CloseWindow), TRUE)
        continue
    END SUBROUTINE SetupExit

    INTEGER(BOOL) FUNCTION CloseWindow(number)
    !DEC$ ATTRIBUTES STDCALL :: CloseWindow

        USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE

        INTEGER(DWORD) :: number

        SELECT CASE (number)
            CASE (0) ! Ctrl c
                PRINT "('Oi!! Stop pressing Ctrl-C!')"
                CloseWindow = TRUE
            CASE (1) ! Ctrl break
                PRINT "('Ouch!! That Ctrl-Break hurt!')"
                CloseWindow = TRUE
            CASE (2) ! Console Window close
                PRINT "('Wait a tick - I don''t want to go away!')"
                CloseWindow = TRUE
            CASE DEFAULT ! 5 for log off, 6 for shutdown -
                PRINT "('Bye bye!!')"
                CloseWindow = FALSE
        END SELECT
    END FUNCTION CloseWindow 
end module my_setconsole

program close_handle
    USE IFCORE
    USE my_setconsole
    implicit none

    ! Variables
    logical :: pressed=.false.
    ! Body of close_handle
    Call SetupExit
    print *, 'Hello World'
    DO WHILE (.NOT. pressed)   
        pressed = PEEKCHARQQ ( )
        CALL SLEEPQQ (200) 
    END DO

end program close_handle[/fortran]

I've just inserted the subroutines inside a module and I've created a test program. Please try it and tell me if it works for you.

Pedro
0 Kudos
reneeculver
Beginner
2,657 Views
Pedro,

I'm at a loss then. Did you have the code in a .F90 module or a .FOR code?

I returned it to .for code. Needles to say they were just subroutines. They were not in a module.

Renee
0 Kudos
IanH
Honored Contributor III
2,657 Views
Quoting reneeculver
...They were not in a module....

That's the problem then. When compiling SetupExit the compiler knows nothing about the symbol CloseWindow, so it "implicitly" assumes that it is a real variable. Note you've also lost the IMPLICIT NONE in both procedures that would have told you that the compiler was guessing about CloseWindow.

If you aren't going to put the two routines in a module, then you need to tell the compiler in SetupExit that close window is a function returning an INTEGER(BOOL) and that it uses the stdcall calling convention.

[fortran]INTEGER(BOOL) :: CloseWindow
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
[/fortran]
The above needs to appear in two places - inside CloseWindow (as it already does in your example) and also inside SetupExit (before the "ff=" line).

0 Kudos
reneeculver
Beginner
2,655 Views
I still have a error.

SUBROUTINE SetupExit

USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE

INTEGER(BOOL) :: ff

INTEGER(BOOL) :: CloseWindow

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

ff = SetConsoleCtrlHandler(LOC(CloseWindow), TRUE)

END SUBROUTINE SetupExit

FUNCTION CloseWindow(number)

USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE

INTEGER(DWORD), INTENT(IN) :: number

INTEGER(BOOL) :: CloseWindow

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

SELECT CASE (number)

CASE (0) ! Ctrl c

PRINT "('Oi!! Stop pressing Ctrl-C!')"

CloseWindow = TRUE

CASE (1) ! Ctrl break

PRINT "('Ouch!! That Ctrl-Break hurt!')"

CloseWindow = TRUE

CASE (2) ! Console Window close

PRINT "('Wait a tick - I don''t want to go away!')"

CloseWindow = TRUE

CASE DEFAULT ! 5 for log off, 6 for shutdown -

PRINT "('Bye bye!!')"

CloseWindow = FALSE

END SELECT

END FUNCTION CloseWindow

The error looks like this:

Unhandled exception at 0x001bb390 in Adventure.exe: 0xC000001D: Illegal Instruction.

I know SetupExit is being called. FF is a 1. but I never see any sign of CloseWindow firing.

The !DEC attribute stdcallsbegin in column 1.

Renee

0 Kudos
IDZ_A_Intel
Employee
2,655 Views
Renee,

Why you are using .for files? If you are working in a old project, just leave the existing .for files and add a .f90 file with the new subroutines. And add them to a module, like a did in the modified code I presented. Modern FORTRAN use modules.

Pedro
0 Kudos
reneeculver
Beginner
2,655 Views
Ok Pedro.

I am working with a historic game (and I am not at alla gamer). I am taking Adventure, the first text game to 32 and 64 bits. The entire game is done it three sources and I hate adding one, but I shall.

A free copy of Adventure and the sources will be available if you run Windows!!!!

I worked for Digital, the original developer of this Fortran compilerand began in Fortran in the 70s. I left Fortran early and went to Bliss which was our system implementation language.

I'll give the .f90 a try. In the days of the VAX the .for looked nothing like the .for files of today. I do hate using the module.

Renee
0 Kudos
reneeculver
Beginner
2,655 Views
OK,

Using a .f90 File I receive

Error 1 error LNK2019: unresolved external symbol SETUPEXIT referenced in function MAIN__ AAMAIN.obj

The compiler will not allow me to place a USE to define SetupExit in the main routine.

Renee
0 Kudos
reneeculver
Beginner
2,655 Views

"USE IFCORE"

What is this?

Why have I never heard of Ifcore? According to Google it's a library.

Renee

0 Kudos
IDZ_A_Intel
Employee
2,655 Views
Renee,

I've removed the module.

[fortran]SUBROUTINE SetupExit

    USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE
    implicit none
        
    INTEGER(BOOL), external :: CloseWindow
    !DEC$ ATTRIBUTES STDCALL :: CloseWindow        
    INTEGER(BOOL) :: ff
    ff = SetConsoleCtrlHandler(loc(CloseWindow), TRUE)
    continue
END SUBROUTINE SetupExit

INTEGER(BOOL) FUNCTION CloseWindow(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow

    USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE
    implicit none
    INTEGER(DWORD) :: number

    SELECT CASE (number)
        CASE (0) ! Ctrl c
            PRINT "('Oi!! Stop pressing Ctrl-C!')"
            CloseWindow = TRUE
        CASE (1) ! Ctrl break
            PRINT "('Ouch!! That Ctrl-Break hurt!')"
            CloseWindow = TRUE
        CASE (2) ! Console Window close
            PRINT "('Wait a tick - I don''t want to go away!')"
            CloseWindow = TRUE
        CASE DEFAULT ! 5 for log off, 6 for shutdown -
            PRINT "('Bye bye!!')"
            CloseWindow = FALSE
    END SELECT
END FUNCTION CloseWindow 

program close_handle
    USE IFCORE
    implicit none

    ! Variables
    logical :: pressed=.false.
    ! Body of close_handle
    Call SetupExit
    print *, 'Hello World'
    DO WHILE (.NOT. pressed)   
        pressed = PEEKCHARQQ ( )
        CALL SLEEPQQ (200) 
    END DO

end program close_handle[/fortran]

I've USEd IFCORE because SLEEPQQ and PEEKCHARQQ are declared inside that module. Hope this solve your problem.

Pedro
0 Kudos
reneeculver
Beginner
2,655 Views
It ALMOST solves the problem, Pedro. It builds with no errors.

When I use it, I receive a breakpoint notication and then it exits.

Renee
0 Kudos
Steven_L_Intel1
Employee
2,655 Views
IFCORE is another of the predefined modules provided by Intel Fortran. It declares a number of routines we supply, including SLEEPQQ. You have not heard of it because you have not read the Intel documentation.
0 Kudos
reneeculver
Beginner
2,655 Views
Actually, other than release notes I would love to read Intel Documentation. Some comes with Help but Help in Visual Studio is of limited usefulness. I'll give some specifics on that.

One is that I use the index a lot, virtually exclusely. Yet there is no index to use with Intel documentation and Visual Sudio 2010.

So it's not there to be read.

Renee
0 Kudos
IDZ_A_Intel
Employee
2,655 Views
Renee,

Create a new project and paste the code in a .f90 file. Build and run. See if it works (try ctrl+c and see if it prints the corresponding message). It should work with no problem. I tried myself with FORTRAN Composer XE update 3 and I have no problem.

Pedro

0 Kudos
IDZ_A_Intel
Employee
2,655 Views
Renee,

Visual Studio do have a index to be used with Intel documentation. Inside Visual Studio: HELP->Intel Visual Fortran Composer XE 2011->Intel Visual Fortran Composer XE 2011 help. It will open Microsft help viewer and you can use the index.

Pedro
0 Kudos
reneeculver
Beginner
2,655 Views
I think now Pedro, I need a little time.

I would say with the debugger but at least in console routines I cannot single step through CloseWidow although breakpoints do work.

So single stepping through these sorts of routines is another problem.

I'm am no longer receiving a breakpoint message. I do receive a FORRTL error messge ever so briefly "that the world is coming to an end" actually I think when I issue a stop. Is there a better END statement to use to
make a exit, in this case?

The code now looks like this:

INTEGER(BOOL) FUNCTION CloseWindow(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE

implicit none

INTEGER(DWORD) :: number

SELECT CASE (number)

CASE (0) ! Ctrl c

PRINT "('Oi!! Stop pressing Ctrl-C!')"

CloseWindow = TRUE

CASE (1) ! Ctrl break

CloseWindow = TRUE

stop

CASE (2) ! Console Window close

CloseWindow = TRUE

stop

CASE DEFAULT ! 5 for log off, 6 for shutdown -

PRINT "('Bye bye!!')"

CloseWindow = FALSE

END SELECT

END FUNCTION CloseWindow



Renee
0 Kudos
Steven_L_Intel1
Employee
2,655 Views
With VS2010, the help comes up in a web browser. While you are not presented with an index, you can search for topics (and can browse the table of contents.)
0 Kudos
IDZ_A_Intel
Employee
2,655 Views
Steve,

It is possible to install Microsoft Help Viewer and it has an index. Indeed this is what I use because I need the index quite often. I found the Composer XE web browser help to be a step back, when compared with VS2008 and Visual FORTRAN 11.1 help.

Pedro
0 Kudos
IDZ_A_Intel
Employee
2,655 Views
Renee,

If you want to end the program when you press ctrl+c (or one of the other events) then the STOP should be fine. I tried it and the program ends smoothly. Renee please use the syntax highlighter when you post code. It is the yellow pen. It is much much more clear than just pasting in text mode.

Pedro
0 Kudos
reneeculver
Beginner
2,657 Views
OK,

The error occurs as the thing exits which means I need to be VERY fast to see it.

The error is:

forrtl: severe (8): internal consistency check failure, file for_exit_handler. c. line 397

The code looks like this:

[fortran]CASE (2) ! Console Window close

Close(16)

CloseWindow = TRUE

stop


[/fortran]


And I still get the error.

Renee
0 Kudos
IDZ_A_Intel
Employee
2,564 Views
Renee,

Clearly I'm missing some pieces. Why you are closing unit 16? Why don't you provide the entire code?

Pedro
0 Kudos
Reply