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 

Call a subroutine when Edit Box (%eb) loses focus?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Sat Aug 02, 2008 5:42 am    Post subject: Call a subroutine when Edit Box (%eb) loses focus? Reply with quote

I've got an edit box set up with a string CSTRNG2 displayed in it. The user can edit the string as usual within an edit box. I'd like the system to call an extra function when the window with the edit box, loses focus (I have three windows actually, the edit box is only one of the, if the user clicks in another window I'd like that extra function to be called). The extra function will do some brief calculations and then the program can go back to what it was doing.

The Help files describe the %eb and mention callback functions. But I'm not sure how to implement a callback that happens when the window loses focus. (Or is a "callback" something different from what I'm asking here?) I have a hunch it has something to do with using the caret (^) as a modifier, something like i=winio@('%^80.20eb',CSTRNG2,4096) but I can't figure out how to use it, if that's the right thing to use at all.

Can anybody give me a hint?

Sorry for the silly beginner question, but I just can't figure this one out from the Help files.
Back to top
View user's profile Send private message
LitusSaxonicum



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

PostPosted: Sat Aug 02, 2008 3:38 pm    Post subject: Reply with quote

What about:

Code:
      i=winio@('%^80.20eb[hook_focus]',CSTRNG2,4096,KALLBACK)


where KALLBACK is the INTEGER FUNCTION that services the callback. Note that the callback function is called when the EB gains the focus initially, so you will need to keep track of whether you have gained or lost focus. Here is my little test program:

Code:
      WINAPP 
      PROGRAM TEST
      CHARACTER*4096 CSTRNG2
      EXTERNAL KALLBACK, KALLBACK0
      COMMON/Counter/KOUNT
      INCLUDE <WINDOWS.INS>
      CSTRNG2 = 'Cockney language'
      KOUNT=0
      I=WINIO@('%ca[Test]%ww%mn[Blimey]&', KALLBACK0)
      i=winio@('%^80.20eb[hook_focus]&',CSTRNG2,4096,KALLBACK)
      I=WINIO@('%ff%nl%cn%6bt[Quit]')
      END
      INTEGER FUNCTION KALLBACK0()
      Write(*,*) 'Cor Blimey!'
      KALLBACK0=1
      END
      INTEGER FUNCTION KALLBACK()
      COMMON/Counter/KOUNT
      KOUNT=KOUNT+1
      Write(*,*) 'Strewth!', KOUNT
      KALLBACK=1
      END


KALLBACK needs to be declared EXTERNAL in the calling program.

Questions for you: Is an %eb what you really want? Don't you need scrollbars?

Here's a Mark 2:

Code:
      WINAPP 
      PROGRAM TEST
      CHARACTER*4096 CSTRNG2
      EXTERNAL KALLBACK, KALLBACK0
      COMMON/Counter/KOUNT
      COMMON/Text/ CSTRNG2
      INCLUDE <WINDOWS.INS>
      CSTRNG2 = 'Cockney language'
      KOUNT=0
      I=WINIO@('%ca[Test]%ww%mn[Blimey]&', KALLBACK0)
      i=winio@('%^80.20eb[hook_focus,hscrollbar]&',
     & CSTRNG2,4096,KALLBACK)
      I=WINIO@('%ff%nl%cn%6bt[Quit]')
      END
      INTEGER FUNCTION KALLBACK0()
      CHARACTER*4096 CSTRNG2
      COMMON/Text/ CSTRNG2
      INCLUDE <WINDOWS.INS>
      CSTRNG2=CSTRNG2(1:LEN_TRIM(CSTRNG2))//' Cor Blimey! '
      CALL WINDOW_UPDATE@(CSTRNG2)
      KALLBACK0=1
      END
      INTEGER FUNCTION KALLBACK()
      CHARACTER*4096 CSTRNG2
      CHARACTER*20 TEXT1
      COMMON/Text/ CSTRNG2
      COMMON/Counter/KOUNT
      INCLUDE <WINDOWS.INS>
      KOUNT=KOUNT+1
      Write(TEXT1,'(A,I5,3X)') ' Strewth!', KOUNT
      CSTRNG2=CSTRNG2(1:LEN_TRIM(CSTRNG2))//TEXT1
      CALL WINDOW_UPDATE@(CSTRNG2)
      KALLBACK=1
      END


It looks to me as though you need to insert your own <newline> characters into CSTRNG2.

It also looks to me as through the [hook_focus] calls the callback 3 times when the %eb and its enclosing window are initially set up.

Eddie
Back to top
View user's profile Send private message
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Sat Aug 09, 2008 10:18 pm    Post subject: Reply with quote

This has helped a lot, Eddie, thank you!

One difference possibly between my program and yours, is that when I call my KALLBACK function, I want to hand it a variable. Specifically, I want to hand it a string that has previously been defined with the statement:

CHARACTER*32000 CHMEM

The string CHMEM is a collection of text, actually English sentences, separated by CR/LF codes and terminated with a CHAR(0). The CHAR(0) usually occurs a few thousand characters after the beginning of the string.

I actually couldn't get the callback from the %eb statement to work, probably did something else wrong. So I chickened out for now, and backed off. Now the winio@ statement that sets up the edit box %eb, does not have a callback function. Instead, I put a new button just below the edit box labelled Save Changes. That button has a callback function. And lo and behold, I am having just as much trouble with that.

At first I set up the callback function with no argument, as follows:

i=winio@('%^10bt[&Save Changes]&',sav_chg0)

Obviously, sav_chg0 is the callback function, which I want to get called every time that button is clicked. sav_chg0 is declared as EXTERNAL earlier in the program, and near the end, it is defined as:

INTEGER FUNCTION sav_chg0()

It takes no arguments, obviously. For now, it is a dummy function with just a few lines. It prints the words "Function sav_chg0 called.", assigns a value of 1 to sav_chg0, returns and ends.

This works! When I compile/run the program and click the button, a generic window appears with that text in it. That is what I wanted from this dummy program.

The trouble started when I tried to make the fuction sav_chg0 take an argument. The argument is the CHMEM string I described above.

I changed the button statement to:

i=winio@('%^10bt[&Save Changes]&',sav_chg0(CHMEM))

and changed the definition statement to:

INTEGER FUNCTION sav_chg0(CSTRG55)

Later in the function definition is the statement:

CHARACTER*(*) CSTRG55

...where I want CSTRG55 to assume the length of the CHMEM string, which is 32000.

Those two statements are the only ones I changed. Now when I try to compile it, I get a compile-time error saying:

F:\Micros\Old\Test6809\SIM09Wae.FOR(528) : error 140 - WINIO@ cannot process REAL(KIND=1) arguments, only CHARACTER, INTEGER(3) or REAL(2)

The (528) is the line number of the button statement (listed here above), that I just changed by inserting the argument (CHMEM) to the callback function sav_chg0.

Earlier when I did not have this argument in the callback function, the program compiled and ran without error. Now, with that change and no other, I get this compile-time error. The callback function is still declared as an EXTERNAL earlier in the main program (as it was before), and is still defined as an INTEGER FUNCTION near the bottom of the file (as it was before). Even the newly-added argument (CHMEM in the calling button-statement and CSTRG55 in the function definition) is properly (I think) defined as a CHARACTER variable, as I described above.

I don't understand why the compiler is complaining about a REAL(KIND=1) argument. There isn't one!

I'm probably missing something that's well known to experienced people on this compiler - another newbie mistake. Can you help me out here?
Back to top
View user's profile Send private message
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Sat Aug 09, 2008 11:49 pm    Post subject: Reply with quote

Well, after writing the above, I tried the obvious thing, and changed all occurances of sav_chg0 to isav_chg0. Now the compile-time error is gone. It compiles and begins running, putting up the first window I designed (the edit-box window should be the second window to come up).

But now it produces a run-time error. After putting up the first window (which comes up perfectly without error, as it has for many weeks), it apparently starts executing the code to put up the second window, which is the edit-box window in question. It then puts up a generic window and prints "Function isav_chg0 has been called", which is the simple trace statement I put in the mostly-dummy callback function. So apparently the callback function is being called (this itself is odd, I haven't seen or clicked the new "Save Changes" button yet). Then it crashes and produces a Run-Time Error saying "Argument no 2 of winio(continuation 7) should be a call-back function". It provides a line number which is the button statement above - the statement where I just changed sav_chg0(CHMEM) to isav_chg0(CHMEM).

That button statement is, in full:

i=winio@('%^10bt[&Save Changes]&',isav_chg0(CHMEM))

The first argument of this winio statement is the '%^10bt[&Save Changes]&' ...is it not? And the second argument is isav_chg0(CHMEM) ...correct?

So, the second argument IS a callback function! I don't see how to make it any clearer or more "correct". Unless, of course, callback functions simply aren't allowed to have arguments.

To reiterate, I had this code working perfectly - compiling and running without error, and producing exactly the results I intended. That was when the callback function had no argument. But when I put an argument into the callback function, I started getting various errors that didn't make a lot of sense to me... and still don't. I'm 90% sure that putting the argument into the callback function, is the source, and possibly the cause, of the problem.

Am I anywhere close?
Back to top
View user's profile Send private message
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Sun Aug 10, 2008 12:15 am    Post subject: Reply with quote

P.P.S. I thought of putting the variable I wanted to pass (the string CHMEM) into a COMMON block and passing it that way, instead of in the callback function header. But that might not work because I eventually want the program to put up more than one of these edit boxes at a time, to have multiple displays, and each edit box would have a different string.

Then thought of assigning the current CHMEM string into a temporary variable called CTEMPBUF which is a CHARACTER*32000 like CHMEM, and putting CTEMPBUF into a COMMON block to pass it. But that might not work either. The edit box might change the contents of CHMEM, and then the Save Changes button get pressed, and I wouldn't have a chance to assign the changed CHMEM into CTEMPBUF before the button is clicked. So the callback function isav_chg0 would get called, and it would find an old version of CTEMPBUF in the COMMON block, that has not been updated with the latest changes to CHMEM.

(sigh)

It would be really nice if I could simply pass CHMEM in the header of the callback function isav_chg0 when the Save Changes button is clicked. But this system seems bound and determined not to let me do that... unless I find the right command or format or whatever, that it wants.
Back to top
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Sun Aug 10, 2008 9:44 am    Post subject: Reply with quote

Hi,

Try letting the program allocate the buffer itself, here is aprogram to open two files test1.txt & test2.txt, which you should create first. It can be extended to 100 files and allows the focused %eb to be printed.

I hope it helps.

Ian

Code:

      winapp
      program editbox
      INCLUDE <WINDOWS.INS>
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      integer*4 iedit1,iedit2,i,iclose_cb
      external  iedit1,iedit2,iclose_cb
      current_eb=1
      display_file_name(1) = 'test1.txt'
      display_file_name(2) = 'test2.txt'
      i=winio@('%ca[EB test]&')
      i=winio@('%bg[btnface]&')
      i=winio@('%mn[File[Edit1,Edit2,Exit]]&',
     &         iedit1,iedit2,
     &         'EXIT')
      i=winio@('%cc',iclose_cb)
      end
      integer*4 function iclose_cb()
      INCLUDE <WINDOWS.INS>
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
!kill remaining windows
      iclose_cb = 0
      do i=1,100
        window_state(i) = 0
        call window_update@(window_state(i))
      enddo
      end
      integer*4 function iedit1()
      INCLUDE <WINDOWS.INS>
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      current_eb = 1
      call display_data
      iedit1 = 1
      end
      integer*4 function iedit2()
      INCLUDE <WINDOWS.INS>
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      current_eb = 2
      call display_data
      iedit2 = 1
      end
      subroutine display_data
      INCLUDE <WINDOWS.INS>
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      integer*4 review
c kill an existing %EB window if any
      window_state(current_eb) = 0
      call window_update@(window_state(current_eb))
c now open the selected file
      itest = review()
      end

continued in next post...
Back to top
View user's profile Send private message Send e-mail
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Sun Aug 10, 2008 9:45 am    Post subject: Reply with quote

Code:

      integer*4 function review()
      INCLUDE <WINDOWS.INS>
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      integer*4 iprintout, ihook_focus
      external iprintout, ihook_focus
      call set_clearwin_string@('printer_document','My List file')
      I=WINIO@('%ca[ EB file viewer]&')
      I=WINIO@('%mn[E&xit,&Print]%es%sc&',
     &           'EXIT',
     &           iprintout,
     &           'edit_file',display_file_name(current_eb))
      I=WINIO@('%ww[no_border]%pv%fn[Courier New]'//
     &  '%ts%126.30^eb[vscrollbar,hscrollbar,read_only,hook_focus]&'
     &  ,0.9d0,'*',0,ihook_focus)
      i=winio@('%lw&',window_state(current_eb))
      i=winio@('%hw',window_ids(current_eb))
      review = 1
      END
      integer*4 function ihook_focus()
      include <windows.ins>
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      ihook_focus = 2
!      print *,'GAINING_FOCUS',clearwin_info@('GAINING_FOCUS')
      if(clearwin_info@('GAINING_FOCUS') .eq. 1)then
!        print *,'ACTIVE_EDIT_BOX',clearwin_info@('ACTIVE_EDIT_BOX')
!        print *,'CALL_BACK_WINDOW',clearwin_info@('CALL_BACK_WINDOW')
!        print *,'FOCUS_WINDOW',clearwin_info@('FOCUS_WINDOW')
        do i=1,2
          if(window_state(i) .eq. -1)then
            if(window_ids(i) .eq.
     &         clearwin_info@('CALL_BACK_WINDOW'))then
              current_eb = i
              exit
            endif
          endif
        enddo
       
      endif 



      end
      integer*4 function iprintout()
      include <windows.ins>
      real*8 scale
      character*155 lineout
      character*256 display_file_name
      common/display_file/display_file_name(100)
      integer*4 current_eb,eb_data,window_ids,window_state
      common/edit_box_data/current_eb,eb_data(24,100),
     &                     window_ids(100),window_state(100)
      lineout =  ' '
      ipage_count = 1
      ihandl = 2
      iblack = rgb@(0,0,0)
      call printer_dialog_options@(1,0,1,0,0,0,0,1,0)
      itest = open_printer@(ihandl)
      if(itest .ne. 0)then
        ipage_range = clearwin_info@("printer_pagenumbers")
        if(ipage_range .eq. 1)then
          istart_page = clearwin_info@("printer_first_page")
          ilast_page  = max(istart_page,
     &                      clearwin_info@("printer_last_page"))
        else
          istart_page = 1
          ilast_page  = 32768
        endif
        call set_text_offset(0,0)
        icurrent_page = 1
        ipage_count = 0
        if(istart_page .eq. 1)ipage_count = 1
        open(unit=27,file=display_file_name(current_eb),
     &       status='readonly')
        call GET_GRAPHICAL_RESOLUTION@( ixxx, iyyy )
        ihsize = ixxx
        ivsize = iyyy
c
c set pixel paper size
        call set_paper_size(ixxx,iyyy)


continued in next post...
Back to top
View user's profile Send private message Send e-mail
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Sun Aug 10, 2008 9:46 am    Post subject: Reply with quote

Code:

c
c get the text size for the main body of the text
        nrow = 1
        if(ixxx .gt. iyyy)then
c
c landscape
          ncol = 155
        else
c
c portrait
          ncol = 140
        endif
        call get_text_scale(ncol,nrow,scale)
c
c set punching margin in pixels
        if(ixxx .gt. iyyy)then
c
c landscape
          ihoff = ixxx/297.0*6.0
          ivoff = int(ivsize*20.0/200.0)
        else
c
c portrait
          ihoff = int(ihsize*20.0/200.0)
          ivoff = ivsize/297.0*10.0
        endif
        call set_text_offset(ihoff,ivoff)
        irow = 1
c
c get the last text start position to set new offset for bulk of text
        call scale_font@(scale)
        call rotate_font@( 0d0 )
        do
          read(27,1000,end=9999)lineout
 1000     format(a)
! detect form feed character
          if(lineout(1:1) .eq. char(12))then
            icurrent_page = icurrent_page+1
            if(icurrent_page .ge. istart_page .and.
     &         icurrent_page .le. ilast_page)then
              if(ipage_count .gt. 0)then
                call new_page@
                call set_text_offset(ihoff,ivoff)
                lineout(1:1) = ' '
                irow = 1
              endif
              ipage_count = ipage_count + 1
            endif
          endif
          if(icurrent_page .ge. istart_page .and.
     &       icurrent_page .le. ilast_page)then
            call DRAW_TEXT_CHAR(lineout,0,irow,scale,iblack)
            irow = irow + 1
          endif
        enddo
 9999   continue
        itest = close_printer@(ihandl)
        close(unit=27)
      endif
      iprintout = 2
      end

      subroutine set_text_offset(ixoff,iyoff)
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      ixpoff = ixoff
      iypoff = iyoff
      end

      subroutine set_paper_size(ixxx,iyyy)
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      ixmax = ixxx
      iymax = iyyy
      ixlast = 0
      iylast = 0
      end

      subroutine get_text_scale(ncol,nrow,scale)
      real*8 scale, scale1, scale2
c
c determines the scale factor for text to fit the printer
c base on a default 8x14 font
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      scale1 = float(ixmax-ixpoff)/8.0/float(ncol)
      scale2 = float(iymax-iypoff)/14.0/float(nrow)
      scale  = min(scale1,scale2)
      end

      subroutine DRAW_TEXT_CHAR(text,ix,iy,scale,icol)
      include <windows.ins>
!ix & iy are column and row number
      real*8 scale
      character*(*) text
      common/printer_text_offset/ixpoff,iypoff,ixmax,iymax,ixlast,iylast
      iy2 = iy*14*scale+iypoff
      ilen = max(1,leng(text))
      do i=1,ilen
        ix2 = (ix+i-1)*7*scale+ixpoff
        call DRAW_characters@(text(i:i),ix2,iy2,icol)
      enddo
      ixlast = ix2
      iylast = iy2
      end

Finished
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



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

PostPosted: Sun Aug 10, 2008 10:33 am    Post subject: Reply with quote

First of all, apologies for not seeing your 6th July posting.

Ian has given a thorough solution to some of the problem. However, there's something fundamental at issue here, and that is the nature of a callback function.

When I started programming fortran, functions had strict rules. A function returned a single value (like sin, cos etc) and could/should not do i/o. Then I got introduced to functions that returned an error code, but otherwise did things that subroutines did. I have to say that I don't much like this form. A callback function is a more extreme version of this, in that it has no parameters either.

If you want to pass a parameter to a callback function, you have to do it through COMMON (in pre-fortran-90 style) or through the use of MODULES and/or USES to make the variable have a scope that encompasses the calling routine as well as the callback function. As far as I can tell, callback functions only need to be declared EXTERNAL, they do not need to be explicitly or implicitly given type integer in the calling program (although they need to be declared as INTEGER FUNCTION.

As I'm comparatively old, and fixed in my ways, and dislike new-fangled innovations, I've gone for lots of named COMMON blocks.

As far as saying "I might have a number of 32k byte blocks of text" is concerned, then don't forget that a gigabyte of RAM can hold 32,000 of them, and there must be a realistic limit to how many you want to open at the same time, say 10 - and this is a drop in the ocean of memory of a modern PC - so just go ahead and declare lots of them to start with. It may not be such a big ocean if you are doing some forms of numerical analysis, and in this case, you have to consider ALLOCATE and DEALLOCATE to create the array and release the memory respectively.

It's a far cry from the 16k I started out with, although to be fair they were words, not bytes, but it still wasn't very much.

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



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Sun Aug 10, 2008 1:35 pm    Post subject: Reply with quote

Eddie,

I used the '*' buffer definition, because it seemed that the "Save changes" function described in Little-Acorn's post could easily be achieved by the standard callback "EDIT_FILE_SAVE", although I didn't put that bit in.

Of course if the data is to be held internally within the program, then, a couple of changes can be made (which I haven't tried but are probably something like):

place this in main program & "review" function and wherever the data is to be used
character*32000 CHMEM
common/working_text/CHMEM(100)



initialisation in main program
chmem = char(0)

in "review"change the %eb to

I=WINIO@('%ww[no_border]%pv%fn[Courier New]'//
& '%ts%126.30^eb[vscrollbar,hscrollbar,hook_focus]&'
& ,0.9d0,CHMEM(current_eb),32000,ihook_focus)


This does not address the printing function which was for demo only, reading the file data would require to be replaced by something that handled the CRLF returned from the %eb, or simply save the character data to a temporary file and read that as normal.

Ian
Back to top
View user's profile Send private message Send e-mail
LitusSaxonicum



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

PostPosted: Sun Aug 10, 2008 5:31 pm    Post subject: Reply with quote

And the simplest way to get an editor to appear:

Code:
       INTEGER FUNCTION Launch1_FN()
C      -------------------------------
C
C      Launch Notepad as file editor
C
C      -----------------------------------------------------------------
       INTEGER START_PPROCESS@
       IA = START_PPROCESS@('Notepad.EXE',' ')
       Launch1_FN = 1
       END


(the second set of ' ' can contain a file name).
Eddie
Back to top
View user's profile Send private message
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Mon Aug 11, 2008 1:26 am    Post subject: Reply with quote

Eddie, no problem at all, you and the others are giving me tremendous amounts of help here.

I guess the text I put on that new button is a little misleading, "Save Changes". Such a thing usually means to save whatever changes one made in the text in the window, to a file. But in my application that's not what it does: It saves the changes made in the text window, to an array of integers.

Eventually, I hope to get rid of the "Save Changes" button, and have the text saved to the integer array automatically when the window loses focus.

An explanation for such a bizarre act is in order here.

Twenty-five years ago when FORTRAN was king, I wrote a series of microprocessor assemblers and simulators. "Windows" meant flat glass, C was a letter in the alphabet, and FORTRAN didn't have string variables. In fact, the FORTRAN-66 compilers I was used to, were the most common ones around, and they didn't have the CHARACTER data type at all. If you wanted to store characters, you had to read them into an integer (or real) variable or an array of such integers. Depending on how the compiler was set up, and what machine it was running on, an integer variable might hold four characters max, or might just hold two. And some got a little weird when signs were extended... whether you wanted the sign extended or not. The only universal way to store characters, was to store one character per integer variable. So a 120-character sentence, usually took an array like INTEGER MYSENT(120). And a simulated memory block that was, say, 8K long, got stored as INTEGER MYMEM(8192), even though each entry was only eight bits wide.

So all the characters in my old programs are stored that way. Same deal for bytes in memory: An 8K "memory" is an array like INTEGER MYMEM(8192). I know, there were more efficient ways to do it, but I was selling these programs as source code to people running everything from PDP-11s to IBM 360s to those newfangled VAXes. The only way I could be sure to please everybody, was to store one character (or byte) per integer location.

So that's how these programs are. And now I'm trying to adapt them to Windows for their controls, displays, file manipulations etc. Most of those functions are canned routines in Windows, thank goodness because that makes them far easier and they are still pretty versatile.

The bad news is, Windows (at least in Salford FTN95 with Clearwin) uses strings almost entirely for manipulating large amounts of text, and my programs nevah hoid of 'em.

So rather than totally rewriting my programs to take advantage of now-common string variables, I've left the cores of the programs as they were, and changed the I/Os and displays only. And written lotsa routines to convert from one to the other and back.

Long story short, one of my windows is a memory display, that shows the contents of segments of that MYMEM(8192) as hex addresses and hex bytes (and ASCII characters too, looks somewhat like an MS-DOS "Debug" display for you old-timers). But the memory is still an integer array. So when the user wants to open one of these windows, I wrote a program to convert the integer array values to strings of hex digits to display addresses and bytes, and then use an edit box to display them.

An example of Memory Display box contents:

4000 FF FF FF FF FF FF FF FF 34 35 48 65 6C 6C 6F 2C ........45Hello,
4010 20 77 6F 72 6C 64 21 20 32 2B 33 3D 35 FF FF FF world! 2+3=5...
4020 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
(etc.)

(The above looks better with a fixed-pitch font like COURIER NEW)

And when the user wants to change the contents of memory, he changes the contents of the edit box... but that's not the integer array, it's the string representation of it. (No, EQUIVALENCE statements won't work, take my word for it). He may think he's changing memory, but he's only changing the string in the edit box.

So I wrote another code segment that takes what's in the string of hex addresses and byt
Back to top
View user's profile Send private message
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Mon Aug 11, 2008 1:45 am    Post subject: Reply with quote

(continued)

So I wrote another code segment that takes what's in the string of hex addresses and bytes in the edit box, and converts the info back into integer values and put them back into the integer array as appropriate. It is this code I would like to execute when the edit box window loses focus. Presently, I am executing it when the user clicks the new Save Changes button.

So, that's the long, sordid story. I want the callback function of the Edit Box, to take the string in the box, and extract the addresses and hex byte values it shows, and plug the VALUES of the bytes back into the appropriate locations of the integer array MYMEM(8192).

The user will probably have more than one memory display window open: One to display a RAM at location $4000-$7FFF, another to display a ROM at $E000-$FFFF, and perhaps other windows for other memory blocks, etc. When he changes text in (say) the second of those Memory Display boxes, and vlcicks that box's "Save Changes" button, the callback function of the button will take the string from te FIRST box and translate it back to integers, placing it in memory; but won't take the changes the user made in the second box.

Passing the name of the string in the box being clicked, would help a lot. But it seems that's not possible.
Back to top
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Mon Aug 11, 2008 8:51 am    Post subject: Reply with quote

Hi,

Sounds a familiar problem changing from integer stored characters to character stored characters. The easiest way that I have found is to replace

integer string_array(32000)

with

character*1 string_array(32000)

Then all the array subscripts remain identical and the storage shrinks, but as you were only using one byte from a two or four byte integer anyway, it probably doesn't matter. By the way, I seem to think that a DEC10/DEC20 used a 36bit word and could store 5 seven bit characters, so work that one out!

Equivalence of the character*1 and character*32000 will now work if necessary, but you can probably still pass the character*1 array to %eb as long as you specify its size to be 32000. Use of equivalence will allow the following:
Code:

character*1 string_array(32000)
character*32000 new_string
equivalence (string_array, new_array)

new_array = ' '
!etc


Instead of :
Code:

character*1 string_array(32000)
do i=1,32000
  string_array(i) = ' '
enddo


Regards

Ian
Back to top
View user's profile Send private message Send e-mail
Little-Acorn



Joined: 06 Jul 2008
Posts: 111
Location: San Diego

PostPosted: Mon Aug 11, 2008 4:01 pm    Post subject: Reply with quote

Thanks, Ian, but it's not going to happen. "If it works, don't fix it." I've got enough on my plate without what could be an extensive rewrite of a core program that basically works well. A few entries in these various integer arrays, ARE treated as larger-than-eight-bits-each, so a lot of detective work and surgery would be needed.

Anybody know if a callback function can take an argument?

Eddie, you seemed to be saying that it couldn't. But the examples you gave of other functions (SIN, COS) *do* take an argument, and of course return a value. I guess I need final clarification before I give up and just update ALL strings in ALL Memory Display boxes when any one fof them loses focus.

If I put a callback function that takes an argument, into an %eb statement (or a button statement) where all other parameters, options etc. are correctly specified, am I going to get an error no matter what?
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 -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
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