  rem A program by Julian Moss -- 9th March 1999
  rem ----------------------------------------
  rem This demonstration application is share-ware.
  rem If you make improvements to it, that illustrate other
  rem useful techniques, please share them with others by
  rem helping us to publish updates for this program.
  rem 
  rem Feel free to use the upload area to publish useful tricks.
  rem You can also send your comments to support@sade.net.

  %%apptitle = Program by Julian Moss
  title %%apptitle
  rem parse command line
  repeat 
    if %1
      rem /W - wordwrap
      if @equal(%1,/w)
        %w = WRAP
      end 
      rem /P - print
      if @equal(%1,/p)
        %p = 1
        %r = 1
      end 
      rem /R - force read-only
      if @equal(%1,/r)
        %g = 1
      end 
      rem /T - tab setting
      if @equal(%1,/t)
        shift 
        %t = %1
      end 
      %e = @file(%1,FZ)
      if %E
        parse "%F;%Z",%E
      end 
    end 
    shift 
  until @null(%1)
  rem check file isn't too big for edit control
  if @greater(%Z,32000)
    if @ask(File %F is too large for Program.@cr()Would you like to use WordPad instead?)
      shell open,wordpad.exe,%F
    end 
    exit 
  end 
  option SCALE,96
  dialog CREATE,Untitled - %%apptitle,-1,0,360,420,RESIZ,SAVEPOS,CLASS TEditor
  dialog ADD,STYLE,FP,Courier New,8,,WHITE
  dialog ADD,MENU,&File,&New|Ctrl+N,&Open|Ctrl+O,&Save|Ctrl+S,Save &As,-,&Print|Ctrl+P,-,E&xit|Alt+X
  dialog ADD,MENU,&Edit,&Undo|Ctrl+Z,-,Cu&t|Ctrl+X,&Copy|Ctrl+C,&Paste|Ctrl+V,Select &All
  dialog ADD,MENU,&Search,&Find|Ctrl+F,Find &Next|F3
  dialog ADD,MENU,&Options,Set &Tab stops
  dialog ADD,MENU,&Help,&Help|F1,-,About Program
  dialog ADD,BITBTN,New,0,2,24,24,Program.dsr
  dialog ADD,BITBTN,Open,0,26,24,24,Program.dsr|247
  dialog ADD,BITBTN,Save,0,50,24,24,Program.dsr|494
  dialog ADD,BITBTN,Print,0,74,24,24,Program.dsr|741
  dialog ADD,GROUP,GROUP1,0,104,2,26
  dialog ADD,BITBTN,Cut,0,108,24,24,Program.dsr|988
  dialog ADD,BITBTN,Copy,0,132,24,24,Program.dsr|1235
  dialog ADD,BITBTN,Paste,0,156,24,24,Program.dsr|1482
  dialog ADD,BITBTN,Undo,0,180,24,24,Program.dsr|1729
  dialog ADD,GROUP,GROUP2,0,208,2,26
  dialog ADD,BITBTN,Find,0,212,24,24,Program.dsr|1976
  dialog ADD,GROUP,GROUP3,0,240,2,26
  dialog ADD,BITBTN,Help,0,244,24,24,Program.dsr|2223
  dialog ADD,EDIT,Editor,28,2,348,342,,MULTI,FP,SCROLL,TABS,%W
  dialog ADD,STATUS,status
  dialog ADD,TEXT,TEXT1,28,2,,,A,FP
  dialog SHOW
  rem determine character width using a TEXT element containing one character
  %%charwidth = @dlgpos(TEXT1,W)
  dialog REMOVE,TEXT1
  rem adjust editor height resize factor
  %%dh = @sum(30,@dlgpos(STATUS,H))
  rem get the id of the edit element so we can send it messages
  %z = @winexists(~editor)
  if %T
    gosub settabs
    %t =
  end 
:evloop
  dialog focus,Editor
  wait event,1
  %e = @event()
  goto %E
:RESIZE
  parse "%H;%W",@dlgpos(,HW)
  dialog SETPOS,Editor,28,1,@pred(%W),@diff(%H,%%dh)
  if @null(%A)
    rem %A is null the first time this event is processed
    rem which occurs when the window is first displayed.
    rem Use it to load and optionally print file named on
    rem command line.
    if %F
      %a = 1
      gosub loadfile
      if %P
        gosub printfile
        exit 
      end 
    else 
      %f = Untitled
    end 
  end 
  goto evloop
:TIMER
  rem get the row number
  %i = @sendmsg(%Z,$0BB,-1,0)
  %l = @sendmsg(%Z,$0C9,%I,0)
  rem get the character position within the line
  %c = @mod(@sendmsg(%Z,$0B0,0,0),65536)
  rem Note: %C does not take account of tab characters so we must
  rem use em_posfromchar to get position of caret within the window
  rem in pixels. To get the character position (column number) we then
  rem divide it by the character width.
  rem Because the text may be scrolled (affecting the position within
  rem the window) and because the position is given as a signed 16-bit
  rem value in the bottom half of a 32-bit value which VDS interprets
  rem as a signed integer, the calculation is actually quite complex...
  %o = @mod(@sendmsg(%Z,214,0,0),65536)
  if @greater(0,%O)
    %o = @sum(%O,65536)
  end 
  if @greater(%O,32768)
    %o = @diff(%O,65536)
  end 
  %c = @mod(@sendmsg(%Z,214,%C,0),65536)
  if @greater(0,%C)
    %c = @sum(%C,65536)
  end 
  if @greater(%C,32768)
    %c = @diff(%C,65536)
  end 
  %c = @div(@diff(%C,%O),%%charwidth)
  rem check if text has been modified
  if @zero(@sendmsg(%Z,$0B8,0,0))
    %m =
  else 
    %m = Modified
  end 
  rem update status line
  dialog set,status,Line: @succ(%L)  Col: @succ(%C)@tab()%M%R
  goto evloop
:NewMENU
:NewBUTTON
  if %M
    if @not(@ask(File has been modified. Discard changes?))
      goto evloop
    end 
  end 
  dialog clear,editor
  %f = Untitled
  %e = @sendmsg(%Z,$0B9,0,0)
  %e = @sendmsg(%Z,$0CF,0,0)
  dialog title,%F - %%apptitle
  goto evloop
:OpenMENU
:OpenBUTTON
  if %M
    if @not(@ask(File has been modified. Discard changes?))
      goto evloop
    end 
  end 
  %f = @filedlg()
  if %F
    gosub loadfile
  end 
  goto evloop
:SaveMENU
:SaveBUTTON
  if @equal(%F,Untitled)
    goto Save asMENU
  end 
  gosub savefile
  goto evloop
:Save asMENU
  %f = @filedlg(,,,SAVE)
  if @ok()
    gosub savefile
  end 
  goto evloop
:PrintMENU
:PrintBUTTON
  gosub printfile
  goto evloop
:ExitMENU
  goto close
  rem The following edit options use standard windows messages to
  rem do their stuff...
:CutMENU
:CutBUTTON
  %e = @sendmsg(%Z,$0300,0,0)
  goto evloop
:CopyMENU
:CopyBUTTON
  %e = @sendmsg(%Z,$0301,0,0)
  goto evloop
:PasteMENU
:PasteBUTTON
  %e = @sendmsg(%Z,$0302,0,0)
  goto evloop
:Select AllMENU
  dialog focus,Editor
  %e = @sendmsg(%Z,$0B1,0,-1)
  goto evloop
:UndoMENU
:UndoBUTTON
  %e = @sendmsg(%Z,$0304,0,0)
  goto evloop
:FindMENU
:FindBUTTON
  %t = @input(Enter text to search for:)
  if @ok()
    %s = @pred(@pos(%T,@dlgtext(Editor)))
    if @greater(%S,-1)
      gosub setsel
    else 
      beep 
    end 
  end 
  goto evloop
:Find NextMENU
  if %T
    %u = @pos(%T,@strdel(@dlgtext(Editor),1,@succ(%S)))
    if @greater(%U,0)
      %s = @sum(%S,%U)
      gosub setsel
    else 
      beep 
    end 
  else 
    beep 
  end 
  goto evloop
:Set Tab stopsMENU
  %t = @input("Enter tab interval (0 - 8):")
  if @ok()
    if @both(@greater(%T,0),@greater(9,%T))
      gosub settabs
    end 
  end 
  %t =
  goto evloop
:HelpMENU
:HelpBUTTON
  info Program accepts the following command line parameters:@cr()<path>@tab()Path of file to be edited@cr()/P@tab()Print file and close@cr()/R@tab()Open file in read-only mode@cr()/T n@tab()Set tab stops to n@cr()/W@tab()Turn word-wrap on@cr()
  goto evloop
:About ProgramMENU
  info Program 1.0@cr()@cr()A Visual DialogScript demonstration@cr()application.@cr()@cr()Written by Julian Moss.@cr()@cr()©1999 S.A.D.E. s.a.r.l. / All rights reserved.
  goto evloop
:CLOSE
  if %M
    if @not(@ask(File has been modified. Discard changes?))
      goto evloop
    end 
  end 
  exit 
:LoadFile
  list create,1
  list loadfile,1,%F
  dialog set,editor,@text(1)
  list close,1
  rem clear modified flag
  %e = @sendmsg(%Z,$0B9,0,0)
  dialog title,%F - %%apptitle
  rem check if file is read-only
  if @file(%F,R)%G
    %e = @sendmsg(%Z,$0CF,1,0)
    %r = Read-only
  else 
    %e = @sendmsg(%Z,$0CF,0,0)
    %r =
  end 
  rem kludge to make cursor appear at 1,1
  window send,%Z,@key(right)
  exit 
:SaveFile
  list create,1
  list assign,1,@dlgtext(Editor)
  list savefile,1,%F
  list close,1
  %e = @sendmsg(%Z,$0B9,0,0)
  dialog title,%F - %%apptitle
  exit 
:PrintFile
  list create,1
  list assign,1,@dlgtext(Editor)
  list print,1
  list close,1
  exit 
:SetSel
  rem EM_SETSEL - select found text
  %e = @sendmsg(%Z,$0B1,%S,@sum(%S,@len(%T)))
  rem EM_SCROLLCARET
  %e = @sendmsg(%Z,$0B7,0,0)
  exit 
:SetTabs
  %e = @sendmsg(%Z,$0CB,1,@chr(@prod(%T,4)))
  exit 
