unit range;
interface
uses sysutils,windows,common,menus;

// This range class started out as just that - a range class for pairs   *
// of lptr's, but ended up as a class for defining a block more than a   *
// range. The block is set by the use in Borg, and then the block can be *
// undefined, exported as txt/asm, decrypted, etc. All of this was added *
// in Borg 2.15                                                          *
procedure blockview;

type
  trange=class
  public
    top,bottom:lptr;
  public
    constructor create;
    function checkblock:boolean;
    procedure undefine;
    procedure settop;
    procedure setbottom;
  end;

var
  blk:trange;

implementation
uses disasm,disio,schedule;

constructor trange.create;
begin
  top:=nlptr;
  bottom:=nlptr;
end;

// checkblock                                                            *
// - This just checks that the top and bottom of the block have been set *
//   and returns true if they have, otherwise puts up a messagebox       *
function trange.checkblock:boolean;
begin
  result:=FALSE;
  if eq(top,nlptr) then begin
    MessageBox(mainwindow,'Set top of block first','Borg Disassembler',MB_OK);
    exit;
  end;
  if eq(bottom,nlptr) then begin
    MessageBox(mainwindow,'Set bottom of block first','Borg Disassembler',MB_OK);
    exit;
  end;
  if gr(top,bottom) then begin
    MessageBox(mainwindow,'Block empty ?','Borg Disassembler',MB_OK);
    exit;
  end;
  result:=TRUE;
end;

// undefine                                                              *
// - this undefines a block if the block has been set                    *
procedure trange.undefine;
begin
  if not checkblock then exit;
  dsm.undefineblock(top,bottom);
end;

// settop                                                                *
// - sets the top of the block to the current line                       *
procedure trange.settop;
begin
  dio.findcurrentaddr(top);
  MessageBox(mainwindow,'Top marked','Borg Disassembler',MB_OK);
end;

// setbottom                                                             *
// - sets the bottom of the block to the current line                    *
procedure trange.setbottom;
begin
  dio.findcurrentaddr(bottom);
  MessageBox(mainwindow,'Bottom marked','Borg Disassembler',MB_OK);
end;

// blockbox                                                              *
// - this is the dialog which just shows the extents of the current      *
//   block                                                               *
function blockbox(hdwnd,msg,wParam,lParam:dword):dword;stdcall;
const
  fmt:pchar='%4.4x:%8.8xh';
  brush:HBRUSH=0;
  s1:array[0..30] of char=#0;
  s2:array[0..30] of char=#0;
  s3:array[0..40] of char=#0;
var
  drect:tRECT;
begin
  result:=0;
  case msg of
   WM_COMMAND:
    case wParam of
     IDOK: begin EndDialog(hdwnd,0); result:=1; end;
    end;
   WM_INITDIALOG:
    begin
      brush:=CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
      GetWindowRect(hdwnd,drect);
      MoveWindow(hdwnd,((mainwnd.right+mainwnd.left)-(drect.right-drect.left)) div 2,
       ((mainwnd.bottom+mainwnd.top)-(drect.bottom-drect.top)) div 2,drect.right-drect.left,drect.bottom-drect.top,TRUE);
      strlfmt(s1,30,fmt,[blk.top.s,blk.top.o]);
      strlfmt(s2,30,fmt,[blk.bottom.s,blk.bottom.o]);
      SendDlgItemMessage(hdwnd,Text_Top,WM_SETTEXT,0,dword(@s1));
      SendDlgItemMessage(hdwnd,Text_Bottom,WM_SETTEXT,0,dword(@s2));
      if eq(blk.top,nlptr) then strcopy(s3,'Top not set')
      else if eq(blk.bottom,nlptr) then strcopy(s3,'Bottom not set')
      else if gr(blk.top,blk.bottom) then strcopy(s3,'Range is empty')
      else strcopy(s3,'Range set');
      SendDlgItemMessage(hdwnd,Text_Status,WM_SETTEXT,0,dword(@s3));
    end;
   WM_DESTROY: DeleteObject(brush);
   WM_CTLCOLORSTATIC, WM_CTLCOLORBTN, WM_CTLCOLORDLG, WM_SYSCOLORCHANGE:
    begin
      SetBkColor(HDC(wParam),GetSysColor(COLOR_BTNFACE));
      result:=brush;
    end;
  end;
end;

// blockview                                                             *
// - this stops the secondary thread and puts up the dialog box for      *
//   viewing the extents of the block                                    *
procedure blockview;
begin
  scheduler.stopthread;
  DialogBox(Inst,MAKEINTRESOURCE(Block_Dialog),mainwindow,@blockbox);
  scheduler.continuethread;
end;

initialization
  blk:=trange.create;
finalization
  blk.free;
end.

