Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29273 Discussions

I need a self-closing "countdown" box.

dboggs
New Contributor I
1,482 Views
I need my application to pause briefly, for say 10 seconds, while displaying a box with a simple warning message, then the box closes and execution continues.

Put another way, how can I provide amessagebox or dialog box that I can close progromatically instead of waiting for the user to press a key? The box message would say something like "continuing in 10 seconds" and ideally would show a clock countdown, but I could do without that for now.

My application is Quickwin. I know I could use a child window for this,but that seems like overkill and I want to make sure there's not a simpler way involving a self-closing messagebox or dialog box. Am I screwed because all such things are modal in Quickwin?

Also, if there isa simple solutionlike this, can I control where it appears within the project frame? For example, in the lower right corner instead of themiddle (wherethe MessageboxQQ result always obscures what the user may need to see)?

Thanks for any hints or sample code that anyone can provide.
0 Kudos
16 Replies
anthonyrichards
New Contributor III
1,482 Views
Add a dialog box that kicks off a timer. Issue a DLGExit command when the timer completes.
Add a progress bar and update it as the timer counts down. You could even start it in its own thread if you want to.
0 Kudos
Steven_L_Intel1
Employee
1,482 Views
You can use modeless dialog boxes from QuickWin.
0 Kudos
dboggs
New Contributor I
1,482 Views
Thanks for the suggestions. Since I'm not proficient with dialog boxes (having only used in artificial "classroom" situations) I will probably be returning for more advice.

Steve: re using modeless dialogs in Quickwin: I suppose I should have tried this. Is this a new, or misunderstood, capability? I had based my statement on the documentation, and on old publications (Digital Programmers Guid by Etzel & Dickinson, and Developing Windows Applications by Norman Lawrence), all of which state clearly that these cannot be used in Quickwin but only Console, DLL, and Static library projects. I just didn't want to waste my time trying something that's known not to work.
0 Kudos
Steven_L_Intel1
Employee
1,482 Views
You'd have to do subclassing the way the Poker sample does. Probably not for the faint-of-heart.
0 Kudos
dboggs
New Contributor I
1,482 Views
So does that mean that Anthony's suggestion is also not for the faint of heart (at least for Quickwin, maybe simpler for Console)? Just call me FaintHeart.
0 Kudos
Steven_L_Intel1
Employee
1,482 Views
I think that would be the case. I am not an expert in this area. It would be fairly simple to do in an application where you were processing the Windows messages.
0 Kudos
Paul_Curtis
Valued Contributor I
1,482 Views
Here is some sample code illustrating a timeout with progress bar. You must process the window's message loop in order to do this, which may not be compatible with Quickwin. Note the SAVE attribute which is required for the handle to the progress bar control so that it will persist over multiple calls to this proc from the opsys.

[bash]INTEGER FUNCTION StartupProc (hwnd, msg, wParam, lParam) RESULT (res)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_StartupProc@16' :: StartupProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'StartupProc' :: StartupProc
!DEC$ ENDIF
        USE comctl32
    IMPLICIT NONE
    SAVE
    
    INTEGER(HANDLE),  INTENT(IN)   :: hwnd
    INTEGER(UINT),    INTENT(IN)   :: msg
    INTEGER(fWPARAM), INTENT(IN)   :: wParam
    INTEGER(fLPARAM), INTENT(IN)   :: lParam
									
    INTEGER							:: rval
    INTEGER(HANDLE), SAVE			:: hwndControl, hwprogressbar
    INTEGER							:: controlId
    INTEGER							:: code

	!	total delay of max_periods x period_delay, value in milliseconds	
	INTEGER							:: period_count, max_periods = 50
	INTEGER, PARAMETER				:: period_delay = 200
									
    res = DefaultDialogProc (hwnd, msg, wParam, lParam)

    SELECT CASE (msg)

    CASE (WM_INITDIALOG)
		CALL InitCC (ICC_PROGRESS_CLASS)
		
		period_count = 0
		rval = SetTimer (hwnd, 1, period_delay, NULL)	! delay in milliseconds

		hwprogressbar = GetDlgItem (hwnd, IDC_STARTUP_PB)
		rval = SendMessage (hwprogressbar, PBM_SETRANGE, 0, MakeLong(INT2(0), INT2(max_periods
		rval = SendMessage (hwprogressbar, PBM_SETPOS,   0, 0)
		rval = SendMessage (hwprogressbar, PBM_SETSTEP,  1, 0)

    CASE (WM_COMMAND)
        code		= HIWORD(wParam)
        controlId	= LOWORD(wParam)
        hwndControl = lParam
        SELECT CASE (controlId)

		CASE (IDOK)
			res = 1

		CASE (IDCANCEL)
			rval = KillTimer (hwnd, 1)
			rval = EndDialog (hwnd, IDCANCEL)
			res = 1

        END SELECT

    CASE (WM_TIMER)
		period_count = period_count + 1
		IF (period_count < max_periods) THEN
			rval = SetTimer (hwnd, 1, period_delay, NULL)
			rval = SendMessage (hwprogressbar, PBM_STEPIT, 0, 0)
		END IF
		res = 1


    CASE (WM_DESTROY)

    END SELECT
END FUNCTION StartupProc
[/bash]
0 Kudos
anthonyrichards
New Contributor III
1,482 Views
In the above code, CALLInitCC(ICC_PROGRESS_CLASS) takes the place of

ret=InitCommonControlsEx(ICC_PROGRESS_CLASS). Correct?

What you need to do is
1) provide a menu item to start your timer dialog, e.g. Call TimerDlg(Whatever) and the Dialog resource IDD_TIMER_DIALOG containing the progress bar IDC_STARTUP_PB.
2) Set up TimerDlg to do the
DlgInit(IDD_TIMER_DIALOG,dlg)
DlgSetSub(dlg,IDD_TIMER_DIALOG, TimerSub)
DlgModal(dlg)
DlgUnInit(dlg)
etc.

3) write TimerSub to process the Dlg_create and Dlg_Destroy messages
4) within the processing of Dlg_Create, use SetWindowLong to substitute StartUpProc in place of the default dialog procedure
5) Then StartUpProc will take over the handling of the timer dialog box messages for you.

You must INCLUDE 'resource.fd' in TimerDlg and StartUpProc to give it access to resource IDs.
0 Kudos
dboggs
New Contributor I
1,482 Views
Thanks to both for these detailed replys. While I have no doubt that the modeless dialog as described is ultimately the best way to accomplish the Timeout box, I'm so far from understanding the concepts that I can only save the sample code for future reference--which I really hope to get to some day. In the meantime, I will use a Quickwin child window to accomplish the task. Given my limited knowledge at this time it will be far, far easier.

It would be interesting to compare the relative advantages of these two methods. One disadvantage of the Quickwin child window method is that it will only work in Quickwin projects. Another is that it will only containtext and/or graphics, but not dialog tools. One advantage is that it is quite easy to cause the window to open wherever I want within the project frame window. That's probably possible with the modeless dialog method too, but it's just one more thing I would have to learn and mess around with.

Can anyone foresee problems with the Quickwin child window method that I haven't seen yet?

Hopefully the 2nd edition of my program can utilize a modeless dialog box and thereby have more of the official Windows look.
0 Kudos
anthonyrichards
New Contributor III
1,482 Views
I attach code for a simple QuickWin project that appears to work.
It adds a 'Start Timer' item under the 'File'menu item which, when selected, opens the timer dialog containing a progress bar which ticks along for ten seconds or so then vanishes.

It uses subclassing to substitute (a modified version of) Paul Curtis's StartUpProc code for the default dialog procedure so that it can take over handling of the timer messages.

Note that there is a module TIMERGLOBALS used in place of COMMON to make progress bar settings available wherever they are needed by means of USE TIMERGLOBALS statements.

I had some 'fun' trying to size the child window to fall completely within the frame window.
I still do not understand how the SetWsizeQQ function arguments translate into child window position. Perhaps Steve can advise?

P.S. Note that the timer dialog is started with a call to subroutine TIMERDLG. Because of this, you can start the timer from anywhere in your code just by calling TIMERDLG. You do not have to start it from the File menu.

P.P.S Further experimentation has resulted in the modified attachment which provides the options of both a Modal and a Modeless timer dialog. Two items are now added under the 'File' menu item, 'Start Modal Timer' and 'Start Modeless Timer'. Both seem to work OK. The 'OK' and 'Cancel' buttons work too. The modeless dialog requires a message loop and it is terminated using a call to PostQuitMessage. The modal dialog is terminated with a call to DLGEXIT. Two routines are added, TIMERDLGMODELESS and TIMERSUBMODELESS.
I have also replaced the call to INITCOMMONCONTROLS, which has been superseded by a call to the function InitCommonControlsEx.
0 Kudos
dboggs
New Contributor I
1,482 Views
Thanks Anthony, I am anxious to try your routine. BUT I can't run it because the linker gives error "cannot open file 'comsuppw.lib'. Can you post?

ps I'm glad someone besides me likes to code in uppercase.
0 Kudos
anthonyrichards
New Contributor III
1,482 Views
Are you using Intel Visual Fortran?
I generated the code I posted using Compaq Visual fortran, but it should work OK in IVF.
Just creat a new project and make it a QuickWin project.
This should be an empty project.
Just add the fortran files, and the resource and header files to it and build.

I have no Idea what 'comsuppw.lib' is. Perhaps you chose the wrong type of project to create and you created something that required C++ libraries?
0 Kudos
dboggs
New Contributor I
1,482 Views
Well now, this is interesting.

First, I am not really comfortable with all the different files involved with a project, especially when using dialogs. When given a load of files and have to make a project of them, I really just guess how to set everything up in Visual Studio (trying to learn, but can't find documentation that leads me through it).

Second, I had done exactly as you suggest, using IVF, and got the error about the "missing library".

Third, I fired up a friend'sold CVF, made an empty project, and then added your files. In the existing files search box, I simply tagged all of them (noting that I first have to set the filter to *.* otherwise they don't all show). CVFputs them in particular locations by default, namely

Header files: resource.fd, resource.h
Resource files: none
Source files: testtimer.f90, timerglobals.f90, resource.rc

IT WORKED.

I tried again using IVF. When existing files are added to the project in IVF, they end up in different places:

Header files: resource.fd, resource.h
Resource files: resource.rc
Source files: testtimer.f90, timerglobals.f90

I don't knowif this should make a difference or not, but I still get the library error. So I removed resource.rc from the project and re-added it as a source file, just to match the CVF setup. Still get theerror.

Anyway, the project looks great (as long as I run it under CVF!), so thanks. AsI absorb it more I will likely have further questions.

Perhaps Steve can explain why it won't run under IVF? (Version 12.0)

0 Kudos
Steven_L_Intel1
Employee
1,482 Views
The arrangement of sources into the project folders is simply cosmetic for the benefit of the user. It does not affect how builds are done.

The problem you're having is due to our inadvertently omitting comsuppw.lib from the VS2008 Shell in earlier versions of 11.1. We fixed this in later updates but it would require you to uninstall and reinstall the shell. An alternative would be for you to download the Windows SDK from microsoft.com and copy comsuppw.lib to the SDK folder.
0 Kudos
dboggs
New Contributor I
1,482 Views
Thanks Steve. I obtained comsuppw.lib from a colleague who had VS. It was a bit difficult to figure out what to do with it though--the "SDK folder" you referred to was simply not apparent on my computer. For the record, the VS Tools > Options > Intel Visual Fortran > Compilers > Libraries shows $(IfortInstallDir)compiler\lib\ia32 as the main (i.e. first) library path, so I put the file there, and it works fine now.

For me, this location is
c:\Program Files\Intel\Composer XE-2011\compiler\lib\ia32.

I am a :) camper now

PS thanks also for the comment about the cosmetic property of where various files are placed in a VS project. This probably saved me hours of reverse engineering and trial/error.
0 Kudos
Steven_L_Intel1
Employee
1,482 Views
For a VS Shell install, I am not sure where the SDK files go. Where you put it may be ok as long as you update Fortran in place. What I suggest is searching the system for the file kernel32.lib and put comsuppw.lib in the same folder.
0 Kudos
Reply