- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Subroutine SetupExit
Use kernel32
Integer*4 FF
ff=SetupConsoleCntlrHandler(CloseWindow,.true.)
Return
End
Subroutine CloseWindow(number)
Integer*4 number
Return
End
I amcallingSetupExit but FFreturns a 1 which means an error ocurred. But what's the error?
Renee
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see several things wrong:
- The name of the function is SetConsoleCtrlHandler
- You did not declare CloseWindow as EXTERNAL (if it is a procedure in the same module, then you don't need to do that.)
- You passed .true. which is a Fortran LOGICAL value, not the C BOOL that the function expects. Use TRUE (declared in KERNEL32) instead
- The documentation for this function indicates that a zero return value indicates error. You would then call GetLastError to get a more detailed error code. A value of 1 indicates success.
- Any Windows callback function needs to be STDCALL. So you need to add "!DEC$ ATTRIBUTES STDCALL :: CloseWindow" to the CloseWindow routine itself and in the caller (again, this last is not needed if it is a module procedure.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CloseWindow is immediately below so it is in the same module.
Let me go try the others.
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I add it to SetupExit also, Irecieve the following error:
Error 1 error #7112: This actual argument must not be the name of a procedure. [CLOSEWINDOW] D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 2458
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Subroutine SetupExit
USE KERNEL32
integer*4 ff
ff=SetConsoleCtrlHandler(closewindow,TRUE)
Return
End
subroutine CloseWindow(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
integer*4 number
Return
end
Where do I put the External?
By the way....TRUE remains undefined in the call to SetConsoleCtrlHandler.
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The EXTERNAL declaration goes in SetupExit.
The error 200 is caused by the Run-Time Library seeing an unexpected Window Close event. You might try adding this to your CloseWindow routine:
[fortran] interface subroutine for_rtl_finish_ () BIND (C) end subroutine for_rtl_finish_ end interface call for_rtl_finish_[/fortran]
After the declaration of "number". I don't know if that will help. What it does is tell the run-time library to shut down.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Subroutine SetupExit
USE KERNEL32
integer*4 ff
ff=SetConsoleCtrlHandler(closewindow,TRUE)
Return
End
subroutine CloseWindow(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
integer*4 number
Return
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With this source, I receive the following errors:
Subroutine SetupExitUSE KERNEL32External Closewindowinteger*4 ffff=SetConsoleCtrlHandler(closewindow,TRUE)ReturnEndsubroutine CloseWindow(number)!DEC$ ATTRIBUTES STDCALL :: CloseWindow
integer*4 numberReturnendError 1 error #7112: This actual argument must not be the name of a procedure. [CLOSEWINDOW] D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 2458
Error 2 error #5508: Declaration of routine 'AT' conflicts with a previous declaration D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 60
Error 3 Compilation Aborted (code 1) D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
By the way, assuming you see the interface the way it's shown, I don't see it with numbers, although I see ms code with numbers.
Unfortunately the book hasn't done me much good. Neither "USE" or "External" are in the index. I need a book on Keywords.
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Pedro
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you had used IMPLICIT NONE, you would have found out.
According to the rules of Fortran, CloseWindow is an uninitialized default REAL variable in SetupExit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here you go - have a look at this. Note your callback needs to be a function too. This is free form source (if you copy it to a file on your computer use the .f90 extension).
[fortran]
! We'll put out utility routines into a module. That helps the compiler check ! that we are calling the routines correctly (amongst numerous other benefits). MODULE RoutinesForHandlingTheConsole IMPLICIT NONE ! Avoid bugs due to typos and confusion about type. CONTAINS ! Subroutine for us to call when we want to install our console event ! handler. SUBROUTINE SetupExit ! Intel provide with the compiler a series of modules which already have ! the "interface definitions" of the commonly used Windows operating ! system calls (Windows API) and associated types and constants. KERNEL32 ! contains the SetConsoleCtrlHandler interface (and probably a thousand ! other things). We use the ONLY clause to document where the interface for ! SetConsoleCtrlHandler (and the definitions of some of the other constants ! that we need) came from. USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE !--------------------------------------------------------------------------- ! Local variables ! Under the windows api true and false are actually represented by a ! particular kind of integer, rather than by the LOGICAL type from the ! fortran language. INTEGER(BOOL) :: ff !*************************************************************************** ! Tell the operating system what we want our handler function to be. The ! TRUE value for the second argument tells the operating system that ! we want to Add the handler. Documentation for SetConsoleCtrlHandler is ! online at: ! http://msdn.microsoft.com/en-us/library/ms686016%28v=vs.85%29.aspx ! (But it is written for C/C++ programmers, not Fortran programmers). ! ! The LOC intrinsic function is an extension provided by ifort that ! converts the address of the procedure into an integer (this is how ! addresses are/were handled historically when interfacing Fortran ! programs with the windows API). ff = SetConsoleCtrlHandler(LOC(CloseWindow), TRUE) END SUBROUTINE SetupExit ! Our handler routine. As per the Window API documentation this needs to be a ! function that returns a BOOL (C declaration - INTEGER(BOOL) in Fortran). It ! must take a single DWORD (C declaration - in Fortran INTEGER(DWORD) is the ! equivalent) argument that describes the type of event to be handled. ! ! A return value of FALSE means the event should be passed onto the next ! handler in the chain. A return value of TRUE means that no further event ! handlers will be called (the event has been processed). ! ! Documentation for the handler routine is online at: ! http://msdn.microsoft.com/en-us/library/ms683242%28v=vs.85%29.aspx ! ! Documentation is also available from within Visual Studio (press F1!). FUNCTION CloseWindow(number) ! As per the USE statement comment above. USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE ! Function result type INTEGER(BOOL) :: CloseWindow ! We need the calling convention of CloseWindow to match what the ! windows operating system expects - that's STDCALL (on 32 bit windows). !DEC$ ATTRIBUTES STDCALL :: CloseWindow ! Our argument type. Because this routine is STDCALL, and this is a scalar, ! this argument will be passed by value (which is what we want per the docs). INTEGER(DWORD), INTENT(IN) :: number !**** ! Meaning of number based on the online documentation. 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 - ! We'll indicate that we want the next handler (which should be the ! fortran runtime) to deal with this, because the user is being ! pretty serious about leaving! PRINT "('Bye bye!!')" CloseWindow = FALSE END SELECT END FUNCTION CloseWindow END MODULE RoutinesForHandlingTheConsole PROGRAM RENEE_1 ! Make available our utility procedures. USE RoutinesForHandlingTheConsole ! For testing we'll run a little loop to take up some time. Each loop ! iteration we'll sleep - intel provide a "Sleep" function to let us ! do that (we could also go directly to sleep routines in the Windows ! API). USE IFPORT, ONLY: SLEEPQQ IMPLICIT NONE INTEGER :: i ! Loop counter !***************************************************************************** ! Install our console handler CALL SetupExit PRINT "('Go ahead - make my day (try Ctrl-C/Ctrl-Break/Close my window!')" DO i = 1, 20 PRINT "(I0)", i CALL SLEEPQQ(500) ! Sleep for half a second END DO END PROGRAM RENEE_1[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I cant use Implicit none because I am working on the oldest game written on computers and it already has Implicits declared.
But the real help's alot. The error messsages have not changed and my code is:
Subroutine SetupExit
USE KERNEL32
External Closewindow1
Real ff
ff=SetConsoleCtrlHandler(closewindow1,TRUE)
Return
End
subroutine CloseWindow1(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
integer*4 number
Return
end
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've never heard of a LOC...it has not been mentioned and it's not in the index either.
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Function CloseWindow1(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
integer*4 number
Return
end
Ok, it compiles and runs. and closewindow1 fires on windows closings (and no telling what else). But within the routine number comes in during window closings which I get now, as as undefined address.
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Subroutine SetupExit
USE KERNEL32
External Closewindow1
Real ff
ff=SetConsoleCtrlHandler(loc(closewindow1),TRUE)
Return
End
Function CloseWindow1(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
integer*4 number
stop
Return
end
So far, it works like this with no stack dumps.
I"d like to thank Steve and especiallly Ian. Thank you.
I still dont know why number was undefined at run time.
Renee
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Function CloseWindow1(number)
!DEC$ ATTRIBUTES STDCALL :: CloseWindow
Careful. 'CloseWindow1' .NE. 'CloseWindow'.
If that's not a transcription problem then CloseWindow1 wouldn't be being declared as StdCall. That has implications for stack cleanup and also how arguments are passed (number would be coming through as garbage attempts to reference number would almost certainly crash your program).

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page