forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to bring dialog windows from subroutine to main program

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Sun Apr 12, 2020 11:02 pm    Post subject: How to bring dialog windows from subroutine to main program Reply with quote

Hello to anyone!

I need to advise how to bring dialog windows defined in a subroutine
to main calling program (thanks in advance).

DESCRIPTION:
I defined a main window in the main program, where the user must define three variables (VARIABLE1: input file name with input data, VARIABLE2: output file name, where the new data will be written and VARIABLE3: to change or not the signs in the output data). When this is specified, all 3 variables are passed to a subroutine, which is called from main program and which - in fact - does the real job.

Since for the subroutine it takes some time (around 35 minutes) to finish the job, it is necessary to define a progress bar, otherwise the user sees nothing in the main window and can have such feeling that the program does not work (although it works). So, I defined within the called subroutine a progress bar window and - when subroutine finishes - a message window that the job is done and then it should be returned to main window of the main program. However, these windows are nowhere seen and never displayed.

The last iowin function in main program (placed directly before calling the subrouitine is:

1 ans=winio@('%3nl%taChange signs for DX and DY in the output TXT file? (y=yes, n=no)%`5.2ls',change,3l,selection)

The three iowin functions in the called subroutine, placed before the real job starts - it means before an outer DO loop) are:

ans=winio@('%ca[Progress bar]&')
ans=winio@('Current status ... %2nl&')
ans=winio@('%60br&',bar_fill,RGB@(255,255,0))

then immediately come three DO loops:

First: do i = 1,I_Pocet_X !outer DP loop
!
! defining the step of the progres bar (corresponds to 1%)
!
krok_bar_fill = 100.0/real(I_Pocet_X)

if (i.eq.1) then
bar_fill=0.0
else
bar_fill = bar_fill+krok_bar_fill
end if
!
! calling progress bar update for the value bar_fill (up to value 1)
! ---------------------------------------------------------
!
do while (bar_fill.lt.1.0) !beginning DO WHILE

CALL window_update@(bar_fill)

if (i.eq.1) then
I_X = I_Xmin
else
I_X = I_X + I_X_krok
end if

Inner1: do j = 1, I_Pocet_Y ! first inner DO loop - beginning


if (j.eq.1) then
I_Y = I_Ymin
else
I_Y = I_Y + I_Y_krok
end if

rewind 3

Inner2: do n = 1, k ! second inner DO loop - beginning

if (n.lt.Cool then
read (3,*) riadok
cycle
else
read (3,*) I_XX, I_YY, DDX, DDY
end if

if (I_X.eq.I_XX.and.I_Y.eq.I_YY) then

if (selection.eq.2) then
write (4,37) I_XX, I_YY, DDX, DDY
37 format (I8,',',I7,',',F6.2, ',',F6.2)
else
DDX = -1.0*DDX
DDY = -1.0*DDY
write (4,95) I_XX, I_YY, DDX, DDY
95 format (I8,',',I7,',',F6.2, ',',F6.2)
end if

exit

else if (n.eq.k) then
write (4,33) I_X, I_Y, DX, DY
33 format (I8,',',I7,',',F6.2, ',',F6.2)
end if

end do Inner2
end do Inner1
end do !end do loop DO WHILE, when bar_fill, is less than 1
end do First

close (3)
close (4)
!
! Message window - conversion done
!
w=200
h=20
ans=winio@('%sz&',w,h)
ans=winio@('%ca%bf%fn[Arial][Program DATA_CONV - Info]&')
a
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Mon Apr 13, 2020 2:09 pm    Post subject: Reply with quote

You could launch a separate application, and use messaging to report back when the job is finished. Return the results in a Windows Message, or via a file named in a Windows message.

Eddie
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7912
Location: Salford, UK

PostPosted: Mon Apr 13, 2020 3:22 pm    Post subject: Reply with quote

Martin

Could you post a very short sample program outlining what you want to do.

Leave out the input statement, replacing them with a comment, the same for the computation.
Back to top
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Mon Apr 13, 2020 4:32 pm    Post subject: Reply with quote

Hi LitusSaxonicum,

Thanks for the advise, however, I wanted as simply solution as possible (since I am new to ClearWin+) and your tip sounds for me as additional complex programming. By the way - new finding: When I close the main program by clicking on the close icon (X) on the top right corner, then the required progres bar suddenly appears! However, it is never filled. Only when I click on its top right corner (X), then suddenly fills up to the half. When I click again on X icon, then jumps nearly to 100% and ends never. I have to kill the process by Windows task manager. So, I am stuck, since I see no error in my program.
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Mon Apr 13, 2020 5:35 pm    Post subject: Reply with quote

Additional info - I have rewritten my source code in such manner that there is no subroutine and all is carried out in the main program - however the progress bar behaves exactly as when it was programmed in the subroutine.
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1214
Location: Morrison, CO, USA

PostPosted: Mon Apr 13, 2020 6:05 pm    Post subject: Reply with quote

I have my own status bars using winio@() statements. One just displays an integer (regardless of the actual end count), the other displays the status bar as filling as it approaches the end count.

The key to doing this is that the status bar has its own window that is not closable. I define this window as "always on top" when it is created so it is always displayed.

The calling routine has to set up the kind of counter, then update the current value. The subroutine that creates, updates, and closes the status bar is responsible for not trying to update the value too quickly because (a) it slows processing and (b) can cause a crash if you were to try every iteration. I have found every second (not sooner) is quite fast enough to keep the user's view occupied so they don't try to kill the processing or believe it is hung up.

The limitation is that it works for positive integers as start/end/current.

The code for the status bar that shows percentages is:
Code:
   SUBROUTINE STATUS_BAR_windows(text,NM,NMAX,NCUR)
   USE MSWIN
   INTEGER:: NM
   integer*4:: NMIN,NMAX,NCUR,i,ifill_val
   integer*4:: ifill_last,iifill,ifill

   integer,parameter:: col_width = 20 ! Allows the bar to be separated into 20 distinct increments

   character*(*) text ! for labelling the status bar
   REAL*8:: FILL,fill_value
   REAL*8:: fill_last,fill_this
   integer(7):: WINDOW_HANDLE!,ICOLOR
   integer*4:: WINDOW_CLOSURE
   integer,external:: button_refresh

! --- INITIALIZE THE STATUS BAR WHEN NCUR = 0
   NMIN = NM
   select case (ncur)
   case (0)   ! initialize
      i = winio@("%ww[no_edge,no_maxbox,no_minbox,topmost]&") !
      i = winio@('%ca@&',text) ! set the caption for the status bar
      fill_value = 0.0d0 ! set the initial value
      ifill_last = -999
      iifill = 0
      ifill_val = 0
      i = winio@('Processing # %`rd of %wd%2nl&',ifill_val,nmax)
      i = winio@('%20br[percentage]&',fill_value,rgb@(0,0,255)) ! a status bar
      i = winio@('%hw%lw',window_handle,window_closure) ! save the handle (locally) and the window_closure flag (locally)
      call dclock(fill_last) ! get the time of the window creation so we don't update it too often
   case (-1) ! end the display
      window_closure = 0
      call window_update@(window_closure)
   case default
      ifill_val = ncur
      call dclock(fill_this)
      if(fill_this-fill_last.le.1.d0) return ! do not update more than once per second (1.0d0)
      fill_last = fill_this
      FILL=DBLE(NCUR-nmin)/DBLE(NMAX-NMIN) ! calculate a number between 0. and 1.
      ! this limiting is done to make SURE the control doesn't throw an exception
      IF(FILL.Ge.1.0D0)FILL  = 1.D0
      if(fill.le.0.0d0) fill = 0.0d0
      fill_value = fill
      ifill = fill*dble(col_width)
      iifill=int(fill*100.d0)
      if(iifill.ne.ifill_last) then ! only update the status bar when there is a visibile change
         call yield_program_control@(Y_Temporarily)
         ifill_last = iifill
         call window_update@(fill_value) ! update the status bar itself
         call window_update@(ifill_val) ! update the count being displayed
      endif
   end select   
   return
   END


Sample code of usage only:
Code:
   call status_bar_window('This is a status bar',1,1000,0) ! initialize
   do i=1,1000
      call sleep1@(0.25)
      call status_bar_windows(' ',1,1000,i) ! will show the progress of the count changing
   end do
    call sleep1@(3.)
   call status_bar_windows(' ',1,1000,-1) ! close the status bar window
Back to top
View user's profile Send private message Visit poster's website
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Mon Apr 13, 2020 6:24 pm    Post subject: Reply with quote

Paul,
As I described in my first post regarding this issue, the purpose of the program is to re-structure the input data available in one TXT file and re-write them in a new required format to other TXT file which will serve as an input source for other program.

Below are ONLY declared the used winio functions in the main program
(without call back functions) and the called subroutine:

!Defining the main window with 3 selectable inputs (variables, which will
be passed to the called subroutine):

w=800
h=400
ans=winio@('%sz&',w,h)
ans=winio@('%ww[thin_border]&')
ans=winio@('%ca[Program: TXT_2_SGF]&')
!
! Select input file (variable called subor3)
!
ans=winio@('%3nl%ta%bf%fn[Courier New]Input TXT for SGF:%ta%bc[yellow]%`^bt[&Select input file]&','FILE_OPENR[Select file]',subor3,sb_vstup3)
ans=winio@('%bg[grey]&')
!
! variable subor3 placed in a box
!
ans=winio@('%2nl%ta%ob%80st%cb&',subor3)
!
! Select output file (variable called subor4)
!
ans=winio@('%3nl%ta%bf%fn[Courier New]Output TXT for SGF:%ta%bc[green]%^bt[&Define output file]&',&
'FILE_OPENW[define file]',subor4,sb_vstup4)
!
! variable subor4 placed in a box
! (however, the output file is NOT displayed in the box, I do not know why
!
ans=winio@('%2nl%ta%ob%80st%cb&',subor4)
!
! Changing the signs in front of DX, DY values - question
!
ans=winio@('%3nl%taChange DX and DY signs in the output file? (y=yes, n=no)%`5.2ls',zmena,3l,vybrate)
!
! Calling subroutine, which makes re-structuring the data
!
call TXT_PRE_SGF (s3, s4, vybrate)

And now - the subroutine follows (only the part, where progress bar is defined):

SUBROUTINE TXT_PRE_SGF (subor3, subor4, vybrate)

!
! Defining progress bar
!
ans=winio@('%ca[Progress bar]&')
ans=winio@('Processing ... %2nl&')
ans=winio@('%60br',bar_fill,RGB@(255,255,0))
!
!Defining the step for window_update@(bar_fill) calling
!
krok_bar_fill = 100.0/real(I_Pocet_X)

FIRST DO LOOP: do i = 1,I_Pocet_X
if (i.eq.1) then
bar_fill=0.0
else
bar_fill = bar_fill+krok_bar_fill
end if
if (bar_fill.le.1) then
CALL window_update@(bar_fill)
end if
if (i.eq.1) then
I_X = I_Xmin
else
I_X = I_X + I_X_krok
end if

INNER DO LOOP1: do j = 1, I_Pocet_Y
if (j.eq.1) then
I_Y = I_Ymin
else
I_Y = I_Y + I_Y_krok
end if
rewind 3
INNER DO LOOP2: do n = 1, k
if (n.lt.Cool then
read (3,*) riadok
cycle
else
read (3,*) I_XX, I_YY, DDX, DDY
end if
if (I_X.eq.I_XX.and.I_Y.eq.I_YY) then
if (vybrate.eq.2) then
write (4,37) I_XX, I_YY, DDX, DDY
37 format (I8,',',I7,',',F6.2, ',',F6.2)
else
DDX = -1.0*DDX
DDY = -1.0*DDY
write (4,95) I_XX, I_YY, DDX, DDY
95 format (I8,',',I7,',',F6.2, ',',F6.2)
end if
exit
else if (n.eq.k) then
write (4,33) I_X, I_Y, DX, DY
33 format (I8,',',I7,',',F6.2, ',',F6.2)
end if

end do INNER DO LOOP2
end do INNER DO LOOP1
end do FIRST DO LOOP

close (3)
close (4)
!
! Info message
!
w=200
h=20
ans=winio@('%sz&',w,h)
ans=winio@('%ca%bf%fn[Arial][Program TXT_PRE_SGF - Info]&')
ans=winio@('%3nl%ta%sfReformatting done!%2nl %cn%9^bt[&Finish]','OK')

return
end subroutine
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Tue Apr 14, 2020 10:55 am    Post subject: Reply with quote

Many thanks wahorger, I will try your approach!
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Thu Apr 16, 2020 12:12 am    Post subject: Reply with quote

Martin,

I answered your original post with the error.

Eddie
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Thu Apr 16, 2020 9:37 pm    Post subject: Reply with quote

Hello wahorger,

Your approach (code) for a progress bar with percentage is perfectly universal and I thank you for it once again!

But, I still need some advise from you. I tried to implement your approach and have the following two (minor) questions and 2 essential questions:

NO-ESSENTIAL:
1. I noticed in your code that there is a declaration to an external function as follows: INTEGER, EXERNAL:: buttton_refresh
However, there is no such function declared, so I removed it. Is it OK?

2. There is also the variable IFILL declared (as INTEGER*4) which is connected with parameter declaration of cold_width=20 and later in the code, in the section CASE DEFAULT is ifill used in the assignment
IFILL=FILL*DBLE(col_width). But the value of IFILL is nowhere used in the code. What´s was the intention or meaning for it? (I removed it from the code, since I got compilation warning that IFILL is declared, but never used).

And now, two ESSENTIAL questions which are - in fact - my problems:

A) Despite the use the TOPMOST declaration in the code of your subroutine for %WW format code in the section CASE (0), when I specify the three required variables in my main program (variable1 - input file, variable2 - output file, variable3 - change or no change of the signs for DX, DY values)
my main program window remains active and the status/progress bar window does NOT appear as active window (is hidden and it seems as if nothing would be done). It appears ONLY then, when I kill my main window (which is unwanted). Where could be an error in my main program? Compiling and linking is OK.

B) The MOST important question (however, it can be irrelevant and can disappear, when question A will be solved):
When I kill my main window (after specifying of all three variables) to see the progress bar, ONLY CASE (0) is carried out and then I get the following run-time error: ERROR 112: Reference to undefined variable, array element or function result (/UNDEF).

And below the ERROR message is specified exactly the following:

STATUS_BAR_WINDOWS (in file ProgresBar.f95 at line 109 [+0339]
MAIN - in file (main.f95) at 291 [+0f4a]

The line 291 of my main program is as follows:

call status_bar_windows(' ',1,I_Pocet_X,i)
where I_Pocet_X is the upper limit of the main DO loop (which still has 2 nested DO loops) and was detected (the value I_Pocet_X) after reading whole input file. The status bar subroutine is called from the outer DO loop, immediately after the statement declared above.

The line 109 of the status_bar_windows subroutine is as follows:

if(fill_this-fill_last.le.1.d0) return

Do you have any idea what could be wrong?

REMARK: In the main program I use the function call ENABLE_UTF8@(1) and saved the whole source code file as Unicode(UFT-8 without signature) - Codepage 65001. In the subroutine I use the same function, but the source code file is saved as ASCII.

Many thanks in advance for your tips!

Martin
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1214
Location: Morrison, CO, USA

PostPosted: Fri Apr 17, 2020 4:00 am    Post subject: Reply with quote

Martin, thanks for the reply. This code has gone through some major revisions/tweaks and as such has some "fluff" left over. I'll answer your questions below

1. Yes, you can remove that. The function used to have a button you could press to cancel, but I found that was not prudent, nor needed for my needs.

2. The IFILL and column width help define the status bar length and the amount of the length that it consumes for a generic status bar that has no defined end point. Just a bar that appears and gets filled and cleared as the program progresses to give the user the idea that it is, indeed running. Again "fluff" left over from development.

BTW, thanks for pointing this fluff out.

Line 109 is the check to make sure at least 1 second has elapsed since the "marker" time. Once this interval has past, then a new marker is set with the current time, and the next call, this new marker is used to make sure at least 1 second has passsed.

Since this code requires variables set in one call to be used in another, it should be compiled with /SAVE option, or every variable needs the SAVE attribute set.

To get a variable to update in a window from the results of a running process, you'll need to call window_update@(xxxx) where xxxx is the name of the variable you wish to refresh. But, don't do this for EVERY trip through the loop unless each iteration takes at least 0.25 seconds. The window_update@() call can consume a lot of CPU resource, so use it sparingly.

Can you post your code again, or put it on DropBox (or other cloud service) and post a link here that I can download the code and take a look at why this might be having trouble at run-time?
Back to top
View user's profile Send private message Visit poster's website
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Fri Apr 17, 2020 10:18 pm    Post subject: Reply with quote

Thanks for your answers, I will send you the code
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Sun Apr 19, 2020 7:22 pm    Post subject: Reply with quote

Martin,
I have some words of advice. If you invent a new way or organising the various operations like opening files in a Windows application, then you will have to face two problems. The first is that preparing your user manual and Help files will grow from a big job into a huge job. The second is that your users (who already know how to run Windows apps will hate you. This also applies if you are the only user!
The normal way to start the selection process for an existing datafile is a submenu ‘Open…’ in the ’File’ menu. It is also common to have a toolbar button for it, but users will always look for the menu item. The three dots mean that selecting ‘Open…’ leads the user on to further dialogs. ‘File|New…’, ‘File|Save’ and ‘File|Save As…’ are only needed if you create and edit your datafile in your application.
My second bit of advice is to use only a few Clearwin+ format codes in any one WINIO@ call. It makes it much easier to see what is going on, and also easier to add or subtract things.
If you need to show the name of the input file continuously, then the right place to do it is in a status bar. Some apps do it in the caption bar. The same applies to an output file.
Have you thought about making your output file have the same basic name as the input file, just with the extension changed? This could cut down on one thing the user has to do. However, before you write you should do a check whether the file already exists and if it does, ask the user if they want to overwrite it.
Your third selection box really belongs in a dialog that you get to in a ‘Settings’ or ‘Options’ menu. You can always display the current option in the status bar.
Eddie
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 227

PostPosted: Mon Apr 20, 2020 10:07 am    Post subject: Reply with quote

Many thanks Eddie! I will take your advises into account!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group