Silverfrost Forums

Welcome to our forums

Hello ClearWin+

1 Jan 2011 10:20 #7324

There are probably several good reasons why one would like to use ClearWin+. From my experience one have several and proven existing code written in Fortran. Adding a user interface implies that a language like VB, Java, C++, etc. is used for the GUI development. The disadvantage: When my colleagues sees a DOS box the firts reaction is that we are using a stone age language. ClearWin+ offers new possibilities.

The user interface here shows a simple basis for the GUI development - as a beginner. This is very cool. However, a few questions exists: 1.) Is there a simple way to align the boxes for data input; 2.) On start a vscroll appears - is there a way to suppress at the begin.

[URL=http://img17.imageshack.us/i/helloclearwin.gif/]http://img17.imageshack.us/img17/26/helloclearwin.gif[/URL]

Uploaded with [URL=http://imageshack.us]ImageShack.us[/URL]

module aps_top
   implicit none
   type par_type
     integer :: p1 = 1
     integer :: p2 = 1
     integer :: p3 = 1
     integer :: p4 = 1
     character(len=1) :: char1
     character(len=6) :: char6
   end type par_type
   integer ::ptr
   integer :: k,j
   integer :: cw_hndl
   type(par_type) :: par
   integer :: lb1_selects
   integer :: lb2_selects
   integer :: lb3_selects
   character (len=*),dimension(2), parameter ::lb1=&
               &(/'lb1-1   ',&
               &  'lb1-2   '/)
   character (len=*),dimension(3), parameter ::lb2=&
               &(/'lb2-1   ',&
               &  'lb2-1   ',&
               &  'lb2-1   '/)
   character (len=*),dimension(3), parameter ::lb3=&
               &(/'lb3-1   ',&
               &  'lb3-1   ',&
               &  'lb3-1   '/)
contains

   integer function cbupdate()
      use mswin
      call see_propertysheet_page@(ptr)
      cbupdate=2
   end function cbupdate
   integer function cbdummy()
      use mswin
      implicit none
      write(*,'(4I3,2X,A1,3X,A6)') &
      & par%p1,par%p2,par%p3,par%p4,par%char1,par%char6
      cbdummy=1
   end function cbdummy
   integer function cb_clear()
      use mswin
      implicit none
      call clear_window@(0)
      cb_clear=1
   end function cb_clear
   integer function cb_lb1()
      use mswin
      implicit none
      select case(lb1_selects)
        case(1)
        par%char1 = 'A'
        case(2)
        par%char1 = 'B'
      end select
      write(*,'(A)') 'char1 = '//par%char1
      cb_lb1=1
   end function cb_lb1
   integer function cb_lb2()
      use mswin
      implicit none
      select case(lb2_selects)
        case(1)
        par%char6 = 'abcdef'
        case(2)
        par%char6 = 'ghijkl'
        case(3)
        par%char6 = 'mnopqr'
      end select
      write(*,'(A)') 'char6 = '//par%char6
      cb_lb2=1
   end function cb_lb2
end aps_top
1 Jan 2011 10:23 #7325

Here the code for the main part - please see previous entry. winapp program propsht use mswin use aps_top integer :: i,crtl integer :: ps1, ps2, ps3 ps1=1;ps2=2;ps3=2 ptr=1 crtl = -1 ! Property sheet for PS-1 i=winio@('%sy[3d_thin]&') i=winio@('%ca[PS-1]&') i=winio@('Combo box %^ls&', lb1,2,lb1_selects,cb_lb1) i=winio@(' Combo box %^ls&',lb2,3,lb2_selects,cb_lb2) i=winio@('%2nl&') i=winio@('Int 1 %rd&',par%p1) i=winio@(' Int 2 %rd&',par%p2) i=winio@('%sh',ps1) ! Property sheet for PS-2 i=winio@('%sy[3d_thin]&') i=winio@('%ca[PS-2]&') i=winio@('%ls%2nl&',lb3,3,lb1_selects) i=winio@(' Int 3 %rd&',par%p3) i=winio@(' Int 4 %rd&',par%p4) i=winio@('%sh',ps2) ! Property sheet for PS-3 i=winio@('%ca[PS-3]&') i=winio@('Sheet three %sh',ps3) ! Start to define the application window i=winio@('%ca[User Interface]&') i=winio@('%ww[no_maxbox]&') i=winio@('%bg[btnface]&') i=winio@('%sy[thin_border]&') i=winio@('%ob[raised]&') ! Define the top property sheet i=winio@('Input data%ff%nl&') i=winio@('%3ps&',ps1,ps2,ps3,ptr) i=winio@('%ff%nl%2ta%^bt[Calculate]&',cbdummy) i=winio@('%ta%^bt[Clear]&',cb_clear) i=winio@('%cb%ff%nl&') ! Define the lower ClearWin window i=winio@('%ob[raised]&') i=winio@('Results%ff%nl&') i=winio@('%ob[depressed]%70.10cw[vscroll]%cb&',0) i=winio@('%lw%cb',crtl) print ,'Hello ClearWin+' print * write(,) 'This is cool, no I can add a simple ClearWin+ user ' write(,) 'interface to my Fortran DOS-window application. Output' write(,) 'data will be displayed here.' write(,) write(,) 'And the best of all: I do not have to change existing' write(,) 'and proven numerical algorithms.' write(,) write(,*) 'What can say: A happy new year!' end program propsht

1 Jan 2011 11:59 #7326

Happy New Year! One simple way to align controls is to use %ob with the option [no_border] - this creates an invisible grid.

1 Jan 2011 12:55 #7327

The %n.mob works fine - one should have nXm %cb otherwise one get a message that some box is still open.

1.) What about alignment - is there a way to have all the boxes the same size and right-alingned?

2.) Is there some way to have the property sheet the same width as the ClearWin window in the lower part?

   i=winio@('%2.2ob[no_border]&')
   i=winio@('Combo box %^`ls%cb&',  lb1,2,lb1_selects,cb_lb1)
   i=winio@('   Combo box %^`ls%cb&',lb2,3,lb2_selects,cb_lb2)
   i=winio@('Int 1 %rd%cb&',par%p1)
   i=winio@('   Int 2 %rd%cb&',par%p2)
1 Jan 2011 2:43 #7328

(yes, I didn't mention the need to close every box you open, since you were doing that anyway, border or no border)

Take out the surplus spaces in lines 3 and 5 for a start, justification is never going to work if it's fighting programmer-injected spaces. The table boxes auto-adjust to the size of the contents. This can be massaged to some extent with stuff like %nl within a box - and yes, controls like %cn and %rj work just as well within the context of a table box as within the context of a window. I don't know of an elegant way to manipulate the width of a property sheet (they also autosize to the contents) - but in a real app, I don't think you would design your main UI like your example anyway. Would you really want to devote 50% of the main window to 'Hello world'? 😉

1 Jan 2011 7:16 #7329

Hi sparge

Yes, you are correct: this might not be the optimal UI design. However, due to our internal develpment history we have a concept as shown below. We use Fortran only for numerical stuff. In many cases debugging is really frustrating since it requires file editing.

As mentioned in the ClearWin+ doccumentation: offers an easy-to-use interface to the Windows API. With the build-in ClearWin window in the UI example, all the screen output (DOS-box) will appear there. This means that one can (for the moment) keep the source files axactly the same for the actual application and for debugging.

Since all our applications follows this concept the basic idea with the UI example is to have a template which covers most of the functionality. Learning Clearwin+ one needs to starts somewhere 😉 The online documentation only provides bits and peaces.

[URL=http://img716.imageshack.us/i/guiflow.gif/]http://img716.imageshack.us/img716/4439/guiflow.gif[/URL]

Uploaded with [URL=http://imageshack.us]ImageShack.us[/URL]

1 Jan 2011 11:02 #7331

Quoted from jjgermis Learning Clearwin+ one needs to starts somewhere 😉 The online documentation only provides bits and peaces.

Dunno about that, I only ever used the .chm help file that comes with FTN95 (how come you don't have one?) and it is extremely comprehensive IMO. But not particularly helpful in learning ClearWin+ expertise, just like a dictionary isn't very helpful in learning to speak a language 😉 can't remember now how I got started, it was quite a few years ago. There was a lot less to learn at the time, that helped ...

2 Jan 2011 10:27 #7336

Hi sparge

I use the help (.chm) quite often - this is where I get my bits and pieces. However, in most cases I 'discover' something cool only by accdident. It is like watching a picture on a bit by bit manner rather than the complete picture. This automatically implies that the (ClearWin+) learning curve is much longer than Matlab for example.

However, even if the learning curve is longer I think that this is the right way to go 😄 At some stage it will pay off.

Coming back to my example: Since I cannot figure out how to set the property sheet to a fixed width is does not looks professional. Even if it works fine the looks still needs some attention.

2 Jan 2011 2:20 #7337

Hi jjgermis,

to set a property to a fixed width I'm using the following code:

  RC=WINIO@ ('%1tl&',12)      !Setting a tab position at the desired width
  RC=WINIO@ ('%ta ')            !Setting a blank at tab position
                                            !somewhere in the property sheet

Detlef Pannhorst

(by the way: I think we have met us in a training at QT software)

2 Jan 2011 3:18 #7338

Hi jjgermis, You are right about the need for a “look” for a program – users nowadays turn their noses up as DOS windows. In the late 1980s I wrote a Fortran program to plot (on a pen plotter) my students’ land surveys . They input their instrument readings and the program produced a map, point by point as they entered the data. It took a day’s worth of boring work away from them. Five or 6 years ago students got very critical of the appearance of the program – it had worked for 15 years without modification – and finally I persuaded myself to do it in Windows with Clearwin+. Now they are all happy. They put in all their readings, see the map on-screen, and then print it now on a big inkjet printer.

Just having a windows “look” isn’t always enough – your program also needs a windows “feel”. This means (in my view) having menus and toolbars. All of the Clearwin+ stuff can take up a lot of space. One of my hints is to remember that you can carry on creating your window with WINIO@ calls in a whole bunch of subroutines. Hence, you can make your program routine look something like this:

CALL INITIAL_SPLASH_SCREEN
CALL CAPTIONS_MAIN_WINDOW
CALL SYTLES_MAIN_WINDOW
CALL MENUS_MAIN_WINDOW
CALL TOOLBAR_MAIN_WINDOW
CALL CONTENTS_MAIN_WINDOW

etc. If you want users with a range of monitor resolutions to get a good experience, it is worth looking at the monitor resolution and adjusting accordingly. For example, if a user is using a netbook with a low res screen, I simplify the toolbar AND reduce the font size. Since for consistency you need to do this font selection and sizing for EVERY window, you might as well have the WINIO@ calls in a routine that you can call every time. If it is a widescreen, then I put the toolbar down the side rather than across the top, and so on (Clearwin+ isn’t good at repositionable toolbars).

Another hint is that if you need to do a lot of %cb commands, you can put them in a loop:

DO J=1,6*4
I=WINIO@(‘%cb&’)
END DO

(I wrote it as 6*4 to remind me 6 columns, 4 rows)

My third hint is to use

1 24 default.manifest

in your RESOURCES as this makes the windows much more modern looking.

Fourth hint: Always make one of the buttons the default.

Fifth hint: to make that top half of the window the same width as the bottom half, put something else in it. You can of course pad it out with space characters, and put something almost invisible like a full stop (very invisible if you make it the right font colour!). You can work out how many characters you need if you use an onscreen grid (%gd). I also use a screen ruler called “Ruler by George!” - which you can download as shareware - to measure pixels on the screen. Better than padding is to include a graphic. Again, once you know how many pixels you have to fill it gets easier. Then, you create a graphics area of the right size with %gr and fill it with a picture using the IMPORT_IMAGE@ function. If you run out of ideas, this can be a company logo, or a logo for the program. Alternatively, it can be something to do with the way your program works. It can even be updated in a callback. Or you can draw something.

Sixth hint: There are absolute and relative positioning (%ap and %rp) formats, and one to affect vertical positioning (%dy). As well as padding with spaces, you can use %ta.

Seventh hint: Have you considered putting the results in a fourth tabbed sheet titled “Results”?

I did once write a lot of these things down in a simple guide but never finished it. If you can bear to see lots of examples in Fortran-77 style, and are prepared to accept the unfinished state of the document, then send me a PM with a valid e mail address and I’ll e mail it.

Eddie

2 Jan 2011 4:10 #7339

One final hint. %di gives you complete control of positioning based on a dialog resource but you will need access to a dialog resource editor such as Visual Studio.

3 Jan 2011 12:58 #7343

Thanks for the tipps! This is very useful and surely boost the confidence. And enough to keep me busy for while testing everthing.

Some last question on the software architecture: The basic software achitecture is shown as given below. As mentioned the basic idea is to keep the required changes to the original code as little as possible. The simplest way I can think of is to define a user type which collects the UI values. When a user starts the calculation the data can be checked (within the module callback) and afterwords calls the original program with the user defined type. Instead of a file read (parameters are passed via a file - as shown in previous entry) the input data is passed to the program via the user defined variable.

Extra property sheet with results: This is a valid option and was considered initially. However, a user finds some system operating point on a sort of trail-and-error basis. This would mean that one needs to switch between the property sheets each time. To avoid this the results is shown in the lower part!

PS: Detlef, yes we have met at QT software!

[URL=http://img266.imageshack.us/i/architecture.gif/]http://img266.imageshack.us/img266/5033/architecture.gif[/URL]

Uploaded with [URL=http://imageshack.us]ImageShack.us[/URL]

3 Jan 2011 9:00 #7349

Hi Eddie!

Your documentation on ClearWin+ (even if it's incomplete) is excellent 😄 It contains very good tips and especially an experienced program style. This is exactly what I was looking for.

The tutorial explains a few stuff that I was wondering how it should be done (I already spent hours of testing and could not figure it out). Well done.

Jacques

4 Jan 2011 11:03 #7359

The example program has an exit function as given below (see definition in the comment part). The user can exit as follows: 1.) first option - exit with save; 2.) second option - exit without save and 3.) cancel, i.e. continue to work.

Qustion: When I press No e.g. then the function should Exit. However, it jumps into the function again which means the user has to press No twice. Is this correct or I am missing something?

C$$$$$$       IA=WINIO@('%mn[File[~Open...,~Close,~Save,~Save As...,|,Exit]]&',
C$$$$$$      &          MY,File_Open_FN,
C$$$$$$      &          MY,File_Close_FN,
C$$$$$$      &          MY,File_Save_FN,
C$$$$$$      &          MY,File_SaveAs_FN,
C$$$$$$      &          File_Exit_FN)

      INTEGER*4 FUNCTION File_Exit_FN()
C     --------------------------------
      EXTERNAL File_SaveAs_FN
      INCLUDE <WINDOWS.INS>
      IA=WINIO@('%ca[Save before Exit?]&')
      IA=WINIO@('%ww[topmost,no_sysmenu]&')
      IA=WINIO@('%cn%si?&')
      IA=WINIO@('%nl%bg[btnface]&')
      IA=WINIO@('%nl%cnSave your work before exit?&')
      IA=WINIO@('%2nl&')
      IA=WINIO@('%cn%^bt[Yes] %^`bt[No] %bt[Cancel]',
     &        File_SaveAs_FN,
     &        'EXIT')

      IF (IA .EQ. 3) THEN
C     User pressed cancel
        File_Exit_FN = 0
      ELSE
        File_Exit_FN = 0
      ENDIF
      
      RETURN
      END 
6 Jan 2011 11:19 #7382

The code below is used to initially display a bitmap e.g. a logo. Understanding callbacks is fine. However, the way ClearWin works with handles is not clear - at the moment this seems to be a black box 😦

The example generates two windows. My questions: 1.) how can I assign or find the handle of a window? 2.) what is the meaning of OPTIONS(INTL)? 3.) the call to sleep does not seem to have any effect.

Working through the ClearWin+ Help helps a lot. However, what I cannot figure out is the link between the provided examples or rather how to effectively combine the examples.

      OPTIONS(INTL)
      WINAPP
      PROGRAM Program_Main

      IMPLICIT DOUBLE PRECISION (A-H, O-Z)
      INCLUDE 'INDEX.INS'
      INCLUDE <WINDOWS.INS>
      SAVE

      K=1
      CALL INITIAL_SPLASH
      CALL SLEEP@(40.0D0)
      K=2
      CALL INITIAL_SPLASH
      END

      SUBROUTINE INITIAL_SPLASH
      IMPLICIT DOUBLE PRECISION (A-H, O-Z)
      INCLUDE 'INDEX.INS'
      INCLUDE <WINDOWS.INS>
      IB=WINIO@('%ww[no_border,'    //
     &              'no_caption,'   //
     &              'no_maxminbox,' //
     &              'topmost,'      //
     &              'toolwindow,'   //
     &              'no_frame]&')
      IF (K==2) THEN
        IB=WINIO@('%^bm[SPLASHBMP_SMALL]&','EXIT')
      ELSE
        IB=WINIO@('%^bm[SPLASHBMP_BIG]&',  'EXIT')
      ENDIF
      IB=WINIO@('%dl&',2.0D0,'EXIT')
      IB=WINIO@('%lw',icrtl)
      RETURN
      END

      RESOURCES
      SPLASHBMP_BIG BITMAP Program_Big_Flash.bmp
      SPLASHBMP_SMALL BITMAP Program_Small_Flash.bmp
      MINIMISED_ICON ICON Minim_icon.ico
6 Jan 2011 11:47 #7385

I can't answer all your questions:

  1. I get confused also, sometimes you you supply or receive a handle. an example that might help is: SUBROUTINE GET_WINDOW_LOCATION@( HANDLE, X, Y, WIDTH, HEIGHT) INTEGER HANDLE, X, Y, WIDTH, HEIGHT

Description HANDLE is a window handle obtained, for example, by using %hw or %lc. Other arguments are returned with the pixel coordinates and dimensions of the window.

  1. See The OPTIONS directive, as it is a way of specifying /INTL, which is the default anyway.

  2. sleep@ expects a single precision real call sleep (40.0)

John

6 Jan 2011 12:14 #7386

Hi John,

thanks. With the sleep I tried 40 and 40.0D0 (not 40.0) - typical Murphy.

I tried the GET_WINDOW_LOCATION@: for the code below there will be 2 windows at the same time, i.e. two handles should be available. However, the subroutine (as given in the example) returns the following: 0 12558 4 -12491 56884468 0 12558 4 -12491 12554

Since the two windows are active at the same time one would expect different values for HNDL1 and HNDL2.

PS: Since I have Matlab as a reference (handle is automatically returned) it might be that I have the wrong concept (or expectation) from ClearWin+

      K=1
      CALL INITIAL_SPLASH
      CALL GET_WINDOW_LOCATION@( HNDL1, X, Y, WIDTH, HEIGHT)
      write(*,*) HNDL1, X, Y, WIDTH,HEIGHT
      K=2
      CALL INITIAL_SPLASH
      CALL GET_WINDOW_LOCATION@( HNDL2, X, Y, WIDTH, HEIGHT)
      write(*,*) HNDL2, X, Y, WIDTH,HEIGHT
6 Jan 2011 2:49 #7393

OPTIONS (INTL) is a way of making sure that all integers are INTEGER4 or 'Long Integers'. When Fortran was invented (I was at school then), it only had implicit typing. Explicit typing was introduced later. Modern computing philosophy is to explicitly type everything. If you use implicit typing, then the OPTIONS command gives you automatically everything as 'Long Integers' – hence INTL. Short integers are INTEGER2. Even if you prefer to explicitly type everything, OPTIONS (INTL) means that just INTEGER will do, and you don't need INTEGER*4 or INTEGER (KIND=2?). When Fortran was invented, INTEGER and REAL variables had to be the same length too ....

Many Windows programs display a splash screen on entry. Microsoft Office programs do, so do programs I use a lot in the CorelDRAW graphics suite. Some smaller applications in Windows (e.g. Notepad, Paint) load so quickly that they don't need to inform the user that they are actually loading. It's the ones that load slowly that do. The little routine you used will display a splash screen. Just imagine the difference between a netbook which may have 800x600 pixels and a dual-monitor setup where each monitor may be 2560x1920. (Ignore what FTN95.CHM says about the maximum size being 1000x1000 by the way!). I have found by trial and error that the optimum time for the splash to stay onscreen is 2 seconds. If the main window takes longer to load (and it takes longer if you use %ib toolbar buttons than %tb), then the splash needs to stay up longer, and maybe it needs to do something. Why two invocations give you the same handle is a mystery - Clearwin is full of them. Only Paul knows the answer!

If you exit windows with the standard callback 'EXIT', you get 'instant death'. This may be OK for something you are testing, but if you have a real user, they will get pretty upset by this if they lose a lot of work. FTN95 has another standard callback called 'CONFIRM_EXIT'. It is a bit better than 'EXIT', because at least it asks the user to say whether they really wanted to exit or not. However, if they say 'No', then what? They just get taken back to where they were working – without any reminder to save before they exit should they try again.

The standard windows way is not to ask 'Are you sure that you want to exit (Y/N)?' but to say 'Would you like to save your files before you exit (Y/N)?'. There's a subtle difference here. In the first method the user might say 'Yes, I do want to exit'. That is not the same as 'Yes, I do want to exit, and I want my work thrown away if I forgot to save it first'. Hence, you can't use a standard callback in code that you want people experienced in the normal way that windows works – because sooner or later, they will be irritated by the difference.

You have to handle exits gracefully. That means putting a callback on the File|Exit menu to handle the case that a user didn't save before they exit. In the longer term, you also need to handle the case that Windows shuts down and the program is forced to close. You also need to handle the case that the user shuts down the program by using the close box at top right of the caption bar. Now here's the difficulty. If your callback function says 'Do you want to save your file first (Yes/No/Cancel)?' what do you do in response to the options – and also what do you do if the user clicks the close box on the pop-up window?

For Yes, you go into the file save routine. But at any time during this, the user can decide not to save. Moreover, in a modern networked system, the user may ask to save in a forbidden location. If the save does not happen, what then? For No, you can just exit. The user has already indicated that they intend to exit, and this confirms that they want to exit. That had just better not be the default! For Cancel, you now have to decide what to do. This also applies to the close box option. Study a few working Windows programs, and you will see that it is NOT the same as 'No, don't save, and just exit', and it isn't the same as 'Yes, save the file and then exit', what it is - is more like 'I can't make up my mind, don't do anything while I decide'.

All of this requires you to write your own callback to handle the sequence. The logical (?) place to keep the callback function is in response to a 'close control' (%cc) and also 'exit windows' (%ew). If the same callback function is used for File|Exit, then you get it called twice. I have got over this problem in code for others to use by keeping an integer 'flag' (mine is called Inhibit_Exit, which conveniently starts with i, kept in a COMMON block mentioned in the PROGRAM routine) to count the passes through the callback.

I modified your listed code, and yes, it appears that the two invocations of the splash screen use the same handle. Some time ago, I posted a discussion on the forum 'when is a handle not a handle?' but can't find it now. If I remember, there are Windows handles, and there are Clearwin handles, and some you give, and some you receive. Normally a 'toolwindow' that is only displayed for 2 seconds isn't something you need to get hold of by its handle!

Eddie

6 Jan 2011 2:56 #7394

OPTIONS(INTL) has been the default for a long time, probably since the full 32bit version of FTN77 (i.e. the one without DBOS) and certainly for all of FTN95.

If you want to revert back to 16 bit integers you can use OPTIONS(INTS) but this is not recommended.

6 Jan 2011 7:10 #7398

Thanks for the replies. I am making good progress 😃

I would like to make even more progress, however, the number of (complete windows) examples in ClearWin+ are limited. In the FTN95 Help there is examples like the factoriser - no question this is a good startting point. Where can I find more ClearWin+ examples?

When it comes to stuff like: 1.) getting the window handle; 2.) exit properly; 3.) saving files; 4.) resizing a window; 5.) etc. things get tricky. Is it possible that Silverfrost can provide a more detailed example showing a typical windows application? This would be great!

Please login to reply.