ScharfBASIC Help

Command reference for the ScharfBASIC compiler and its accepted extensions.

About ScharfBASIC

ScharfBASIC is a forward-development fork of the recovered ScharfBASIC-compatible compiler. It keeps the established PB language surface and adds source-owned ScharfBASIC extensions.

Command Index

AVAILABLE = available in ScharfBASIC. EXTENSION = ScharfBASIC-specific accepted extension.

Control Flow

  • CHOOSE function AVAILABLE
  • DO/LOOP statements AVAILABLE
  • END statement AVAILABLE
  • Error Trapping AVAILABLE
  • Error Trapping Summary AVAILABLE
  • ERROR$ function AVAILABLE
  • EXIT statement AVAILABLE
  • Exiting an error handler AVAILABLE
  • Flow Control AVAILABLE
  • FOR EACH/NEXT statements AVAILABLE
  • FOR/NEXT statements AVAILABLE
  • GOSUB statement AVAILABLE
  • How error traps work AVAILABLE
  • IF statement AVAILABLE
  • IF/END IF block AVAILABLE
  • IIF function AVAILABLE
  • ITERATE statement AVAILABLE
  • Long lines AVAILABLE
  • ON ERROR statement AVAILABLE
  • ON GOSUB statement AVAILABLE
  • ON GOTO statement AVAILABLE
  • RESUME statement AVAILABLE
  • SELECT CASE/END SELECT block AVAILABLE
  • Setting an error trap AVAILABLE
  • Statement separation AVAILABLE
  • Structured Programming AVAILABLE
  • SWITCH function AVAILABLE
  • TRY/END TRY block AVAILABLE
  • WHILE/WEND statements AVAILABLE
  • Writing an error handler AVAILABLE

ScharfBASIC Extensions

  • SBYTE data type EXTENSION
  • JESCAPE$ function EXTENSION
  • JSLASH$ function EXTENSION
  • JSTRING$ function EXTENSION
  • JUNESCAPE$ function EXTENSION
  • JUNQUOTE$ function EXTENSION
  • /ASMOUT Startup Switch EXTENSION
  • Command-Line Options AVAILABLE

Procedures
  • CALL statement AVAILABLE
  • Callbacks AVAILABLE
  • CB Callback functions AVAILABLE
  • DECLARE statement AVAILABLE
  • DLLMAIN function AVAILABLE
  • FUNCNAME$ function AVAILABLE
  • FUNCTION/END FUNCTION statements AVAILABLE
  • LibMain AVAILABLE
  • METHOD / END METHOD statements AVAILABLE
  • PBLIBMAIN function AVAILABLE
  • PBMAIN function AVAILABLE
  • Private and Exported Procedures AVAILABLE
  • PROPERTY / END PROPERTY statement AVAILABLE
  • RETURN statement AVAILABLE
  • SUB/END SUB statements AVAILABLE
  • WINMAIN function AVAILABLE

Variables & Scope

  • #DIM metastatement AVAILABLE
  • #REGISTER metastatement AVAILABLE
  • Array storage requirements AVAILABLE
  • DATA statement AVAILABLE
  • Default Variable Typing AVAILABLE
  • DIM statement AVAILABLE
  • ERASE statement AVAILABLE
  • GLOBAL statement AVAILABLE
  • INSTANCE statement AVAILABLE
  • LET statement AVAILABLE
  • LOCAL statement AVAILABLE
  • Multidimensional arrays AVAILABLE
  • OPTION EXPLICIT statement AVAILABLE
  • READ$ function AVAILABLE
  • REDIM statement AVAILABLE
  • REGISTER statement AVAILABLE
  • STATIC statement AVAILABLE
  • String arrays AVAILABLE
  • Subscripts AVAILABLE
  • THREADED statement AVAILABLE
  • Variable scope AVAILABLE

Types

  • Accessing the fields of a User-Defined Type AVAILABLE
  • Arrays within User-Defined Types AVAILABLE
  • Defining User-Defined Types AVAILABLE
  • ENUM/END ENUM statements AVAILABLE
  • MACRO/END MACRO block AVAILABLE
  • Nesting User-Defined Types AVAILABLE
  • TYPE SET statement AVAILABLE
  • TYPE/END TYPE block AVAILABLE
  • UNION/END UNION block AVAILABLE
  • User-Defined Types (UDTs) AVAILABLE
  • Using arrays of User-Defined Types AVAILABLE
  • Using User-Defined Types with procedures AVAILABLE

Data Types

  • Array Data Types AVAILABLE
  • Bit Data Types AVAILABLE
  • Byte (?) AVAILABLE
  • SBYTE EXTENSION
  • Currency and Extended-currency AVAILABLE
  • Data Types AVAILABLE
  • Data types in Registers AVAILABLE
  • Double-precision floating-point (#) AVAILABLE
  • Double-word (???) AVAILABLE
  • Dynamic (Variable-length) strings ($) AVAILABLE
  • Extended-precision floating-point (##) AVAILABLE
  • FIELD statement AVAILABLE
  • FIELD strings AVAILABLE
  • Fixed-length strings AVAILABLE
  • GUID data types AVAILABLE
  • GUID$ function AVAILABLE
  • Integers (%) AVAILABLE
  • Long integers (&) AVAILABLE
  • Nul-Terminated Strings AVAILABLE
  • Numeric Equates AVAILABLE
  • Object Data Type AVAILABLE
  • OBJECT statement AVAILABLE
  • Pointers (@) AVAILABLE
  • Pointers to Nul-Terminated and fixed-length strings AVAILABLE
  • Quad integers (&&) AVAILABLE
  • Single-precision floating-point (!) AVAILABLE
  • String Equates AVAILABLE
  • Variant Data Types AVAILABLE
  • VARIANT# function AVAILABLE
  • VARIANT$/VARIANT$$ function AVAILABLE
  • VARIANTVT function AVAILABLE
  • Word (??) AVAILABLE

Math & Numeric

  • ABS function AVAILABLE
  • ATN function AVAILABLE
  • BGR function AVAILABLE
  • BIN$ function AVAILABLE
  • BIT CALC statement AVAILABLE
  • BIT function AVAILABLE
  • BIT statement AVAILABLE
  • BITS function AVAILABLE
  • BITS$ function AVAILABLE
  • BITSE function AVAILABLE
  • CEIL function AVAILABLE
  • COS function AVAILABLE
  • CVBYT function AVAILABLE
  • EXP function AVAILABLE
  • FIX function AVAILABLE
  • FRAC function AVAILABLE
  • HEX$ function AVAILABLE
  • HI function AVAILABLE
  • INT function AVAILABLE
  • ISWIN function AVAILABLE
  • LO function AVAILABLE
  • LOG function AVAILABLE
  • MAK function AVAILABLE
  • MAX function AVAILABLE
  • MIN function AVAILABLE
  • OCT$ function AVAILABLE
  • RANDOMIZE statement AVAILABLE
  • REMAIN$ function AVAILABLE
  • RGB function AVAILABLE
  • RND function AVAILABLE
  • ROTATE statement AVAILABLE
  • ROUND function AVAILABLE
  • SGN function AVAILABLE
  • SHIFT statement AVAILABLE
  • SIN function AVAILABLE
  • SQR function AVAILABLE
  • SWAP statement AVAILABLE
  • TAN function AVAILABLE

Operators

  • AND operator AVAILABLE
  • Arithmetic Operators AVAILABLE
  • EQV operator AVAILABLE
  • IMP operator AVAILABLE
  • ISFALSE operator AVAILABLE
  • ISMISSING function AVAILABLE
  • ISNOTHING function AVAILABLE
  • ISNOTNULL function AVAILABLE
  • ISNULL function AVAILABLE
  • ISOBJECT function AVAILABLE
  • MOD operator AVAILABLE
  • NOT operator AVAILABLE
  • Operator Precedence AVAILABLE
  • OR operator AVAILABLE
  • Relational Operators AVAILABLE
  • XOR operator AVAILABLE

String Functions

  • ACODE$ function AVAILABLE
  • ASC function AVAILABLE
  • ASC statement AVAILABLE
  • BUILD$ function AVAILABLE
  • CHR$ function AVAILABLE
  • CHRBYTES function AVAILABLE
  • CSET statement AVAILABLE
  • CSET$ function AVAILABLE
  • EXTRACT$ function AVAILABLE
  • FORMAT$ function AVAILABLE
  • INSTR function AVAILABLE
  • IStringBuilderA.Add method AVAILABLE
  • JOIN$ function AVAILABLE
  • LCASE$ function AVAILABLE
  • LEFT$ function AVAILABLE
  • LEN function AVAILABLE
  • LSET statement AVAILABLE
  • LSET$ function AVAILABLE
  • LTRIM$ function AVAILABLE
  • MCASE$ function AVAILABLE
  • MID$ function AVAILABLE
  • MID$ statement AVAILABLE
  • PARSE statement AVAILABLE
  • PARSE$ function AVAILABLE
  • PARSECOUNT function AVAILABLE
  • PART$ function EXTENSION
  • REMOVE$ function AVAILABLE
  • REPEAT$ function AVAILABLE
  • REPLACE statement AVAILABLE
  • RETAIN$ function AVAILABLE
  • RIGHT$ function AVAILABLE
  • RSET statement AVAILABLE
  • RSET$ function AVAILABLE
  • RTRIM$ function AVAILABLE
  • SHRINK$ function AVAILABLE
  • SPACE$ function AVAILABLE
  • SPLIT statement AVAILABLE
  • STR$ function AVAILABLE
  • STRDELETE$ function AVAILABLE
  • String expressions AVAILABLE
  • String Operations Commands AVAILABLE
  • STRING$ function AVAILABLE
  • STRINSERT$ function AVAILABLE
  • STRREVERSE$ function AVAILABLE
  • TAB DELETE statement AVAILABLE
  • TAB$ function AVAILABLE
  • TALLY function AVAILABLE
  • TRIM$ function AVAILABLE
  • UCASE$ function AVAILABLE
  • UCODE$ function AVAILABLE
  • UCODEPAGE statement AVAILABLE
  • UNWRAP$ function AVAILABLE
  • USING$ function AVAILABLE
  • VAL function AVAILABLE
  • VAL statement AVAILABLE
  • VERIFY function AVAILABLE
  • WRAP$ function AVAILABLE

File I/O

  • ASMDATA/END ASMDATA statements AVAILABLE
  • Binary Files AVAILABLE
  • CLOSE statement AVAILABLE
  • EOF function AVAILABLE
  • FILEATTR function AVAILABLE
  • FILENAME$ function AVAILABLE
  • FILESCAN statement AVAILABLE
  • FLUSH statement AVAILABLE
  • FREEFILE function AVAILABLE
  • GET statement AVAILABLE
  • GRAPHIC INPUT statement AVAILABLE
  • GRAPHIC LINE INPUT statement AVAILABLE
  • Input Commands AVAILABLE
  • INPUT# statement AVAILABLE
  • LINE INPUT# statement AVAILABLE
  • LOC function AVAILABLE
  • LOCK statement AVAILABLE
  • LOF function AVAILABLE
  • OPEN statement AVAILABLE
  • PRINT# statement AVAILABLE
  • PUT statement AVAILABLE
  • Random Access Files AVAILABLE
  • RESET statement AVAILABLE
  • SEEK function AVAILABLE
  • SEEK statement AVAILABLE
  • Sequential Files AVAILABLE
  • SETEOF statement AVAILABLE
  • TCP LINE INPUT statement AVAILABLE
  • UNLOCK statement AVAILABLE
  • WRITE# statement AVAILABLE

File Management

  • CHDIR statement AVAILABLE
  • CHDRIVE statement AVAILABLE
  • CURDIR$ function AVAILABLE
  • DIR$ function AVAILABLE
  • DISKFREE function AVAILABLE
  • DISKSIZE function AVAILABLE
  • FILECOPY statement AVAILABLE
  • Files AVAILABLE
  • GETATTR function AVAILABLE
  • ISFILE Function AVAILABLE
  • ISFOLDER function AVAILABLE
  • KILL statement AVAILABLE
  • MKDIR statement AVAILABLE
  • NAME statement AVAILABLE
  • RMDIR statement AVAILABLE
  • SETATTR statement AVAILABLE

Memory & Pointers

  • #STACK metastatement AVAILABLE
  • CODEPTR function AVAILABLE
  • Effective Addressing AVAILABLE
  • GLOBALMEM ALLOC statement AVAILABLE
  • MEMORY COPY statement AVAILABLE
  • MMX registers AVAILABLE
  • OBJPTR function AVAILABLE
  • PEEK function AVAILABLE
  • POKE statement AVAILABLE
  • Registers AVAILABLE
  • Saving registers AVAILABLE
  • Saving Registers at the Procedure level AVAILABLE
  • Saving the FPU registers AVAILABLE
  • Stack Overhead Reduction AVAILABLE
  • STRPTR function AVAILABLE
  • Tricks in preserving registers AVAILABLE
  • Tricks of the stack AVAILABLE
  • VARPTR function AVAILABLE

Utilities

  • BEEP statement AVAILABLE
  • COMMAND$ function AVAILABLE
  • ENVIRON statement AVAILABLE
  • ENVIRON$ function AVAILABLE
  • INPUTBOX$ function AVAILABLE
  • MOUSEPTR statement AVAILABLE
  • MSGBOX function AVAILABLE
  • MSGBOX statement AVAILABLE
  • PLAY WAVE statement AVAILABLE
  • PROFILE statement AVAILABLE
  • SHELL function AVAILABLE
  • SHELL statement AVAILABLE
  • SLEEP statement AVAILABLE
  • TIMER function AVAILABLE
  • TIX statement AVAILABLE

Preprocessor

  • #ALIGN metastatement AVAILABLE
  • #BLOAT metastatement AVAILABLE
  • #COM metastatement AVAILABLE
  • #COMPILE metastatement AVAILABLE
  • #DEBUG CODE metastatement AVAILABLE
  • #DEBUG DISPLAY metastatement AVAILABLE
  • #DEBUG ERROR metastatement AVAILABLE
  • #DEBUG PRINT metastatement AVAILABLE
  • #EXPORT metastatement AVAILABLE
  • #IF metastatement AVAILABLE
  • #INCLUDE metastatement AVAILABLE
  • #LINK metastatement AVAILABLE
  • #MESSAGES metastatement AVAILABLE
  • #OPTIMIZE metastatement AVAILABLE
  • #OPTION metastatement AVAILABLE
  • #PAGE metastatement AVAILABLE
  • #PBFORMS metastatement AVAILABLE
  • #RESOURCE metastatement AVAILABLE
  • #TOOLS metastatement AVAILABLE
  • #UNIQUE metastatement AVAILABLE
  • #UTILITY metastatement AVAILABLE
  • COM Commands AVAILABLE
  • Compiler Operations AVAILABLE
  • Metastatements AVAILABLE

Error Reference

  • Error Overview AVAILABLE
  • ERROR statement AVAILABLE

Inline Assembler

  • ASM statement AVAILABLE
  • ASM statement AVAILABLE
  • Commenting Assembly code AVAILABLE
  • Inline Assembler code syntax AVAILABLE
  • Intermixing ASM and BASIC code AVAILABLE
  • Mnemonics and Operands AVAILABLE
  • Opcodes and Mnemonics AVAILABLE
  • The Inline Assembler AVAILABLE
  • Using assembly-language in your code AVAILABLE

UI, Graphics & DDT

  • Adding Controls to the Dialog AVAILABLE
  • Built In RGB Color Equates AVAILABLE
  • COMBOBOX ADD statement AVAILABLE
  • COMM PRINT statement AVAILABLE
  • Communication Control AVAILABLE
  • CONTROL ADD BUTTON statement AVAILABLE
  • CONTROL ADD CHECK3STATE statement AVAILABLE
  • CONTROL ADD CHECKBOX statement AVAILABLE
  • CONTROL ADD COMBOBOX statement AVAILABLE
  • CONTROL ADD FRAME statement AVAILABLE
  • CONTROL ADD GRAPHIC statement AVAILABLE
  • CONTROL ADD HEADER statement AVAILABLE
  • CONTROL ADD IMAGE statement AVAILABLE
  • CONTROL ADD IMAGEX statement AVAILABLE
  • CONTROL ADD IMGBUTTON statement AVAILABLE
  • CONTROL ADD IMGBUTTONX statement AVAILABLE
  • CONTROL ADD LABEL statement AVAILABLE
  • CONTROL ADD LINE statement AVAILABLE
  • CONTROL ADD LISTBOX statement AVAILABLE
  • CONTROL ADD LISTVIEW statement AVAILABLE
  • CONTROL ADD OPTION statement AVAILABLE
  • CONTROL ADD PROGRESSBAR statement AVAILABLE
  • CONTROL ADD SCROLLBAR statement AVAILABLE
  • CONTROL ADD statement AVAILABLE
  • CONTROL ADD STATUSBAR statement AVAILABLE
  • CONTROL ADD TAB statement AVAILABLE
  • CONTROL ADD TEXTBOX statement AVAILABLE
  • CONTROL ADD TOOLBAR statement AVAILABLE
  • CONTROL ADD TREEVIEW statement AVAILABLE
  • CONTROL DISABLE statement AVAILABLE
  • CONTROL ENABLE statement AVAILABLE
  • CONTROL GET CHECK statement AVAILABLE
  • CONTROL GET CLIENT statement AVAILABLE
  • CONTROL GET LOC statement AVAILABLE
  • CONTROL GET SIZE statement AVAILABLE
  • CONTROL GET TEXT statement AVAILABLE
  • CONTROL GET USER statement AVAILABLE
  • CONTROL HANDLE statement AVAILABLE
  • CONTROL HIDE statement AVAILABLE
  • CONTROL KILL statement AVAILABLE
  • CONTROL NORMALIZE statement AVAILABLE
  • CONTROL POST statement AVAILABLE
  • CONTROL REDRAW statement AVAILABLE
  • CONTROL SEND statement AVAILABLE
  • CONTROL SET CHECK statement AVAILABLE
  • CONTROL SET CLIENT statement AVAILABLE
  • CONTROL SET COLOR statement AVAILABLE
  • CONTROL SET FOCUS statement AVAILABLE
  • CONTROL SET FONT statement AVAILABLE
  • CONTROL SET IMAGE statement AVAILABLE
  • CONTROL SET IMAGEX statement AVAILABLE
  • CONTROL SET IMGBUTTON statement AVAILABLE
  • CONTROL SET IMGBUTTONX statement AVAILABLE
  • CONTROL SET LOC statement AVAILABLE
  • CONTROL SET OPTION statement AVAILABLE
  • CONTROL SET SIZE statement AVAILABLE
  • CONTROL SET TEXT statement AVAILABLE
  • CONTROL SET USER statement AVAILABLE
  • CONTROL SHOW STATE statement AVAILABLE
  • Control Styles AVAILABLE
  • Controls AVAILABLE
  • Creating a Dialog AVAILABLE
  • DESKTOP GET CLIENT statement AVAILABLE
  • DESKTOP GET LOC statement AVAILABLE
  • DESKTOP GET SIZE statement AVAILABLE
  • DIALOG DEFAULT FONT statement AVAILABLE
  • DIALOG DISABLE statement AVAILABLE
  • DIALOG DOEVENTS statement AVAILABLE
  • DIALOG ENABLE statement AVAILABLE
  • DIALOG END statement AVAILABLE
  • DIALOG GET CLIENT statement AVAILABLE
  • DIALOG GET LOC statement AVAILABLE
  • DIALOG GET SIZE statement AVAILABLE
  • DIALOG GET TEXT statement AVAILABLE
  • DIALOG GET USER statement AVAILABLE
  • DIALOG HIDE statement AVAILABLE
  • DIALOG MAXIMIZE statement AVAILABLE
  • DIALOG MINIMIZE statement AVAILABLE
  • DIALOG NEW statement AVAILABLE
  • DIALOG NONSTABLE statement AVAILABLE
  • DIALOG NORMALIZE statement AVAILABLE
  • DIALOG PIXELS statement AVAILABLE
  • DIALOG POST statement AVAILABLE
  • DIALOG REDRAW statement AVAILABLE
  • DIALOG SEND statement AVAILABLE
  • DIALOG SET CLIENT Statement AVAILABLE
  • DIALOG SET COLOR statement AVAILABLE
  • DIALOG SET ICON statement AVAILABLE
  • DIALOG SET LOC statement AVAILABLE
  • DIALOG SET SIZE statement AVAILABLE
  • DIALOG SET TEXT statement AVAILABLE
  • DIALOG SET USER statement AVAILABLE
  • DIALOG SHOW MODAL statement AVAILABLE
  • DIALOG SHOW MODELESS statement AVAILABLE
  • DIALOG SHOW STATE statement AVAILABLE
  • DIALOG STABILIZE statement AVAILABLE
  • Dialog Styles AVAILABLE
  • DIALOG UNITS statement AVAILABLE
  • DISPLAY BROWSE statement AVAILABLE
  • DISPLAY COLOR statement AVAILABLE
  • DISPLAY FONT statement AVAILABLE
  • DISPLAY OPENFILE statement AVAILABLE
  • DISPLAY SAVEFILE statement AVAILABLE
  • Dynamic Dialog Tools AVAILABLE
  • Dynamic Dialog Tools (DDT) AVAILABLE
  • FONT END statement AVAILABLE
  • FONT NEW statement AVAILABLE
  • GRAPHIC ARC statement AVAILABLE
  • GRAPHIC ATTACH statement AVAILABLE
  • GRAPHIC BITMAP END statement AVAILABLE
  • GRAPHIC BITMAP LOAD statement AVAILABLE
  • GRAPHIC BITMAP NEW statement AVAILABLE
  • GRAPHIC BOX statement AVAILABLE
  • GRAPHIC CLEAR statement AVAILABLE
  • GRAPHIC Code Group AVAILABLE
  • GRAPHIC COLOR statement AVAILABLE
  • Graphic Commands AVAILABLE
  • GRAPHIC COPY statement AVAILABLE
  • GRAPHIC DETACH statement AVAILABLE
  • GRAPHIC ELLIPSE statement AVAILABLE
  • GRAPHIC GET BITS statement AVAILABLE
  • GRAPHIC GET SCALE statement AVAILABLE
  • GRAPHIC IMAGELIST statement AVAILABLE
  • GRAPHIC INPUT FLUSH statement AVAILABLE
  • GRAPHIC LINE statement AVAILABLE
  • GRAPHIC PAINT statement AVAILABLE
  • GRAPHIC PIE statement AVAILABLE
  • GRAPHIC POLYGON statement AVAILABLE
  • GRAPHIC POLYLINE statement AVAILABLE
  • GRAPHIC PRINT statement AVAILABLE
  • GRAPHIC REDRAW statement AVAILABLE
  • GRAPHIC RENDER statement AVAILABLE
  • GRAPHIC SAVE statement AVAILABLE
  • GRAPHIC SCALE statement AVAILABLE
  • GRAPHIC SET AUTOSIZE statement AVAILABLE
  • GRAPHIC SET BITS statement AVAILABLE
  • GRAPHIC SET CAPTION statement AVAILABLE
  • GRAPHIC SET CLIENT statement AVAILABLE
  • GRAPHIC SET CLIP statement AVAILABLE
  • GRAPHIC SET FIXED statement AVAILABLE
  • GRAPHIC SET FOCUS statement AVAILABLE
  • GRAPHIC SET FONT statement AVAILABLE
  • GRAPHIC SET LOC statement AVAILABLE
  • GRAPHIC SET MIX statement AVAILABLE
  • GRAPHIC SET OVERLAP statement AVAILABLE
  • GRAPHIC SET PIXEL statement AVAILABLE
  • GRAPHIC SET POS statement AVAILABLE
  • GRAPHIC SET SCROLLTEXT statement AVAILABLE
  • GRAPHIC SET SIZE statement AVAILABLE
  • GRAPHIC SET STRETCHMODE statement AVAILABLE
  • GRAPHIC SET VIEW statement AVAILABLE
  • GRAPHIC SET VIRTUAL statement AVAILABLE
  • GRAPHIC SET WORDWRAP statement AVAILABLE
  • GRAPHIC SET WRAP statement AVAILABLE
  • GRAPHIC SPLIT statement AVAILABLE
  • GRAPHIC STRETCH statement AVAILABLE
  • GRAPHIC STYLE statement AVAILABLE
  • GRAPHIC WIDTH statement AVAILABLE
  • GRAPHIC WINDOW CLICK statement AVAILABLE
  • GRAPHIC WINDOW END statement AVAILABLE
  • GRAPHIC WINDOW HIDE statement AVAILABLE
  • GRAPHIC WINDOW MINIMIZE statement AVAILABLE
  • GRAPHIC WINDOW NONSTABLE statement AVAILABLE
  • GRAPHIC WINDOW NORMALIZE statement AVAILABLE
  • GRAPHIC WINDOW STABILIZE statement AVAILABLE
  • GRAPHIC WINDOW statement AVAILABLE
  • GRAPHIC$(CAPTION) function AVAILABLE
  • GRAPHIC$(INKEY$) function AVAILABLE
  • GRAPHIC$(WAITKEY$) function AVAILABLE
  • GRAPHIC(CANVAS.X) function AVAILABLE
  • GRAPHIC(Cell.Size.X) function AVAILABLE
  • GRAPHIC(Chr.Size.X) function AVAILABLE
  • GRAPHIC(Client.X) function AVAILABLE
  • GRAPHIC(Clip.X) function AVAILABLE
  • GRAPHIC(COL) function AVAILABLE
  • GRAPHIC(DC) function AVAILABLE
  • GRAPHIC(INSTAT) function AVAILABLE
  • GRAPHIC(LINES) function AVAILABLE
  • GRAPHIC(LOC.X) function AVAILABLE
  • GRAPHIC(MIX) function AVAILABLE
  • GRAPHIC(OVERLAP) function AVAILABLE
  • GRAPHIC(PIXEL...) function AVAILABLE
  • GRAPHIC(POS.X) function AVAILABLE
  • GRAPHIC(PPI.X) function AVAILABLE
  • GRAPHIC(SCROLLTEXT) function AVAILABLE
  • GRAPHIC(SIZE.X) function AVAILABLE
  • GRAPHIC(STRETCHMODE) function AVAILABLE
  • GRAPHIC(TEXT.SIZE.X...) function AVAILABLE
  • GRAPHIC(View.X) function AVAILABLE
  • GRAPHIC(WORDWRAP) function AVAILABLE
  • GRAPHIC(WRAP) function AVAILABLE
  • Graphics AVAILABLE
  • HEADER GET COUNT statement AVAILABLE
  • IMAGELIST ADD BITMAP statement AVAILABLE
  • LISTBOX ADD statement AVAILABLE
  • LISTVIEW DELETE COLUMN statement AVAILABLE
  • LPRINT ATTACH statement AVAILABLE
  • LPRINT CLOSE statement AVAILABLE
  • LPRINT FLUSH statement AVAILABLE
  • LPRINT FORMFEED statement AVAILABLE
  • LPRINT statement AVAILABLE
  • LPRINT$ function AVAILABLE
  • MENU ADD POPUP statement AVAILABLE
  • MENU ADD STRING statement AVAILABLE
  • MENU ATTACH statement AVAILABLE
  • MENU CONTEXT statement AVAILABLE
  • MENU DELETE statement AVAILABLE
  • MENU DRAW BAR statement AVAILABLE
  • Menu Example AVAILABLE
  • MENU GET STATE statement AVAILABLE
  • MENU GET TEXT statement AVAILABLE
  • MENU NEW BAR statement AVAILABLE
  • MENU NEW POPUP statement AVAILABLE
  • MENU SET STATE statement AVAILABLE
  • MENU SET TEXT statement AVAILABLE
  • Menu State AVAILABLE
  • Menu Walkthrough AVAILABLE
  • Menus AVAILABLE
  • More on the Menu AVAILABLE
  • Options Dialog AVAILABLE
  • PRINTER$ function AVAILABLE
  • PRINTERCOUNT function AVAILABLE
  • PROGRESSBAR GET POS statement AVAILABLE
  • SCROLLBAR GET PAGESIZE statement AVAILABLE
  • STATUSBAR SET PARTS statement AVAILABLE
  • Syntax Custom Color Selector AVAILABLE
  • TCP PRINT statement AVAILABLE
  • Thread Control AVAILABLE
  • TOOLBAR ADD BUTTON statement AVAILABLE
  • TREEVIEW DELETE statement AVAILABLE
  • WINDOW GET HANDLE statement AVAILABLE
  • WINDOW SET ID statement AVAILABLE
  • XPRINT ARC statement AVAILABLE
  • XPRINT ATTACH statement AVAILABLE
  • XPRINT BOX statement AVAILABLE
  • XPRINT CANCEL statement AVAILABLE
  • XPRINT CLOSE statement AVAILABLE
  • XPRINT Code Group AVAILABLE
  • XPRINT COLOR statement AVAILABLE
  • XPRINT COPY statement AVAILABLE
  • XPRINT ELLIPSE statement AVAILABLE
  • XPRINT FORMFEED statement AVAILABLE
  • XPRINT GET MARGIN statement AVAILABLE
  • XPRINT GET PAGES statement AVAILABLE
  • XPRINT GET SCALE statement AVAILABLE
  • XPRINT IMAGELIST statement AVAILABLE
  • XPRINT LINE statement AVAILABLE
  • XPRINT PIE statement AVAILABLE
  • XPRINT POLYGON statement AVAILABLE
  • XPRINT POLYLINE statement AVAILABLE
  • XPRINT PREVIEW statement AVAILABLE
  • XPRINT PRINT statement AVAILABLE
  • XPRINT RENDER statement AVAILABLE
  • XPRINT SCALE statement AVAILABLE
  • XPRINT SET CLIP statement AVAILABLE
  • XPRINT SET COLLATE statement AVAILABLE
  • XPRINT SET COLORMODE statement AVAILABLE
  • XPRINT SET COPIES statement AVAILABLE
  • XPRINT SET DUPLEX statement AVAILABLE
  • XPRINT SET FONT statement AVAILABLE
  • XPRINT SET MIX statement AVAILABLE
  • XPRINT SET ORIENTATION statement AVAILABLE
  • XPRINT SET OVERLAP statement AVAILABLE
  • XPRINT SET PAGES statement AVAILABLE
  • XPRINT SET PAPER statement AVAILABLE
  • XPRINT SET PIXEL statement AVAILABLE
  • XPRINT SET POS statement AVAILABLE
  • XPRINT SET QUALITY statement AVAILABLE
  • XPRINT SET STRETCHMODE statement AVAILABLE
  • XPRINT SET TRAY statement AVAILABLE
  • XPRINT SET WORDWRAP statement AVAILABLE
  • XPRINT SET WRAP statement AVAILABLE
  • XPRINT SPLIT statement AVAILABLE
  • XPRINT STRETCH statement AVAILABLE
  • XPRINT STYLE statement AVAILABLE
  • XPRINT WIDTH statement AVAILABLE
  • XPRINT$ function AVAILABLE
  • XPRINT$(PAPERS) function AVAILABLE
  • XPRINT$(TRAYS) function AVAILABLE
  • XPRINT(CANVAS.X) function AVAILABLE
  • XPRINT(Cell.Size.X) function AVAILABLE
  • XPRINT(Chr.Size.X) function AVAILABLE
  • XPRINT(Client.X) function AVAILABLE
  • XPRINT(Clip.X) function AVAILABLE
  • XPRINT(COL) function AVAILABLE
  • XPRINT(COLLATE) function AVAILABLE
  • XPRINT(COLORMODE) function AVAILABLE
  • XPRINT(COPIES) function AVAILABLE
  • XPRINT(DC) function AVAILABLE
  • XPRINT(DUPLEX) function AVAILABLE
  • XPRINT(LINES) function AVAILABLE
  • XPRINT(MIX) function AVAILABLE
  • XPRINT(ORIENTATION) function AVAILABLE
  • XPRINT(OVERLAP) function AVAILABLE
  • XPRINT(PAPER) function AVAILABLE
  • XPRINT(PIXEL...) function AVAILABLE
  • XPRINT(POS.X) function AVAILABLE
  • XPRINT(PPI.X) function AVAILABLE
  • XPRINT(QUALITY) function AVAILABLE
  • XPRINT(SELECTION) function AVAILABLE
  • XPRINT(SIZE.X) function AVAILABLE
  • XPRINT(STRETCHMODE) function AVAILABLE
  • XPRINT(TEXT.SIZE.X...) function AVAILABLE
  • XPRINT(TRAY) function AVAILABLE
  • XPRINT(WORDWRAP) function AVAILABLE
  • XPRINT(WRAP) function AVAILABLE

COM & Objects

  • Built-in Interfaces AVAILABLE
  • CLASS/END CLASS block AVAILABLE
  • CLSID$ function AVAILABLE
  • Collection Objects AVAILABLE
  • Creating a DISPATCH Object AVAILABLE
  • Enumerating Collections AVAILABLE
  • EVENT SOURCE statement AVAILABLE
  • EVENTS statement AVAILABLE
  • GUIDTXT$ function AVAILABLE
  • ID Binding AVAILABLE
  • IDISPINFO pseudo-object AVAILABLE
  • INTERFACE / END INTERFACE Block (Direct) AVAILABLE
  • INTERFACE/END INTERFACE block (Dispatch) AVAILABLE
  • IPowerThread.Close method AVAILABLE
  • IPowerTime.AddDays method AVAILABLE
  • ISINTERFACE Function AVAILABLE
  • Just what is COM? AVAILABLE
  • Late Binding AVAILABLE
  • LET statement (with Objects) AVAILABLE
  • LET statement (with Variants) AVAILABLE
  • OBJACTIVE function AVAILABLE
  • OBJEQUAL function AVAILABLE
  • OBJRESULT function AVAILABLE
  • Opening a type-library AVAILABLE
  • POWERARRAY Object AVAILABLE
  • PROGID$ function AVAILABLE
  • RAISEEVENT statement AVAILABLE
  • StackCollection AVAILABLE
  • What is DISPATCH? AVAILABLE
  • What is inheritance? AVAILABLE

Communications

  • A simple communications program AVAILABLE
  • An ECHO client and server using TCP AVAILABLE
  • COMM CLOSE statement AVAILABLE
  • COMM function AVAILABLE
  • COMM LINE statement AVAILABLE
  • COMM OPEN statement AVAILABLE
  • COMM RECV statement AVAILABLE
  • COMM RESET statement AVAILABLE
  • COMM SEND statement AVAILABLE
  • COMM SET statement AVAILABLE
  • COMM TIMEOUT statement AVAILABLE
  • HOST ADDR statement AVAILABLE
  • HOST NAME statement AVAILABLE
  • Opening a communications port AVAILABLE
  • TCP ACCEPT statement AVAILABLE
  • TCP CLOSE statement AVAILABLE
  • TCP NOTIFY statement AVAILABLE
  • TCP OPEN statement AVAILABLE
  • TCP RECV statement AVAILABLE
  • TCP SEND statement AVAILABLE
  • UDP CLOSE statement AVAILABLE
  • UDP NOTIFY statement AVAILABLE
  • UDP OPEN statement AVAILABLE
  • UDP RECV statement AVAILABLE
  • UDP SEND statement AVAILABLE

Threading

  • PROCESS GET PRIORITY statement AVAILABLE
  • PROCESS SET PRIORITY statement AVAILABLE
  • THREAD CLOSE statement AVAILABLE
  • THREAD Code Group AVAILABLE
  • THREAD CREATE statement AVAILABLE
  • THREAD GET PRIORITY statement AVAILABLE
  • THREAD RESUME statement AVAILABLE
  • THREAD SET PRIORITY statement AVAILABLE
  • THREAD STATUS statement AVAILABLE
  • THREAD SUSPEND statement AVAILABLE
  • THREADCOUNT function AVAILABLE
  • THREADID function AVAILABLE

General

  • %DEF operator AVAILABLE
  • %PB_COMPILETIME numeric equate AVAILABLE
  • ACCEL ATTACH statement AVAILABLE
  • Accessing ScharfBASIC variables by name AVAILABLE
  • Add-on Libraries, Utilities and Tools AVAILABLE
  • Additional Source Code and Examples AVAILABLE
  • Addressing and pointers AVAILABLE
  • Are there other important "Buzz-Words"? AVAILABLE
  • ARRAY ASSIGN statement AVAILABLE
  • ARRAY DELETE statement AVAILABLE
  • ARRAY INSERT statement AVAILABLE
  • Array operations AVAILABLE
  • ARRAY SCAN statement AVAILABLE
  • ARRAY SORT statement AVAILABLE
  • ARRAYATTR function AVAILABLE
  • Balancing the stack AVAILABLE
  • Built-in numeric equates AVAILABLE
  • Built-in string equates AVAILABLE
  • Built-in User Defined Types AVAILABLE
  • CALL DWORD statement AVAILABLE
  • CALLSTK statement AVAILABLE
  • CALLSTK$ function AVAILABLE
  • CALLSTKCOUNT function AVAILABLE
  • CBYT function AVAILABLE
  • Characters, Strings, and Unicode AVAILABLE
  • ChrToOem$ function AVAILABLE
  • ChrToUtf8$ function AVAILABLE
  • CLIP$ function AVAILABLE
  • CLIPBOARD GET BITMAP statement AVAILABLE
  • Command Summary AVAILABLE
  • Constants and Literals AVAILABLE
  • Converting a .RC to a .RES AVAILABLE
  • Creating a Dynamic Link Library AVAILABLE
  • Creating a Static Link Library AVAILABLE
  • DATACOUNT function AVAILABLE
  • DATE$ system variable AVAILABLE
  • DAYNAME$ function AVAILABLE
  • DEC$ function AVAILABLE
  • DECR statement AVAILABLE
  • DEFBYT statement AVAILABLE
  • Defining Constants AVAILABLE
  • DIR$ CLOSE statement AVAILABLE
  • Dll example AVAILABLE
  • ERL system variable AVAILABLE
  • ERL$ function AVAILABLE
  • ERR system variable AVAILABLE
  • ERR system variable AVAILABLE
  • Evaluating a variable AVAILABLE
  • EXE.Inst member AVAILABLE
  • FASTPROC/END FASTPROC statements AVAILABLE
  • File Commands AVAILABLE
  • GET$ statement AVAILABLE
  • GET$$ statement AVAILABLE
  • GOTO statement AVAILABLE
  • IMPORT ADDR statement AVAILABLE
  • INCR statement AVAILABLE
  • Internal representations of arrays AVAILABLE
  • ISFALSE operator AVAILABLE
  • Keyword Reference AVAILABLE
  • LBOUND function AVAILABLE
  • LET statement (with Types) AVAILABLE
  • Line numbers and Labels AVAILABLE
  • MAT statement AVAILABLE
  • ME pseudo-variable AVAILABLE
  • METRICS function AVAILABLE
  • Misc Operations AVAILABLE
  • MKBYT$ function AVAILABLE
  • Modal vs. Modeless AVAILABLE
  • MONTHNAME$ function AVAILABLE
  • MYBASE pseudo-variable AVAILABLE
  • NUL$ function AVAILABLE
  • Numeric Operations AVAILABLE
  • OBJRESULT$ function AVAILABLE
  • OemToChr$ function AVAILABLE
  • Operating System AVAILABLE
  • Parameters passed by reference or by copy AVAILABLE
  • Passing arrays AVAILABLE
  • Passing dynamic strings AVAILABLE
  • Passing parameters AVAILABLE
  • PATHNAME$ function AVAILABLE
  • PATHSCAN$ function AVAILABLE
  • Pointers to arrays AVAILABLE
  • Pointers to arrays with dual indexes AVAILABLE
  • PREFIX/END PREFIX statements AVAILABLE
  • PUT$ statement AVAILABLE
  • PUT$$ statement AVAILABLE
  • Reading and writing data AVAILABLE
  • REGEXPR statement AVAILABLE
  • REGREPL statement AVAILABLE
  • REM statement AVAILABLE
  • RESOURCE$ function AVAILABLE
  • Saving the Source Code AVAILABLE
  • SIZEOF function AVAILABLE
  • SLL example AVAILABLE
  • Storage requirements and restrictions AVAILABLE
  • Storage requirements and restrictions AVAILABLE
  • Text Commands AVAILABLE
  • The Stack AVAILABLE
  • Time Commands AVAILABLE
  • TIME$ system variable AVAILABLE
  • TRACE statement AVAILABLE
  • UBOUND function AVAILABLE
  • Unions AVAILABLE
  • Using ESP and EBP AVAILABLE
  • Utf8ToChr$ function AVAILABLE
  • Variables AVAILABLE
  • What is a Dll? AVAILABLE
  • What is an SLL? AVAILABLE
  • Why use Dlls? AVAILABLE

Total command/reference pages: 817 | ScharfBASIC command reference


Built-in Interfaces - ScharfBASIC Help

Built-in Interfaces

The compiler provides a set of built-in Interfaces, including:

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

ICONNECTIONPOINTCONTAINER

What are the parts of an object?

Are there other important "Buzz-Words"?

What does an Interface look like?

Back to command index


CLASS/END CLASS - ScharfBASIC Help

CLASS/END CLASS

Create the code and data for an

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CLASS name [ $GUID ] [COMMON] [OPTIMIZE] [AS COM | AS EVENT]
Class Method code blocks...
INSTANCE ClassName AS STRING
INTERFACE name $GUID [AS EVENT]
INHERIT IUNKNOWN
Method and Property code blocks...
END INTERFACE
EVENT SOURCE interface-name
END CLASS

Description

CLASS / END CLASS statements enclose the Interface implementation(s) and Instance variable declarations of a Class . METHOD and PROPERTY blocks contain the code to be executed on an object. INSTANCE statements define the variables which are unique to each instance of an object of this class.

The name and optional $GUID are supplied by the programmer to identify the class. By default, a class is considered private, so that the methods are accessible only from within the EXE or DLL where it is defined. The AS COM attribute makes the class available externally, to virtually any process which is COM -aware.

With a private class, the $GUID may be freely omitted, as ScharfBASIC can readily identify the class by name. With a published COM class, you should insert a specific GUID of your choice. If omitted, a random GUID will be created by the compiler, but it will change every time you compile the program. This will be difficult to synchronize with other programs which wish to identify and access your object.

COMMON

The optional COMMON descriptor may be included to specify that this class may be freely referenced by and between linked unit modules (Host/Main or SLL ). This has the added side effect of ensuring that the class will not be removed by #OPTIMIZE CODE ON .

AS EVENT

If a class is an Event Source (it generates events rather than handling events), one or more EVENT SOURCE statements are included to name the event interfaces. The event interfaces must be declared and implemented separately. An event is generated by executing a RAISEEVENT statement or an OBJECT RAISEEVENT statement in the class. If a class is an Event Handler (it contains code to handle an event generated by an Event Source), the AS EVENT attribute must appear on the CLASS statement and each INTERFACE statement. An Event Handler is also known as an "Event Sink", using COM terminology.

OPTIMIZE

With code optimization enabled ( #OPTIMIZE CODE ON) , ScharfBASIC removes code for subs and functions which are not called. Where possible, this technique is even applied to individual methods and property methods within classes.

Of course, if an object variable is transferred out of the current module (to another EXE/SLL/DLL), there is no way to determine (at compile-time) which methods may be called on it at run-time, so none can be safely removed. COM, COMMON, and EVENT classes allow variables to be transferred out of the module, so they block removal of any code in the class.

The OPTIMIZE descriptor allows you to control this code optimization to a high degree. If you specify the OPTIMIZE option, you are stating that no object variables on this class will be transferred out of the module. Therefore, ScharfBASIC is free to remove any code in the class which is not referenced. This is a powerful tool which can allow you to substantially reduce the size of your program.

The OPTIMIZE rules can be summarized:

See Also

  • #OPTIMIZE
  • EVENT SOURCE
  • EVENTS
  • INSTANCE
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • Just what is COM?
  • METHOD
  • PROPERTY
  • RAISEEVENT
  • What is an object, anyway?


CLSID$ - ScharfBASIC Help

CLSID$

Return a 16-byte

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = CLSID$( ProgramID$ )

Description

A CLSID string is a 128-bit (16-byte) binary string representing the GUID or UUID of a COM object/component. A CLSID string is not in a human-readable format.

You can convert textual ID name of a COM object/component into a CLSID string with the CLSID$ function. CLSID examines the system registry in order to determine the CLSID string associated with the ProgramID$ string.

The ProgramID$ parameter is not case-sensitive, so "MSAGENT.CONTROL.2", "MSAgent.Control.2" and "msagent.control.2" all refer to the same COM object/component. If the ProgramID$ cannot be found, or if any error occurs during the lookup and conversion process, CLSID$ will not set the ERR system variable, but will return an empty string.

To convert the binary CLSID string into human-readable GUID/UUID format, use the GUIDTXT$ function. CLSID$ is the complement to the PROGID$ function.

ScharfBASIC programmers rarely, if ever, need to deal with CLSID strings in order to utilize a COM object or component.

The return string may be assigned to a dynamic string , fixed-length or nul-terminated string (at least 16 bytes long), or (typically) a GUID variable. See DIM for more information.

See Also

  • DIM
  • GUID$
  • GUIDTXT$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISNOTHING
  • ISOBJECT
  • LET (with Objects)
  • OBJECT
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • What does a Class look like?
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x204a54
call   0x203184
call   0x201e9b
lea   ebx,[ebp-0xa4]
call   0x203107
call   0x203038


Collection Objects - ScharfBASIC Help

Collection Objects

The following operations provides a convenient way to refer to a related group of items:

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

ILinkListCollection.ADD

An item is added to the end of the LinkListCollection.

ILinkListCollection.CLEAR

All items are removed from the LinkListCollection.

ILinkListCollection.COUNT

Returns the number of data items currently contained in the LinkListCollection.

ILinkListCollection.FIRST

Sets the index to the first item and returns the previous value.

ILinkListCollection.INDEX


Creating a DISPATCH Object - ScharfBASIC Help

Creating a DISPATCH Object

DISPATCH objects are easy to create. The technique is virtually identical to that for direct interfaces . You must first declare the object variable -- if you wish to use " Late Binding ", you'll use

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

LOCAL DispVar AS IDISPATCH

LET DispVar = NEWCOM "DispProgID"

If you wish to use " ID Binding ", you'll use the interface name from your Interface IDBIND structure.

LOCAL DispVar AS MyDispIfaceName

LET DispVar = NEWCOM "DispProgID"

If all went well, you now have an object ! (And an object reference in your object variable). Of course, it's always a good idea to use the ISOBJECT ( DispVar ) function to be certain that the operation was a success. If it failed, an attempt to use the object variable could cause a fatal exception.

What is an object, anyway?


Enumerating Collections - ScharfBASIC Help

Enumerating Collections

A collection is simply a set or group of items, where each can be accessed through its own Interface . For example, Microsoft Word? can have multiple documents open at the same time, and it can provid

Kind | Structure
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Therefore, enumerating a collection is simply a matter of determining the number of items in the collection, looping through and retrieving the appropriate information for one or more Interface members of the collection.

We'll start off with the Visual Basic syntax and show how to perform the same kind of task with ScharfBASIC.

Visual Basic syntax for enumerating a collection looks something like this:

Dim Item As InterfaceItem

Dim Items As InterfaceItemsCollection

For Each Item In Items

'do something with the Item.member Method/Property, e.g.,

var$ = Item.StringProp


EVENT SOURCE - ScharfBASIC Help

EVENT SOURCE

Declare an

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

EVENT SOURCE InterfaceName

Description

With objects , normally a client module calls a server module to perform specific operations as they are needed. However, in many situations, it's convenient and efficient for a server to notify its client of a condition or event immediately, without forcing the client to inquire about the status. At the appropriate time, the server calls back to a client method, passing information via the method parameters. This is the exact opposite of normal communication, because the server module is now calling the client module. In effect, the client is acting as a server for the purpose of handling these events. In the world of objects, a server which can call such "Event Methods" is said to offer a " Connection Point ". A Connection Point can be used with COM objects or internal objects. Further, it may use either a direct interface or the DISPATCH interface . Event methods may take parameters, but may not return a result.

Each server class created by ScharfBASIC may offer up to four event interfaces. A client module may subscribe to any or all of these event interfaces. When it's time for the server object to notify the client of an event, the RAISEEVENT statement is used. For the Dispatch interface, OBJECT RAISEEVENT is used instead. RAISEEVENT may only appear within a class which declares the Event Source interface.

The client must initiate a connection to the server with EVENTS FROM statement, and disconnect when done with EVENTS END statement.

A Connection Point may be attached to one Event Method, multiple Event Methods, or no Event Method at all. Whenever a RAISEEVENT statement or OBJECT RAISEEVENT statement is executed, all Event Methods attached to the source object are called, one after another. There is no guarantee of the sequence of the calls, and you must consider the possibility that RAISEEVENT with a ByRef parameter could change the value of a parameter variable before any particular Event Method is executed.

InterfaceName

Specifies the "Event Source" Interface name. If InterfaceName is DISPATCH, you can reference it with the OBJECT RAISEEVENT statement -- otherwise, regular Method references are used.

See Also

  • EVENTS
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • Just what is COM?
  • METHOD
  • OBJECT RAISEEVENT
  • RAISEEVENT
  • What are Connection Points?


EVENTS - ScharfBASIC Help

EVENTS

Attach or detach an

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIM oSource AS InterfaceName
DIM oEvent AS EventInterface
LET oSource = NEWCOM CLSID $ClassId
LET oEvent = CLASS "EventClass"
EVENTS FROM oSource CALL oEvent
[ statements ]
EVENTS END oEvent

Description

In the above source code sample, oEvent is an object variable which references an event handler object, and oSource is an object variable which references an event source object which generates events.

The EVENTS FROM statement attaches event handler code to an event source object variable. The object variable oEvent must be declared as a supported event interface, while ?EventClass" specifies the class which implements the event handler code. The object variable oSource specifies the event source. EVENTS END detaches the event handler from the event source.

Generally speaking, a server object "sources" events, and a client object "handles" events by supplying a METHOD which is called by the server to perform a user-defined notification. This event handler is code in the client object, which is sometimes referred to as an "event sink" (analogous to the electrical engineering terms source/sink).

One or more clients may choose to "subscribe" to events from a server object by executing the EVENTS FROM statement. The subscription is terminated by execution of the EVENTS END statement. When the server executes RAISEEVENT or OBJECT RAISEEVENT , all clients which have unsubscribed to these events are called. ScharfBASIC servers support up to 32 concurrent client subscribers per server object.

Event sources and event handlers may be used within a single module, or through COM services supplied by the Windows operating system.

See Also

  • CLASS
  • EVENT SOURCE
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • Just what is COM?
  • OBJECT RAISEEVENT
  • RAISEEVENT
  • What is an object, anyway?
  • What are Connection Points?


GUIDTXT$ - ScharfBASIC Help

GUIDTXT$

Return a 38-byte human-readable Globally Unique Identifier (

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

id$ = GUIDTXT$( guid16$ )

Description

The GUIDTXT$ function takes a string parameter guid16$ that must be exactly 16-bytes long (and represents a 128-bit GUID string), and returns a 38-byte GUID text string. guid16$ is usually a GUID variable but may also be a dynamic or fixed-length string, etc.

The GUIDTXT$ function is the logical complement to the GUID$ function.

Restrictions

If any errors are encountered, GUIDTXT$ returns a null (zero-length) string instead of the 38-byte GUID text string.

See Also

  • DIM
  • CLSID$
  • GUID$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • LET (with Objects)
  • OBJECT
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • What is an object, anyway?


ID Binding - ScharfBASIC Help

ID Binding

So, how can we speed things up?

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Well, the worst bottleneck is the name lookup, and that's something we can deal with! We usually know all the METHOD definitions at compile-time. If we can tell the compiler the DispID's and the parameter info at compile-time, one whole step can be eliminated! That's called ID-BINDING of the Dispatch Interface. We create a simple IDBIND Interface , which is written like this:

INTERFACE IDBIND MyDispIfaceName

MEMBER CALL Method1<77> (WideVal AS LONG, WideText AS WSTRING)

MEMBER CALL Method2<78> ()

MEMBER CALL MethodX<79> ()

ScharfBASIC can use this IDBIND Interface to create faster Dispatch execution. Just create this structure, and place it in your source code prior to any references. Then, when you create an object variable, just use the IDBIND Interface Name instead of DISPATCH:

LOCAL DispVar AS MyDispIfaceName

LET DispVar = NEWCOM "DispProgID"


IDISPINFO pseudo-object - ScharfBASIC Help

IDISPINFO pseudo-object

Sets and returns additional information about certain

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

info& = IDISPINFO.CODE
info& = IDISPINFO.CONTEXT
info$ = IDISPINFO.DESC$
info$ = IDISPINFO.HELP$
info$ = IDISPINFO.SOURCE$
IDISPINFO.CLEAR
IDISPINFO.SET code& [, source$ , desc$ , help$ , context& ]

Description

GET Properties

IDISPINFO.CODE

When OBJRESULT is %DISP_E_EXCEPTION, this Get Property returns a long integer value which represents a more specific error code. If the value is less than 65536, it is known as a WCODE, which is usually defined by the application when found in 32-bit or 64-bit Windows. Much more common are the larger values known as an SCODE. These are usually defined by Windows, although application defined values are allowed. The most common are:

%E_UNEXPECTED = &H8000FFFF&

%E_NOTIMPL = &H80004001&

%E_NOINTERFACE = &H80004002&

%E_POINTER = &H80004003&

%E_ABORT = &H80004004&

%E_FAIL = &H80004005&

%E_ACCESSDENIED = &H80070005&

%E_HANDLE = &H80070006&

%E_OUTOFMEMORY = &H8007000E&

%E_INVALIDARG = &H80070057&

IDISPINFO.CONTEXT

When OBJRESULT is %DISP_E_EXCEPTION, this Get Property returns a long integer value which is the context of the topic within the help file (IDISPINFO.HELP$). This property is only valid if IDISPINFO.HELP returns a valid string .

IDISPINFO.DESC$

When OBJRESULT is %DISP_E_EXCEPTION, this Get Property returns a string containing a textual, human-readable description of the status. It is intended to be read by the customer. If no description is available, a null, zero-length string is returned.

IDISPINFO.HELP$

When OBJRESULT is %DISP_E_EXCEPTION, this Get Property returns a string containing drive, path, and filename of a Help File with more information about this particular status code. If no help is available, a null, zero-length string is returned.

IDISPINFO.PARAM

When OBJRESULT is either %DISP_E_PARAMNOTFOUND or %DISP_E_TYPEMISMATCH, this Get Property returns a long integer value which represents the parameter number of the first parameter which failed to match the requirements needed. The value is indexed to zero, which is the standard numbering convention for Dispatch parameters. The first parameter is 0, the second is 1, and so on.

IDISPINFO.SOURCE$

When OBJRESULT is %DISP_E_EXCEPTION, this Get Property returns a string containing a textual, human-readable description of the source of the exception. Typically, this will be the application name. If no source is available, a null, zero-length string is returned.

SET Properties

IDISPINFO.CLEAR

Clears all properties which may have been set by prior execution of IDISPINFO.SET in this thread.

IDISPINFO.SET

This statement may be executed in a METHOD or PROPERTY on a Dual Interface, so that the calling code can obtain additional information about Dispatch exception conditions. These five data items are passed back to the caller in the EXCEPINFO structure, so that they can be retrieved with IDISPINFO GET Properties, or other functions in other programming languages. This data is only available when using the Dispatch interface. It is unavailable to Direct Methods . The first parameter ( code& ) is required, and must be identical to the value which you return with METHOD OBJRESULT or PROPERTY OBJRESULT. The actual OBJRESULT will then be changed to %DISP_E_EXCEPTION, so that the caller will know that this data must also be retrieved. Note that the last four parameters are optional.

Restrictions

You should only execute the GET PROPERTY methods listed above when OBJRESULT returns the specified status code. In any other case, IDISPINFO Get Properties will return zero or a null string.

See Also

  • OBJECT
  • OBJRESULT
  • OBJRESULT$
  • What is an object, anyway?
  • What is DISPATCH?


INTERFACE / END INTERFACE Block (Direct) - ScharfBASIC Help

INTERFACE / END INTERFACE Block (Direct)

Declare a direct

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

INTERFACE interfacename [$GUID] [AS EVENT] [AS HIDDEN]
{METHOD | PROPERTY} name [([ arguments ])] [AS type ]]
END INTERFACE

Description

The first line in an Interface Block must be an INHERIT statement. INHERIT specifies the base class or the user interface upon which this new interface is built. It defines the base methods available, the optional user methods which are available, and the calling conventions which will apply. In the current version of ScharfBASIC, the following may be used:

INHERIT IUnknown

This defines a Custom Interface with only direct access to the interface methods . OBJRESULT (an hResult value) is not supported. Return values are typically passed in CPU/FPU registers, just like a user defined FUNCTION . This is the format most often used for internal objects, as it offers access to more data types than the other forms. You may substitute the word CUSTOM for IUNKNOWN, as they are synonyms.

INHERIT IAutomation

This defines an Automation Interface with only direct access to the interface methods. OBJRESULT (an hResult value) is always supported. Return values are passed as a hidden, last parameter (automatically, by ScharfBASIC). Parameters and return values are limited to COM data types. A User Defined Type used as a return value or parameter will be converted to a BYVAL DWORD. This is the format most often used for COM objects which do not require access to the IDispatch interface. You may substitute the word AUTOMATION for IAUTOMATION, as they are synonyms.

INHERIT IDispatch

This defines a Dual Interface, which offers both direct access and Dispatch access to the interface methods. OBJRESULT (an hResult value) is always supported. This interface inherits from IAutomation, so the calling conventions are identical to IAutomation when used for direct access. You may substitute the word DUAL for IDISPATCH, as they are synonyms.

INHERIT < UserClass >, < UserInterface >

This defines an inherited user-written interface, so the new interface implements the base class IUnknown, IDispatch, etc.) and all of the Methods and Properties, as well. It's necessary to specify both the class and the interface name to be inherited, because it's possible to have multiple implementations of any particular interface.

INTERFACE / END INTERFACE statements enclose the METHOD and PROPERTY definitions which constitute a class. There are two forms of the INTERFACE / END INTERFACE block. When it appears outside of a CLASS block, it is simply a declaration of the interface, much like DECLARE statements are used for functions:

INTERFACE name [$GUID] [AS EVENT]

INHERIT IUnknown

METHOD MyMethod(xyz AS LONG)

PROPERTY GET MyProp() AS STRING

END INTERFACE

The above form is used to declare an interface which is implemented in another .EXE or .DLL, but will be accessed here through COM services. It may also be used for added self-documentation of internal classes. If it appears within a CLASS block, it is the implementation of the Methods/Properties for the Class. The interface implementation must precisely match any prior interface declaration.

CLASS name [$GUID] [AS COM]

INTERFACE name [$GUID] [AS HIDDEN]

INHERIT iUnknown

METHOD MyMethod(xyz AS LONG)

[ statements ]

END METHOD

PROPERTY GET MyProp() AS STRING

[ statements ]

END PROPERTY

END INTERFACE

END CLASS

The name and optional $GUID are supplied by the programmer to uniquely identify the interface. The first entry in every INTERFACE block must be the base class upon which it is built. Every interface must ultimately inherit from IUnknown, which is a requirement.

By default, a class is considered private, so that the methods are accessible only from within the EXE or DLL where it is defined. The AS COM attribute to the CLASS statement makes the class available externally, to virtually any process which is COM-aware.

The optional AS HIDDEN attribute to the INTERFACE statement prevents the interface from being documented when the type library is created. When marked as hidden, any and all uses of the interface are hidden, even if they appear in multiple classes.

With an internal class, the $GUID on CLASS and INTERFACE statements may be freely omitted, as ScharfBASIC can readily identify them by name. With a published COM class, you should insert a specific GUID of your choice. If omitted, a random GUID will be created by the compiler, but it will change every time you compile the program. This will be difficult to synchronize with other programs which wish to identify and access your object.

The following code defines a dual interface whose methods are available for both direct access and Dispatch access. This is the form you will typically use for COM objects, since it offers the best compatibility with varied client modules.

INTERFACE DispatchIface

INHERIT IDispatch

METHOD MethodDef()

[ statements ]

END METHOD

END INTERFACE

You should note that the IDispatch interface itself inherits from IUnknown, so that both interfaces are ultimately available. As an additional required base class, the IDispatch declaration is built into the ScharfBASIC Compiler.

Every method and property in a dual interface needs a positive, long integer value to identify it. That integral value is known as a DispID (Dispatch ID), and it's used internally by COM services to call the correct function on a Dispatch interface. You can specify a particular DispID by enclosing it in angle brackets immediately following the Method/Property name in an Interface definition block.

INTERFACE DualIface

INHERIT IDispatch

METHOD MethodOne <76> ()

METHOD MethodTwo <77> ()

END INTERFACE

If you don't specify a DispID, ScharfBASIC will assign a random value for you. This is fine for internal objects, but may cause a failure for published COM objects, as the DispID could change each time you compile your program. It is particularly important that you specify a DispID for each Method/Property in a COM Event Interface.

Inherited User-Written Interfaces

ScharfBASIC offers Implementation Inheritance of user-written interfaces. That is, an interface can inherit all of the code in the methods and properties of a selected interface. You can then add additional methods and properties to the new interface. When you inherit a user-written interface, you must specify both the class name and the interface name, since COM allows you to have multiple implementations of any particular interface.

You can override an inherited method or property by coding a replacement which is preceded by the word OVERRIDE. It's possible to one or many override procedures, but they must appear in the same sequence as the ones they replace.

CLASS MyClass

INTERFACE MyFace

INHERIT IDispatch

METHOD aaa()

' code...

END METHOD

METHOD bbb()

' code...

END METHOD

METHOD ccc()

' code...

END METHOD

METHOD ddd()

' code...

END METHOD

END INTERFACE

END CLASS

CLASS TheClass

INTERFACE TheFace

INHERIT MyClass, MyFace

OVERRIDE METHOD bbb()

' new code...

END METHOD

OVERRIDE METHOD ddd()

' new code...

END METHOD

METHOD xxx()

' code...

END METHOD

END INTERFACE

END CLASS

Note that in the above example, the new interface "TheFace" first inherits all four methods from "MyFace" (aaa,bbb,ccc,ddd). However, because of the OVERRIDE statements, both bbb() and ddd() are replaced by newer versions of the methods. Because of the nature of Virtual Function Tables, the OVERRIDE procedures must remain in the original sequence. That is, bbb() must precede ddd(), and both must precede any added methods, such as xxx().

Because of the nature of code replacement necessary in implementation inheritance, the interface to be inherited must always physically precede the new, child interface.

See Also

  • INTERFACE (IDBind)
  • CLASS
  • INSTANCE
  • ISINTERFACE
  • LET (with Objects)
  • ME
  • METHOD
  • MYBASE
  • PROPERTY
  • What does an Interface look like?
  • What is inheritance?


INTERFACE/END INTERFACE block (Dispatch) - ScharfBASIC Help

INTERFACE/END INTERFACE block (Dispatch)

Declare a

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

INTERFACE IDBIND interfacename
MEMBER {CALL | GET | SET | LET} membername < dispid > ( [[OPTIONAL
[IN | OUT | INOUT]] paramname < dispid > [AS type ] [,...]] )
[AS { vartype | interface }]
[...]
END INTERFACE

Description

In order to provide IDBinding services, ScharfBASIC must be able to pre-construct the references to the DISPATCH COM interface members at compile-time. Without an interface definition block, only late-binding at run-time would be possible. Late-binding is less efficient than IDBinding.

You may list every Method/Property in the interface, or just the ones that are referenced in the code. They can appear in any sequence. Member names may contain (normally) reserved keywords such as INPUT or KILL , etc

The most important aspect of an interface block is that it clearly associates a dispid with the each Method/Property name. Named parameters in the paramname list also require an appropriate dispid value, as does any Property which returns an object to be used in a nested object reference. All dispid values must be enclosed in angle brackets (< and >), and may be expressed as hexadecimal or decimal numeric literals.

You can look up the dispid values of COM servers using an Object Browser , or by reading your object documentation. You can even insert additional information about the types and return value for your own reference, even though the compiler does not use them.

Previous versions of ScharfBASIC compilers used an older style syntax of "INTERFACE DISPATCH interfacename " for this structure. It was updated to better reflect the nature of the description. While the older syntax will be recognized in this version, we suggest you update the word DISPATCH to IDBIND soon.

Restrictions

If the compiler cannot resolve the interface name definition specified in a DIM or LET statement, a compile-time error is generated accordingly.

interfacename must not be a ScharfBASIC keyword. If a keyword conflict arises, the addition of an arbitrary prefix is acceptable. For example, INTERFACE IDBIND Shell() could be changed to INTERFACE IDBIND MyShell() and ScharfBASIC will still resolve the interface correctly.

Method/Property membername items may freely use ScharfBASIC keywords without concern for conflicts with normal code syntax. For example, MEMBER CALL Open() is a valid syntax for an interface method.

See Also

  • DIM
  • ID Binding
  • INTERFACE (Direct)
  • ISINTERFACE
  • LET (with Objects)
  • Late Binding
  • LET (with Variants)
  • OBJACTIVE
  • OBJECT
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • What is an object, anyway?
  • What is DISPATCH?


IPowerThread.Close method - ScharfBASIC Help

IPowerThread.Close method

A thread

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

< ObjectVar >. membername ( params )
RetVal = < ObjectVar >. membername ( params )
< ObjectVar >. membername ( params ) TO ReturnVariable

Description

With the advent of multi-core CPU's and multi-CPU computers, it's clearly desirable to encapsulate all of the information about a particular thread in a single component. We recommend that all new code use THREAD OBJECTS exclusively, rather than the Thread Code Group . Thread objects provide much greater control, and much better thread parameter handling for the programmer.

IPowerThread Methods

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

METHOD CLOSE() <2>

Releases the thread handle of this thread. Note that it does not stop a thread if it is still running; it simply releases the thread handle (i.e., the resources used to track the thread).

Thread handles should not be released until there is no further need to use other thread methods or properties. If a thread does not need to be monitored, its handle can be released immediately. The thread resources will be freed automatically when the thread terminates naturally.

THREADCOUNT continues to report a thread tally that will include threads whose handle has already been released. A thread ID value may not be used interchangeably with a thread handle value.

METHOD EQUALS( ObjectVar AS InterfaceName ) AS Long <3>

Compares the parameter ObjectVar to determine if it references the same object as this object. If they both reference the same object, true (-1) is returned; if not, false (0) is returned.

METHOD HANDLE() AS Long <4>

Retrieves the handle of the thread for use with Windows API functions.

METHOD ID() AS Long <5>

Retrieves the ID of the thread for use with Windows API functions.

METHOD ISALIVE() AS Long <6>

Checks the thread to see if it is currently "alive". If the thread has been launched, but has not yet ended, the value true (-1) is returned; if not, the value false (0) is returned.

METHOD JOIN( ThreadObjectVar AS InterfaceName , TimeOutVal AS Long) <7>

Waits for the thread referenced by ThreadObjectVar to complete before execution of this thread continues. TimeOutVal specifies the maximum length of time to wait, in MilliSeconds. If TimeOutVal is zero (0), the time to wait is infinite.

METHOD LAUNCH(ByRef Param as UDT ) <8>

LAUNCH begins execution of the thread, passing parameter data to it. Since the thread is hosted by an object, it is only fitting that the parameter data be contained in the most robust form, another object.

THREADPARAM is a mandatory Instance variable which you must define in each thread class. It is normally declared as the interface name of your choice:

INSTANCE ThreadParam as MyInterface

When the thread begins, ScharfBASIC automatically creates a copy of the LAUNCH parameter, and assigns it to ThreadParam. Since it is stored in an Instance variable, it is visible to all of your code in your member methods, yet is kept private from the rest of the program. The use of an object as the parameter is the normally the best choice, as it allows virtually any number of data items to be contained.

In simpler cas es, you may choose to declare THREADPARAM as a pointer , Long Integer , or Dword . In that case, you must pass the launch parameter using a byval option, to override the expected object variable.

INSTANCE ThreadParam as LONG

MyThread.Launch(ByVal MyNumber&)

Of course, the Pointer parameter option can be used to pass a pointer to any variable, of any type. For example, it could be used to pass a used-defined type if that fits your needs:

INSTANCE ThreadParam AS MyType POINTER

THREAD METHOD MyMethod() AS LONG

xyz# = ThreadParam.member1

... other code

END METHOD

MyThread.Launch(ByVal VARPTR(MyType))

PROPERTY GET PRIORITY() AS Long <9>

Retrieves the priority value for this thread. The thread priority value is one of the following:

%THREAD_PRIORITY_IDLE = -15

%THREAD_PRIORITY_LOWEST = -2

%THREAD_PRIORITY_BELOW_NORMAL = -1

%THREAD_PRIORITY_NORMAL = 0

%THREAD_PRIORITY_ABOVE_NORMAL = +1

%THREAD_PRIORITY_HIGHEST = +2

%THREAD_PRIORITY_TIME_CRITICAL= +15

PROPERTY SET PRIORITY (LEVEL AS Long) <9>

Sets the Priority Value for this thread. The thread priority value must be one of the following:

%THREAD_PRIORITY_IDLE = -15

%THREAD_PRIORITY_LOWEST = -2

%THREAD_PRIORITY_BELOW_NORMAL = -1

%THREAD_PRIORITY_NORMAL = 0

%THREAD_PRIORITY_ABOVE_NORMAL = +1

%THREAD_PRIORITY_HIGHEST = +2

%THREAD_PRIORITY_TIME_CRITICAL= +15

METHOD RESULT() AS Long <10>

If the thread has ended, the result value returned by the THREAD METHOD is retrieved and returned to the caller. The result may be any integral value in the range of a long integer. However, you should avoid using the number &H103 (decimal 259), as that is the value used by Windows to signify that the thread is still running.

If the result is retrieved successfully, the OBJRESULT is set to %S_OK (0). If the thread has not ended, the value zero (0) is returned, and the OBJRESULT is set to %S_FALSE (1).

METHOD RESUME() AS Long <11>

Resumes execution of a suspended thread. The suspend count of the thread is decremented. When it reaches zero (0), execution of the thread resumes. If the resume is successful, the prior suspend count is returned; otherwise, -1 is returned.

A thread can suspend itself with SUSPEND (which increments the suspend count), but logically, cannot RESUME itself because it is not running at that time.

PROPERTY GET STACKSIZE() AS Long <13>

Retrieves the size of the stack for this thread. If the value returned is zero (0), the thread StackSize is the same as that of the main thread.

PROPERTY SET STACKSIZE(BYVAL Long) <13>

Sets the size of the stack for this thread to the value specified by the parameter. The value should always be specified in multiples of 64K (65536). PROPERTY SET must only be executed prior to thread execution with LAUNCH, or it will be ignored. If no PROPERTY SET STACKSIZE is executed, the size of the stack for the main thread will be used for this thread.

METHOD SUSPEND() AS Long <14>

Suspends execution of the thread. The suspend count of the thread is incremented. If the suspend was successful, the suspend count is returned; otherwise, -1 is returned.

If SUSPEND is executed prior to LAUNCH of the thread, the suspend count is incremented, and the subsequent LAUNCH is treated as a suspended launch. That is, all the necessary setup tasks are performed, but the thread is suspended just before execution of your THREAD METHOD begins. You can continue execution with RESUME.

A thread can suspend itself with SUSPEND (which increments the suspend count), but logically, cannot RESUME itself because it is not running while suspended.

METHOD TIMECREATE() AS Quad <16>

Retrieves the date and time-of-day of the thread creation, and returns it as a Quad Integer value. The internal format of the value is that of a FILETIME structure, so you can use the PowerTime object to convert it to a human readable format of Month/Day/Year/Time.

METHOD TIMEEXIT() AS Quad <17>

Retrieves the date and time-of-day of the thread exit, and returns it as a Quad Integer value. The internal format of the value is that of a FILETIME structure, so you can use the PowerTime object to convert it to a human readable format of Month/Day/Year/Time. If the thread has not yet exited, the return value is undefined.

METHOD TIMEKERNEL() AS Quad <18>

Retrieves the amount of time this thread has spent in kernel mode, and returns it as a Quad Integer value. The internal format of the value is that of a FILETIME structure, so you can use the PowerTime object to convert it to a human readable format.

METHOD TIMEUSER() AS Quad <19>

Retrieves the amount of time this thread has spent in user mode, and returns it as a Quad Integer value. The internal format of the value is that of a FILETIME structure, so you can use the PowerTime object to convert it to a human readable format.

Restrictions

Functions from the Thread Code Group and THREAD OBJECTS may co-exist in the same application. However, it is important that they not be intermixed when you reference one particular thread.

See Also

  • PowerTime
  • THREAD Code Group


IPowerTime.AddDays method - ScharfBASIC Help

IPowerTime.AddDays method

A PowerTime Object contains a date and time value, allowing easy calculations. The internal representation emulates the Windows FILETIME structure as a

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

An immediate use for the PowerTime Object is the built-in numeric equate %PB_COMPILETIME . Each time you compile your program, this equate is filled with the current date and time of the compilation in PowerTime binary format. You can use the PowerTIME Class to convert it to a text equivalent for use in your application.

LOCAL Built AS IPowerTime

LET Built = CLASS "PowerTime"

Built.FileTime = %PB_COMPILETIME

MSGBOX Built.DateString

MSGBOX Built.TimeString

POWERTIME Methods

AddDays <1> (ByVal Days& )

Adds the specified number of days to the value of this object. You can subtract days by using a negative number.

AddHours <2> (ByVal Hours& )

Adds the specified number of hours to the value of this object. You can subtract hours by using a negative number.

AddMinutes <3> (ByVal Minutes& )

Adds the specified number of minutes to the value of this object. You can subtract minutes by using a negative number.

AddMonths <4> (ByVal Months& )

Adds the specified number of months to the value of this object. You can subtract months by using a negative number.

AddMSeconds <5> (ByVal Milliseconds& )

Adds the specified number of milliseconds to the value of this object. You can subtract milliseconds by using a negative number.

AddSeconds <6> (ByVal Seconds& )

Adds the specified number of seconds to the value of this object. You can subtract seconds by using a negative number.

AddTicks <7> (ByVal Ticks& )

Adds the specified number of ticks to the value of this object. You can subtract ticks by using a negative number.

AddYears <8> (ByVal Years& )

Adds the specified number of years to the value of this object. You can subtract years by using a negative number.

DateDiff <11> ( PowerTime , Sign& , Years& , Months& , Days& )

The date part of the internal PowerTime object is compared to the date part of the specified external PowerTime object. The time-of-day part of each is ignored. The difference is assigned to the parameter variables you provide. Sign& is -1 if the internal value is smaller. Sign& is 0 if the values are equal. Sign& is +1 if the internal value is larger. The other parameters tell the difference as positive integer values. If parameters are invalid, an appropriate error code is returned in OBJRESULT .

DateString <12> (OPT ByVal LCID& ) AS String

Returns the Date component of the PowerTime object expressed as a

. The date is formatted for the locale, based upon the LCID& parameter. If LCID& is zero, or not given, the default LCID for the user is substituted.

DateStringLong <13> (OPT ByVal LCID& ) AS WString

Returns the Date component of the PowerTime object, expressed as a string, with a full alphabetic month name. The date is formatted for the locale, based upon the LCID& parameter. If LCID& is zero, or not given, the default LCID for the user is substituted.

Day <15> () AS Long

Returns the Day component of the PowerTime object. It is a

value in the range of 1-31.

DayOfWeek <16> () AS Long

Returns the Day-of-Week component of the PowerTime object. It is a numeric value in the range of 0-6 (representing Sunday through Saturday).

DayOfWeekString <17> (OPT ByVal LCID& ) AS WString

Returns the Day-of-Week name of the PowerTime object, expressed as a string (Sunday, Monday...). The day name is appropriate for the locale, based upon the LCID& parameter. If LCID& is zero, or not given, the default LCID for the user is substituted.

DaysInMonth <18> () AS Long

Returns the number of days which comprise the month of the date of the PowerTime object. This is a numeric value in the range of 28-31.

PROPERTY GET FileTime <20> () AS Quad

Returns a Quad-Integer value of the PowerTime object as a FileTime.

PROPERTY SET FileTime <20> (ByVal FileTime&& )

The FileTime Quad-Integer value specified by the parameter is assigned as the PowerTime object value.

Hour <21> () as Long

Returns the Hour component of the PowerTime object. It is a numeric value in the range of 0-23.

IsLeapYear <22> () as Long

Returns true / false (-1/0) to tell if the PowerTime object year is a leap year.

Minute <23> () as Long

Returns the Minute component of the PowerTime object. This is a numeric value in the range of 0-59.

Month <24> () as Long

Returns the Month component of the PowerTime object. This is a numeric value in the range of 1-12.

MonthString <25> () AS String

Returns the Month component of the PowerTime object, expressed as a string (January, February...).

MSecond <26> () as Long

Returns the millisecond component of the PowerTime object. This is a numeric value in the range of 0-999.

NewDate <27> (ByVal Year& , Opt ByVal Month& , Opt ByVal Day& )

The date component of the PowerTime object is assigned a new value based upon the specified parameters. The time component is unchanged. If parameters are invalid, an appropriate error code is returned in OBJRESULT.

NewTime <28> (ByVal Hour& , Opt ByVal Min& , Opt ByVal Sec& , Opt ByVal MSec& , Opt ByVal Tick& )

The time component of the PowerTime object is assigned a new value based upon the specified parameters. The date component is unchanged. If parameters are invalid, an appropriate error code is returned in OBJRESULT.

Now <29> ()

The current local date and time on this computer is assigned to this PowerTime object.

NowUTC <30> ()

The current Coordinated Universal date and time (UTC) is assigned to this PowerTime object.

Second <31> () as Long

Returns the Second component of the PowerTime object. This is a numeric value in the range of 0-59.

Tick <32> () as Long

Returns the Tick component of the PowerTime object. This is a numeric value in the range of 0-999.

TimeDiff <33> ( PowerTime , Sign& , Days& , OPT Hours& , OPT Minutes& , OPT Seconds& , OPT MSeconds&& , OPT Ticks&& )

The internal PowerTime object is compared to the specified external PowerTime object. The difference is assigned to the parameter variables you provide. Sign& is -1 if the internal value is smaller. Sign& is 0 if the values are equal. Sign is +1 if the internal value is larger. The other parameters tell the difference as positive integer values. If you wish to return the time difference in units smaller than days, fill the unwanted parameters with BYVAL 0 and they will be ignored. For example:

ThisObject .TimeDiff( ThatObject , Sign& , BYVAL 0 , BYVAL 0 , Minutes& )

In the above, if the difference was precisely one day, the value 1440 would be assigned to Minutes& (24 hours * 60 minutes). If parameters are invalid, an appropriate error code is returned in OBJRESULT.

TimeString <34> () AS String

Returns the Time component of the PowerTime object expressed as a string. The time is formatted as hh:mm AM/PM.

TimeString24 <35> () AS WString

Returns the Time component of the PowerTime object expressed as a string. The time is formatted as hh:mm in 24-hour notation.

TimeStringFull <36> () AS WString

Returns the Time component of the PowerTime object expressed as a string. The time is formatted as hh:mm:ss.mmm in 24-hour notation.

Today <38> ()

The current local date on this computer is assigned to this PowerTime object. This is suitable for applications that work with dates only.

ToLocalTime <39> ()

The PowerTime object is converted to local time. It is assumed that the previous value was in Coordinated Universal Time (UTC).

ToUTC <40> ()

The PowerTime object is converted to Coordinated Universal Time (UTC). It is assumed that previous value was in local time.

Year <42> () as Long

Returns the Year component of the PowerTime object as a numeric value.

Details

A PowerTime Object contains a date and time value, allowing easy calculations. The internal representation emulates the Windows FILETIME structure as a quad-integer . This value represents the number of 100-nanosecond intervals since January 1, 1601. A nanosecond is one-billionth of a second.

You create a PowerTime object the same way you create other objects , but using a predefined internal class and a predefined internal interface .

LOCAL MyTime AS IPowerTime

LET MyTime = CLASS "PowerTime"

Once you have created a PowerTime object, you can manipulate it using the member methods . The IPowerTime interface is DUAL -- member methods may be referenced using either Direct or Dispatch form.

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

An immediate use for the PowerTime Object is the built-in numeric equate %PB_COMPILETIME . Each time you compile your program, this equate is filled with the current date and time of the compilation in PowerTime binary format. You can use the PowerTIME Class to convert it to a text equivalent for use in your application.

LOCAL Built AS IPowerTime

See Also

  • DATE$
  • DAYNAME$
  • MONTHNAME$
  • TIME$


ISINTERFACE - ScharfBASIC Help

ISINTERFACE

Determine whether an

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

IfaceValid = ISINTERFACE( ObjectVar , InterfaceName )

Description

The object referenced by the parameter ObjectVar is tested to determine if the specified InterfaceName is supported. If so, the value true (-1) is returned. Otherwise, the value false (0) is returned.

See Also

  • CLASS
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • What is an object, anyway?


Just what is COM? - ScharfBASIC Help

Just what is COM?

COM is an acronym. It represents the words "Component Object Model".

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The short answer is that COM defines a way to communicate between modules of code. The slightly longer answer follows.

You should know that every object created or defined in ScharfBASIC is fully compatible with the COM specification. Many popular compilers are not able to make that claim accurately. The COM specification defines a standardized method of communication between modules of code (frequently called components ), regardless of the platform or the tool used to create them. COM components are reusable chunks of code and associated data, which may be accessed by other "COM-Aware" components and applications.

One of the most frustrating things about this technology has been the ever-changing list of buzz-words used to describe it. We've evolved through OLE, VBX, and OCX, to COM, ActiveX, and more. Though nuances of difference abound, the important thing to remember is that COM and ActiveX describe a means of accessing code and data located outside of the current module. COM+ refers to some extensions which are specific to Win2000, WinXP, and WinVista. Throughout this discussion, we'll use the terms COM Object and ActiveX Object to describe components: reusable chunks of code and associated data.

Prior versions of ScharfBASIC introduced client COM services, which were accessible through the COM DISPATCH interface. While the DISPATCH interface is very flexible and easy-to-use, that very flexibility adds a level of overhead which is unacceptable for many applications. This version of ScharfBASIC adds the capability to create and access COM objects through a DIRECT INTERFACE or a DISPATCH INTERFACE .

All objects in ScharfBASIC, COM or not, follow all the guidelines and implementation rules established for COM Objects. This simplifies usage by the programmer, yet adds no measurable overhead at run-time. ScharfBASIC encapsulates all the low-level details of the actual COM communication process. This provides a straightforward way to load and communicate with a COM component using BASIC syntax. You'll find that the ScharfBASIC object implementation is very efficient, with virtually no degradation of execution speed as compared to standard Subs and Functions .

What is an object, anyway?

What is a COM component?

How do you publish an object?


Late Binding - ScharfBASIC Help

Late Binding

The standard methodology of DISPATCH is called "Late Binding", because nothing is done in advance. No method definitions. No Interface signatures. You can pretty much just start writing code:

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

LOCAL DispVar AS IDISPATCH

LET DispVar = NEWCOM "DispProgID"

OBJECT CALL DispVar.Method1(x&, y$)

It's just that easy. The first line declares an object variable which assumes the DISPATCH interface , while the second line creates an object and assigns a reference to DispVar. The third line just executes a method on the new object.

The OBJECT statement is always used to execute methods on a DISPATCH interface. This differentiates it from direct access, so ScharfBASIC can handle your request in the appropriate manner.

It's important to note that this version of ScharfBASIC relaxes the strict type checking of Dispatch parameters. While DISPATCH interfaces require that all parameters and return values be passed as a VARIANT variable, this version of ScharfBASIC relaxes that requirement for you. You may substitute any COM -compatible variable, and ScharfBASIC will convert them automatically to and from Variant variables as an integral part of the OBJECT statement. How could it get easier?

So, how does this work internally?

Well, each method name is assigned a positive integer number as its Dispatch ID (or DispID), to differentiate it from the other methods. In a similar fashion, each parameter is numbered from 0 - n to identify each of them uniquely. When you execute a statement like:

OBJECT CALL DispVar.Method1(x&, y$)


LET statement (with Objects) - ScharfBASIC Help

LET statement (with Objects)

Assign an

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

[LET] objvar = object expression

Description

The LET Statement, and its implied form (without using the word LET), may be used to assign an object reference to an object variable. After you declare an object variable as a particular interface , you must create an object and or assign an object reference to it before you can use the objects members ( methods , properties , etc.).

If an object creation or assignment fails for any reason, the objvar is set to NOTHING . If this statement fails, no errors are generated, nor is an OBJRESULT set. You should test for success of the operation with ISOBJECT ( objvar ) before trying to use the object or execute its methods.

LET objvar = CLASS ClassName$

The term ClassName must be specified as a quoted string literal , which is the name of a class implemented within the program. Since the class is internal (the name is known at compile-time), you may not use a string variable or expression . Upon execution, a new object is created, and a reference to that object is assigned to the object variable objvar. The interface requested is determined by the original declaration of objvar. If InterfaceName is DISPATCH, you can reference it with the OBJECT statement -- otherwise, regular Method and Property references are used.

LET objvar = NEWCOM PrgID$

LET objvar = GETCOM PrgID$

LET objvar = ANYCOM PrgID$

This form of the LET statement is used to obtain an object reference external to the program using the COM facilities of Windows. If the requested object is in a DLL (in-process server), you will always use the NEWCOM option, as you're asking for a new object. If the request is successful, the object reference is assigned to the objvar .

If the requested object is in an EXE (out-of-process server), you may use any of the three options. If the director word NEWCOM is specified, a new instance of a COM application is created. With GETCOM, an interface will be opened on an existing, running application, which has been registered as the active automation object for its class. With ANYCOM, the compiler will first try to use an existing, running application if available, or a new instance if not.

The string expression ProID$ evaluates to a ProgID name on an external COM server. If the InterfaceName is DISPATCH, you can reference it with the OBJECT statement -- otherwise, regular Method and Property references are used instead.

LET objvar = NEWCOM CLSID ClassID$

LET objvar = GETCOM CLSID ClassID$

LET objvar = ANYCOM CLSID ClassID$

This form also obtains a COM object , just as the examples in the above section. There is always a one-to-one relationship between a ProgID and a CLSID (Class ID). An object can be identified by either of these tokens, as long as they are both available. In some instances, you may encounter an object which has no ProgID published. You can substitute the clause "CLSID ClassID$ " for the PrgID$ . It works exactly as the usual form above, except that it describes the requested object by its 16-byte GUID which is the CLSID (Class ID) of the object.

LET objvar = NEWCOM CLSID ClassID$ LIB DLLPath$

ScharfBASIC offers the unique ability to create and reference COM objects without any reference to the registry at all. As long as you know the CLSID (Class ID) and the file path/name of the DLL to be accessed, you can do so with no registry access at all. You don't need a special type of COM server. This technique can be used with any server, whether created by ScharfBASIC or another compiler. By using this method of object creation, there is simply no need for the server to be registered at all. That allows you to keep local copies of the COM servers you use, with no chance they will be altered or replaced by another application. You use the above form, where the clause "CLSID ClassID$ " identifies the 16-byte Class ID, and the clause "LIB DllPath$ " identifies the file path and file name of the COM Server. Once you've obtained the COM object reference in objvar , it is used exactly as you would with a traditional object.

LET objvar1 = objvar2

If both object variables have been declared as the same object type (the same interface name), the source variable ( objvar2 ) is copied to the destination variable ( objvar1 ), and the reference count of the object is incremented. If the object variables are of different object types, a new interface (of the type implied by objvar1 ) is opened on objvar2 , and a reference to it is assigned to objvar1 .

LET objvar = objmethod ( params )

It is assumed that the METHOD or GET PROPERTY specified by objmethod returns an object of the type of objvar . The objmethod is evaluated, and the object reference which it returns is assigned to objvar .

LET objvar = ME

This form may only be used within a METHOD or PROPERTY. A new interface (of the type implied by objvar ) is opened on the current object, and a reference to it is assigned to objvar .

LET objvar = NOTHING

This destroys an object variable, discontinuing its association with a specific object. This in turn releases all system and memory resources associated with the object when no more object variables refer to it.

LET objvar = vrnt

Attempts to open an interface of the specified class for objvar on the object of vrnt , and assigns a reference to objvar . It assumes that vrnt contains a reference to an object of type %VT_UNKNOWN or %VT_DISPATCH. If the desired interface can not be opened, the object variable objvar is set to NOTHING.

LET vrnt = objvar

This may be used to assign an object reference from an object variable to a variant variable. It attempts to open an IDispatch interface, else an IUnknown interface on the object of objvar , and assigns that reference to vrnt . Variant variables can not contain references to custom interfaces, only IDispatch or IUnknown. If the assignment is successful, VARIANTVT ( vrnt ) will return either %VT_UNKNOWN or %VT_DISPATCH. If it is unsuccessful, vrnt is set to %VT_EMPTY.

Previous versions of ScharfBASIC Compilers used the SET statement for creation of objects. LET now includes all the functionality of the old SET statement, so you should plan to remove all SET statements as soon as possible. This involves nothing more than changing every SET to LET, or simply deleting every SET.

See Also

  • LET
  • LET (with Variants)
  • LET (with Types)
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • Just what is COM?
  • ME
  • OBJECT
  • What is an object, anyway?


LET statement (with Variants) - ScharfBASIC Help

LET statement (with Variants)

Assign a value or an

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

[LET] VariantVar = variant expression
[LET] VariantVar = TypeVar AS STRING

Description

Although notoriously lacking in efficiency, Variant variables are commonly used as COM Object parameters due to their flexibility. They also prove valuable in a situation where a procedure must run properly with parameters of multiple data types (a Collection would be a good example). You can think of a Variant as a kind of container, which can hold a variable of most any data type, nu meric , string , object, or even a UDT or an entire array . This simplifies the process of calling procedures in a COM Object Server, as there is little need to worry about the myriad of possible data types for each parameter.

This flexibility comes at a great price in performance, so ScharfBASIC limits their use to data storage and parameters only. You may assign a numeric value, a string value, a UDT, an object, or even an entire array to a Variant with the LET statement, or its implied equivalent. In the same way, you may assign one Variant value to another Variant variable, or even assign an array contained in a Variant to a compatible ScharfBASIC array, or the reverse.

You may extract a scalar value from a Variant with VARIANT# (for numeric values), VARIANT$ (for ANSI byte strings or user-defined types), or VARIANT$$ (for wide Unicode strings). When you assign string data to a variant variable, ANSI strings are automatically converted to wide Unicode characters, as this is the accepted standard for variants. However, when you assign UDT data to a variant variable, it is stored as a dynamic string of bytes. When you retrieve that UDT data (with Variant$), ScharfBASIC understands the content and handles it accurately. However, other programming languages may not, so the use of this technique should be limited to ScharfBASIC applications.

LET VrntVar = vrntvar

This form duplicates the contents of one variant variable, assigning it to a second variant variable.

LET VrntVar = expression [AS vartype ]

The numeric or string expression is evaluated, and the result is stored in the variant variable. ScharfBASIC will choose an appropriate numeric or string data type to use. However, you can specify a preferred format by adding an optional AS vartype clause. This can be BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , CURRENCY , or WSTRING . Strings in a variant are always stored in wide Unicode , regardless of whether you add AS WSTRING or not. ScharfBASIC handles the conversion automatically, if it is needed.

In prior versions of ScharfBASIC, the term AS STRING was interpreted to mean AS WSTRING for wide Unicode. However, with the new support for Unicode data types, this can no longer be allowed. All references to AS STRING with variants must be changed to AS WSTRING.

LET VrntVar = TypeVar AS STRING

The data contained in the User-Defined Type variable (UDT) is stored in the variant variable. It is stored internally as a dynamic string of bytes (vt_bstr). When you retrieve that UDT data (with Variant$), ScharfBASIC understands the content and handles it accurately. However, other programming languages may not understand this technique, so it should generally be limited to ScharfBASIC applications.

In prior versions of ScharfBASIC, the AS STRING clause was not a requirement, as it is currently. Although it represents a change, it was a necessary restriction to confirm that the conversion to string is your intention.

LET VrntVar = EMPTY

The variant variable is set to %VT_EMPTY, which means it contains no value of any kind.

LET VrntVar = ERROR numr

This form assigns a specific COM error number, which is usually a COM specific error, such as %E_NOINTERFACE, etc.

LET VrntVar = array()

An entire ScharfBASIC array is assigned to a variant variable. In the case of a string array , ScharfBASIC automatically handles Unicode conversions needed for the COM specification. Array assignment is limited to the following data types: BYTE, WORD, DWORD, INTEGER, LONG, QUAD, SINGLE, DOUBLE, CURRENCY, or STRING, as Windows does not support all ScharfBASIC data forms.

LET array() = vrntvar

An entire array is assigned from a variant variable to a ScharfBASIC array. In the case of a string array , ScharfBASIC automatically handles Unicode conversions. You can not assign an array with more than eight dimensions to a ScharfBASIC array.

LET VrntVar = BYREF variable

This form is used to allow a variant to contain a typed pointer to a specific variable. Any changes to the variant will cause the variable to be changed, as it is the target of the pointer. The variable may be of any data type which is supported by variants and COM objects: Byte, Word, Dword, Integer, Long, Quad, Single, Double, Currency, Variant, String, and WString. If you attempt to use an unsupported variable type (like Extended , Bit , STRINGZ , etc.), ScharfBASIC will generate an error 482 (Data Type Mismatch). Further, you may not use a register variable (automatic or explicit), or an error 491 (Invalid Register Variable) will be generated. Note that strings used with COM objects are expected to be in Unicode format, rather than ANSI. The ACODE$ and UCODE$ functions may be used to convert the strings as necessary. You should exercise caution with a BYREF ANSI string, as it may not be recognized accurately by other code which expects only Unicode strings.

LET objvar = vrnt

Attempts to open an interface of the specified class for objvar on the object of vrnt , and assigns a reference to objvar . It assumes that vrnt contains a reference to an object of type %VT_UNKNOWN or %VT_DISPATCH. If the desired interface can not be opened, the object variable objvar is set to NOTHING. You can test for success/failure with the ISOBJECT ( objvar ) function.

LET vrnt = objvar

This may be used to assign an object reference from an object variable to a variant variable. It attempts to open an IDispatch interface, else an IUnknown interface on the object of objvar , and assigns that reference to vrnt . Variant variables can not contain references to custom interfaces, only IDispatch or IUnknown. If the assignment is successful, VARIANTVT ( vrnt ) will return either %VT_UNKNOWN or %VT_DISPATCH. If it is unsuccessful, vrnt is set to %VT_EMPTY.

See Also

  • Just what is COM?
  • LET
  • LET (with Objects)
  • LET (with Types)
  • VARIANT#
  • VARIANT$
  • VARIANTVT


OBJACTIVE - ScharfBASIC Help

OBJACTIVE

Return

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

lResult& = OBJACTIVE( prgid$ )

Description

Return value: TRUE / FALSE as an indication of the running state of an initialized COM object (EXE based). Syntax lResult& = OBJACTIVE( prgid$ )

OBJACTIVE can provide information that may prove useful in determining whether to use the NEWCOM or GETCOM options with the LET (with Objects) statement. OBJACTIVE may only be used on COM objects that are in EXE format, not DLL/OCX/etc. In the latter case, OBJACTIVE returns FALSE (0).

prgid$

The registered program ID string for the COM object. For example, "Word.Application.8", or a version-independent program ID such as "Word.Application". A valid program ID string can be obtained from a 16-byte class ID string using the PROGID$ function, or derived from a 38 character GUID string using PROGID$ and GUID$ .

See Also

  • DIM
  • CLSID$
  • GUID$
  • GUIDTXT$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISNOTHING
  • ISOBJECT
  • Just what is COM?
  • LET (with Objects)
  • OBJECT
  • OBJEQUAL
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • What is a COM component?


OBJEQUAL - ScharfBASIC Help

OBJEQUAL

Check if

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

Result = OBJEQUAL( ObjectVar1 , ObjectVar2 )

Description

Compares two object variables to determine if they refer to the same object. It returns true (-1) if both refer to the same object (or both refer to NOTHING); otherwise it returns false (0).

If the two object variables refer to the same class, but not the same specific object, false (0) is returned.

See Also

  • BITSE


OBJRESULT - ScharfBASIC Help

OBJRESULT

Returns a status code (hResult) to describe the success or failure of the most recent

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

lResult& = OBJRESULT

Description

An Automation procedure is a METHOD or PROPERTY on an IAUTOMATION , IDISPATCH , or DUAL interface. By definition, an Automation procedure always returns a hidden result code which is cryptically called an hResult . OBJRESULT the most recent hResult generated by the program, and can be used to identify the success or failure of an operation.

If an Automation procedure fails with a severe error, the ERR system variable is set to an appropriate ScharfBASIC error code. This is usually Error 99 ("Object error"). In such cases, you can use the OBJRESULT function to return the result (hResult&) of the last run-time OBJECT statement or direct METHOD/PROPERTY reference.

Numeric equates for most OBJRESULT errors can be found in the WIN32API.INC file, and are mostly prefixed with %E_, %CO_, %OLE_, and %DISP_. The following list includes the most common codes that may be returned by a direct call of a Method or Property:

%S_OK = &H0

%S_FALSE = &H1

%E_UNEXPECTED = &H8000FFFF&

%E_NOTIMPL = &H80004001&

%E_NOINTERFACE = &H80004002&

%E_POINTER = &H80004003&

%E_ABORT = &H80004004&

%E_FAIL = &H80004005&

%E_ACCESSDENIED = &H80070005&

%E_HANDLE = &H80070006&

%E_OUTOFMEMORY = &H8007000E&

%E_INVALIDARG = &H80070057&

This list tells the most common status codes which may be returned by a DISPATCH call using the OBJECT statement:

%S_OK = &H0

%DISP_E_ARRAYISLOCKED = &H8002000D

%DISP_E_BADINDEX: = &H8002000B

%DISP_E_BADPARAMCOUNT = &H8002000E

%DISP_E_BADVARTYPE = &H80020008

%DISP_E_EXCEPTION = &H80020009

%DISP_E_MEMBERNOTFOUND = &H80020003

%DISP_E_NONAMEDARGS = &H80020007

%DISP_E_OVERFLOW = &H8002000A

%DISP_E_PARAMNOTFOUND = &H80020004

%DISP_E_TYPEMISMATCH = &H80020005

%DISP_E_UNKNOWNINTERFACE = &H80020001

%DISP_E_UNKNOWNLCID = &H8002000C

%DISP_E_UNKNOWNNAME = &H80020006

%DISP_E_PARAMNOTOPTIONAL = &H8002000F

If the status code %DISP_E_EXCEPTION is returned, you can use the IDISPINFO object to secure much additional information about the status. This includes a more specific error code, a description, help file information, etc. If the status code %DISP_E_PARAMNOTFOUND or %DISP_E_TYPEMISMATCH, you can use IDISPINFO.PARAM to determine which parameter actually caused the problem. Please refer to the IDISPINFO section for more details.

As can be seen from the above lists, a large numeric status code can be cryptic. However, you can translate the OBJRESULT code into a descriptive message using the OBJRESULT$ function. This can be most helpful, especially during application development and debugging .

Restrictions

Methods and Properties on a custom interface (a direct interface based upon IUnknown rather than IDispatch) do not support OLE Automation, and do not return an OBJRESULT (hResult).

See Also

  • DIM
  • CLASS
  • CLSID$
  • IDISPINFO
  • GUID$
  • GUIDTXT$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • LET (with Objects)
  • METHOD
  • PROPERTY
  • OBJECT
  • OBJACTIVE
  • OBJEQUAL
  • OBJPTR
  • OBJRESULT$
  • PROGID$
  • What is an hResult?
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x34
call   0x201ba8
call   0x201c88


Opening a type-library - ScharfBASIC Help

Opening a type-library

The ScharfBASIC COM Browser supports opening both registered an unregistered Type Libraries . A registered type library can be opened from the Registered Type Library view or by clicking the Open butto

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The ScharfBASIC COM Browser User Interface

Saving the Source Code

What is an object, anyway?

What are Type Libraries?


POWERARRAY Object - ScharfBASIC Help

POWERARRAY Object

The PowerArray object encapsulates the Windows SAFEARRAY structure. Each object contains exactly one SAFEARRAY, and allows you to read, write, and manipulate the elements easily.

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

All array operations are executed with METHOD and PROPERTY invocations on a PowerArray object. When you create or examine a PowerArray, the specific data type is identified by the following VT codes. All of them are predefined in the compiler. VT codes numbered above 200 are unique to ScharfBASIC. Other programming languages will not recognize them, giving undefined results.

%vt_i2 = 2 %vt_ui4 = 19

%vt_i4 = 3 %vt_i8 = 20

%vt_r4 = 4 %vt_int = 22

%vt_r8 = 5 %vt_uint = 23

%vt_cy = 6 %vt_ptr = 26

%vt_date = 7 %vt_userdefined = 29

%vt_bstr = 8 %vt_filetime = 64

%vt_dispatch = 9 %vt_astr = 201

%vt_bool = 11 %vt_stringfix = 203

%vt_variant = 12 %vt_wstringfix = 204

%vt_unknown = 13 %vt_stringz = 205

%vt_decimal = 14 %vt_wstringz = 206

%vt_i1 = 16 %vt_type = 211

%vt_ui1 = 17 %vt_ext = 221

%vt_ui2 = 18 %vt_curx = 222

The array dimensions are stated at the time the array is created by executing the DIM method. The ByRef Bounds parameter refers to a PowerBounds UDT which is predefined in the compiler. Bound is a PowerBOUND UDT for use with RedimPreserve . It is also predefined in the compiler.

TYPE PowerBounds

Elements1 AS LONG

LowBound1 AS LONG

Elements2 AS LONG

LowBound2 AS LONG

Elements3 AS LONG

LowBound3 AS LONG

Elements4 AS LONG

LowBound4 AS LONG

END TYPE

TYPE PowerBound

Elements AS LONG

LowBound AS LONG

END TYPE

This class is named PowerArray, and the interface is named IPowerArray. If any of the following operations should fail, the OBJRESULT function will return a non-zero result rather than %S_OK (zero).

IPowerArray Methods/Properties

METHOD ARRAYBASE () AS DWORD <1>

This method returns the address of the first element of the array.

METHOD ARRAYDESC () AS DWORD <2>

This method returns the address of the SAFEARRAY descriptor.

PROPERTY GET ARRAYINFO () AS WString <3>

You can attach a wide text string to an array for informational or documentation. This Get Property retrieves the info string, if one is present.

PROPERTY SET ARRAYINFO () = WString <3>

You can attach a wide text string to an array for informational or documentation. This Set Property assigns a wide dynamic string to the array.

METHOD CLONE (PowerArray) <4>

The parameter PowerArray is another object of the same class as this object, which is PowerArray. An exact duplicate of the SafeArray in the parameter is created, and stored in this object.

METHOD COPYFROMVARIANT (ByRef Variant ) <5>

An exact copy is made of the SafeArray contained in the parameter Variant . The array copy is stored in this PowerArray object.

METHOD COPYTOVARIANT (ByRef Variant ) <6>

An exact copy is made of the SafeArray in this object. The array copy is stored in the parameter Variant . Only arrays of data items which are Automation compatible may be stored in a Variant. Data types which are ScharfBASIC-Specific cannot be copied.

METHOD DIM (ByVal VT& , ByVal Subscripts& , ByRef Bounds , OPTIONAL ByVal SIZE ) <9>

Dimensions (creates) a new array. The VT& parameter is specified by one of the %VT values listed in remarks. Subscripts& is the number of dimensions (1 to 4), Bounds is a PowerBounds UDT which is prefilled with the lower bound and size of each dimension. The optional parameter SIZE tells the size (in bytes) of each element. SIZE is only used with %vt_stringfix, %vt_wstringfix, %vt_stringz, %vt_wstringz, and %vt_type.

METHOD ERASE () <10>

The contained array is destroyed and the object is then considered empty.

METHOD ELEMENTPTR (ByVal Index1& , Opt ByVal Index2& , _

Opt ByVal Index3& , Opt ByVal Index4& ) AS LONG <11>

Calculates and retrieves the address of the data element specified by the Index parameter(s).

METHOD ELEMENTSIZE () <12>

Retrieves the storage size (in bytes) of each data element of the array.

METHOD LBOUND ( Subscript& ) AS LONG <13>

Retrieves the lower bound number for the dimension specified by the Subscript& parameter. The first subscript is 1, the second is 2, etc.

METHOD LOCK () <14>

Increments the lock count of the SAFEARRAY. Locks can be nested, but there must be an equal number of Unlocks executed.

METHOD MOVEFROMVARIANT (ByRef Variant ) <17>

Transfers ownership of the SafeArray contained in the variant parameter to this PowerArray object. The variant is then changed to %vt_empty.

METHOD MOVETOVARIANT (ByRef Variant ) <18>

Transfers ownership of the SafeArray contained in this PowerArray object to the variant parameter. The PowerArray object is then changed to empty.

METHOD REDIM (ByVal VT& , ByVal Subscripts& , ByRef Bounds , OPTIONAL ByVal SIZE ) <19>

REDIM allows the SafeArray to be erased and re-dimensioned to a new size. It is really just a shortcut for the two-step process of ERASE, followed by DIM. The VT& parameter is specified by one of the %VT values listed in remarks. Subscripts& is the number of dimensions (1 to 4), Bounds is a PowerBounds UDT which is prefilled with the lower bound and size of each dimension. The optional parameter SIZE tells the size (in bytes) of each element. SIZE is only used with %vt_stringfix, %vt_wstringfix, %vt_stringz, %vt_wstringz, and %vt_type.

METHOD REDIMPRESERVE (ByRef Bound ) <20>

REDIMPRESERVE allows the least significant (rightmost) bound to be changed to a new size. The remaining data items in the array are preserved. Bound is a PowerBound UDT which is prefilled with the lower bound and size of the dimension to be changed.

METHOD RESET () <21>

All elements in the SafeArray are set back to their initial, default value. Numerics are set to zero, strings to zero-length, variants to %vt_empty, and object variables are set to nothing. The array memory is not deallocated.

METHOD SUBSCRIPTS () <22>

Retrieves the number of dimensions (subscripts) for this array.

METHOD UBOUND ( Subscript& ) AS LONG <23>

Retrieves the upper bound number for the dimension specified by the Subscript& parameter. The first subscript is 1, the second is 2, etc.

METHOD UNLOCK () <24>

Decrements the lock count of the SAFEARRAY. Locks can be nested, but there must be an equal number of Unlocks executed.

METHOD VALUEGET (ByRef GetVar , ByVal Index1& , Opt ByVal Index2& , _

Opt ByVal Index3& , Opt ByVal Index4& ) AS LONG <25>

Calculates and retrieves the value of the array element specified by the Index parameter(s). This value is then assigned to the GetVar variable. It is the programmer's responsibility to ensure that the type of GetVar matches the type of the array precisely.

METHOD VALUESET (ByRef SetVar , ByVal Index1& , Opt ByVal Index2& , _

Opt ByVal Index3& , Opt ByVal Index4& ) AS LONG <26>

Assigns the value of the SetVar variable to the array element specified by the Index parameter(s). It is the programmer's responsibility to ensure that the type of SetVar matches the type of the array precisely.

METHOD VALUETYPE () <27>

Retrieves the %VT code which describes the data contained in this array. The %VT codes are listed in the Remark section above.

Details

The PowerArray object encapsulates the Windows SAFEARRAY structure. Each object contains exactly one SAFEARRAY, and allows you to read, write, and manipulate the elements easily.

The SAFEARRAY is generally considered to be the lowest common denominator of arrays . It's not as fast as a standard ScharfBASIC array, but it serves an excellent purpose: It's a "standard" form of array data which can be used to transfer data between programs, modules, and even DLLs created with different versions of the compiler. Other than the possibility of added data types, we do not expect to see the internal format to change in the foreseeable future.

A SAFEARRAY is frequently contained in a VARIANT variable. However, you'll usually find that the array is referenced and identified by a 32-bit pointer to its array descriptor.

All array operations are executed with METHOD and PROPERTY invocations on a PowerArray object. When you create or examine a PowerArray, the specific data type is identified by the following VT codes. All of them are predefined in the compiler. VT codes numbered above 200 are unique to ScharfBASIC. Other programming languages will not recognize them, giving undefined results.

%vt_i2 = 2 %vt_ui4 = 19

%vt_i4 = 3 %vt_i8 = 20

%vt_r4 = 4 %vt_int = 22

%vt_r8 = 5 %vt_uint = 23

See Also

  • ARRAY ASSIGN
  • ARRAY DELETE
  • ARRAY INSERT
  • ARRAY SCAN
  • ARRAY SORT
  • DIM
  • LBOUND
  • REDIM
  • UBOUND


PROGID$ - ScharfBASIC Help

PROGID$

Return the unique alphanumeric PROGID string

Kind | Function
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = PROGID$( ClassID$ )

Description

A PROGID string is the unique alphanumeric text name associated with a given COM object/component. For example, "Word.Application.8".

You convert the 16-byte (128-bit) binary class ID of a COM object/component into a PROGID string with the PROGID$ function.

PROGID$ takes the (16-byte) binary string ClassID$ representing the GUID or UUID of a COM object/component, and examines the system registry in order to determine the PROGID string associated with the ClassID$ string. ClassID$ may be a dynamic string or fixed-length string of at least 16 bytes, or (typically) a GUID variable.

If the ClassID$ cannot be found, or any error occurs in the lookup process, PROGID$ will not set the ERR system variable, but will return an empty string.

PROGID$ is the complement to the CLSID$ function. Using these two functions together, it is possible to extract the precise capitalization of the PROGID from the system registry. See the example below.

See Also

  • DIM
  • CLSID$
  • GUID$
  • GUIDTXT$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • Just what is COM?
  • LET (with Objects)
  • METHOD
  • OBJECT
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • PROPERTY
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x204a54
call   0x20331c
call   0x2020cb
lea   ebx,[ebp-0xa4]
call   0x2018c0
call   0x20329f
call   0x2031d0


RAISEEVENT - ScharfBASIC Help

RAISEEVENT

Call

Kind | Statement
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

RAISEEVENT ObjVar . Method ()

Description

The RAISEEVENT statement is used to call event handler code from an Event Source. RAISEEVENT may only appear within a class which declares the Event Source interface. The concept of RAISEEVENT is very similar to the CALL statement, but it may only be used to execute event procedures:

RaiseEvent Status.Progress(10) ' advise the code is 10% done

It should be noted that RAISEEVENT does not reference an object variable at all, because it calls any and all Direct, V-Table event handlers which are currently subscribed to these events. Instead, it references the interface name (in this case "Status"), followed by the name of the Event Method to be executed (in this case "Progress"). If your program is using a Dispatch event handler you should use the OBJECT RAISEEVENT statement instead.

See Also

  • CLASS
  • EVENT SOURCE
  • EVENTS
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • Just what is COM?
  • EVENTS
  • OBJECT RAISEEVENT
  • What is an object, anyway?
  • What are Connection Points?


StackCollection - ScharfBASIC Help

StackCollection

A collection object is a set of items which can be referred to as a unit. It provides a convenient way to refer to a related group of items as a single object. The items in a collection need only be related by the fact that they exist in the collection. They do not have to share the same data type.

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

< ObjectVar >.membername( params )
RetVal = < ObjectVar >.membername( params )
< ObjectVar >.membername( params ) TO ReturnVariable

Description

Items in a PowerCollection may be retrieved by their key using the ITEM method. They may be retrieved sequentially using the NEXT or PREVIOUS method. Each key in a PowerCollection must be unique. Keys in a PowerCollection are case-sensitive. To access the keys in a case-insensitive manner, you must create and retrieve all keys as either upper case or lower case, but not mixed.

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

Power Collection Methods

ADD <3> ( PowerKey AS WString, PowerItem AS Variant)

The PowerItem variant is added to the end of the PowerCollection. It is associated with the PowerKey string for later retrieval. If the operation was successful, an HResult of S_OK (0) is returned. If it fails because of a duplicate key, an HResult of E_DUPLICATEKEY (&H800A01C9) is returned, and an Object Error (99) is generated.

CLEAR <4>

All PowerKeys and PowerItems are removed from the PowerCollection.

CONTAINS <5> ( PowerKey AS WString) AS Long

The PowerCollection is scanned to determine if the specified PowerKey is present. If found, the Index number of this Item (range of 1 - COUNT) is returned. This value will always evaluate as true . If not found, the value false (0) is returned.

COUNT <6> AS Long

The number of data items currently contained in the PowerCollection is returned to the caller.

ENTRY <7> ( Index AS Long, OUT PowerKey as WString, OUT PowerItem as Variant)

The PowerCollection entry specified by the Index number is returned to the caller in the two specified OUT parameters. If the index number is less than one, or greater than the item count, the variant returned will be of type empty (VT_EMPTY), and the OBJRESULT will be %S_FALSE (1).

FIRST <1> AS Long

The current INDEX for the PowerCOLLECTION is set to one (1), so that subsequent references to the NEXT method will access member items from the beginning. The previous value of the INDEX is returned to the caller.

INDEX <8> ( Index AS Long) AS Long

The current INDEX for the PowerCOLLECTION is set to the specified index number. If the parameter is less than one, or greater than the current count of data items, the INDEX is not changed. The previous value of the INDEX is returned to the caller.

IndexVar& = ObjectVar .INDEX(0)

The above example retrieves the current index number, without changing it, and assigns it to the variable IndexVar& .

ITEM <9> ( PowerKey AS WString) AS Variant

The PowerItem associated with the specified PowerKey is returned. If the specified key is not found, the variant returned will be of type empty (VT_EMPTY), and the OBJRESULT will be %S_FALSE (1).

LAST <10> AS Long

The current INDEX for the PowerCOLLECTION is set to the last item so that subsequent references to the PREVIOUS method will access member items from the end. The previous value of the INDEX is returned to the caller.

NEXT <2> AS Variant

The NEXT method allows the PowerCollection data items to be retrieved sequentially. Each time NEXT is referenced, the data item at the position specified by the INDEX is returned to the caller, and the INDEX is incremented. If the operation is successful, the OBJRESULT is set to %S_OK (0). When there are no more data items to retrieve, the OBJRESULT is set to %S_FALSE (1).

PREVIOUS <11> AS Variant

The PREVIOUS method allows the PowerCollection data items to be retrieved sequentially. Each time PREVIOUS is referenced, the data item at the position specified by the INDEX is returned to the caller, and the INDEX is decremented. If the operation is successful, the OBJRESULT is set to %S_OK (0). When there are no more data items to retrieve, the OBJRESULT is set to %S_FALSE (1).

REMOVE <12> ( PowerKey AS WString)

The specified PowerKey , and the PowerItem associated with it, are removed from the PowerCollection. The index number of each data item past the removed item is decremented by one. If the requested PowerKey is not found, OBJRESULT returns %S_FALSE (1) and no operation is performed.

REPLACE <13> ( PowerKey AS WString, PowerItem AS Variant)

The PowerItem associated with the specified PowerKey is replaced by the new specified PowerItem . If the requested PowerKey is not found, OBJRESULT returns %S_FALSE (1) and no operation is performed.

SORT <14> ( Flags AS Long)

The data items in the PowerCollection are sorted based upon the text in the associated PowerKeys . If the parameter Flags is zero(0), the items are sorted in ascending sequence. If one (1), the items are sorted in descending sequence.

LinkList Collection

A Linked List Collection is an ordered set of data items, which are accessed by their position in the list rather than by an alphanumeric string key. Each data item is passed and stored as a variant variable. You can retrieve these data items by their position number, or sequentially in ascending or descending sequence.

Syntax

The CLASS is "LinkListCollection". The INTERFACE is ILinkListCollection (a DUAL interface).

< ObjectVar >.membername( params )

RetVal = < ObjectVar >.membername( params )

< ObjectVar >.membername( params ) TO ReturnVariable

Remarks

Items in a LinkListCollection may be retrieved by their position number using the ITEM method. They may be retrieved sequentially using the NEXT or PREVIOUS methods.

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

LinkList Collection Methods

ADD <3> ( PowerItem AS Variant)

The PowerItem variant is added to the end of the LinkListCollection.

CLEAR <4>

All PowerItems are removed from the LinkListCollection.

COUNT <5> AS Long

The number of data items currently contained in the LinkListCollection is returned to the caller.

FIRST <1> AS Long

The current INDEX for the LinkListCOLLECTION is set to one (1), so that subsequent references to the NEXT method will access member items from the beginning. The previous value of the INDEX is returned to the caller.

INDEX <6> ( Index AS Long) AS Long

The current INDEX for the LinkListCOLLECTION is set to the specified index number. If the parameter is less than one, or greater than current count of data items, the INDEX is not changed. The previous value of the INDEX is returned to the caller.

IndexVar& = ObjectVar .INDEX(0)

The above example retrieves the current index number, without changing it, and assigns it to the variable IndexVar& .

INSERT <7> ( Index AS Long, PowerItem AS Variant)

The PowerItem variant is added to the collection at the position specified by the Index . If the index number is less than one, or greater than the count, the item is added to the end of the list.

ITEM <8> ( Index AS Long) AS Variant

The PowerItem at the position specified by Index is returned. If the specified item is not present, the variant returned will be of type empty (VT_EMPTY), and the OBJRESULT will be %S_FALSE (1).

LAST <9> AS Long

The current INDEX for the LinkListCOLLECTION is set to the last item so that subsequent references to the PREVIOUS method will access member items from the end. The previous value of the INDEX is returned to the caller.

NEXT <2> AS Variant

The NEXT method allows the LinkListCollection data items to be retrieved sequentially. Each time NEXT is referenced, the data item at the position specified by the INDEX is returned to the caller, and the INDEX is incremented. If the operation is successful, the OBJRESULT is set to %S_OK (0). When there are no more data items to retrieve, the OBJRESULT is set to %S_FALSE (1).

PREVIOUS <10> AS Variant

The PREVIOUS method allows the LinkListCollection data items to be retrieved sequentially. Each time PREVIOUS is referenced, the data item at the position specified by the INDEX is returned to the caller, and the INDEX is decremented. If the operation is successful, the OBJRESULT is set to %S_OK (0). When there are no more data items to retrieve, the OBJRESULT is set to %S_FALSE (1).

REMOVE <11> ( Index AS Long)

The PowerItem at the position specified by Index is removed from the LinkListCollection. The index number of each data item past the removed item is decremented by one. If the requested item is not present, OBJRESULT returns %S_FALSE (1) and no operation is performed.

REPLACE <12> (Index AS Long, PowerItem AS Variant)

The PowerItem at the position specified by Index is replaced by the new specified PowerItem . If the requested PowerItem is not present, OBJRESULT returns %S_FALSE (1) and no operation is performed.

Stack Collection

A Stack Collection is an ordered set of data items, which are accessed on a LIFO (Last-In / First-Out) basis. This collection follows the same algorithm as the machine stack on your Intel CPU. Each data item is passed and stored as a variant variable, using the PUSH and POP methods.

Syntax

The CLASS is "StackCollection". The INTERFACE is IStackCollection (a DUAL interface).

< ObjectVar >.membername( params )

RetVal = < ObjectVar >.membername( params )

< ObjectVar >.membername( params ) TO ReturnVariable

Remarks

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

Stack Collection Methods

CLEAR <1>

All PowerItems are removed from the StackCollection.

COUNT <2> AS Long

The number of data items currently contained in the StackCollection is returned to the caller.

POP <3> AS Variant

The PowerItem at the "Stack-Top" (the item most recently added) is retrieved and returned to the caller. When there are no more data items to retrieve, the variant returned will be of type empty (VT_EMPTY), and the OBJRESULT will be %S_FALSE (1).

PUSH <4> (PowerItem AS Variant)

The specified PowerItem is added to the StackCollection at the "Stack-Top" position.

Queue Collection

A Queue Collection is an ordered set of data items, which are accessed on a FIFO (First-In / First-Out) basis. Each data item is passed and stored as a variant variable, using the ENQUEUE and DEQUEUE methods.

Syntax

The CLASS is "QueueCollection". The INTERFACE is IQueueCollection (a DUAL interface).

< ObjectVar >.membername( params )

RetVal = < ObjectVar >.membername( params )

< ObjectVar >.membername( params ) TO ReturnVariable

Remarks

The Dispatch ID (DispID) for each member method is displayed within angle brackets.

Queue Collection Methods

CLEAR <1>

All PowerItems are removed from the QueueCollection.

COUNT <2> AS Long

The number of data items currently contained in the QueueCollection is returned to the caller.

DEQUEUE <3> AS Variant

The PowerItem at the "oldest" position is retrieved and returned to the caller. When there are no more data items to retrieve, the variant returned will be of type empty (VT_EMPTY), and the OBJRESULT will be %S_FALSE (1).

ENQUEUE <4> ( PowerItem AS Variant)

The specified PowerItem is added to the QueueCollection at the "newest" position.

See Also

  • FOR EACH/NEXT


What is DISPATCH? - ScharfBASIC Help

What is DISPATCH?

The DISPATCH INTERFACE is a slower form of interface , originally introduced as a part of Microsoft Visual Basic. An implementation of COM DISPATCH support was introduced in a prior version of PowerBA

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

When you use DISPATCH, the compiler actually passes the name of the METHOD you wish to execute as a text string. The parameters can also be passed in the same way. The object must then look up the names, and decide which METHOD to execute, and which parameters to use, based upon the text strings provided. As if that weren't enough, DISPATCH requires that all parameters and return values be passed as VARIANT variables, with all those conversions the responsibility of the programmer. That's right, you. This is a slow process. However, DISPATCH is flexible, convenient, and forgiving. Further, you'll find that many scripting languages and application use DISPATCH as their sole method of operation, so continued support is absolutely necessary.

What is an object, anyway?


What is inheritance? - ScharfBASIC Help

What is inheritance?

Inheritance is all about code reuse. You can reuse the definitions of an interface , or you can reuse complete sections of code.

Kind | Keyword
Category | COM & Objects
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

INTERFACE INHERITANCE is defined by COM standards, and available for use by any COM object . This form of inheritance applies only to the definition of each item in an interface, rather than the underlying code. Interface inheritance gives you the option to use one interface in multiple classes (objects). Because the interface definition remains identical in each instance, you can often use the identical (or similar) code to manipulate different objects. With this form of inheritance, the programmer must provide appropriate code for each of the Methods and Properties in every implementation of the interface.

IMPLEMENTATION INHERITANCE is the process whereby a CLASS derives all of the functionality of an interface implemented elsewhere. That is, the derived class now has all the methods and properties of this new, extended version of a Base Class ! This form of inheritance is offered by ScharfBASIC, even though it is not required by the COM Specification.

You can extend the functionality of an interface you created earlier by adding new methods and properties to the derived interface/class. The syntax for adding extra methods (not in the Base Class) is the same as adding methods to a standard class -- just add methods and properties, as always.

You can add to, or replace, the functionality of a particular method or property by coding a replacement which is preceded by the word OVERRIDE . The overriding method must have the same name and signature (parameters, return value, etc.) as the one it replaces. When you implement a new method in a derived class, you may call a method in the Base Class by using the pseudo-object MYBASE . This allows you to extend the original functionality, or replace it entirely.

Inheritance is implemented by use of the INHERIT statement within an INTERFACE / END INTERFACE block. The word INHERIT is followed by the class name and interface name of the code to be inherited. Both are necessary, because COM allows you to have multiple implementations of any particular interface.


A simple communications program - ScharfBASIC Help

A simple communications program

Let's assume you want a simple communications program to use for accessing a local computer bulletin board. You know the parameters for the board: it is 14400 baud, 8 data bits, one stop bit, and no p

Kind | Keyword
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

You want to display data on your screen, be able to type data, and have it sent to the bulletin board. You intend to use a modem connected to COM1. The following short program serves as a starting point, and uses ScharfBASIC's new DDT features to create the user interface:

'----------------------------------------------------------

' Serial Communications Example for ScharfBASIC for Windows

' Copyright (C) 2004-2009 ScharfBASIC, Inc.

' Be sure to set the $ComPort constant to the appropriate

' COM port before compiling this example!


An ECHO client and server using TCP - ScharfBASIC Help

An ECHO client and server using TCP

The simplest TCP server application is an Echo Server (RFC 862). It simply listens to port 7, and when it receives a data packet, it returns the data packet back to the client.

Kind | Keyword
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Writing a TCP server in ScharfBASIC is quite straightforward, but your application must contain a (GUI) window or dialog to receive notification requests from Winsock . It is therefore necessary to either: (1) create a dialog with DDT , or (2) use the Windows API to create a GUI window for the application to receive these notifications. The following function will register a window class, and create a hidden window that can be used by your server.

FUNCTION MakeWindow() AS DWORD

LOCAL wce AS WndClassEx

LOCAL szClassName AS ASCIIZ * 80

STATIC registered AS LONG

IF ISFALSE registered THEN

szClassName = "PBTCPCOMM"

wce.cbSize = SIZEOF(wce)


COMM CLOSE - ScharfBASIC Help

COMM CLOSE

Close an open

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM CLOSE [#] hComm [, [#] hComm ...]

Description

Closes one or more communication ports, as specified by the ScharfBASIC file number held in each hComm parameter. COMM CLOSE ends the relationship between a ScharfBASIC file number, and the serial port device that was previously associated with it by the COMM OPEN statement.

The Number symbol (#) prefix is optional, but recommended for the purposes of clarity.

It is also recommended that you explicitly close any serial port that you have opened before your application terminates. Note that COMM CLOSE is a synonym for CLOSE .

See Also

  • Serial Communications
  • CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x201e28
call   0x201dab
mov   ecx,0x10
mov   eax,0x1
call   0x201c74
call   0x201cdc


COMM - ScharfBASIC Help

COMM

Retrieve the value or status of a

Kind | Function
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

lResult& = COMM([#] hComm , Comfunc )

Description

hComm is the ScharfBASIC file number as was used by the COMM OPEN statement to open the communications port. Select a Comfunc keyword from the following table to retrieve the associated setting.

Comfunc

value (TRUE <> 0, FALSE = 0)

Port Baud Rate (9600, 14400, 19200, etc).

TRUE/FALSE Break is asserted. Break is generally used to "get the attention" of the connected modem, terminal or system.

Number of bits per byte (4, 5, 6, 7, or 8).

TRUE/FALSE Carrier Detect state; synonym for RLSD (READ-ONLY) . When CD is TRUE, the DCE (modem) has a suitable connection on the communications channel present. When CD is FALSE, there is no suitable connection.

TRUE/FALSE Clear-To-Send state is returned (READ-ONLY).

CTSFLOW

TRUE/FALSE Enable CTS output flow control (Input signal). When CTSFLOW is enabled, it causes the DTE (computer) to stop sending data whenever the CTS signal is set to logic low by the DCE (modem). Transmission continues when the DCE (modem) sets the CTS signal back to logic high. The CTS signal is usually used in response to an RTS signal.

TRUE/FALSE Data-Set-Ready state is returned (READ-ONLY).

DSRFLOW

TRUE/FALSE Enable DSR output flow control (Input signal). When DSRFLOW is enabled, it causes the DTE (computer) to stop sending data whenever the DSR signal is set to logic low by the DCE (modem). Transmission is enabled when the DSR signal returns to logic high. The DSR signal is often used in conjunction with CTS in response to a RTS signal.

DSRSENS

TRUE/FALSE Enable DSR sensitivity. When DSRSENS is enabled, data received by the DTE (computer) is placed into the receive buffer only if DSR is set to logic high. If DSR is set low, received data is discarded. Enabling DSRSENS allows DSR to enable or disable the DTE (the computer) to receive data from the DTE (the modem). DSRSENS is rarely used in practical communications situations.

DTRFLOW

TRUE/FALSE Enable DTR handshaking flow control (Output signal). When DTRFLOW is enabled, it signals that the DCE (modem) should prepare to connect to the communications channel. DTR is usually used for modem on-hook/off-hook control, but can also be used in conjunction with DSR for handshaking.

DTRLINE

TRUE/FALSE Enable DTR line. When enabled, DTRLINE leaves the DTR line active when the port is closed by the DTE (computer). This ensures that the DCE (modem) does not close the communications channel when the port is closed.

TRUE/FALSE Null ($NUL) bytes are discarded when read.

PARITY

TRUE/FALSE Enable parity checking. This mode must be enabled for the other Parity options to be selected.

PARITYCHAR

Character to use for parity error replacement. PARITY must be enabled.

PARITYREPL

TRUE/FALSE Enable character replacement on parity error. PARITY must be enabled.

PARITYTYPE

0 = None, 1 = Odd, 2 = Even, 3 = Mark, 4 = Space. PARITY must be enabled. Default = 0.

TRUE/FALSE Ring indicator is on (READ-ONLY) . When RING returns TRUE, a ringing signal is being received on the communications channel (by the modem). RING approximates the state of the ringing signal; however, it may not be reported accurately on all Windows platforms.

Receive-line-signal-detect (READ-ONLY). See CD/Carrier Detect above.

RTSFLOW

Ready To Send (Output signal). 0 = Disable, 1 = Enable, 2 = Handshake, 3 = Toggle. Toggle is used for half-duplex (2-wire) operations to "reverse" the line. While the DTE (computer) is busy sending data, it raises the RTS signal and the DCE (modem) blocks its data receive channel. When RTS signal reverts to logic low, the DCE (modem) reverts to transmit mode and the DTE (computer) switches to receive mode.

Handshake mode causes the DTE (computer) to check the receive buffer (RXQUE) after each character is placed into the buffer. When the buffer is 5/6th full, the RTS signal is dropped. When the receive buffer drops to below 1/6th full, RTS is raised again

RXBUFFER

Size of the receive buffer in bytes.

Characters currently in the receive buffer (READ-ONLY) .

0 = 1 stop bits, 1 = 1.5 stop bits, 2 = 2 stop bits.

TXBUFFER

Size of the transmit buffer in bytes. In some cases, Windows may not be able to report the transmit size.

Characters currently in the transmit buffer (READ-ONLY) .

XINPFLOW

TRUE/FALSE Enable XON/XOFF input flow control. When the DTE (computer) receive buffer is full, an XOFF character is sent to the DCE (modem) to instruct it to halt transmission. When the DCE is ready to resume transmission, an XON character is sent to the DCE. Typically, XOFF is sent when the receive buffer has less than 1/16th remaining, and XON is sent when the receive buffer drops to less than 1/16th of its maximum size. Default = FALSE.

XOUTFLOW

TRUE/FALSE Enable XON/XOFF out flow control. When enabled, the DCE (modem) sends an XOFF to the DTE (computer) to halt data transmission to the DCE. When the DCE is ready to receive more data, an XON character is sent. XOUTFLOW typically uses the same 1/16th rules as XINPFLOW. Default = FALSE.

Common baud rates range from 110 to 256000. There are equates defined in the WIN32API.INC file, prefixed with %CBR_ to assist you with specifying a common baud rate, but you are not restricted to a limited set of rates.

ScharfBASIC sets the ERR system variable if an error occurs when using the COMM function.

The Number symbol (#) prefix is optional, but recommended for the purposes of clarity.

Restrictions

Due to differences between Win32 operating systems, parameters (such as the TXBUFFER and TXQUE) may not be queried successfully in all circumstances.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT


COMM LINE - ScharfBASIC Help

COMM LINE

Receive a CR/LF (

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM LINE [INPUT] [#] hComm , string_var

Description

Read a delimited line of data from the receive buffer, where a "line" is defined as a stream of data that is terminated by a CR/LF (carriage return and linefeed, $CRLF , or CHR$ (13,10)). COMM LINE INPUT is ideal for retrieving modem response strings in reply to "AT" commands sent to a modem.

hComm is the file number you used with COMM OPEN, an integer in the range of 1 to 32767. The Number symbol (#) prefix is optional, but recommended for clarity.

COMM LINE reads the receive buffer up to the next $CRLF character pair. The $CRLF bytes are removed from the buffer but do not form part of the string data returned by COMM LINE. Note that if there is no $CRLF pair in the receive buffer, the statement will wait indefinitely for a complete $CRLF terminated line of data. In this sense, COMM LINE is a blocking statement. The COMM TIMEOUT statement can be used to specify COMM timeouts limits.

The data received is assigned to the string_var . The character mode of the string_var must match the CHR option in COMM OPEN (ANSI/WIDE). If not, an error 5 (Illegal function call) will be generated, and no data will be received.

The EOF function may also be used with COMM LINE (and TCP LINE ) to detect that an incomplete line was received. Normally, the COMM LINE statement reads data until a $CRLF character pair is found, and in that case, EOF will return false (zero). However, if a timeout does occur, COMM LINE will return whatever data has been accumulated, and set EOF to logical TRUE (non-zero).

In many cases, it would be prudent to test EOF after every COMM LINE statement to verify that a full line has been received. In some cases, you may wish to execute the statement one or more additional times, combining the data, in order to obtain a full line of text.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT
  • EOF

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202be0
call   0x202b63
mov   WORD PTR [ebp-0x46],0x1
call   0x202762
call   0x202b63
call   0x202a94


COMM OPEN - ScharfBASIC Help

COMM OPEN

Open a

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM OPEN "COM n " AS [#] hComm [CHR = ANSI|WIDE]

Description

Opens a serial port to begin communications, creating a relationship between a file number and a specific serial port device.

Identifies the serial port number, for example, COM1, COM4, etc. A colon must not follow the port specification. See Restrictions below.

A numeric expression specifying an unused ScharfBASIC file number, in the range of 1 to 32767. This is typically provided by the FREEFILE function. The Number symbol (#) prefix is optional, but recommended for clarity.

If the port was not opened successfully, the ERR system variable will contain the error code. Before actual communications through the port can commence, you must configure the communication parameters by using a COMM SET statement for each parameter.

Restrictions

A colon may not be used in the port name, as was common in DOS code. COMM OPEN cannot use an operating system file handle, nor open a port that is already in use. When opening ports above COM9, Windows requires the port name to be specified using the following syntax:

COMM OPEN "\\.\COM15" AS #hComm

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT
  • FREEFILE
  • OPEN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x20266c
call   0x2025ef
mov   edx,0x203a60
call   0x20266c
mov   WORD PTR [ebp-0x46],0x1
mov   ecx,0x200
mov   dx,0x10e1
call   0x201d90
call   0x2018da
call   0x202520


COMM RECV - ScharfBASIC Help

COMM RECV

Receive binary data from a

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM RECV [#] hComm , count& , string_var

Description

Retrieve the count& number of bytes from the receive buffer , placing the results in string_var . Program execution will halt until count& bytes are available, so it is wise to check how many bytes are available before making a COMM RECV request. You can do this by checking the RXQUE value with the COMM function , as shown in the example below.

hComm is the file number you used with COMM OPEN , an integer in the range of 1 to 32767. The Number symbol (#) prefix is optional, but recommended for clarity.

The data received is assigned to the string_var . The character mode of the string_var must match the CHR option in COMM OPEN (ANSI/WIDE). If not, an error 5 (Illegal function call) will be generated, and no data will be received.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202be0
call   0x202b63
mov   WORD PTR [ebp-0x46],0x1
mov   eax,0x64
call   0x2025dd
call   0x202b63
call   0x202a94


COMM RESET - ScharfBASIC Help

COMM RESET

Disable flow control for a given

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM RESET [#] hComm , FLOW

Description

Switches off all flow control to the serial port as specified by the file number stored in hComm .

The Number symbol (#) prefix is optional, but recommended for the purposes of clarity.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT


COMM SEND - ScharfBASIC Help

COMM SEND

Send a string of data through a

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM SEND [#] hComm , string_expression TO [ CharCountVar ]

Description

The data contained in string_expression is sent to the serial port associated with the file number hComm. The number symbol (#) is optional.

The data is sent in the character form specified in the COMM OPEN statement. If CHR=WIDE was given, the data is sent in wide Unicode characters. Otherwise, it is sent in ANSI bytes. The data will be converted to the appropriate form automatically.

With COMM SEND, no delimiters are added to the data. If a trailing CR/LF is needed, it's usually best to use COMM PRINT instead.

If the optional "TO CharCountVar " clause is included, a count of the number of characters written is assigned to it. This will allow you to gauge the success of the operation. If a TimeOut occurred, this value will be less than expected, and a run-time error 24 (Device Timeout) will be generated.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SET
  • COMM TIMEOUT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202be0
call   0x202b63
mov   WORD PTR [ebp-0x46],0x1
mov   edx,DWORD PTR [ebp-0xa0]
call   0x202b4c
call   0x202410
call   0x202a94


COMM SET - ScharfBASIC Help

COMM SET

Set communication options for a

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM SET [#] hComm , Comfunc = value

Description

Set the parameters needed to communicate with a serial port. This must always be done before you can send and receive data through the port.

To configure the communication parameters, use keywords from the following table to specify the Comfunc as well as a suitable value chosen from the range applicable to the Comfunc parameter you want to set. If an error occurs when attempting to set a parameter, ScharfBASIC sets the ERR system variable to indicate the error number. While each parameter must be set individually, it is also possible to change certain parameters without the need to close and re-establish communications.

COMM SET keywords table

Comfunc

value (TRUE <> 0, FALSE = 0)

Port Baud Rate (9600, 14400, 19200, etc). See notes below.

TRUE/FALSE Break is asserted. Break is generally used to "get the attention" of the connected modem, terminal or system.

Number of bits per byte (4, 5, 6, 7, or 8).

TRUE/FALSE Carrier Detect state; synonym for RLSD (READ-ONLY) . When CD is TRUE, the DCE (modem) has a suitable connection on the communications channel present. When CD is FALSE, there is no suitable connection.

CTSFLOW

TRUE/FALSE Enable CTS output flow control (Input signal). When CTSFLOW is enabled, it causes the DTE (computer) to stop sending data whenever the CTS signal is set to logic low by the DCE (modem). Transmission continues when the DCE (modem) sets the CTS signal back to logic high. The CTS signal is usually used in response to an RTS signal.

DSRFLOW

TRUE/FALSE Enable DSR output flow control (Input signal). When DSRFLOW is enabled, it causes the DTE (computer) to stop sending data whenever the DSR signal is set to logic low by the DCE (modem). Transmission is enabled when the DSR signal returns to logic high. The DSR signal is often used in conjunction with CTS in response to a RTS signal.

DSRSENS

TRUE/FALSE Enable DSR sensitivity. When DSRSENS is enabled, data received by the DTE (computer) is placed into the receive buffer only if DSR is set to logic high. If DSR is set low, received data is discarded. Enabling DSRSENS allows DSR to enable or disable the DTE (the computer) to receive data from the DTE (the modem). DSRSENS is rarely used in practical communications situations.

DTRFLOW

TRUE/FALSE Enable DTR handshaking flow control (Output signal). When DTRFLOW is enabled, it signals that the DCE (modem) should prepare to connect to the communications channel. DTR is usually used for modem on-hook/off-hook control, but can also be used in conjunction with DSR for handshaking.

DTRLINE

TRUE/FALSE Enable DTR line. When enabled, DTRLINE leaves the DTR line active when the port is closed by the DTE (computer). This ensures that the DCE (modem) does not close the communications channel when the port is closed.

TRUE/FALSE Null ($NUL) bytes are discarded when read.

PARITY

TRUE/FALSE Enable parity checking. This mode must be enabled for the other Parity options to be selected.

PARITYCHAR

Character to use for parity error replacement. PARITY must be enabled.

PARITYREPL

TRUE/FALSE Enable character replacement on parity error. PARITY must be enabled.

PARITYTYPE

0 = None, 1 = Odd, 2 = Even, 3 = Mark, 4 = Space. PARITY must be enabled. Default = 0.

TRUE/FALSE Ring indicator is on (READ-ONLY) . When RING returns TRUE, a ringing signal is being received on the communications channel (by the modem). RING approximates the state of the ringing signal; however, it may not be reported accurately on all Windows platforms.

Receive-line-signal-detect (READ-ONLY). See CD/Carrier Detect above.

RTSFLOW

Ready To Send (Output signal). 0 = Disable, 1 = Enable, 2 = Handshake, 3 = Toggle. Toggle is used for half-duplex (2-wire) operations to "reverse" the line. While the DTE (computer) is busy sending data, it raises the RTS signal and the DCE (modem) blocks its data receive channel. When RTS signal reverts to logic low, the DCE (modem) reverts to transmit mode and the DTE (computer) switches to receive mode.

Handshake mode causes the DTE (computer) to check the receive buffer (RXQUE) after each character is placed into the buffer. When the buffer is 5/6th full, the RTS signal is dropped. When the receive buffer drops to below 1/6th full, RTS is raised again.

RXBUFFER

Size of the receive buffer in bytes.

Characters currently in the receive buffer (READ-ONLY) .

0 = 1 stop bits, 1 = 1.5 stop bits, 2 = 2 stop bits.

TXBUFFER

Size of the transmit buffer in bytes. In some cases, Windows may not be able to report the transmit size.

Characters currently in the transmit buffer (READ-ONLY) .

XINPFLOW

TRUE/FALSE Enable XON/XOFF input flow control. When the DTE (computer) receive buffer is full, an XOFF character is sent to the DCE (modem) to instruct it to halt transmission. When the DCE is ready to resume transmission, an XON character is sent to the DCE. Typically, XOFF is sent when the receive buffer has less than 1/16th remaining, and XON is sent when the receive buffer drops to less than 1/16th of its maximum size. Default = FALSE.

XOUTFLOW

TRUE/FALSE Enable XON/XOFF out flow control. When enabled, the DCE (modem) sends an XOFF to the DTE (computer) to halt data transmission to the DCE. When the DCE is ready to receive more data, an XON character is sent. XOUTFLOW typically uses the same 1/16th rules as XINPFLOW. Default = FALSE.

Common baud rates range from 110 to 256000. There are equates defined in the WIN32API.INC file, prefixed with %CBR_ to assist you with specifying a common baud rate, but you are not restricted to a limited set of rates.

Attempting to set a READ-ONLY attribute will result in a compile-time Error 542 ("May not be altered").

The Number symbol (#) prefix is optional, but recommended for the purposes of clarity.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM TIMEOUT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202bd0
call   0x202b53
mov   WORD PTR [ebp-0x46],0x1
mov   ecx,0x1
mov   eax,0x2580
call   0x201d14
call   0x202a84


COMM TIMEOUT - ScharfBASIC Help

COMM TIMEOUT

Place a limit on the time to complete a COMM

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM TIMEOUT [#] hComm , TimeOutMS&

Description

COMM TIMEOUT allows you to specify how long a COMM operation should wait to send or receive a byte of data. This value is measured in milliseconds. If the specified number of milliseconds elapses without a response, the COMM operation will fail and a run-time error 24 (Device Timeout) will be generated.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM PRINT
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT
  • FREEFILE
  • OPEN


HOST ADDR - ScharfBASIC Help

HOST ADDR

Translate a host name into a corresponding

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

HOST ADDR [ hostname$ ] TO ip&
HOST ADDR( index& ) TO ip&

Description

hostname$ is the name of a computer on the network or a domain name such as "scharfbasic.com". If hostname$ is zero-length or not specified, the primary IP address of the current computer is returned.

ip& receives the IP address of the specified host name. ip& may be a REGISTER or memory variable .

It is possible for a computer to have more than one IP address. For example, if you have a network card in your computer, and you are dialed into the Internet using a modem, your computer will have two IP addresses. By using the indexed form of the statement:

HOST ADDR(index&) TO ip&

you can retrieve the first IP address with index& = 1 , the second with index& = 2 , etc. If, on return, ip& contains zero (0), there are no further IP addresses to retrieve on that computer.

A numeric IP address can be easily converted to a dotted IP address string with the following code:

DIM p AS BYTE PTR

HOST ADDR "localhost" TO ip&

p = VARPTR(ip&)

a$ = USING$("#_.#_.#_.#", @p, @p[1], @p[2], @p[3])

' returns "127.0.0.1"

Restrictions

In order to obtain the IP address of the current computer, you must have at least one socket open, or you must first obtain the name of the computer by using the HOST NAME statement.

See Also

  • HOST NAME
  • TCP and UDP Communications
  • TCP OPEN
  • UDP OPEN


HOST NAME - ScharfBASIC Help

HOST NAME

Translate an

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

HOST NAME [ ip& ] TO hostname$

Description

ip& is the IP address you want to look up. If ip& is zero (0) or not specified, the name of the current computer is returned. hostname$ receives the name of the host corresponding to the IP address.

In order to translate an IP address into an Internet domain name, your computer will need to be connected to a DNS server on the Internet or local Intranet.

See Also

  • HOST ADDR
  • TCP and UDP Communications
  • TCP OPEN
  • UDP OPEN


Opening a communications port - ScharfBASIC Help

Opening a communications port

Before we can actually open a communications port , we must first obtain a ScharfBASIC file number so we may manage input and output to the communications port. The best method of obtaining a file numb

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The general way of opening a communications port in a ScharfBASIC program is with a COMM OPEN statement. The syntax is similar to a simple random-access file OPEN, where n is the communications port number

COMM OPEN "COMn" AS #hComm

Note the trailing colon typical in DOS communications is not permitted with COMM OPEN.

If you are familiar with serial communications with DOS compilers (where all of the communications parameters are configured within a single OPEN statement), you will realize that we must instead configure these parameters individually. For this purpose, ScharfBASIC offers the COMM SET statement:

COMM SET #hComm, Comfunc = value

Although configuring a serial port for communications can mean using quite a few COMM SET statements, ScharfBASIC offers a greater control of the serial port than was possible before, plus a completely new method of querying existing settings and status. Retrieving a setting is performed with the COMM function, which returns a Long-integer value:

x& = COMM(#hComm, Comfunc)


TCP ACCEPT - ScharfBASIC Help

TCP ACCEPT

Accept an incoming request for communication from a specified

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP ACCEPT [#] fNum& AS newfNum&

Description

Accept an incoming connection request to the fNum& socket, and create a newfNum& socket handle to communicate with the new connection.

TCP ACCEPT is only valid with sockets opened using TCP OPEN SERVER .

See Also

  • TCP and UDP communications
  • TCP CLOSE
  • TCP LINE INPUT
  • TCP NOTIFY
  • TCP OPEN
  • TCP PRINT
  • TCP RECV
  • TCP SEND
  • UDP OPEN


TCP CLOSE - ScharfBASIC Help

TCP CLOSE

Close a previously opened

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP CLOSE [#] fNum&

Description

Close the previously opened TCP/IP port specified by fNum& .

See Also

  • TCP and UDP communications
  • TCP ACCEPT
  • TCP LINE INPUT
  • TCP NOTIFY
  • TCP OPEN
  • TCP PRINT
  • TCP RECV
  • TCP SEND
  • UDP CLOSE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x201e28
call   0x201dab
mov   ecx,0x40
mov   eax,0x1
call   0x201c74
call   0x201cdc


TCP NOTIFY - ScharfBASIC Help

TCP NOTIFY

Designate which

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP NOTIFY [#] fNum& , {SEND | RECV | ACCEPT | CONNECT | CLOSE} TO hWnd& AS wMsg&

Description

Designates which events (SEND, RECV, ACCEPT, CONNECT and CLOSE) will generate a wMsg& notification message to the window procedure (callback) of the GUI window or dialog whose window handle is contained in hWnd& .

Your program defines the wMsg& value, and this value should be equal or larger than %WM_USER + 500 to avoid conflict with other (common) callback message values.

When the nominated callback function receives the wMsg& notification, the wParam& parameter identifies the operating system's handle of the socket (see FILEATTR ), the low-order Word of lParam& specifies the code of the event (see table below), and the high-order Word of lParam& contains the error code (if any).

LO(WORD, lParam& )

Definition

%FD_READ

Data is available to be read from the socket.

%FD_WRITE

The socket is ready for data to be written.

%FD_ACCEPT

The socket is able to accept a new connection.

%FD_CONNECT

The connection has been established.

%FD_CLOSE

The socket has been closed.

Notification messages do not arrive in unabated or continuous streams. That is, once a particular notification message arrives, it will not be sent again until the initial message is acted upon. For example, if a %FD_READ notification is received, it will not be resent until after a TCP RECV statement is executed.

The Winsock error codes are listed in WINSOCK2.INC, prefixed with %WSAE.

See Also

  • TCP and UDP communications
  • TCP ACCEPT
  • TCP CLOSE
  • TCP LINE INPUT
  • TCP OPEN
  • TCP PRINT
  • TCP RECV
  • TCP SEND
  • UDP NOTIFY


TCP OPEN - ScharfBASIC Help

TCP OPEN

Enable an application to communicate with a

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP OPEN {PORT p& | srvc$ } AT address$ AS [#] fNum& [TIMEOUT timeoutval& ]
TCP OPEN SERVER [ADDR ip& ] {PORT p& | srvc$ } AS [#] fNum& [TIMEOUT timeoutval& ]

Description

Open a TCP/IP port or service for communication, either as a client or as a server.

SERVER

If the keyword server is included, the TCP port is opened as a TCP/IP server; otherwise, it is opened as a TCP/IP client.

ADDR ip&

As a server, if you specify the optional ADDR ip& , the TCP server monitors connections at the specified ip& address. Otherwise, the primary IP address for the computer is used by default.

PORT p&

As a client, PORT identifies the server port that the client attempts to connect to. As a server, PORT identifies the port the server will monitor for connection requests. You may specify either a port number or a service name, but not both.

If the port number is not specified, a service name must be specified instead. A service name takes the form of "http", "smtp", or "ftp", etc. You may specify either a port number or a service name, but not both.

AT address$

As a client, address $ identifies the address to connect with. address $ can be a domain such as "scharfbasic.com", or a dotted IP address in string form, such as "127.0.0.1".

A file number such as #1, or a variable with a value obtained using the FREEFILE function.

TIMEOUT

The optional TIMEOUT value allows you to specify how long a TCP SEND , RECV , PRINT , or LINE operation should wait for completion, in milliseconds ( mSec ). If the specified number of milliseconds elapses without a response, the TCP operation will fail, and the ERR system variable will be set to indicate a run-time Error 24 ("Device timeout"). The default timeout is 60000 milliseconds (60 seconds).

See Also

  • TCP and UDP communications
  • FREEFILE
  • TCP ACCEPT
  • TCP CLOSE
  • TCP LINE INPUT
  • TCP NOTIFY
  • TCP PRINT
  • TCP RECV
  • TCP SEND
  • UDP OPEN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202aa0
call   0x202a23
mov   edx,DWORD PTR [ebp-0xa0]
call   0x202a0c
mov   ecx,0xffffffff
mov   edx,0x203a60
call   0x202aa0
mov   WORD PTR [ebp-0x46],0x1
mov   eax,0xea60
call   0x2018d8
call   0x202954


TCP RECV - ScharfBASIC Help

TCP RECV

Receive data from a specified

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP RECV [#] fNum& , count& , Buffer$

Description

Receive count& bytes from the fNum& TCP/IP port and place them in Buffer$ . If count& bytes are not available, Buffer$ will receive whatever bytes are available and EOF ( fNum& ) will return TRUE (non-zero).

Typically used in a loop to retrieve a stream of data, a TCP RECV loop should be terminated if Buffer$ returns an empty , or if EOF(fNum&) returns TRUE, or if ERR becomes set. If a time-out occurs, ERR will be set to indicate a run-time Error 24 ("Device timeout"). See TCP OPEN to specify the TCP socket timeout value.

See Also

  • TCP and UDP communications
  • EOF
  • TCP ACCEPT
  • TCP CLOSE
  • TCP LINE INPUT
  • TCP NOTIFY
  • TCP OPEN
  • TCP PRINT
  • TCP SEND
  • UDP RECV

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202a90
call   0x202a13
mov   WORD PTR [ebp-0x46],0x1
mov   eax,0x400
call   0x201bf2
call   0x202a13
call   0x202944


TCP SEND - ScharfBASIC Help

TCP SEND

Write a string to a nominated

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP SEND [#] fNum& , string_expression

Description

Write the specified string_expression to the TCP/IP port specified by fNum& .

The TCP SEND statement does not return until string_expression has been sent, or an error occurs. That is, TCP SEND is a synchronous or "blocking" statement. If a time-out occurs, ERR will be set to indicate a run-time Error 24 ("Device timeout"). See TCP OPEN to specify the TCP socket timeout value.

See Also

  • TCP and UDP communications
  • TCP ACCEPT
  • TCP CLOSE
  • TCP LINE INPUT
  • TCP NOTIFY
  • TCP OPEN
  • TCP PRINT
  • TCP RECV
  • UDP SEND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202a90
call   0x202a13
mov   WORD PTR [ebp-0x46],0x1
mov   edx,DWORD PTR [ebp-0xa0]
call   0x2029fc
call   0x201b22
call   0x202944


UDP CLOSE - ScharfBASIC Help

UDP CLOSE

Close a previously opened

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UDP CLOSE [#] fNum&

Description

Close the previously opened UDP/IP port specified by fNum& .

See Also

  • TCP and UDP Communication
  • TCP CLOSE
  • UDP NOTIFY
  • UDP OPEN
  • UDP RECV
  • UDP SEND


UDP NOTIFY - ScharfBASIC Help

UDP NOTIFY

Designate which

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UDP NOTIFY [#] fNum& , {SEND | RECV | CLOSE} TO hWnd& AS wMsg&

Description

Designates which events (SEND, RECV, and CLOSE) will generate a notification wMsg& message, to be sent to the window/dialog procedure (CALLBACK), identified by the window handle hWnd& .

Your program defines the wMsg& value, and this value should be equal or larger than %WM_USER + 500, to avoid conflict with common Windows callback message values.

When the nominated Callback Function receives the wMsg& notification, the wParam& parameter identifies the operating system's handle of the socket (see FILEATTR ). The low-order Word of lParam& specifies the code of the event (see table below), and the high-order Word of lParam& contains the error code (if any).

LO(WORD, lParam& )

Definition

%FD_READ

Data is available to be read from the socket.

%FD_WRITE

The socket is ready for data to be written.

%FD_CLOSE

The socket has been closed.

Notification messages do not arrive in unabated or continuous streams. That is, once a particular notification message arrives, it will not be sent again until the initial message is acted upon. For example, if an %FD_READ notification is received for a particular socket, it will not be resent until after a UDP RECV statement is executed.

The Winsock error codes are listed in WINSOCK2.INC, prefixed with %WSAE .

See Also

  • FILEATTR
  • TCP and UDP Communication
  • TCP NOTIFY
  • UDP CLOSE
  • UDP OPEN
  • UDP RECV
  • UDP SEND


UDP OPEN - ScharfBASIC Help

UDP OPEN

Create a socket for an application to communicate with a

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UDP OPEN [PORT p& ] AS [#] fNum& [TIMEOUT timeoutval& ]

Description

Open a UDP socket (port or service) for UDP communication. FNum& is a file number such as #1, or a variable with a value obtained using the FREEFILE function.

If PORT p& is specified, the socket is opened as a server that can receive UDP data. Use the UDP NOTIFY statement to receive server notifications from the socket so that the data can be retrieved. Common port numbers include 7 (Echo, see RFC 862); 37 (Time, see RFC868); and 123 (NTP - RFC1305).

TIMEOUT

The TIMEOUT option allows you to specify how long, in milliseconds ( mSec ), a UDP SEND/RECV operation should wait for completion. If the specified number of milliseconds elapses, the UDP operation will fail, and the ERR system variable will be set to indicate a run-time Error 24 ("Device timeout"). The default timeout is 60000 milliseconds (60 seconds).

See Also

  • TCP and UDP Communication
  • FREEFILE
  • TCP OPEN
  • UDP CLOSE
  • UDP NOTIFY
  • UDP RECV
  • UDP SEND


UDP RECV - ScharfBASIC Help

UDP RECV

Receive data from a previously opened

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UDP RECV [#] fNum& , FROM ip& , pNum& , Buffer$

Description

Receive any bytes from the previously opened UDP port specified by fNum& , and place them into Buffer$ . The IP address that sent the UDP packet is placed into the ip& variable, and the port number is placed into the pNum& variable .

ip& and pNum& may be subsequently used to send data back in response to data received.

UDP RECV is a blocking statement. That is, execution does not continue until either data is retrieved from the socket, or the timeout period expires.

If a timeout occurs, a run-time Error 24 ("Device timeout") is generated and placed in the ERR system variable. See UDP OPEN to specify the UDP socket timeout value.

See Also

  • TCP and UDP Communication
  • TCP RECV
  • UDP CLOSE
  • UDP NOTIFY
  • UDP OPEN
  • UDP SEND


UDP SEND - ScharfBASIC Help

UDP SEND

Send a string

Kind | Statement
Category | Communications
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UDP SEND [#] fNum& , AT ip& , pNum& , string_expression

Description

Write the specified string_expression to the UDP/IP port pNum& at the IP address specified in ip& , using the UDP connection specified by fNum& .

See Also

  • TCP and UDP Communication
  • TCP SEND
  • UDP CLOSE
  • UDP NOTIFY
  • UDP OPEN
  • UDP RECV


CHOOSE - ScharfBASIC Help

CHOOSE

Return one of several values, based upon the value of an index.

Kind | Function
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = CHOOSE( index& , choice1 [, choice2 ] ...[ELSE choice9 ])
y& = CHOOSE&( index& , choice1 [, choice2 ] ...[ELSE choice9 ])
y$ = CHOOSE$( index& , choice1 [, choice2 ] ...[ELSE choice9 ])
y = CHOOSE([BIT] index&, choice1 [, choice2 ] ...[ELSE choice9 ])
y& = CHOOSE&([BIT] index&, choice1 [, choice2 ] ...[ELSE choice9 ])
y$ = CHOOSE$([BIT] index&, choice1 [, choice2 ] ...[ELSE choice9 ])
y$ = CHOOSE$([BITS] index&, choice1 [, choice2 ] ...[ELSE choice9 ])

Description

These functions may take any number of choice parameters. They return one of the parameters, or a combination of them, based upon the value of index& . In the standard form, index& makes the choice based upon the sequence of the parameters. That is, if index& is one, choice1 is returned. If two, choice2 is returned, etc. If index& is not equal to one of the choice values, the default value is returned to the calling code.

CHOOSE expects choices of any numeric type. CHOOSE& expects choices optimized for an integral data type. CHOOSE$ expects choices of string type. CHOOSE% is recognized as a valid synonym for CHOOSE&.

If no match is made with one of the choice values, the value zero (0) or an empty (zero-length) string is normally returned. However, if an ELSE clause is included as the last choice, its value is returned as the default value. For example:

ChoiceVar$ = CHOOSE$(7,"ONE", "TWO" ELSE "NUL")

In this case, the ELSE expression "NUL" is returned.

If the BIT option is included, the selection is based upon the first bit set (lowest to highest) in index& . That is, the lowest bit (1) returns choice1 , the next bit (2) returns choice2 , the next bit (4) returns choice3 , the next bit(8) returns choice4 , etc. Evaluation of index& stops as soon as one set bit is found. This is particularly valuable when used with an ENUMERATION which also uses the BIT option, to describe a set of attributes for an item in your program.

This is similar to the BIT option, but is only available with the CHOOSE$() version. index& is evaluated in the same general fashion, but the function may return multiple choices, as a concatenated string, if more than one bit is set. For example:

x$ = CHOOSE$(BITS 5, "Computer ", "Laptop ", "Desktop ")

Since the value 5 consists of 2 bits (the lowest and third-lowest) set, the first and third strings are concatenated and returned to the caller. In this case, "Computer Desktop " is the result.

Restrictions

ScharfBASIC only evaluates the selected choice(s) at run-time, not all of them. This ensures optimum execution speed, as well as the elimination of unanticipated side effects.

See Also

  • IIF
  • IIF&
  • IIF$
  • MAX
  • MAX&
  • MAX$
  • MIN
  • MIN&
  • MIN$
  • SWITCH
  • SWITCH&
  • SWITCH$
  • SELECT


DO/LOOP statements - ScharfBASIC Help

DO/LOOP statements

Define a group of program statements that are executed repetitively as long as a certain condition is met.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DO [{WHILE | UNTIL} expression ]
[ statements ]
[EXIT LOOP]
[ITERATE LOOP]
LOOP [{WHILE | UNTIL} expression ]

Description

expression is a numeric expression, in which non-zero values represent logical TRUE, and zero values represent logical FALSE. If a string expression is used (i.e., A$ <> ""), ScharfBASIC returns TRUE if the length of result of the string expression is greater than zero.

DO/LOOP statements are extremely flexible. They can be used to create loops for almost any imaginable programming situation. They allow you to create loops with the test for the terminating condition at the top of the loop, the bottom of the loop, both places, or none of the above.

A DO statement must always be paired with a matching LOOP statement at the bottom of the loop. Failure to match each DO with a LOOP results in either a compile-time Error 448 ("DO loop expected") or an Error 456 ("LOOP/WEND expected").

The WHILE and UNTIL keywords are used to add tests to a DO/LOOP. Use the WHILE if the loop should be repeated if expression is TRUE, and terminated if expression is FALSE. UNTIL has the opposite effect; that is, the loop will be terminated if expression is TRUE, and repeated if FALSE.

For example:

DO WHILE a = 13

[ statements ]

executes the statements between DO and LOOP as long as a is 13. If a is not 13 initially, the statements in the loop are never executed. Conversely:

DO UNTIL a = 13

[ statements ]

executes the statements between DO and LOOP as long as a is not 13. If a equals 13 initially, the loop is never executed.

At any point in a DO/LOOP, you can include an EXIT LOOP or ITERATE LOOP statement. EXIT LOOP causes the loop to terminate, so that execution continues after the terminating loop statement. ITERATE LOOP causes the loop to continue at the terminating loop statement.

The WHILE/WEND statements can be used in many cases to perform the same functions as DO/LOOP. For example, this DO/LOOP:

DO WHILE a < b

[ statements ]

has the same effect as this WHILE/WEND loop:

WHILE a < b

[ statements ]

When using nested loops, be careful that inner loops do not modify variables that are used by the outer loop's terminating condition test. For example, the following code was intended to get all 20 elements of a 10 x 2 array (dimensioned arry (9,1)):

Count1 = 0

DO WHILE Count1 < 10

FOR Count2 = 0 TO 1

x = arry(Count1,Count2)

Count1 = Count1 + 1

NEXT Count2

Because Count1 is incremented within the inner loop, which executes twice for each pass through the outer loop, this code would not get all the array values, but would only get the values for arry (0,0), arry (1,1), arry (2,0), arry (3,1) and so on. By moving the Count1 = Count1 + 1 statement to just below the NEXT Count2 statement, the code functions as intended.

If an EXIT LOOP statement is used within nested loops, it exits only the current loop, not the entire nest. Similarly, an ITERATE within nested loops iterates the current loop. For advice on exiting nested block structures, please refer to the EXIT statement. The ScharfBASIC logical operators can be used to construct multiple test conditions for loop control. For example:

DO WHILE x < 10 AND y < 10

[ statements ]

is executed only as long as both x and y are less than 10. Similarly, the loop:

DO UNTIL X > 10 OR Y > 10

[ statements ]

is executed until either x or y (or both) is (are) greater than 10. See the data types and Arithmetic Operators topics for more information about using logical operators.

Although the compiler doesn't care about such things, it is a good idea when writing your source code to indent the statements between DO and LOOP. The same is true of FOR/NEXT loops, WHILE/WEND loops, and multi-line IF statements. Such indenting makes the appearance of your source code reflect the logical structure of your program, resulting in greater readability. Indenting is particularly valuable when nesting multiple loops of the same type, since it makes it easier to see which LOOP goes with which DO.

Also see the discussion on the IF statement for notes on ScharfBASIC's Short-circuit evaluation and its possible side effects.

See Also

  • #OPTIMIZE
  • EXIT
  • FOR EACH/NEXT
  • FOR/NEXT
  • ITERATE
  • WHILE/WEND

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Do Until Loop

jle   0x2010cc

Variant 2: Do While Loop

jle   0x2010cc


END - ScharfBASIC Help

END

Terminate program immediately.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

END [ nErrorLevel& ]

Description

Normally, ScharfBASIC programs are terminated when you exit the PBMAIN or WINMAIN() function. It should always be your goal to end programs in this fashion, so that the compiler and the operating system can do everything possible to leave things in an orderly state.

The END statement is an alternative termination method which should only be used in limited circumstances. It may be helpful in emergency situations, such as a fatal error like "out of memory". It's also useful (temporarily) in the conversion of DOS programs, just for the sake of compatibility. However, once conversion is complete, you should eliminate it as soon as possible.

The optional nErrorLevel& value has an effective range of 0 to 255. Batch files may act on the result through the IF [NOT] ERRORLEVEL batch command.

Restrictions

END may not be used in a DLL . END is intended only for temporary use in converting DOS programs to Windows. You should convert it to the standard EXIT FUNCTION method as soon as possible. It should be avoided while any COM objects are active.

See Also

  • EXIT
  • PBMAIN
  • WINMAIN


Error Trapping - ScharfBASIC Help

Error Trapping

Error traps let you intercept and deal with run-time errors, rather than having programs unceremoniously abort or ignore a fatal error, possibly causing loss of data.

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

There are three steps you must take to trap errors, as described in the following sections:

For example, here is a piece of code that fills an array with the filenames from a directory. This section will add complete Error Trapping to prevent run-time errors when the user chooses a directory that does not have any files or a drive that is not ready.

SUB GetFileNames(File() AS STRING)

DIM CurrentDir AS STRING

DIM fName AS STRING, Mask AS STRING

Path = AskUserForPath$()


Error Trapping Summary - ScharfBASIC Help

Error Trapping Summary

Error Trapping is a useful and powerful feature of ScharfBASIC. Many programmers avoid trapping errors because of the substantial penalties other BASIC dialects impose when Error Trapping is turned on.

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Finally, ScharfBASIC now includes the following list of predefined (built-in) equates to assist in the creation of more verbose error handling code. They include:

%ERR_ILLEGALFUNCTIONCALL


ERROR$ - ScharfBASIC Help

ERROR$

Return a string

Kind | Function
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

msg$ = ERROR$[( ErrNum )]

Description

ERROR$ returns the verbose text title of a ScharfBASIC run-time error identified by ErrNum .

ErrNum must be in the range 1 to 255 inclusive. Values outside of this range return "No error". If ErrNum is not specified, ERROR$ returns the description of the current value of ERR.

See Also

  • #DEBUG DISPLAY
  • ERL
  • ERR
  • ERRCLEAR
  • ERROR
  • Error Overview
  • Error Trapping
  • ON ERROR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x5
call   0x2013d5


EXIT - ScharfBASIC Help

EXIT

Transfer program execution out of a block structure.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

EXIT FASTPROC ' FastProc / End FastProc
EXIT FOR ' For / Next Loop
EXIT FUNCTION ' Function / End Function
EXIT IF ' If / End If
EXIT DO ' Do / Loop or While / Wend
EXIT LOOP ' Do / Loop or While / Wend
EXIT MACRO ' Macro / End Macro
EXIT METHOD ' Method / End Method
EXIT PROPERTY ' Property / End Property
EXIT SELECT ' Select / End Select
EXIT SUB ' Sub / End Sub
EXIT TRY ' Try / End Try
EXIT [,ITERATE] ' Exit one loop and immediately iterate another
EXIT [,EXIT...] ' The nearest enclosing block structure

Description

The EXIT statement allows you to leave a code section block immediately. Using EXIT by itself will leave the most recently executed structure, but not an outer block. EXIT, EXIT will leave two block structures, and EXIT, EXIT, EXIT will leave three levels. For example:

FOR ix = 1 TO 10

DO UNTIL x > 10

EXIT FOR' will exit from the DO LOOP

EXIT is preferred over GOTO for this purpose. If you want to exit a structure other than the one most recently executed, you may include the type of structure, or you can use multiple EXIT's. The following two examples are functionally identical:

FOR ix = 1 TO 10

DO UNTIL x > 10

EXIT FOR ' will exit DO and FOR NEXT loop

FOR ix = 1 TO 10

DO UNTIL x > 10

EXIT, EXIT ' will exit DO and FOR NEXT loop

You can also exit one loop and immediately iterate another:

FOR x = 1 TO 10

EXIT, ITERATE

See Also

  • DO/LOOP
  • FASTPROC
  • FOR EACH/NEXT
  • FOR/NEXT
  • FUNCTION/END FUNCTION
  • IF/END IF block
  • ITERATE
  • MACRO/END MACRO
  • METHOD
  • PROPERTY
  • SELECT
  • SUB/END SUB
  • TRY/END TRY
  • WHILE/WEND

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Exit Do

cmp   edi,0x5
jmp   0x2010d0

Variant 2: Exit For

mov   DWORD PTR [ebp-0xac],esi
mov   edi,0x1
jmp   0x2010e2
cmp   edi,0x3
jmp   0x2010ec
inc   DWORD PTR [ebp-0xa4]
cmp   eax,DWORD PTR [ebp-0xac]

Variant 3: Exit Function

cmp   esi,0x0
jmp   0x2010c1

Variant 4: Exit Loop

cmp   esi,0x5
jmp   0x2010be

Variant 5: Exit Sub

cmp   esi,0x0
jmp   0x2010b6


Exiting an error handler - ScharfBASIC Help

Exiting an error handler

You must exit an error handler with the RESUME LABEL statement. Execution branches immediately to the specified local label , and the original error trap operation is restored ready to catch the next

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

In the sample program, you want to use RESUME to a specific line. Put the line label before the line that requests user input to give the user another chance to enter a correct path.

Here is the sample program, complete with Error Trapping:

SUB GetFileNames(File() AS STRING)

DIM CurrentDir AS STRING

DIM fName AS STRING, Mask AS STRING

ON ERROR GOTO ErrorTrap


Flow Control - ScharfBASIC Help

Flow Control

The following functions can be used to manage program execution/flow:

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Determine if an equate has been previously defined.

Define sections of source code to be compiled or ignored.

Enable/disable integrated development tools in compiled code.

Invoke a procedure ( Sub , Function , Method , Property , or FastProc ).


FOR EACH/NEXT statements - ScharfBASIC Help

FOR EACH/NEXT statements

Define a loop of program statements which can sequentially examine and act upon each member of a

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FOR EACH VariantVar IN CollectionObjectVar
[ statements ]
NEXT

Description

The FOR EACH loop allows you to examine each member of a collection in sequence, to perform needed operations with that data. If there are no member items in the collection, the loop is skipped.

When the loop begins, the first member variant in the collection is assigned to the VariantVar . Statements in the loop can act upon or with that data to perform whatever functions are needed. When the NEXT statement is reached, the next member item is assigned to the VariantVar , and the loop is repeated. This repetition continues until there are no more member items.

VariantVar contains a copy of the variant in the collection. You can alter the value of VariantVar , but these changes do not affect the member variant in the collection.

See Also

  • EXIT FOR
  • FOR/NEXT
  • ITERATE FOR
  • LINKLISTCOLLECTION
  • POWERCOLLECTION


FOR/NEXT statements - ScharfBASIC Help

FOR/NEXT statements

Define a loop of program statements whose execution is controlled by an automatically incrementing or decrementing counter.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FOR Counter = start TO stop [STEP increment ]
[ statements ]
[EXIT FOR]
[ITERATE FOR]
NEXT [ Counter ]

Description

Counter is a numeric variable serving as the loop counter.

start is a numeric expression specifying the value initially assigned to Counter .

stop is a numeric expression giving the value that Counter must reach for the loop to be terminated.

increment is an optional numeric expression defining the amount by which Counter is incremented with each loop execution. If not specified, increment defaults to 1.

Note that increment must be the same data type or in the same range as Counter . For example:

FOR x?? = 50 TO 1 STEP -1

will fail because -1 is not within the range of an unsigned Word variable.

When a FOR statement is encountered, start is assigned to Counter, and Counter is tested to see if it is greater than (or, for negative increment , less than) stop . If not, the statements within the FOR/NEXT loop are executed, increment is added to Counter , and Counter again tested against stop . The statements in the loop are executed repeatedly until the test fails, at which time control passes to the statement immediately following the NEXT.

If increment is equal to the maximum value of a variable class (255 for a byte , 32767 for an Integer , 65535 for a Word , etc), the compiler will generate an error . If step is zero, an infinite loop can be created.

When using floating point values with FOR/NEXT, be sure to allow for round-off errors when mixing numbers of different precision. Using constants or variables of the same type throughout will help solve this problem:

FOR n# = 1.0 TO 1.5 STEP 0.1

x$ = STR$(n#)

NEXT n#

executes 5 times and returns:

1.10000000149012

1.20000000298023

1.30000000447035

1.40000000596046

while:

FOR n@ = 1.0@ TO 1.5@ STEP 0.1@

x$ = STR$(n@)

NEXT n@

executes 6 times and returns:

FOR/NEXT loops run fastest when Counter is a Long-integer variable, and start and increment are Long-integer constants. The value of Counter is available like any other variable within the loop. It is wise to avoid explicitly modifying the value of Counter within the loop. If you need to exit the loop prematurely, use an EXIT FOR statement. Keep range considerations in mind. For example, if Counter is an Integer variable, you may not use the maximum value for an Integer for stop , as Counter would be incremented outside the Integer range at the end of the loop.

The body of the loop is skipped altogether if the initial value of Counter is greater than stop (or, for a negative increment , if Counter is less than stop ).

FOR/NEXT loops can be nested within other FOR/NEXT loops. Be sure to use unique counter variables. Note that ScharfBASIC allows the Counter in the NEXT keyword simply as a comment, which is ignored. For example, the following will compile, even though the counter variables are "crossed":

FOR n = 1 TO 10

FOR m = 1 TO 20

NEXT n

NEXT m

You can omit the counter variable in the NEXT statement altogether. For example:

FOR n = 1 TO 10

If a NEXT is encountered without a corresponding FOR (or vice versa), a compile-time error is generated.

Previous version of ScharfBASIC supported a single NEXT statement used with multiple nested FOR/NEXT loops, such as NEXT c, b, a. This is no longer supported and you will need to update your code to use multiple NEXT statements.

In certain situations, previous versions of ScharfBASIC optimized FOR/NEXT loops to count down instead of up for improved execution speed. This optimization could cause the counter variable to contain a value which was not expected when execution of the loop was complete. This optimization has been improved so that the counter variable value is always correct upon loop completion, even if EXIT FOR was used to force an early termination.

Although the compiler does not care about such things, it is considered good programming practice to indent the statements between FOR and NEXT by two or three spaces to set off the structure of the loop.

For additional performance, use a REGISTER variable for the loop counter variable.

Restrictions

The counter variable must be a simple numeric scalar variable, such as LOCAL , STATIC , GLOBAL , or REGISTER . This aids in maintaining high performance levels for a simple loop structure. Variables which require multiple operations to access are specifically disallowed: THREADED , INSTANCE , BYREF Parameters, POINTER Targets, and ARRAY .

See Also

  • #OPTIMIZE
  • #REGISTER
  • DO/LOOP
  • EXIT
  • FOR EACH/NEXT
  • ITERATE
  • WHILE/WEND
  • REGISTER

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: For Next

mov   DWORD PTR [ebp-0xac],esi
mov   edi,0x1
jmp   0x2010d8
inc   DWORD PTR [ebp-0xa4]
cmp   eax,DWORD PTR [ebp-0xac]

Variant 2: For Step

mov   edi,0xa
inc   DWORD PTR [ebp-0xa4]


GOSUB - ScharfBASIC Help

GOSUB

Invoke a subroutine.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GOSUB { label | linenumber }
GOSUB DWORD dwpointer

Description

GOSUB causes execution to branch to the statement prefaced by label or linenumber , after first saving its current location on the stack . The label or linenumber must be local to the Sub , Function , Method , or Property where the GOSUB statement is located. Executing a RETURN statement returns control to the instruction immediately following the GOSUB.

When using GOSUB, be sure that each subroutine returns to its caller gracefully through a RETURN statement. Run-away (recursive) GOSUBs that loop upon themselves will eat up large chunks of stack space, reducing available memory.

All labels and line numbers are private. You cannot GOSUB to a label outside of the current procedure.

For time critical or high-performance code, using a GOSUB to perform a repetitive task is almost always faster then performing a call to a procedure, since there is no overhead in setting up a stack frame for a GOSUB.

GOSUB DWORD causes execution to branch to address stored in dw pointer , after first saving its current location on the stack. dwpointer must be a Double word , Long integer , or pointer variable that contains the address of a label that is in the same procedure as the GOSUB DWORD statement. Executing a RETURN statement returns control to the instruction immediately following the GOSUB DWORD statement.

See Also

  • #STACK
  • FUNCTION
  • METHOD
  • ON GOSUB
  • PROPERTY
  • SUB
  • RETURN


How error traps work - ScharfBASIC Help

How error traps work

In ScharfBASIC, error codes - returned by the ERR or ERRCLEAR functions - and error traps are local to each Sub , Function , Method , or Property . An error trap will only trap errors that occur within

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

ScharfBASIC uses the following steps to determine what to do when a run-time error occurs:

Consider the following:

ON ERROR GOTO ErrorTrap

' some code goes in here

' some more code goes in here


IF/END IF - ScharfBASIC Help

IF/END IF

Create IF/THEN/ELSE constructs with multiple lines and/or conditions.

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

IF integer_expression THEN
[ statements ]
[ELSEIF integer_expression THEN
[ statements ]]
[ELSE
END IF

Description

In executing IF blocks, the truth of the integer_expression in the initial IF statement is checked first. If it evaluates to FALSE (zero), each of the following ELSEIF statements is examined in order. There can be as many ELSEIF statements as desired. As soon as one is found to be TRUE (non-zero), ScharfBASIC executes the statement(s) following the associated THEN and before the next ELSEIF or ELSE.

Execution then jumps to the statement just after the terminating END IF without making any further tests. If none of the test expressions evaluates to TRUE, the statement(s) in the ELSE clause (which is optional) are executed.

Note that there must be nothing following the THEN keyword in an IF block; that's how the compiler distinguishes an IF block from a conventional IF statement. There must also be nothing on the same line as the ELSE (except for remarks).

IF blocks can be nested; that is, any of the statements after any of the THENs may contain IF blocks. Although the compiler doesn't care, the clarity of source code is improved by indenting the statements controlled by each test a couple of spaces, as shown in the example.

IF blocks must be terminated with a matching END IF statement. Note that the END IF statement requires a space and the ELSEIF statement does not.

See the IF statement for notes on ScharfBASIC's Short-circuit evaluation and its possible side effects.

See Also

  • CHOOSE
  • CHOOSE&
  • CHOOSE$
  • EXIT
  • IF
  • IIF
  • IIF&
  • IIF$
  • MAX
  • MAX&
  • MAX$
  • MIN
  • MIN&
  • MIN$
  • SELECT
  • Short-circuit evaluation
  • SWITCH
  • SWITCH&
  • SWITCH$
  • SELECT

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: If Elseif

cmp   esi,0x1
jne   0x2010cc
mov   edi,0xa
jmp   0x2010e6
cmp   esi,0x2
jne   0x2010e0
mov   edi,0x14
jmp   0x2010e6

Variant 2: If Then

cmp   esi,0x0
mov   edi,0x1

Variant 3: If Then Else

cmp   esi,0x0
jle   0x2010cc
mov   edi,0x1
jmp   0x2010d2


IIF - ScharfBASIC Help

IIF

Return one of two values based upon a

Kind | Function
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

var = IIF( num_expression , truepart , falsepart )
var& = IIF&( num_expression , truepart& , falsepart& )
var$ = IIF$( num_expression , truepart$ , falsepart$ )

Description

IIF expects parts of any numeric type. IIF& expects parts optimized for long integer type. IIF$ expects parts of string type.

If num_expression evaluates to TRUE (non-zero), the truepart is returned, else the falsepart is returned. num_expression is evaluated as a normal ScharfBASIC Boolean expression, which offers short-circuit expression evaluation as needed.

IIF(1 AND 2, 3, 4) would return the truepart (3) because both terms in num_expression are TRUE, and therefore evaluate to TRUE.

To force a bitwise evaluation of num_expression , enclose it in parentheses. For example, IIF$( (1 AND 2), "True", "False") would return "False".

IIF% is recognized as a valid synonym for IIF&.

Restrictions

Contrary to the implementation in some other languages, only the selected expression ( truepart or falsepart ) is evaluated at run-time, not both. This ensures optimum execution speed, as well as the elimination of unanticipated side effects.

See Also

  • CHOOSE
  • CHOOSE&
  • CHOOSE$
  • SWITCH
  • SWITCH&
  • SWITCH$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0xffffffff
fild   DWORD PTR ds:0x202a58
fild   DWORD PTR ds:0x202a54
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]


ITERATE - ScharfBASIC Help

ITERATE

Start an immediate iteration of a loop

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ITERATE [DO | LOOP | FOR]

Description

ITERATE is just like using a GOTO to the line immediately before the NEXT statement (of a FOR...NEXT loop), the LOOP statement (of a DO...LOOP loop), or the WEND statement (of a WHILE..WEND loop). For example, the following code fragments are equivalent:

FOR ix = 1 TO 100

[ statements ]

ITERATE FOR

[ statements ]

FOR ix = 1 TO 100

[ statements ]

GOTO iterateForLoop

[ statements ]

iterateForLoop:

If you do not specify DO, LOOP, or FOR, ITERATE will iterate the most recently executed structure. For example:

FOR ix = 1 TO 10

DO UNTIL x > 10

[ statements ]

ITERATE ' will iterate the DO LOOP

[ statements ]

ITERATE DO and ITERATE LOOP are interchangeable.

Use this statement...

To iterate this kind of loop

ITERATE FOR

FOR/NEXT

ITERATE DO, ITERATE LOOP

DO/LOOP, WHILE/WEND

See Also

  • DO/LOOP
  • EXIT
  • FOR EACH/NEXT
  • FOR/NEXT
  • WHILE/WEND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edi,0x1
cmp   edi,0x3
jmp   0x2010bc
cmp   edi,0x5


Long lines - ScharfBASIC Help

Long lines

The underscore character ( _ ) can be used to split "logical" lines of source code, across physical lines in the source code file. The underscore character must be preceded by at least one white space

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The effect of using a line continuation character is for "visual" appearance only - the compiler itself treats lines split this way as only one contiguous line of code.

For example, if we take the following line of code:

DECLARE FUNCTION Call32& LIB "CALL32.DLL" ALIAS "Call32" (Param1 AS ANY, BYVAL id&)

We could rewrite this line to place its component parts on separate lines of code for clarity:

DECLARE FUNCTION Call32& _

(Param1 AS ANY, BYVAL id&)

The compiler treats text that appears after the line continuation character as a remark. However, we still recommend that such comments are preceded by a REM or an apostrophe ( ' ) symbol to clearly distinguish remarks from the actual code.


ON ERROR - ScharfBASIC Help

ON ERROR

Specify an

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ON ERROR GOTO { label | line_number }
ON ERROR RESUME NEXT
ON ERROR GOTO 0

Description

label or line_number identifies the first line of the error trapping routine. Once error handling has been turned on with this statement, all run-time errors result in a jump to your error handling code. When the error handler begins execution, additional error trapping is temporarily suspended. When your error handling is complete, you must use the RESUME statement (any form) to continue execution. RESUME reactivates the temporary suspension of error trapping.

You must use additional care when you trap an error within a GOSUB block of code, because a RETURN address has been saved on the system stack . If you use a form of RESUME which re-enters the GOSUB block, a RETURN will still be executed later, and the stack will be balanced. However, if RESUME

To disable error trapping, use ON ERROR GOTO 0 or ON ERROR RESUME NEXT. You can use this technique if an error occurs for which you have not defined a recovery path; you can also choose to display the contents of ERR or ERRCLEAR at this time.

The default for error trapping is disabled. If an error occurs while error trapping is disabled, the error code is placed into the ERR system variable, and execution continues. Errors can still be trapped by checking the value of the ERR or ERRCLEAR variable with IF ERR THEN or SELECT CASE ERR statements.

Error trapping is local to each Sub , Function , Method , and Property . ScharfBASIC does not support global error trapping.

Numeric errors such as Divide-by-zero, Overflow and Underflow are not trapped. Array out-of-bounds and null-pointer trapping are only enabled if #DEBUG ERROR ON is used.

If you're running a program with error trapping turned off, a run-time error may cause a General Protection Fault (GPF). A GPF cannot be trapped with ON ERROR.

It is not possible to branch to an error handler from within an expression. The compiler tests for an error only after the statement is completed. This means that a statement such as:

ON ERROR GOTO ErrorHandlerLabel

IF GETATTR( sFile ) THEN

' Do something

END IF

will generate an Error 53 when sFile does not exist, but will not branch to the ErrorHandlerLabel . This is because the GETATTR ( sFile ) is an expression in the IF/ END IF block. You could do a

ON ERROR GOTO ErrorHandlerLabel

a& = GETATTR(sFile)f

IF a& THEN

' Do something

END IF

which will branch to the ErrorHandlerLabel if sFile does not exists. You could also check the value of the ERR variable or use a TRY/ END TRY block to see if an error occurred when checking for errors that occur during an expression.

See Also

  • #DEBUG DISPLAY
  • #DEBUG ERROR
  • ERR
  • ERRCLEAR
  • ERROR
  • Error Overview
  • ERROR$
  • Errors and Error Trapping
  • RESUME

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201ad4


ON GOSUB - ScharfBASIC Help

ON GOSUB

Call one of several subroutines according to the value of a numeric expression.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ON n GOSUB { label | line_number } [, { label | line_number }] ...

Description

n is a numeric expression ranging from 1 to 255, and each label or line number identifies a statement to branch to. When this statement is encountered, the n th label in the list is branched to; for example, if n equals 4, the fourth label in the list receives control. If n is less than one or greater than the number of labels, no branch occurs, and ScharfBASIC continues execution with the statement immediately following the ON GOSUB statement.

Each subroutine should end with RETURN , which causes execution to resume with the statement immediately following the ON GOSUB statement. ON GOSUB can only branch to labels or line numbers that have the same scope as the ON GOSUB statement.

The SELECT and IF blocks also perform multiple branching and are more flexible than ON GOSUB.

Note that ON GOSUB (and ON GOTO ) have been internally optimized to produce greater run-time performance than was possible with previous versions of ScharfBASIC.

See Also

  • GOSUB
  • FUNCTION/END FUNCTION
  • IF block
  • METHOD
  • ON GOTO
  • PROPERTY
  • RETURN
  • SELECT
  • SUB/END SUB


ON GOTO - ScharfBASIC Help

ON GOTO

Send program flow to one of several possible destinations based on the value of a boolean

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ON n GOTO { label | line_number } [, { label | line_number }] ...

Description

n is a numeric expression ranging from 1 to 255, and label or line_number identifies a statement in the program to branch to. The n th label is branched to; for example, if n equals 4, the fourth label in the list receives control. If n is less than one or greater than the number of labels in the list, program execution continues with the statement that immediately follows the ON GOTO statement.

ON GOTO behaves exactly like ON GOSUB , except that it performs a GOTO rather than a GOSUB. This means that the program retains no memory of where the branch originated. ON GOTO can only branch to labels or line numbers that have the same scope as the ON GOTO statement.

The SELECT and IF blocks also perform multiple branching, and are more flexible than ON GOTO. See the GOTO entry for a discussion of ways to avoid using GOTOs in your programs.

Note that ON GOTO (and ON GOSUB) have been internally optimized to produce greater run-time performance than was possible with previous versions of ScharfBASIC.

See Also

  • GOTO
  • IF block
  • ON GOSUB
  • SELECT


RESUME - ScharfBASIC Help

RESUME

Restart program execution after

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

RESUME
RESUME NEXT
RESUME FLUSH
RESUME < Label >

Description

The RESUME statement is used to continue execution of a program after a run-time error has been trapped and processed with an ON ERROR handler. RESUME (in any form) tells ScharfBASIC that error processing has been completed, and it is now time to continue normal execution of the programming. Whenever an error is trapped and processed by ON ERROR GOTO, execution of a matching RESUME is mandatory.

RESUME

If the first form of RESUME is used (without any modifier), the statement which generated the error is executed again and program flow continues normally. Be certain that you've corrected the condition which generated the error in the first place before you do this!

RESUME NEXT

If you execute RESUME NEXT, program execution continues on the line immediately following the one which generated the error. Program flow continues normally after that. Be certain that your error handler did whatever was necessary to substitute new actions to replace what was expected from the code which errored.

RESUME FLUSH

If you execute RESUME FLUSH, there is no transfer of control to a different line. Program execution simply continues on the line immediately following the RESUME FLUSH.

RESUME < Label >

If a label is specified, program execution continues at the specified label location. The label must be "local"; that is, it must be located within the same procedure as the RESUME.

Restrictions

ON ERROR and RESUME may not be used within a TRY/END TRY block or a FASTPROC procedure.

See Also

  • ERL
  • ERR
  • ERROR
  • Error Overview
  • ERROR$
  • Error Trapping
  • ON ERROR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x2010c3
call   0x201b28
fild   DWORD PTR ds:0x202a58
fidivr   DWORD PTR ds:0x202a54
fistp   QWORD PTR [ebp-0x6c]
mov   esi,DWORD PTR [ebp-0x6c]
mov   eax,0x2
call   0x201af4


SELECT CASE/END SELECT - ScharfBASIC Help

SELECT CASE/END SELECT

Control program flow based on the value of an expression.

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SELECT CASE [AS] [LONG | CONST | CONST$ | CONST$$] expression
CASE [IS] testlist
[ statements ]
[CASE [IS] testlist
[ statements ]]
[CASE ELSE
END SELECT

Description

testlist is one or more tests, separated by commas, to be performed on expression . expression can be either string or numeric .

When a SELECT statement is encountered, expression is evaluated using the testlist in the first CASE clause. If the evaluation is FALSE, the evaluation is repeated using the next testlist . As soon as an evaluation is TRUE (non-zero), the statements following that CASE clause are executed, up to the next CASE clause.

Execution then passes to the statement following the END SELECT statement. If none of the evaluations is TRUE, the statements following the optional CASE ELSE clause are executed.

The tests that may be performed by a CASE clause include: equality, inequality, greater than, less than, and range ("from-to") testing. The SELECT CASE block can do string or numeric tests, but these cannot be interchanged.

Examples of numeric CASE clause tests include:

SELECT CASE numeric_expression

CASE > b ' relational; is expression > b?

CASE 14 ' equality (= is assumed); is e xpression equal to 14?

CASE b TO 99 ' range; is expression between the value of the

' variable b and 99 (inclusive)?

CASE 14, b ' two equality tests; is expression equal to

' 14 or equal to b?

CASE 25 TO 99,14 ' combination range and equality; is expression

' between 25 and 99 (inclusive) or equal to 14?

Examples of string CASE clause tests include:

SELECT CASE string_expression

CASE > b$ ' relational; is expression > b$?

CASE "X" ' equality (= is assumed); is expression equal

' to "X"?

CASE "A" TO "C" ' range; is expression between "A" and

' "C"(inclusive)?

CASE "Y", b$ ' two equality tests; is expression equal to

' "Y" or equal to b$?

CASE "A" TO "C","Q" ' combination range and equality; is expression

' between "A" and "C" (inclusive) or equal

' to "Q"?

When a CASE clause contains multiple tests separated by commas, a logical OR is performed. That is, if any one (or more) of the tests is TRUE, the entire clause is deemed to be TRUE.

Use EXIT SELECT to jump out of a SELECT block prematurely.

ScharfBASIC now offers four optional modifiers to provide highly optimized code generation for specific circumstances. By default, numeric exp ressions are evaluated either as floating point values (to offer the widest range of compatibility for any possible circumstance) or as integer class (for example, if ScharfBASIC can establish that all case clauses are integer class values, etc). Further, string expressions are evaluated dynamically to allow virtually any data. However, if limits on the type and range of the data used for CASE comparison are restricted, performance can be dramatically enhanced with the LONG, CONST, CONST$, or CONST$$ clauses.

AS LONG

In this case, the controlling expression and the CASE expressions must evaluate in the range of a Long-integer . Each of these expressions are calculated dynamically, so all of the normal operators are still available. Performance is enhanced by the integral class of code generation, rather than floating-point. For example, DWORD values are treated as Long-integer values, so &H0FFFFFFFF??? and -1& would be considered equal values. This can help eliminate the need to use functions such as BITS when performing comparisons between signed and unsigned values.

AS CONST

In this case, the controlling expression must evaluate in the range of a Long-integer. However, each of the case values must be strictly specified by a numeric literal (or numeric equate ) in the range of a Long-integer. Multiple case values may be given (CASE 2,3,7), but operators and ranges of values are not allowed. CASE ELSE is permitted. Performance is enhanced by the internal creation of a vector jump table, one entry for each number from the smallest to the largest case value.

While this form of the structure offers the utmost performance possible, the execution speed must be carefully weighed against the increased program size, particularly when using sparse case values. For example, with just two CASE values of 2 and 1000, the generated jump table would need 999 table entries (3996 bytes in size). The largest allowed jump table for this form is approximately 3200 entries (12K bytes). If exceeded, an Error 402 is generated ("Statement too long/complex").

AS CONST$

In this case, the controlling expression must evaluate to an ANSI string of length zero through 255 bytes. However, each of the case values must be strictly specified by a string literal (a quoted ANSI string, or an ANSI string equate). Multiple case values may be given (CASE "a","Bob",$value), but operators and ranges of values are not allowed. Performance is enhanced by the internal creation of a vectored scan table, eight bytes for each case value specified.

AS CONST$$

In this case, the controlling expression must evaluate to a WIDE (Unicode) string of length zero through 127 characters. However, each of the case values must be strictly specified by a string literal (a quoted wide string, or a wide string equate). Multiple case values may be given (CASE "a"$$,"Bob"$$,$$value), but operators and ranges of values are not allowed. Performance is enhanced by the internal creation of a vectored scan table, eight bytes for each case value specified.

See Also

  • CHOOSE
  • CHOOSE&
  • CHOOSE$
  • EXIT SELECT
  • IF
  • IF block
  • IIF
  • IIF&
  • IIF$
  • MAX
  • MAX&
  • MAX$
  • MIN
  • MIN&
  • MIN$
  • ON GOTO
  • ON GOSUB
  • SWITCH
  • SWITCH&
  • SWITCH$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
fstp   TBYTE PTR [ebp-0x50]
fild   DWORD PTR ds:0x202a58
fld   TBYTE PTR [ebp-0x50]
jne   0x2010e0
mov   edi,0xa
jmp   0x2010fa
fild   DWORD PTR ds:0x202a60
fld   TBYTE PTR [ebp-0x50]
jne   0x2010fa
mov   edi,0x14


Setting an error trap - ScharfBASIC Help

Setting an error trap

To enable an error trap , use the ON ERROR GOTO statement where you want trapping enabled within the procedure . The error-handling code must be within that procedure. An error trap is enabled only wh

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Writing an error handler

Exiting an error handler

Error Trapping Summary


Statement separation - ScharfBASIC Help

Statement separation

The colon character ( : ) can be used to separate multiple statements on a single (logical) line of source code. For example:

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

FOR x& = 1 TO 10 : INCR y& : NEXT x&

is directly equivalent to:

In general, placing only one statement per line leads to more readable and maintainable source code; however, using the colon separator can be useful for combining statements on single-line IF/THEN statements, etc. For example

IF x! < 0 THEN INCR y# : INCR z# : DECR Count& : GOTO LastX

Line numbers and Labels


Structured Programming - ScharfBASIC Help

Structured Programming

For most applications, good programmers use an organized approach to programming called structured programming . The original interpreted BASICs did not really support this kind of programming. Howeve

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Structured programming is based on the theory that modularization makes for better programs. Modularization means grouping statements together (making modules) that have some relation to each other. In other words, you break up your program into logical functional sections. This makes it easier to write, debug , and understand the program.

Ideally, modules should be no more than a page long. This seemingly arbitrary constraint makes it easier to absorb the entire module at a glance. It is easier to understand a series of ten single-page modules than it is a single ten-page program.

For some projects, after this initial breakup, you're ready to write the program. More complicated problems might require you to break the modules into subsidiary pieces. This process continues until you have refined the material enough so that you can write the code that corresponds to your ideas. This entire process is often described in books as "top-down design", since you start with a general description and work toward a more specific one.

Once you have the logical organization, you can start to design the overall structure of your program. For short, simple programs, these steps may only take a few minutes. For complex programs, it could take months.

To summarize the steps of structured programming (also known as 'top-down programming' or 'top-down design'):

1. Plan your program on paper. Ask yourself the following questions:

a. What is the overall purpose of the program?

b. What kind of input will it need?

c. How will it process that input?


SWITCH - ScharfBASIC Help

SWITCH

Return one of a series of values based upon a

Kind | Function
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

var = SWITCH( expr1 , val1 [[, expr2 , val2 ], ...])
var& = SWITCH&( expr1 , val1& [[, expr2 , val2& ], ...])
var$ = SWITCH$( expr1 , val1$ [[, expr2 , val2$ ], ...])

Description

SWITCH expects values of any numeric type. SWITCH& expects values optimized for Long-integer type. SWITCH$ expects values of string type.

If expr1 evaluates TRUE , val1 is returned, if expr2 evaluates TRUE, val2 is returned, etc.

Each control expression in the series is evaluated as a typical ScharfBASIC Boolean expression, which offers short-circuit expression evaluation as needed. To force a bitwise evaluation of an expression, enclose it in parentheses. The value parameters may be expressions, literals or variables of the appropriate data type for the SWITCH function in use.

SWITCH returns the matching value parameter from the first TRUE evaluation of the control expressions, evaluated from left to right in the list. Therefore, it would be wise to place the most likely selections at the front of the SWITCH list to achieve the utmost efficiency. If no expressions evaluate to TRUE, then zero (0) is returned.

Restrictions

Contrary to the implementation in some other languages, only the chosen value (one of val1 , val2 , val3 ) is evaluated at run-time; the other value parameters are not. This ensures optimum execution speed, as well as the elimination of unanticipated side effects.

See Also

  • CHOOSE
  • IF
  • IIF
  • SELECT


TRY/END TRY - ScharfBASIC Help

TRY/END TRY

A structured method of trapping and responding to

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TRY
[ statements ]
[EXIT TRY]
CATCH
[ error handling statements ]
[FINALLY
[ statements ]]
END TRY

Description

Statements in the TRY section are executed normally. The first time a run-time error occurs, control is transferred to the CATCH section. If no run-time errors are generated in the TRY section, the CATCH section is skipped entirely.

Then, regardless of error status, the FINALLY section is executed, if it is present. Error trapping and control transfer are disabled in the CATCH and FINALLY sections, so you would normally use conventional "IF ERR = " tests to check the success of error-prone operations in those sections.

However, TRY structures can be nested to any level, so it may be desirable to use another TRY block within these clauses.

Restrictions

CATCH is a mandatory section of this structure, although the FINALLY section is optional.

Because of the nesting requirements, the ERR value is local to the TRY structure. Upon exit, the prior ERR value is restored, so be sure to save the value of ERR if it will be needed outside of the TRY structure.

To leave the TRY structure, execution must pass normally through END TRY, or by an EXIT TRY statement. Leaving a TRY block any other way is strongly discouraged because error trapping will remain disabled, and the previous ERR value will not be restored. Future versions of ScharfBASIC may disallow such practices.

ON ERROR GOTO is invalid within a TRY structure, but may be used within the same Sub / Function / Method / Property .

See Also

  • #DEBUG ERROR
  • ERL
  • ERR
  • ERRCLEAR
  • ERROR
  • Error Overview
  • ERROR$
  • Error Trapping
  • ON ERROR


WHILE/WEND statements - ScharfBASIC Help

WHILE/WEND statements

Define a block of program statements that are executed repeatedly for as long as certain conditions are met.

Kind | Statement
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

WHILE integer_expression
[ statements ]
[EXIT LOOP]
WEND

Description

If integer_expression is TRUE (it evaluates to a non-zero value), all of the statements between the WHILE and the terminating WEND are executed. ScharfBASIC then jumps back to the WHILE statement and repeats the test. If it is still TRUE, ScharfBASIC executes the enclosed statements again. This process is repeated until the test expression evaluates to zero, or an EXIT statement is encountered. In either case, execution passes to the statement following WEND.

If integer_expression evaluates to FALSE (zero) on the first pass, none of the statements in the loop are executed.

Loops built with WHILE/WEND statements can be nested (enclosed within each other). Each WEND matches the most recent unmatched WHILE.

One use of a WHILE/WEND loop is to input data from a file until the end of the file is reached:

i& = 0

WHILE ISFALSE EOF(1)

INCR i&

LINE INPUT #1, FileTxt$(i&)

Although the compiler does not care, it's a good idea to indent the statements between WHILE and WEND, to clarify the structure of the loop you have constructed.

Note that the following code creates in infinite loop:

WHILE -1

[ statements ]

To exit a WHILE/WEND loop prematurely, use the EXIT LOOP statement.

ScharfBASIC's DO/LOOP construct offers a more flexible way to build conditional loops.

Also see the discussion on the IF statement for notes on ScharfBASIC's Short-circuit evaluation and its possible side effects.

See Also

  • #OPTIMIZE
  • DO/LOOP
  • EXIT
  • FOR EACH/NEXT
  • FOR/NEXT
  • ITERATE
  • Short-circuit evaluation

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

jle   0x2010cc


Writing an error handler - ScharfBASIC Help

Writing an error handler

When an error occurs and an error trap invokes your error-handling routine, the first thing the code should do is to determine which error occurred. ScharfBASIC's ERR and ERRCLEAR functions return the

Kind | Keyword
Category | Control Flow
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Setting an error trap

Exiting an error handler

Error Trapping Summary


Array Data Types - ScharfBASIC Help

Array Data Types

It is often useful to treat a set of variables as a group. This lets you perform repetitive operations more easily. An array is a group of string or numeric data sharing the same variable name. The in

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

ScharfBASIC provides several statements that perform operations on an array as a whole, allowing you to sort its contents, scan its contents for data that matches a certain condition, and insert data into or delete data from the existing structure.

You can think of an array as a row of boxes, numbered from zero to a predetermined number: four, in the example figure below. Each box holds a distinct value, which may or may not differ from the values in the other boxes. The boxes and their numbers are represented by parentheses surrounding a number; for example, item%(3) represents box number three of the array item% . Thus, if the value held within box number 3 is 1952, the statement total%=item%(3) would place the value 1952 into the variable total% .

Dimensioning a dynamic array with DIM or REDIM also clears each element, unless the PRESERVE option is present. Each element of each numeric array is set to zero; string arrays are set to the null string ("", length zero). Declaring the name and type of an array, as well as the number and organization of its elements, is performed by the DIM statement. For example:

DIM payments(55) AS CURRENCYX

creates an array variable payments , consisting of 56 Extended-currency elements, numbered 0 through 55. Array payments and an Extended-currency variable also named payments are separate variables. If this is confusing, you'll understand why we suggest that you use different variable names.

Multidimensional arrays


Bit Data Types - ScharfBASIC Help

Bit Data Types

TYPE and UNION structures may contain bit variables, which are named BIT (unsigned values) or SBIT (signed values). Each bit variable may occupy from 1 to 31 bits. When used in a TYPE, bit variables a

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Bit variables may only be used as TYPE or UNION members, not as scalar, array, or pointer variables. The size of a bit variable is defined as:

var AS BIT * nlit [IN BYTE|WORD|DWORD]

where the term "* nlit" defines the number of bits (1 to 31), and the optional term "IN BYTE|WORD|DWORD", if present, defines the start of a new bit field of 1, 2, or 4 bytes.

valu AS BIT * 31 IN DWORD

nybl2 AS BIT * 4 IN BYTE


Byte (?) - ScharfBASIC Help

Byte (?)

Bytes are 8-bit (1 byte) unsigned integers ranging in value from 0 to 255 ( 0 to 2^8-1). The type-specifier character for a Byte is: ?.

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Byte variables are identified by following the variable name with a question mark (i.e., var? ), or by using the DEFBYT statement as described in the previous discussion of Integers. You can also declare Byte variables using the BYTE keyword with the DIM statement. For example:

Byte variables are particularly useful for storing small, unsigned integral quantities like the number of days in a month. You should not use Byte variables in FOR/NEXT loops, as they are highly inefficient.

A ScharfBASIC Byte variable is equivalent to a bool data type (in lowercase) used by most modern C compilers. A bool is a non-traditional 8-bit unsigned data type, whereas a BOOL data type (in capital letters) is equivalent to a Long-integer in ScharfBASIC. Be aware that some older C compilers may freely interchange bool and BOOL keywords.

A Delphi byte is equivalent to a ScharfBASIC Byte.


SBYTE - ScharfBASIC Help

SBYTE

Signed 8-bit integer data type with one-byte storage.

Kind | Data Type
Category | Data Types
ScharfBASIC | EXTENSION
Notes | Native ScharfBASIC signed byte type

Syntax

LOCAL x AS SBYTE
DIM a(1 TO 10) AS SBYTE
TYPE T
    value AS SBYTE
END TYPE

Description

SBYTE stores a signed 8-bit integer in one byte. The intended value range is -128 through 127.

SBYTE has the same storage width as BYTE, but reads are signed. BYTE remains unsigned and keeps its 0 through 255 behavior.

Examples

FUNCTION PBMAIN() AS LONG
    LOCAL x AS SBYTE
    x = -1
    PRINT x
    PRINT SIZEOF(x)
END FUNCTION

TYPE Packet
    code AS SBYTE
    tag  AS BYTE
END TYPE

LOCAL p AS Packet
p.code = -128
p.tag = 255

Behavior Notes

  • Scalar locals, static variables, dynamic arrays, and UDT fields are covered by the ScharfBASIC feature prototypes.
  • SIZEOF for an SBYTE value is one byte.
  • Dynamic string fields inside UDTs remain rejected by the compiler's existing UDT layout rules.

See Also

  • BYTE
  • INTEGER
  • WORD
  • SIZEOF


Currency and Extended-currency - ScharfBASIC Help

Currency and Extended-currency

Currency variables are 8 byte binary representations of floating point numbers, which are considered to always have a fixed number of digits to the right of the decimal point. Currency numbers have a

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The type-specifier character for Currency and Extended-currency floating-point is: @ and @@ respectively.

You can also use the DEFCUR or DEFCUX statement as described under Integers . They can also be declared using the CUR/CURRENCY or CUX/CURRENCYX keywords with the DIM statement. For example:

Currency variables (@) have up to 4 digits of precision after the decimal point, and are useful for prices and quantities where fractions of a cent are desired. Extended-currency variables (@@) have two digits of precision after the decimal point. They are optimized for financial calculations where fractions of a cent are not required.

The currency data types are especially useful for financial calculations, as they avoid the round-off errors associated with Single, Double, and Extended-precision numbers (which must be an exact power of two in order to be represented exactly). While many numbers can be represented exactly as a power of two, there are also many that cannot. For example, 1.10000002384185791 is the closest power of two to 1.1, in single precision.

So, when assigning numeric literal values to a Currency or Extended-currency variable, we recommend using a type specifier to ensure the value is given the intended precision. For example:


Data Types - ScharfBASIC Help

Data Types

The care of numbers constitutes an important part of every programming system. Fortunately, ScharfBASIC allows you to ignore most technical considerations about internal number handling. If you never g

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

For efficiency, ScharfBASIC stores and processes data in different forms. It supports eleven unique numeric types, three string types, and also pointers. The following tables summarize the most important features and distinctions of these data types. The rest of this section explains these features in detail.

Numeric Data storage requirements and ranges

16 bits (2 bytes), signed


Data types in Registers - ScharfBASIC Help

Data types in Registers

There are three basic types of operands that can be placed in a register : immediate, memory or another register.

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

An immediate operand is usually a numeric literal (number) but it can also be a string literal in the form "a" which is converted by ScharfBASIC to its ASCII equivalent code.

! MOV AL, "a" ; String literal

! MOV EDX, 0 ; Numeric immediate/literal

A memory operand is an address in memory of some form of data:

! MOV AL, [ESI] ; Copy byte at address in ESI into AL

! MOV EDX, lpMemvar ; Copy variable address into EDX

A register operand is a register with a value in it:

! MOV ECX, EDX ; Copy EDX into ECX

The actions that can be performed are determined by the available opcodes . For example, trying to move one memory operand directly into another does not work because there is no opcode in the 80x86 processor to do it.

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edi,0x2a


Double-precision floating-point (#) - ScharfBASIC Help

Double-precision floating-point (#)

Double-precision floating-point numbers are to Single-precision numbers what Long-integers are to Integers . They take twice as much space in memory (8 bytes versus 4 bytes), but have a greater range

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Double-precision variables are identified by following the variable name with a Number symbol (i.e., var# ) or by using the DEFDBL statement as described in the previous discussion of Integers. You can also declare Double-precision variables using the DOUBLE keyword with the DIM statement. For example:

C/C++, Delphi, and Visual Basic all offer a double data type that is identical to the ScharfBASIC Double-precision variable.

Constants and Literals


Double-word (???) - ScharfBASIC Help

Double-word (???)

Double-words are 32-bit (four byte ) unsigned integer with a range of 0 to 4,294,967,295 ( 0 to 2^32-1). The type-specifier character for a Double-word is: ???.

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Double-word variables are identified by following the variable name with three question marks (i.e., var??? ), or by using the DEFDWD statement as described in the previous discussion of Integers. You can also declare Double word variables using the DWORD keyword with the DIM statement. For example:

As for Word values and Integers, Double-word values have a larger positive range than a Long-integer , and still require only four bytes. Double-word values are useful for indicating absolute memory addresses, such as may be used to store pointer values.

A ScharfBASIC Double-word is equivalent to a UINT32 in C/C++. In 32-bit C/C++ code, a UINT is also equivalent to a ScharfBASIC Double-word variable. Note that 16-bit C/C++ code uses UINT to describe a 16-bit Word variable.

A C++ unsigned int and a Delphi longword are equivalent to a ScharfBASIC Double-word.

Constants and Literals


Dynamic (Variable-length) strings ($) - ScharfBASIC Help

Dynamic (Variable-length) strings ($)

Dynamic string variables (also known as variable-length) may contain an arbitrary number of characters. Internally, each variable uses four bytes that contain a handle number, which is used to identif

Kind | Data Type
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

String variables are automatically declared when the variable name is followed by one or two dollar signs ($). You can also declare dynamic string variables using the STRING or WSTRING keywords with the DIM statement. For example:

ScharfBASIC allocates strings using the Win32 OLE string engine. This allows you to pass strings from your program to DLLs , or API calls that support OLE strings. The address of the contents of a non-empty string can be obtained with the STRPTR function. The address of the string handle can be obtained with VARPTR function. An empty (null) string may not return a valid STRPTR value. Dynamic strings move in memory with each assignment statement: that is, STRPTR will return a different address when the content of the string is changed. However, the associated string handle obtained by VARPTR stays constant for the duration of the life ( scope ) of the string variable.

LOCAL dynamic string memory and handles are released when the associated Sub , Function , Method , or Property ends. Subsequent calls to a routine will result in new storage locations for both the handle and the string data. The address of the handle of a STATIC or GLOBAL dynamic string stays constant for the duration of the module. Dynamic strings and field strings cannot be part of UDT (User-Defined Type) or UNION structures. In C/C++ , a dynamic wide string ($$) is referred to as a BSTR data type.

Nul-Terminated Strings


Extended-precision floating-point (##) - ScharfBASIC Help

Extended-precision floating-point (##)

Extended-precision floating point numbers are the basis of computation in ScharfBASIC. The type-specifier character for an Extended-precision floating-point is: ##. In ScharfBASIC, all floating point ca

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Extended-precision variables require 10 bytes of storage each. They have a range of approximately +/- 3.4*10^-4932 to 1.2*10^4932, and offer 18 digits of precision. All 18 digits can be "displayed" using the extended STR$ format (eg, STR$( var## ,18)).

Extended-precision variables are identified by adding two Number symbols following a variable name (i.e., var## ) or by using the DEFEXT statement.. You can also declare Extended-precision variables using the EXT or EXTENDED keywords with the DIM statement. For example:

Constants and Literals


FIELD - ScharfBASIC Help

FIELD

Bind a field string

Kind | Statement
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FIELD # filenum , nSize AS fieldvar , [FROM] nStart TO nEnd AS fieldvar [, ...]
FIELD DynamicStr , nSize AS fieldvar , [FROM] nStart TO nEnd AS fieldvar [, ...]
FIELD RESET fieldvar [, ...]
FIELD STRING fieldvar [, ...]

Description

A field variable is a special form of string variable which may be used just like a standard dynamic string variable, or it may be declared to reference a particular sub-section of a random file buffer or a dynamic string variable. Because of the added capabilities, it requires 12 bytes more storage space (16 vs 4) than a standard string variable. A field variable may not be used as a member of a User-Defined TYPE or UNION .

By default, a field variable mimics a dynamic string variable, and may be considered a virtual replacement. Then, at any time, the FIELD statement can be used to declare that the field variable now refers to a specific portion of a random file buffer or a dynamic string. FIELD RESET is used to change it back to a nul (zero-length) dynamic string. FIELD STRING also changes it back to a dynamic string, but first assigns the current sub-section data to it. This last action is particularly useful in the case where the sub-section data might be lost when the bound random file is closed.

In the first form, FIELD binds a field string variable to a specific sub-section of a random-access file buffer. In the second form, FIELD binds a field string variable to a specific sub-section of a dynamic string variable .If the sub-section extends beyond the actual size of the file buffer or string, that portion of the FIELD is empty. Otherwise, it represents a fixed size string, and may be referenced as any other string variable.

When used with a file:

A random-access file buffer is automatically created for use when GET or PUT are used without a target variable. In this case, the file data is read or written using this buffer, which is accessed with one or many field variables.

If a field is defined by a single field (size) parameter, it represents the length of the field in characters, with the start position implied by the preceding field within the statement. If two parameters are used, they represent the start ( nStart ) and end ( nEnd ) positions in characters, indexed to one.

If a string value shorter than the declared size is assigned to a field string, it is padded with blank spaces as it is placed into the file buffer. There is no requirement to use LSET for assignment.

Finally, it should be noted that FIELD statements are tied to an open file , i.e. they are valid only as long as the file is open. Once the file is closed , any field strings that had been defined for the file will return nul (empty), not a string of the previously specified length.

LOCAL sFirst AS FIELD, sSecond AS FIELD

OPEN "ABC.TXT" FOR RANDOM AS #1 LEN=20

FIELD #1, 10 AS sFirst, 10 AS sSecond

sFirst = "0123456789"

sSecond = "9876543210"

Put #1 ' creates a record of: 01234567899876543210

When used with a dynamic string:

A field variable bound to a dynamic string works very much like a pointer, so the programmer must use care in field variable selection. For example, if you bind a GLOBAL FIELD variable to a LOCAL string variable, then attempt to reference the global string after the local is destroyed (i.e., released when the owning Sub / Function / Method / Property exits), a fatal exception error (GPF) is likely to occur. The same could happen after an array has been erased , or a REDIM is used to change the memory allocation.

To avoid problems with scope , it is suggested that field variables be bound only with strings within the same scope (LOCAL, GLOBAL, etc.).

LOCAL x$, sFirst AS FIELD, sSecond AS FIELD

FIELD x$, 3 AS sFirst, 3 AS sSecond

x$ = SPACE$(6) ' Allocate the space for the field

SFirst = "111"

sSecond = "222"

? x$ ' Displays 111222

x$ = "abcd"

? sFirst ' Displays abc

? sSecond ' Displays d

Restrictions

Field string variables must be explicitly declared using DIM, INSTANCE , LOCAL, STATIC , GLOBAL, or THREADED . Attempting to bind a variable other than a declared field variable results in a compile-time Error 544 ("Field variable expected"). Field strings cannot be used in UDT or UNION structures. Attempting to do so results in a compile-time Error 485 ("Dynamic/Field strings not allowed").

See Also

  • Field Strings
  • GET
  • PUT
  • TYPE/END TYPE
  • User-Defined Types
  • Unions
  • UNION/END UNION


Fixed-length strings - ScharfBASIC Help

Fixed-length strings

As their name implies, fixed-length strings have a pre-defined length, and any attempt to assign a string longer than the defined length will result in truncation. If you assign a string to a fixed-le

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

You declare fixed-length string variables using STRING * x (for ANSI characters) or WSTRING * x (for WIDE characters). For example

DIM MyStr1 AS STRING * 10 ' occupies 10 bytes

DIM MyStr2 AS WSTRING * 10 ' occupies 20 bytes

The declared length refers to the number of characters, not the number of bytes . Unlike dynamic strings, the length of fixed-length strings is determined at compile-time, not run-time. In addition, unlike dynamic strings, fixed-length strings do not use handles. When you pass a fixed-length string to a procedure as a parameter, you are actually passing a pointer to the string data.

In ScharfBASIC (and most versions of BASIC), new fixed-length strings (and all variables) are initialized by filling with nuls, CHR$(0). When you assign a value, that text is padded to the right with the fill character, which defaults to a space).

A declaration of a fixed-length string or fixed-length string pointer must explicitly state the length of the variable, because the compiler must know it to allocate memory, and to pad the variable with spaces upon assignment.

The address of the contents of a fixed length string can always be obtained with the VARPTR function. LOCAL fixed-length string memory is released when the associated Sub , Function , Method , or Property ends. Subsequent calls to the routine will result in new storage locations for the fixed-length string data; however, the location of a LOCAL fixed-length string does not move until the string memory is released when the routine terminates.

LOCAL fixed-length strings are created on the stack frame, so LOCAL fixed-length strings will be limited to available stack space. Typically this is less than 1 MB unless a larger stack frame has been allocated with the #STACK metastatement. If larger fixed-length strings are required, it is advisable to make them INSTANCE , STATIC , or GLOBAL , since those are not created within the stack frame.

The address of the contents of STATIC and GLOBAL fixed-length strings stays constant for the duration of the module. STATIC and GLOBAL Scalar (non- array ) fixed-length strings may be up to 16,777,216 bytes each.


GUID$ - ScharfBASIC Help

GUID$

Return a 16-byte (128-bit) Globally Unique Identifier (

Kind | Function
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

id$ = GUID$[()]
id$ = GUID$(guidtext$)

Description

The GUID$ function, with no parameter (or a null, zero-length string parameter) will return a new, unique 16-byte string GUID (Globally Unique Identifier). This GUID may be used as a new class identifier or an interface identifier, or for some other purpose where a unique identifier may be required, such as for a one-time encryption key.

If guidtext$ is specified, GUID$ examines a text string, and converts the first standard format, human-readable GUID it finds, and returns a 16-byte binary string. This 16-byte string contains the internal GUID representation as a 128-bit data item.

To be valid, the GUID string in guidtext$ string must contain exactly 32 hexadecimal digits, optionally delimited by spaces or hyphens, but which must be enclosed overall by curly braces. For example: "{01234567-89AB-CDEF-FEDC-BA9876543210}".

The GUID$ function is the logical complement to the GUIDTXT$ function.

The return string may be assigned to a dynamic string , or a fixed-length string of at least 16 bytes, or (typically) a GUID variable. See DIM for more information on creating GUID variables.

Restrictions

If any errors are encountered, GUID$ returns a null (zero-length) string instead of the 16-byte GUID string. GUID$ can also be used in string equate assignments provided an explicit human-readable GUIDTXT$ argument string is assigned. For example:

$AppGuid = GUID$("{01234567-89AB-CDEF-FEDC-BA9876543210}")

See Also

  • DIM
  • CLSID$
  • GUIDTXT$
  • How are GUID's used with objects?
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • Just what is COM?
  • LET (with Objects)
  • OBJECT
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2020dc
call   0x2018f8
call   0x201d50
lea   ebx,[ebp-0xa4]
call   0x20205f
call   0x201f90


Integers (%) - ScharfBASIC Help

Integers (%)

To ScharfBASIC, an Integer is a number with no decimal point (what mathematicians would call whole numbers) with a range of -32,768 to +32,767 ( -2^15 to 2^15 - 1). These values stem from the underlyin

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Integers are identified by following the variable name with a percent sign (eg: var% ), or by using the DEFINT statement. For example, if you use this declaration in your program code:

then all variables following this declaration that start with the letter I, J, or K will be an Integer by default. You can also declare an Integer variable using the INTEGER keyword with the DIM statement. For example:

A C/C++ short variable and a Delphi smallint are both equivalent to a ScharfBASIC Integer.


Long integers (&) - ScharfBASIC Help

Long integers (&)

Like regular Integers , Long integers cannot contain decimal points. However, they span a much greater range, from -2,147,483,648 to +2,147,483,647 ( -2^31 to 2^31 - 1) yet occupy just 4 bytes (32-bit

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Long integers are identified by following the variable name with an ampersand (i.e., var& ) or by using the DEFLNG statement as described in the previous discussion of Integers. You can also declare Long-integer variables using the LONG keyword with the DIM statement. For example:

Long integers are the most efficient numeric data type in ScharfBASIC and should be used in all cases where speed is important and a greater numeric range is not required. (Using Byte and Integer variables in FOR/NEXT loops is actually slower than using a Long integer.)

A ScharfBASIC Long-integer variable is equivalent to the BOOL data type (in capital letters) commonly used by C/C++ compilers. Note that a bool (lowercase) is a non-traditional data type, equivalent to a Byte in ScharfBASIC. Be aware that some older C compilers may freely interchange bool and BOOL keywords.

A C/C++ int and a Delphi longint variable are also equivalent to a ScharfBASIC Long integer.


Nul-Terminated Strings - ScharfBASIC Help

Nul-Terminated Strings

A Nul-Terminated string is called a STRINGZ with ANSI characters, or WSTRINGZ with WIDE , Unicode characters. When declared with ANSI characters, they are commonly known as ASCIIZ strings. You can thi

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

If you assign a string that is shorter than the defined length, the string will not be padded on the right. The contents of the remainder of the string buffer are undetermined. Because a NulTerm string requires a NUL terminator, they are usually defined with a length of at least two characters.

You declare STRINGZ variables using the STRINGZ or WSTRINGZ keywords with the DIM statement. For example:

DIM MyStr1 AS STRINGZ * 40

DIM MyStr2 AS WSTRINGZ * 40

This creates a 40 byte STRINGZ (ASCIIZ) string named MyStr1, and an 80 byte WSTRINGZ string named MyStr2. The declared size always refers to the number of characters, not the number of bytes. The number of characters you can actually store is always one less than the defined length of the string. One character position is used to hold the NUL terminator. Therefore, MyStr1 and MyStr2 can each hold up to 39 characters.

When assigning string data to a NulTerm string, the assignment will stop if an embedded CHR $(0) (nul) is encountered. For example:

DIM b AS STRINGZ * 10

a = "ABC" + CHR$(0) + "DEF"


Numeric Equates - ScharfBASIC Help

Numeric Equates

ScharfBASIC allows you to refer to numeric constants by name. Be aware that equates have global scope ; that is, they are visible throughout your program. Unlike variables , you can use an equate on th

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

%Q = (1& OR 2&) + (NOT 0)

A value must be assigned to each equate before it is referenced, even if that value is zero. If you fail to define an equate, an error will be generated during compilation. Numeric equates must be created outside of any SUB , FUNCTION , METHOD , or PROPERTY . All equates are global , and may be referenced anywhere in the module. For readability, we suggest placing equates at the top of your code.

A numeric equate name must always begin with a leading percent sign (%) and a letter (A-Z). This is optionally followed by any combination of letters (A-Z), numbers (0-9), and underscores (_). Equates created within an ENUM structure may also contain one period (.), which is inserted by the compiler as a delimiter. All other characters are illegal.

If you are using a version of ScharfBASIC which creates COM servers , you can easily include numeric equates in your type library ; just append the words AS COM to the equate definitions:


OBJECT - ScharfBASIC Help

OBJECT

Communicate with a

Kind | Statement
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

OBJECT GET interface . member [. member .] [([[ paramname =] param1 [, ...]])] TO ResultVar
OBJECT LET interface . member [. member .] [([[ paramname =] param1 [, ...]])] = ValueVar
OBJECT SET interface . member [. member .] [([[ paramname =] param1 [, ...]])] = ValueVar
OBJECT CALL interface . member [. member .] [([[ paramname =] param1 [, ...]])] [TO ResultVar ]
OBJECT RAISEEVENT [ interface .] member [([[ paramname =] param1 [, ...]])]

Description

There are five general forms of the OBJECT statement which are used to communicate through a Dispatch interface to an object .

OBJECT GET

Retrieve or read the value of an Interface member Property . This is similar to retrieving the value of a variable .

OBJECT LET

Assign or write a value to an Interface member Property. This is similar to assigning a value to a variable.

OBJECT SET

Assign or write a value to an Interface member Property that contains a reference to an object. For example, a reference to another Interface.

OBJECT CALL

Call or execute a member Method of an Interface. This is equivalent to calling a Sub or Function .

OBJECT RAISEEVENT

Call or execute a member Method of a Dispatch event Interface . Because the Dispatch event interface is pre-defined, you are not required to specify the interface name in this form of the statement. However, including it aids in self-documentation of your program. If your program is using a Direct, V-Table event handler you should use the RAISEEVENT statement instead. See the EVENT SOURCE statement for an OBJECT RAISEEVENT example.

All parameters, return values, and assignment values must be in the form of COM -compatible variables. Literals and expressions are not allowed. COM-compatible variables include BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , CURRENCY , POINTER , and VARIANT . You should use caution passing string data since COM Objects require that unicode format be used. When string data is contained in a VARIANT variable, conversion to/from unicode is automatic, and no intervention is needed from the programmer. However, if you pass data in a dynamic string variable, you must use the ACODE$ () and UCODE$ () functions to convert the data to an appropriate format. For this reason, we recommend that string data be passed using VARIANT variables.

Dispatch OBJECT Method calls may be bound at run-time using late binding , which requires no declaration of Properties and Methods . However, for this very reason, the validity of these references can not be verified by ScharfBASIC at the time the program is compiled.

The OBJECT statement can use both positional and named parameters, but you should keep in mind that not all COM Dispatch Servers support named parameters. Positional parameters are universally supported.

A positional parameter is simply a variable containing an appropriate value. It is identified by its position in the parameter list, just as in a traditional SUB or FUNCTION. A named parameter consists of a parameter identifier (a name), an equal (=) sign, and a variable containing an appropriate value. Positional parameters must precede any and all named parameters, but named parameters may be specified in any sequence.

Each time you call a Method or Property using the OBJECT statement, a status code is returned in a hidden parameter to indicate the success or failure of the operation. You can retrieve information about this status code with the OBJRESULT function, and also by using the IDISPINFO Dispatch Information Object. If the failure was severe, then a ScharfBASIC error 99 (Object Error) is also generated and the ERR system variable is set. You can find more information about these items by referring to OBJRESULT, IDISPINFO, and ERR. This information can be very useful for both debugging and handling run-time errors .

Restrictions

All parameters, return values, and assignment values must be in the form of COM-compatible variables. Use of the wrong member mode (GET/LET/SET/CALL/RAISEEVENT) can sometimes result in unexpected and fatal run-time errors. So, it's usually prudent to test the result code in OBJRESULT after every OBJECT statement.

See Also

  • ACODE$
  • DIM
  • CLASS
  • CLSID$
  • EVENT SOURCE
  • IDISPINFO
  • GUID$
  • GUIDTXT$
  • ID Binding
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • Just what is COM?
  • Late Binding
  • LET (with Objects)
  • METHOD
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • PROPERTY
  • UCODE$
  • What is an object, anyway?
  • What is DISPATCH?


Pointers (@) - ScharfBASIC Help

Pointers (@)

A pointer is a variable that holds the 32-bit (4 byte ) address of code or data located elsewhere in memory. It is called a pointer because it literally points to that location. The location pointed t

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Pointers represent a powerful addition to the BASIC programmer's arsenal. The address is defined at run-time, so your program can reference any memory location as if it were a standard variable . When a pointer is used to access a memory location, it is called "indirect addressing".

Pointers are declared using the DIM statement, and the type of the target must be specified. The keywords PTR and POINTER are synonymous.

DIM i AS INTEGER PTR 'declares i as a pointer to an Integer

DIM i AS INTEGER POINTER

The above example declares i as an Integer pointer. Before it can be used, i must be initialized with an actual address of a variable (easily done with the VARPTR function; or STRPTR for strings ). When you assign a value to a pointer variable, you are giving it an address to use later when you wish to reference the actual target. A pointer's name alone references the pointer variable. A pointer's name with an at sign (@) prefix, references the pointer's target:

DIM Ptr1 AS BYTE PTR ' declares Ptr1 as a byte pointer

DIM Ptr2 AS BYTE PTR ' declares Ptr2 as a byte pointer

DIM Byte1 AS BYTE ' Declares Byte1 as a byte variable


Pointers to Nul-Terminated and fixed-length strings - ScharfBASIC Help

Pointers to Nul-Terminated and fixed-length strings

A declaration of an Nul-Terminated or fixed-length string must explicitly state the maximum length of the string, in order for the compiler to allocate memory accordingly. When declaring pointers to f

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

However, with an Nul-Terminated string pointer, the length limit may be explicitly stated, or it may be left as an ambiguous value, by skipping the length clause entirely. For example, the following lines are valid:

DIM x AS ASCIIZ PTR * 41

DIM y AS STRINGZ PTR * 2

DIM z AS WSTRINGZ PTR

This rule applies to scalar pointers, arrays of pointers, pointers as function parameters, and pointers as members of a User-Defined Type or Union . If the optional length limit is specified, ScharfBASIC will always truncate a string assignment to fit correctly in the memory allocated to the variable.

If the length is ambiguous, it becomes the programmer's responsibility to ensure the target buffer is not overflowed leading to memory corruption or General Protection Faults (GPF). Use caution in this case.


Quad integers (&&) - ScharfBASIC Help

Quad integers (&&)

Quad-integers are 64-bit (8 byte ) signed integers (twice as many bits as Long integers ) with a range of -9.22x10^18 to 9.22x10^18 ( -2^63 to 2^63 -1). The type-specifier character for a Quad integer

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Quad-integer variables are identified by following the variable name with two ampersands (i.e., var&& ), or by using the DEFQUD statement as described in the previous discussion of Integers. You can also declare Quad-integer variables using the QUAD keyword with the DIM statement. For example:

Although a Quad integer actually has 19 digits of precision, only 18 digits of accuracy can be "displayed" with STR$ . A 19-digit value will be rounded to 18 digits in scientific notation when used with STR$. STR$ works with up to 16 significant digits by default, so the enhanced form of STR$ (eg: STR$( var ,18)), must be used to generate the 17th and 18th digits of a Quad integer for display purposes.

A C/C++ LARGE_INTEGER and a Delphi int64 are both equivalent to a ScharfBASIC Quad integer.


Single-precision floating-point (!) - ScharfBASIC Help

Single-precision floating-point (!)

Single-precision floating-point numbers (or more simply, Single-precision) may be the most versatile numeric type supported by ScharfBASIC. Single-precision values can contain decimal points and have a

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Single-precision variables are identified by following the variable name with an exclamation point (i.e., var! ) or by using the DEFSNG statement as described in the previous discussion of integrals. You can also declare Single-precision variables using the SINGLE keyword with the DIM statement. For example:

While Single-precision numbers can represent both enormous and microscopic values, they are limited to six digits of precision. In other words, Single-precision does a good job with figures like $451.21 and $6,411.92, but $671,421.22 cannot be represented exactly because it contains too many digits. Neither can 234.56789 or 0.00123456789. A Single-precision representation will come as close as it can in six digits: $671,421, or 234.568, or 0.00123457. Depending on your application, this rounding off can be a trivial or crippling deficiency. Like most modern compilers, ScharfBASIC uses the IEEE standard for all floating-point arithmetic.

C/C++, Delphi, and Visual Basic all offer a single data type that is identical to the ScharfBASIC Single-precision variable.

Currency (@) and Extended-currency (@@)

Double-precision floating-point (#)

Extended-precision floating-point (##)


String Equates - ScharfBASIC Help

String Equates

You can create a string equate by prefixing $ (for ANSI ) or $$ (for WIDE ) to the equate name. The value on the right side of the equate assignment must be a string literal , or an expression created

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

$$Fullname = "John"$$ & " Smith"$$

$$UserNam = $$First & $$Last

$PrintCode = CHR$(27, 34, "E") + SPACE$(10) + CHR$(65 TO 90)

$AppGuid = GUID$("{01234567-89AB-CDEF-FEDC-BA9876543210}")

A string equate can include the double-quote character, simply by doubling the character within the string. For example:

$ABC = "This is a ""string"""

ANSI string equates are each limited to 255 characters, while WIDE equates are limited to 127 characters. An attempt to create a longer string equate will trigger a compile-time Error 489 ("Invalid string length").

As with numeric equates, ScharfBASIC pre-calculates the string equate content during compilation to limit calculations at run-time. Duplicate definitions of both numeric and string equates are permitted by ScharfBASIC, provided the actual content is identical. If the content is not identical, a compile-time Error 468 ("Duplicate Equate") will be generated.


VARIANT$/VARIANT$$ - ScharfBASIC Help

VARIANT$/VARIANT$$

Returns the byte string

Kind | Function
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

AnsiVar = VARIANT$( VrntVar )
WideVar = VARIANT$$( VrntVar )
TypeVar = VARIANT$(BYTE, VrntVar )

Description

VARIANT$ extracts a string from a variant variable if a dynamic string (VT_BSTR) is found there. If the variant contains any other VT type , an empty string is returned. By definition, a BSTR is a wide Unicode string. It is generally safe to assume this is the case, unless the variant was created by ScharfBASIC and you know the internal format is bytes rather than wide Unicode words.

The first form of VARIANT$ converts the wide Unicode contents to ANSI , returning it as an ANSI string. The second form of VARIANT$$ returns the contents directly as a wide Unicode string. Of course, in all assignment and parameter situations, ScharfBASIC will automatically handle any conversions needed between ANSI and WIDE string values. For that reason, no additional code should be added to this operation for ANSI/WIDE conversion. Also, keep in mind that the correct choice of function can improve the performance of your program.

If the BYTE option is specified, you are telling ScharfBASIC that the string contains a set of BYTES rather than wide Unicode words. This would be the case if you stored a User-Defined Type in a variant:

LET VariantVar = ThisUDTVar AS STRING

ThatUDTVar = VARIANT$(BYTE, VariantVar )

This form of VARIANT$ always returns the contents as an ANSI byte string. This result can be assigned to an ANSI string variable or a User-Defined Type.

Legacy

Older legacy programs were forced to store Unicode characters in an ANSI string variable because wide string variables were not yet available. These programs should continue to use VARIANT$ with ACODE$ and variant assignment with UCODE$ until the program logic is updated to use wide Unicode variables.

See Also

  • DIM
  • LET
  • OBJECT
  • LET (with Variants)
  • VARIANT#
  • VARIANTVT


VARIANTVT - ScharfBASIC Help

VARIANTVT

Determine the internal data type of the data stored in a

Kind | Function
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

numericvar = VARIANTVT( vrntvar )

Description

The VARIANTVT function returns the internal VT data type stored in the Variant. The entire range of %VT_ prefixed values are documented by the OLE ( COM ) specification and are available in WIN32API.INC.

The most important values in this limited context include %VT_EMPTY (=0) and %VT_BSTR (=8), since most of the others are numeric formats automatically resolved by the LET (with Variants) statement and VARIANT# function.

Result

Equate

Content Type

%VT_EMPTY

An Empty Variant

%VT_NULL

Null value

%VT_I2

Integer

%VT_I4

Long-Integer

%VT_R4

Single

%VT_R8

Double

%VT_CY

Currency

%VT_DATE

%VT_BSTR

Dynamic String

%VT_DISPATCH

IDispatch

%VT_ERROR

Error Code

%VT_BOOL

Boolean

%VT_VARIANT

Variant

%VT_UNKNOWN

IUnknown

%VT_DECIMAL

Decimal

%VT_I1

Byte (signed)

%VT_UI1

Byte (unsigned)

%VT_UI2

%VT_UI4

%VT_I8

Quad (signed)

%VT_UI8

Quad (unsigned)

%VT_INT

Long-Integer

%VT_UINT

%VT_VOID

A C-style void type

%VT_HRESULT

COM result code

%VT_PTR

Pointer

%VT_SAFEARRAY

VB Array

%VT_CARRAY

A C-style array

%VT_USERDEFINED

User Defined Type

%VT_LPSTR

%VT_LPWSTR

Unicode string

%VT_RECORD

%VT_FILETIME

A FILETIME value

%VT_BLOB

An arbitrary block of memory

%VT_STREAM

A stream of bytes

%VT_STORAGE

Name of the storage

%VT_STREAMED_OBJECT

A stream that contains an object

%VT_STORED_OBJECT

A storage object

%VT_BLOB_OBJECT

A block of memory that represents an object

%VT_CF

Clipboard format

%VT_CLSID

Class ID

&H1000

%VT_VECTOR

An array with a leading count

&H2000

%VT_ARRAY

&H4000

%VT_BYREF

A reference value

If a Variant contains a complete array , the Variant type is determined by adding the base type to the array modifier. That is, for a string array , it would be %VT_BSTR plus %VT_ARRAY (= &H2008).

Quad arrays within Variants are not supported by most versions of Windows. The result from VARIANTVT can be used to see whether such an array was created properly.

See Also

  • DIM
  • Just what is COM?
  • OBJECT
  • LET (with Variants)
  • VARIANT#
  • VARIANT$
  • VARIANT$$
  • What is an object anyway?


Word (??) - ScharfBASIC Help

Word (??)

Words are 16-bit (two byte ) unsigned integers with a range of 0 to 65535 ( 0 to 2^16-1). The type-specifier character for a Word is: ??.

Kind | Keyword
Category | Data Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Word variables are identified by following the variable name with two question marks (i.e., var?? ), or by using the DEFWRD statement as described in the previous discussion of Integers. You can also declare word variables using the WORD keyword with the DIM statement. For example:

Word values effectively extend the positive range for Integer, but still only require two bytes for storage.

A C/C++ UINT16 and a Delphi word are equivalent to a ScharfBASIC Word.


Error Overview - ScharfBASIC Help

Error Overview

Unlike the DOS versions of ScharfBASIC , Windows versions of ScharfBASIC employ a completely different philosophy: to generate the smallest and fastest possible code. Consequently, error handling is pla

Kind | Keyword
Category | Error Reference
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Compile-time errors are generated when the compiler cannot resolve a problem in your source code while it is compiling. Examples include: typographical errors; assigning incorrect values to variables (such as "x$ = 5"); and attempting to use a variable name which has not been dimensioned when OPTION EXPLICIT (or #DIM ALL ) has been turned on.

When a compile-time error is detected, ScharfBASIC will display a message box indicating the error code, plus a brief description, along with the line number in the code where the error occurred. The offending line of code will also be displayed. If you are using the ScharfBASIC IDE, the caret will move to the offending line once the error dialog has been dismissed.

Run-time errors are generated when execution of a particular code statement or function results in an error condition being set. Run-time errors caught by ScharfBASIC include Disk access violations (i.e., trying to write data to a full disk), out of bounds array and pointer access, and Memory allocation failures. Array bounds and null-pointer checking is only performed when #DEBUG ERROR ON is used.

Run-time errors can be trapped; that is, you can cause a designated error-handling subroutine to get control should an error occur. Use the ON ERROR statement to accomplish this. This routine can "judge" what to do next based on the type of error that occurs. File-system errors (for example, disk full) in particular are prime candidates for run-time error-handling routines. They are the only errors that a thoroughly debugged program should have to deal with.

The ERROR statement (which simulates run-time errors) can be used to debug your error-handling routines. It allows you to deliberately cause an error condition to be flagged. Avoid using error numbers higher than 240, as they are reserved for use in critical error situations which can never be trapped with ON ERROR. Run-time error values are restricted to the range 1 through 255, and the compiler reserves codes 0 through 150, and 241 through 255 for predefined errors. Attempting to set an error value (with the ERROR statement) outside of the valid range 1 to 255 will result in a run-time Error 5 ("Illegal function call") instead. In addition to the predefined run-time errors, you may also set your own customized run-time error codes in the range 151 through 240. These error codes may be useful to signal specific types of errors in your own applications, ready to be handled by your error trapping code.

In the situation where an undocumented run-time error occurs, the chief suspect is memory corruption. This can typically be cause by writing beyond an array boundary, improper use of pointers, bad Inline Assembly code, etc.


ASMDATA/END ASMDATA statements - ScharfBASIC Help

ASMDATA/END ASMDATA statements

Define a block where primitive read-only data is stored.

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ASMDATA BlockName
DB 1, "ABC"$, 0
DW 2, "XYZ"$$, 0
DD &H12345678
DQ 1234567890
END ASMDATA

Description

It is frequently convenient to define some data within the code section of your program. This data is read-only, so it may never be altered. An attempt to do so will result in a GPF (General Protection Fault), which will cause termination of your program. This type of data is generally accessed only by ASM code.

Defined Data can be placed inside of a Sub , Function , Method , or Property using ASM statements, but there are a number of pitfalls to that technique. When debugging, or when using TRACE , PROFILE , #DEBUG DISPLAY , ERL , ERL$ , etc., ScharfBASIC must insert special code in various places which makes if difficult (if not impossible) for you to access the data accurately. You don't know the size of the inserted code, so you'll have some difficulty addressing it accurately.

An ASMDATA block solves that problem entirely. It is designed for the sole purpose of defining data, and no extra code or extra data is ever inserted for any reason. Data within the block is never aligned , so you always know the exact location of each item. The ASMDATA block must be located outside of any Sub, Function, Method, or Property. However, the BlockName you assign is public, so it may be referenced from any place in your program. You may have one block on your program, or many.

By default, all ASMDATA blocks are positioned at the first available byte . This allows contiguous blocks to be accessed as though they were one larger block. You can align any or all of the blocks differently by preceding the block with an #ALIGN metastatement.

Labels and line numbers are not allowed in an ASMDATA block. If you need a reference point to a particular sub-section of your data, just split it into two or more blocks, using each BlockName as the reference point.

The only statements allowed within an ASMDATA block are DB, DD, DQ, and DW, so they do not need to be preceded by an ASM statement. An ANSI string literal expression may be placed in a DB statement, and a WIDE (unicode) string literal expression may be placed in a DW statement, it should be noted that strings in ASM blocks must be 255 characters or less. A string literal expression may consist of quoted string literals, string equates , and the concatenation operators (&,+). You may also use CHR$() , SPACE$() , and STRING$() if they use only literal parameters.

You can access the address of an ASMDATA block with the CODEPTR() function. So, if you create a block named ABC, like this:

ASMDATA ABC

DB 5,2,3

DB 7,8,9

END ASMDATA

You would access it something like this:

AsmVar = CODEPTR(ABC)

Another option is to access it directly to a CPU register of your choice by using one of these opcodes:

ASM LEA EBX, abc

ASM MOV EBX, Offset abc

This would result in moving the first data byte (5) into register AL.

Or even move it directly to a 32-bit variable:

ASM MOV AsmVar, Offset abc

See Also

  • ASM

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x2a


Binary Files - ScharfBASIC Help

Binary Files

ScharfBASIC's binary file technique, an extension to Interpretive BASIC, allows you to treat any file as a numbered sequence of bytes without regard to anything, including the following: ASCII characte

Kind | Keyword
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Flexibility always comes at a price. Binary files require that you do all the work to decide what goes where. Binary may be the best option when dealing with alien files that aren't in ASCII format; for example, a file created by a spreadsheet or database product. Of course, you will have to know the precise structure of the file before you can even attempt to break it down into numbers and strings agreeable to ScharfBASIC.

Every file opened in binary mode has an associated position indicator that points to the place in the file that will be read or written to next. Use the SEEK statement to set the position indicator, and the SEEK function to read it.

Binary files are accessed in the following way:


CLOSE - ScharfBASIC Help

CLOSE

Conclude I/O (input/output) to / from a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CLOSE [[#] filenum& [, [#] filenum& ] ...]

Description

CLOSE ends the relationship between a ScharfBASIC file number and the disk file or device that was associated with it by an OPEN statement. Any pending I/O operations on the file/device are concluded, buffers are flushed and released, and the disk directory information (if any) for that file is updated.

If no file number is specified, CLOSE closes all open files.

If the file was opened using OPEN HANDLE, the CLOSE statement is still needed, although it does not tell the operating system to close the file. In this special case, the file was already open when OPEN HANDLE provided access to it, and will remain open after CLOSE disassociates the file from ScharfBASIC.

CLOSE works with all types of files and devices (disk files, devices, COMM , TCP , UDP , etc).

The number symbols (#) are optional but recommended for clarity.

See Also

  • COMM CLOSE
  • FILEATTR
  • FLUSH
  • OPEN
  • TCP CLOSE
  • UDP CLOSE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x201e28
call   0x201dab
mov   eax,0x1
call   0x201c74
call   0x201cdc


EOF - ScharfBASIC Help

EOF

Return the end-of-file status of an opened file or

Kind | Function
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = EOF([#] filenum& )

Description

Use EOF to determine when the end of a file has been reached while reading its data. filenum& is the file number specified when the file was Opened. EOF returns -1 (TRUE) if the end of the specified file has been reached, or if an error occurs trying to check for the end of the file. Otherwise, EOF returns 0 (FALSE).

If filenum& is not a valid, open file, a run-time Error 53 will occur ("File not found"). If filenum& is for a binary file , EOF returns TRUE only if the most recent file operation was a read operation, and that operation could not read the requested number of bytes.

The EOF function may also be used with the COMM LINE and TCP LINE statements to detect that an incomplete line was received. Normally, these statements read data until a $CRLF character pair is found, and in that case, EOF will return 0 (FALSE). However, even if no $CRLF has been found, the statements will end when no additional data is available. In that case, they will return whatever data has already been accumulated, and set EOF to -1 (TRUE).

In many cases, it would be prudent to test EOF after every COMM LINE and TCP LINE to verify that a full line has been received. In some cases, you may wish to execute the statement one or more additional times, combining the data, in order to obtain a full line of text.

See Also

  • COMM LINE
  • LOC
  • LOF
  • OPEN
  • TCP LINE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x204a54
call   0x203004
call   0x202f87
mov   eax,0x1
call   0x2018b8
call   0x202eb8


FILEATTR - ScharfBASIC Help

FILEATTR

Return information about an

Kind | Function
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

lResult& = FILEATTR([#] filenum& , fattr )

Description

filenum& is the handle of a currently open file. fattr is an integer between -3 and 3 that specifies the type of information required, according to the following table:

Definition

The device type. Returns 1 for a file , 2 for a device. COMM , TCP and UDP are classified as devices.

Logical first byte (base) position of a disk file. By default, ScharfBASIC opens files with a default first location of 1, but this can be overridden via the BASE= clause of the OPEN statement. This function can be useful when the base is not known or when performing SEEK operations.

The minimum amount of data that can be read or written at one time. For RANDOM files , it is the record length. For INPUT files , it is the input buffer length (set with LEN= in the OPEN statement). For BINARY , OUTPUT and APPEND , there is no buffering, so it always returns 1 (1 byte).

The open state. TRUE (non-zero) if open, FALSE (zero) if closed.

The file mode (which may be a combination of the following):

result&

File mode

Output

Random

Append

Serial Communications (COMM)

Binary

TCP Winsock

UDP Winsock

(for example, an APPEND file will return 8 + 2 = 10).

The operating system file handle for the file. This handle can be used with particular Windows API calls files to manipulate files opened with ScharfBASIC, and with the OPEN HANDLE statement.

Enumerates existing file numbers. This mode enumerates existing file numbers, in the range of 1 to 32767. FILEATTR(1,3) returns the first located file number, FILEATTR(2,3) the second, and so on until -1 is returned to indicate that there are no more file numbers active. The file numbers returned are not guaranteed to be returned in any particular sequence, nor be open. You can use FILEATTR(#filenum,0) to determine whether a given file number is open or closed.

The number symbol [#] is optional, but recommended for clarity.

See Also

  • COMM OPEN
  • EOF
  • FILENAME$
  • GETATTR
  • LOF
  • OPEN
  • SEEK function
  • SEEK statement
  • SETATTR
  • TCP OPEN
  • UDP OPEN


FILENAME$ - ScharfBASIC Help

FILENAME$

Return the file-system name of an

Kind | Function
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = FILENAME$( filenum& )

Description

a$ receives the name of the open file identified by the file number filenum& . This function is not valid with a file opened using OPEN HANDLE , COMM OPEN , TCP OPEN , or UDP OPEN .

See Also

  • CLOSE
  • FILEATTR
  • FREEFILE
  • GETATTR
  • OPEN
  • SETATTR


FILESCAN - ScharfBASIC Help

FILESCAN

Rapidly scan a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FILESCAN [#] fnum& , RECORDS TO y& [, WIDTH TO x& ]

Description

FILESCAN assigns a count of the lines/records/strings to y& , and if the WIDTH clause is specified, the length of the longest string to x& .

In INPUT mode, it is assumed the data is standard text, with lines delimited by a CR/LF ( $CRLF ) pair. FILESCAN stops reading the file if it encounters an "end of file" (EOF) marker byte ( CHR$ (26) or $EOF ). Text that occurs after the last CR/LF but before the EOF is considered the last record of the file. Use the LINE INPUT# statement to read a complete text file into an array.

In BINARY mode, it is assumed the file was written in the ScharfBASIC and/or VB packed string format using PUT of an entire string array. If a string is shorter than 65535 bytes, a 2-byte length WORD is followed by the string data. If a string is equal to or longer than 65535 bytes, a 2-byte value of 65535 is followed by a length DWORD value, then finally the string data.

Use the GET statement to read a complete binary file into an array.

Restrictions

If FILESCAN is applied to other file formats, the results are undefined.

See Also

  • GET
  • GET$
  • GET$$
  • LINE INPUT#
  • PUT
  • PUT$
  • PUT$$


FLUSH - ScharfBASIC Help

FLUSH

Flush

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FLUSH [[#] filenum& [, [#] filenum& ] ...]

Description

FLUSH ensures that all data you have written to disk files has actually been written to disk. The CLOSE statement also flushes the buffers, but FLUSH has the advantage of leaving the files open.

filenum&

The file number of an OPEN file. If filenum& is specified, only the data for that file is flushed. Otherwise, data for all open files is flushed. The Number (#) symbol is optional, but recommended for the purposes of clarity.

See Also

  • CLOSE
  • OPEN


FREEFILE - ScharfBASIC Help

FREEFILE

Return the next available ScharfBASIC file number.

Kind | Function
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x% = FREEFILE

Description

FREEFILE returns an Integer value in the range 1 to 32767, which dictates the next available file number that may be used to OPEN a file or device. Using FREEFILE, your program can open files and devices without the need to keep track of which file numbers are already in use.

FREEFILE is thread-safe, returning a new file number with each invocation. This means that two or more consecutive calls to FREEFILE will return different file numbers regardless of whether they were used to open a file or not. This behavior differs from previous versions of ScharfBASIC, where FREEFILE returned the same file number consistently until the file number was actually used to open a file or device.

FREEFILE is vastly superior to using hard-coded file numbers because it eliminates the possibility of a file number being used more than once in a module at any given moment.

A file number returned by FREEFILE can be used with the COMM OPEN , TCP OPEN and UDP OPEN statements, as well as standard file I/O OPEN and OPEN HANDLE statements.

Use FILENAME$ to return the name of the open file that corresponds to a given file number.

Restrictions

FREEFILE returns file numbers within a predictable and convenient range of values. ScharfBASIC file numbers are also specific (private) to the ScharfBASIC module in which they are used to OPEN a file or device. This means that a file number in use in one module will have no definition or meaning if passed to another module or API function.

However, it can sometimes be necessary for a different module or even an API function to access a file that is already open. In this case, it is necessary to use the FILEATTR function to obtain the operating system file handle, and this value can be passed to other modules or API functions. These modules would use the OPEN HANDLE statement to gain access into the already-open file.

See Also

  • COMM OPEN
  • FILEATTR
  • FILENAME$
  • OPEN
  • TCP OPEN
  • UDP OPEN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201df8
call   0x201d7b
call   0x201d24
call   0x201c6c


GET - ScharfBASIC Help

GET

Read a record from a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

Random-Access files:
GET [#] filenum& , [ Rec ], [ABS] Var
GET [#] filenum& [, Rec ]
Binary files:
GET [#] filenum& , [ RecPos ], Var
GET [#] filenum& , [ RecPos ], Arr() [RECORDS rcds ] [TO count ]

Description

A string variable used to receive data may be either ANSI or WIDE , but it must match the CHR mode of the data read from the file. That is, if the data was written as an ANSI string, it should be read into an ANSI string variable. If it was written as a WIDE string, it should be read into a WIDE string variable. Failure to match this CHR mode can cause unpredictable interpretation of the data. GET never performs conversions of ANSI/WIDE characters, regardless of the CHR mode specified in the OPEN statement. It reads data from the file based upon the type of string variable you use. It is the responsibility of the programmer to choose the correct type.

filenum&

The file number under which the file was opened.

Random Access files

For random-access files, Rec is the record number to be read, from 1 to 2^63-1 (the maximum positive value for a Quad-integer ). If Rec is omitted, the next record in sequence (following the one specified by the most recent GET or PUT ) is read. If the file was just opened, the first record is read.

If Var is smaller than the defined record length, GET will read enough data to fill Var. The remainder of the record is discarded and the file pointer is placed at the next record position. If Var is larger than the defined record length, GET will read one record into Var, and the file pointer will be moved to the next record.

When GET is used to retrieve data from a random access file into a dynamic (variable-length) string , ScharfBASIC looks for a 2-byte ( WORD ) size field at the beginning of each record which indicates the number of data bytes which follow. If the data is in WIDE format, the size is double the number of characters because each character occupies two bytes. This 2-byte size field is placed in the file automatically by the PUT statement when used with dynamic (variable-length) strings.

When the second form of GET is used (without a Var target string), GET reads the file data from the current file pointer into an internal buffer. This data can then be accessed using FIELD string variables.

When GET is used to read a random file into a dynamic string, it normally expects the first two bytes of the record to contain the length of the valid data contained in the record. The ABS keyword specifies that no length word exists in the data, and the number of bytes to read is defined by the current length of the dynamic string variable. If the variable length is greater than the file record length, the remainder of the string variable is filled with nul's ( CHR$ (0) or $NUL ). This offers greater compatibility with the actual operation of other versions of BASIC, such as ScharfBASIC for DOS .

A random access file record is limited to 32768 bytes to ensure consistent behavior across all supported Win32 platforms. GET$ and other related functions are not constrained in this manner.

Binary files

RecPos

For binary files, RecPos is the starting byte or seek position from where the GET should begin. The optional BASE = clause of the OPEN statement defines whether the first position is 0 or 1. The base position is 1 by default. If RecPos is greater than the number of records or bytes in the file, no error occurs but unpredictable data may be read. Use the EOF function to avoid reading past the end of the file.

When used with a binary file, GET retrieves enough data from the file to fill Var . The Var parameter can be a simple (scalar) variable like an Integer or a dynamic (variable-length) string, an element in an array, or a variable of User-Defined Type .

When GET is used to read a binary file into a dynamic string, the number of bytes to read is defined by the current size of the dynamic string variable. If the variable length is greater than the file record length, the remainder of the string variable is filled with nuls (CHR$(0) or $NUL). This offers greater compatibility with the actual operation of other versions of BASIC, such as ScharfBASIC for DOS.

When reading an array from the disk file, GET assigns data from the file into each element in the array, starting at the arrays LBOUND subscript. GET attempts to read the number of elements specified by rcds in the RECORDS option, or the number of elements in the array, whichever is smaller. The actual number of elements read is assigned to the variable count specified in the optional TO clause.

With a dynamic string array , it is assumed the file was written in the ScharfBASIC and/or VB packed string format using PUT of an entire string array. If a string is shorter than 65535 bytes, a 2-byte length WORD is followed by the string data. Otherwise, a 2-byte value of 65535 is followed by a length Double-word (DWORD), then finally the string data.

With other array arrays types, the entire data area is read as a single block. In either case, it is presumed the file was created with the complementary PUT Array statement.

EOF is set just as with other GET statements.

You can use the FILESCAN statement to determine the number of records contained in the file, allowing an array of the appropriate type to be dimensioned before using the GET statement to read the file.

See Also

  • CSET
  • CSET$
  • EOF
  • FIELD
  • FILESCAN
  • GET$
  • GET$$
  • LINE INPUT#
  • LSET
  • OPEN
  • PRINT#
  • PUT
  • PUT$
  • PUT$$
  • RSET
  • TYPE
  • SEEK
  • WRITE#


GRAPHIC INPUT - ScharfBASIC Help

GRAPHIC INPUT

Reads data from the keyboard from within a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC INPUT [ prompt ,] varlist
prompt

Description

GRAPHIC INPUT displays the prompt on the graphic window or graphic control, waits for the user to enter data from the keyboard, and assigns the data to the variables in varlist . Data entered from the keyboard must match the type of the variables -- that is, non-numeric characters are unacceptable for numeric variables.

If a single GRAPHIC INPUT statement prompts for more than one variable, the user must enter the proper number of values on a single line, separated by commas. If not enough comma-delimited values are entered, remaining variables are set to zero or nul.

See Also

  • GRAPHIC INKEY$
  • GRAPHIC INPUT FLUSH
  • GRAPHIC INSTAT
  • GRAPHIC LINE INPUT
  • GRAPHIC WAITKEY$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2024b0
call   0x202433
mov   WORD PTR [ebp-0x46],0x1
mov   ecx,0x4
mov   eax,0x80
call   0x2018c8
call   0x202364


GRAPHIC LINE INPUT - ScharfBASIC Help

GRAPHIC LINE INPUT

Read an entire line from the keyboard from within a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC LINE INPUT [" prompt "] string_variable

Description

GRAPHIC LINE INPUT displays the optional prompt on the Graphic Window or Control and waits for user input. Keystrokes are accepted until you press ENTER, at which time the entire typed string is assigned to the string_variable . Input is limited to 255 characters.

See Also

  • GRAPHIC INKEY$
  • GRAPHIC INPUT
  • GRAPHIC INPUT FLUSH
  • GRAPHIC INSTAT
  • GRAPHIC WAITKEY$


INPUT# - ScharfBASIC Help

INPUT#

Load

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

INPUT # filenum& , variable_list

Description

filenum& is the file number , or variable containing a file number, given when the file was opened . variable_list is a comma-delimited sequence of one or more string or numeric variables. When the INPUT# statement reads an unquoted data item from a file, it removes leading spaces. If leading spaces are significant, place quotes around the file data, either directly or by using WRITE# to save the data to disk. Please note that data to be quoted should not contain embedded quotes.

The data in the file must match the type(s) of the variable(s) defined in the INPUT# statement. The file data should be separated by commas with a carriage return at the end. The WRITE# statement is ideal for creating such files.

INPUT# also supports fixed-length and nul-terminated string variables; however, data that is longer than the string is truncated to fit into the string. Dynamic strings receive the data without truncation. UDT variables may not be used, although fixed-length and nul-terminated UDT member variables are supported.

See Also

  • LINE INPUT#
  • PRINT#
  • WRITE#

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x204a54
call   0x203534
call   0x2034b7
mov   WORD PTR [ebp-0x46],0x1
call   0x202810
fistp   QWORD PTR [ebp-0x6c]
mov   esi,DWORD PTR [ebp-0x6c]
call   0x2033e8


LINE INPUT# - ScharfBASIC Help

LINE INPUT#

Read line(s) from a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LINE INPUT # filenum& , string_variable
LINE INPUT # filenum& , Arr$() [RECORDS rcds ] [TO count ]

Description

filenum& is the file number , or variable containing a file number, given when the file was opened . string_variable is the string variable to be loaded with the data read from the file.

string_variable may be a fixed-length , nul-terminated , or dynamic string. For fixed-length and nul-terminated strings, data that is longer than the string is truncated to fit into the string. Dynamic strings receive the data without truncation. string_variable may not be a UDT variable, although fixed-length and nul-terminated UDT member variables are supported.

LINE INPUT# is intended for use with text files composed of lines terminated by CR/LF ( $CRLF or CHR$ (13,10)) sequences. It reads a line from the file and returns it, minus the CR/LF delimiter. Commas, quotation marks and other characters have no special meaning for LINE INPUT#, and are treated like any other text.

If the file consists of comma-delimited data items, INPUT# is likely to be more suitable then LINE INPUT#.

The second syntax definition of LINE INPUT# reads a file opened for INPUT, assigning full lines of text to each element of the array .

It is assumed the data is standard text, delimited by a CR/LF ($CRLF) or EOF (1A hex or $EOF ). LINE INPUT# attempts to read the number of lines specified in the RECORDS rcds option, or the number of elements in the array, whichever is smaller.

The actual number of lines read is assigned to the variable specified in the optional TO count clause. FILESCAN is useful in conjunction, to determine the dimensioned size of the string array. EOF is set just as with single Line Input.

See Also

  • EOF
  • FILESCAN
  • INPUT#
  • PRINT#

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x204a54
call   0x202f60
call   0x202ee3
mov   WORD PTR [ebp-0x46],0x1
call   0x2019b4
call   0x202ee3
call   0x202e14


LOC - ScharfBASIC Help

LOC

Determine the current

Kind | Function
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

qResult&& = LOC([#] filenum& )

Description

LOC is provided for compatibility with older BASICs. It is recommended that code is modified to use the SEEK function instead. The Number symbol (#) is optional, but recommended for clarity.

See Also

  • FILEATTR
  • SEEK function
  • SEEK statement

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201e0c
call   0x201d8f
mov   eax,0x1
call   0x2018b8
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
call   0x201cc0


LOCK - ScharfBASIC Help

LOCK

Lock part or all of an

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LOCK [#] filenum& [, { record&& | startbyte&& TO endbyte&& }]

Description

LOCK prevents another process from accessing a record, range of records, byte, or range of bytes in a file opened as file number filenum& .

If the file was opened in random-access mode, record&& , startbyte&& , and endbyte&& specify record numbers. When used with binary mode files, record&& , startbyte&& , and endbyte&& specify byte positions, starting from either zero or one (the default).

If a record is specified, only that record (or byte) is locked. Otherwise, a range of records (or bytes) is locked, from startbyte&& to endbyte&& .

If no records are specified, or if the file was opened in sequential mode, the entire file is locked.

All records (or bytes) to be locked must be subsequently unlocked using the UNLOCK statement. Multiple locks may be placed on a file, and locks may be unlocked in any order. However, the parameters used for each UNLOCK statement must exactly match those used for the previous corresponding LOCK statement.

All locked records (or bytes) must be unlocked using the UNLOCK statement before the file can be closed.

If a lock attempt fails, ScharfBASIC sets the ERR system variable to reflect a run-time Error 70 ("Permission denied"), or Error 75 ("Path/file access error").

See Also

  • OPEN
  • UNLOCK


LOF - ScharfBASIC Help

LOF

Return the length of an

Kind | Function
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y&& = LOF([#] filenum& )

Description

filenum& is the file number with which the file was opened. LOF returns the size of the indicated file in bytes , in the Quad-integer range 0 to 2^63-1. The Number symbol (#) is optional, but recommended for clarity.

See Also

  • FILEATTR
  • LOC
  • SEEK function
  • SEEK statement

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201df8
call   0x201d7b
mov   eax,0x1
call   0x2018b8
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
call   0x201cac


OPEN - ScharfBASIC Help

OPEN

Prepare a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

OPEN filespec [FOR mode ] [ACCESS access ] [LOCK lock ] AS _
[#] filenum& [LEN = record_size ] [BASE = base ] [CHR = ANSI|WIDE]
OPEN HANDLE filehandle [FOR mode ] [ACCESS access ] [LOCK lock ] AS _

Description

The main function of OPEN is to associate a file number ( filenum& ) with a file or physical device and to prepare that device for reading and/or writing. This file number is then used, rather than its name, in every statement that refers to the file. The FREEFILE function can be used to determine the next unused file number, or you can pick one yourself. An OPEN statement is usually balanced by a matching CLOSE statement. The OPEN statement comprises the following elements:

filespec

A string expression specifying the name of the file to be opened, and may optionally include a drive and/or path specification. filespec may be either a Short File Name (SFN) or a Long File Name (LFN). filespec has a limit of 259 characters (%MAX_PATH - 1), although the file name portion of filespec may be no more than 255 characters (%MAX_FNAME - 1).

Specifies the file organization and style of access ( sequential , random access , or binary ) for reading, writing (or both), or appending. If mode is not specified, the default is RANDOM access.

File type

Action

Sequential

Read from

OUTPUT

Sequential

Write to

APPEND

Sequential

Append to

BINARY

Binary

Reading or writing

RANDOM

Random

Reading or writing (default)

access

Specifies the type of access this process will have to the file. By default, the file may be written to and read from.

Access

Description

Only read operations allowed

Only write operations allowed

READ WRITE

Both read and write operations allowed (default)

Note that APPEND mode requires READ/WRITE access.

Specifies the type of access other processes will have to the file. If a LOCK clause is not specified in the OPEN statement, the default LOCK READ WRITE mode is applied. This mode ensures exclusive access to the file, and enables ScharfBASIC to optimize its internal buffering for utmost I/O performance. If other processes or threads are to be permitted WRITE access to the file (LOCK SHARED or LOCK READ), internal buffering is disabled. Whilst performance may be marginally lower, it ensures that data read from the file is completely up-to-date.

Description

SHARED

Both read and write operations allowed

Prevent write operations

Prevent read operations

READ WRITE

Neither read nor write operations allowed (default)

To open a text file for OUTPUT and allow other processes to only read the file, use the following:

OPEN "MYFILE.TXT" FOR OUTPUT LOCK WRITE AS #1

It is possible for an application to open more than one copy of a given file at the same time. In this case, each OPEN statement must use a unique file number, and LOCK READ WRITE mode should not be used.

filenum&

A unique integer value identifying the file, in the range 1 to 32767. Typically, this value is obtained from the FREEFILE function.

record_size

Specifies the size of each record of a random access file. The default record length is 128 if not specified. If record_size is specified for a sequential file, it instructs ScharfBASIC to use internal buffering to improve I/O performance. A random access file is limited to 32768 bytes per record, to ensure consistent behavior across all Win32 platforms.

Specifies the number of the first record in a random access file, or the number of the first byte in a sequential or binary file. It can be either zero (0) or one (1). The default value for base is 1, if not specified.

Specifies the character mode for this file: ANSI or WIDE (Unicode). Since sequential files consist of text alone, the selected mode is enforced by ScharfBASIC. All data read or written to the file is automatically forced to the selected mode, regardless of the type of variables or expressions used. With binary or random files, this specification has no effect, but it may be included in your code for self-documentation purposes.

ANSI characters in the U.S. range of CHR$ (0) to CHR$(127) are known as ASCII , and are always represented by a single byte. International ANSI characters in the range of CHR$(128) to CHR$(255) may be followed by one or more additional bytes in order to accurately represent non-U.S. characters. The exact definition of these characters depends upon the character set in use. WIDE characters are always represented by two bytes per character. If the Chr option is not specified, the default mode is ANSI.

HANDLE

The HANDLE option allows you to access files that have already been opened by another process, DLL, or API function. The filehandle specified here must be a valid Win32 operating system file handle.

When ScharfBASIC closes a file opened with OPEN HANDLE, the Win32 handle is simply detached from the internal ScharfBASIC handle table. The file is not physically closed since ScharfBASIC did not originally open it. In ScharfBASIC, the FILEATTR function can be used to obtain the operating system file handle for a file opened with the OPEN statement.

Restrictions

Attempting to OPEN a file for INPUT that does not exist causes a run-time Error 53 ("File not found"). Attempting to open a file that is locked can result in either an Error 70 ("Permission denied"), or an Error 75 ("Path/file access error"). Similarly, attempting to OPEN a file using a file number that is already in use will result in a run-time Error 55 ("File is already open "). For this reason, programs that use hard-coded file numbers should take special care to close files before the file number is used again. In addition, code that may be used by more than one thread should use FREEFILE and avoid hard-coded file numbers.

If you try to open a nonexistent file for OUTPUT, APPEND, RANDOM, or BINARY operations, a new file is automatically created. For this reason, files on Read-only network drives may only be opened in INPUT mode.

See Also

  • CLOSE
  • FILEATTR
  • FILENAME$
  • FILESCAN
  • FREEFILE
  • TCP OPEN
  • UDP OPEN


PRINT# - ScharfBASIC Help

PRINT#

Write data to a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PRINT # fNum&
PRINT # fNum& , [ ExpList ] [SPC( n )] [TAB( n )] [,] [;] [...]
PRINT # fNum& , array$()

Description

The first form of the PRINT# statement (with or without a trailing comma) outputs a blank line to the file (i.e. a CR/LF only).

The second form of the PRINT# statement has the following parts, which may occur in any order and quantity, within a single PRINT# statement:

Number used in an OPEN statement to open a sequential file. It can be any numeric expression that evaluates to the number of an open file. Note that the Number symbol (#) preceding fNum& is not optional.

ExpList

Numeric and/or string expression (s) to be written to the file.

SPC( n )

An optional function used to insert n spaces into the printed output. Multiple use of the SPC argument is permitted in the PRINT statement, for example, between expressions. Values of n less than 1 are ignored.

TAB( n )

An optional function used to tab to the n th column before printing ExpList . Multiple use of the TAB argument is permitted in the PRINT, for example, to position arguments in columns. Values of n less than 1 are ignored.

Character that determines the position of the next character printed. A semicolon (;) means the next character is printed immediately after the last character; a comma (,) means the next character is printed at the start of the next print zone. Print zones begin every 14 columns.

If the final argument of a PRINT# statement is a semicolon or comma, PRINT# will not append the (default) CR/LF byte pair to the data as it is written to the file. For example:

PRINT #1, "Hello";

PRINT #1, " world!"

...produces the contiguous string "Hello world!" in the disk file.

If you omit all arguments, the PRINT# statement prints a blank line in the file (i.e., a CR/LF pair only), but you must include the comma after the file number. Because PRINT# writes an image of the data to the file, you must delimit the data so it is printed correctly. If you use commas as delimiters, PRINT# also writes the blanks between print fields to the file. Also, remember that spacing of data displayed on a text screen using monospaced characters may not work well when the data is redisplayed in a graphical environment using proportionally spaced characters.

If you are not careful, you can waste a lot of disk space with unnecessary spaces, or worse, put fields so close together that you cannot tell them apart when they are later input with INPUT#. For example:

PRINT #1,1,2,3

sends:

to file #1. Because of the 14-column print zones between characters, superfluous spaces are sent to the file. On the other hand:

PRINT #1,1;2;3

sends:

to the file, and you cannot read the separate numeric values from this record because INPUT# requires commas as delimiters. The best way to delimit fields is to put a comma between each field, like so:

PRINT #1, 1 "," 2 "," 3

which writes:

1, 2, 3

to the file, and wastes the least possible space and is easy to read with an INPUT# statement. The WRITE# statement delimits fields with commas automatically.

PRINT# is advantageous when writi ng a single number or string on each line in a file. Use PRINT# followed by a comma but no arguments to write a blank line (carriage return/linefeed) to a file:

PRINT #1, 'writes a blank line to file #1

array$()

When PRINT# specifies an array name with empty parentheses, the entire array is written to the disk file as text strings, with each element delimited by a CR/LF ( $CRLF or CHR$ (13,10)). Numeric arrays are converted to the ASCII text equivalent.

Restrictions

Arrays of User-Defined Types (UDTs) may not be used with the array form of the PRINT# statement.

See Also

  • GET
  • GET$
  • GET$$
  • INPUT#
  • LINE INPUT#
  • PUT
  • PUT$
  • PUT$$
  • WRITE#


PUT - ScharfBASIC Help

PUT

Write a record to a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

Random-Access and Binary files:
PUT [#] FileNum& , [ RecPos ], [ABS] Var
PUT [#] FileNum& [, RecPos ]
Binary files:
PUT [#] FileNum& , [ RecPos ], Arr()

Description

If a string variable is specified as Var, the CHR mode of the variable determines whether the data is written as ANSI or WIDE characters. That is, ANSI string variables are always written as 1- byte characters, while WIDE string variables are written as 2-byte WIDE characters. The data is always written to the file in the same format as it appears in the variable.

FileNum&

The file number under which the file was opened .

RecPos

Identifies the position in the file to write the data. If RecPos is greater than the number of existing records or bytes in the file, the file is extended to the appropriate length, and the record is written at the specified position.

For random access files, RecPos is the record to be written, in the range 1 to (2^63)-1. If RecPos is omitted, the next record in sequence (following the one specified by the most recent GET , PUT or SEEK ) is written. If the file was only just opened, the first record is written.

For binary files , RecPos is the starting byte position where VarName should be written. The default byte position is 1, unless the BASE = 0 clause was used in the OPEN statement. RecPos may be no larger than 2^63-1. RecPos is optional. If it is omitted, ScharfBASIC uses the current file pointer position.

The name of a variable to write to the file. VarName can specify a simple variable, an element in an array, or a variable of User-Defined Type (UDT).

When writing a dynamic string to a random access file, PUT writes a 2-byte descriptor containing the string's length, before the actual string data. This descriptor reduces the available space in a record by two bytes. The descriptor is written as a WORD value. If Var contains more characters than record, Var is truncated at record length less two bytes, and the descriptor is written to reflect the truncated string size.

When writing a dynamic string to a binary file, PUT only writes the actual string data: no length descriptor is written.

PUT is complementary to GET; it writes one record to a file. It is possible to PUT to records out of contiguous order, as in:

PUT #1, 1, MyVar

PUT #1, 100, MyVar

which creates a random-access file 100 records long. The data in records 2 through 99, however, are undefined until you explicitly PUT something there. PUT writes the contents of Var to the specified record or byte positions.

(no VarName )

When the second form of PUT is used (without a VarName source string), PUT writes the data from an internal buffer into the file at the point where the file pointer indicates. This data must first be assigned to the file buffer using FIELD string variables.

When PUT is used to write a dynamic string to a random file, it normally precedes the actual data with a two-byte binary length Word to define the number of valid bytes in the record. If you precede the variable name with ABS (i.e., PUT #1, , ABS x$), no length Word is written: only the actual data, subject to the defined random record length. This offers greater compatibility with the actual operation of other versions of BASIC, such as ScharfBASIC for DOS .

The record length in a random access file is limited to 32768 bytes, in order to ensure consistent behavior across all Win32 platforms.

When PUT is used on a binary file, the entire array specified by Arr() is written to the file. With dynamic strings, the file is written in the ScharfBASIC and/or VB packed string format. If the string is shorter than 65535 bytes, a 2-byte length Word is followed by the string data. Otherwise, a 2-byte value of 65535 is followed by a length Double-word (DWORD), then finally the string data.

With other data types, the entire data area is written as a single block.In either case, it is presumed the file will be read with the complementary GET Array statement.

See Also

  • CSET
  • CSET$
  • FIELD
  • GET
  • GET$
  • GET$$
  • LOF
  • LSET
  • PUT$
  • PUT$$
  • RSET
  • SETEOF
  • TYPE
  • WRITE#


Random Access Files - ScharfBASIC Help

Random Access Files

Random access files consist of records that can be accessed in any sequence. This means the data is stored exactly as it appears in memory, thus saving processing time (because no translation is neces

Kind | Keyword
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Random files are a better solution to database problems than sequential files , although there are a few disadvantages. For one thing, random files are not especially transportable. Unlike sequential files, you cannot peek inside them with an editor, or type them in a meaningful way to the screen. In fact, moving a ScharfBASIC random file to another computer or language will probably require that you write a translator program to read the random file and output a text (sequential) file.

One example of the transportability problem strikes close to home. Interpretive BASIC uses Microsoft's non-standard format for floating point values, and ScharfBASIC uses IEEE standard floating-point conventions, this means you cannot read the floating-point fields of random files created by Interpretive BASIC with a ScharfBASIC program, or vice versa, without a bit of extra work.

The major benefit of random files is implied in their name: every record in the file is available at any time. For example, in a database of 23,000 alumni, a program can go straight to record number 11,663 or 22,709 without reading any of the other records. This capability makes it the only reasonable choice for large files, and probably the better choice for small ones, especially those with relatively consistent record lengths.

However, random access files can be wasteful of disk space because space is allocated for the longest possible field in every record. For example, a 100-byte comment field forces every record to use an extra 100 bytes of disk space, even if only one in a thousand actually uses it.

At the other extreme, if records are consistent in length, especially if they contain mostly numbers, random files can save space over the equivalent sequential form. In a random file, every number of the same type ( Integer , Long-integer , Quad-integer , Byte , Word , Double-word , Single-precision , Double-precision , Extended-precision or Currency ) occupies the same amount of disk space, regardless of the value itself. For example, the following five Single-precision values each require four bytes (the same space they occupy in memory):


RESET - ScharfBASIC Help

RESET

Set a scalar (non-array)

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

RESET variable [, ...]
RESET array() [, ...]
RESET array(index) [, ...]

Description

If variable is numeric, it is set to zero. If variable is a dynamic string, it is set to null (""; an empty string). If variable is a nul-terminated string , the first byte is set to nul ( $NUL ). If variable is a fixed-length string or User-Defined Type/ Union , all bytes in variable are set to nul, or CHR$ (0). If variable is a Variant, it is cleared and set to data type %VT_EMPTY .

If array() is numeric , all elements are set to zero; otherwise all elements are set to zero/null. If an array index value is specified within the parentheses, just that array element is set to zero/null, as if it were a scalar (non-array) variable.

RESET also works with absolute arrays , clearing the contents to zeroes or empty strings. For more information on absolute arrays, please refer to the DIM statement.

See Also

  • ARRAYATTR
  • DIM
  • ERASE
  • LET
  • LET (with Types)
  • LET (with Variants)
  • REDIM


SEEK - ScharfBASIC Help

SEEK

Set the position in a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SEEK [#] filenum& , position&&

Description

SEEK sets the file pointer position of file filenum& to position&& . position&& is a Quad-integer variable, constant , or expression.

The next GET$ or PUT$ performed on the file filenum& will occur position&& bytes (or records) deep into the file. If file filenum& was opened in binary or sequential mode, position&& indicates the new file position in bytes; for random-access files, position is in records.

The first byte position (for binary and sequential files) or record position (for random-access files) may be 0 or 1, depending on the BASE option used when the file was initially Opened. If no BASE was specified, the default position is 1.

Use the SEEK function to determine a binary file's current pointer position, and LOF to determine its length. Seeking past the end of a file does not produce an error, but no data can be read from beyond the true end of the file.

See Also

  • EOF
  • FILEATTR
  • GET$
  • GET$$
  • LOC
  • LOF
  • OPEN
  • PUT$
  • PUT$$
  • SEEK function
  • SETEOF


Sequential Files - ScharfBASIC Help

Sequential Files

Sequential file techniques provide a straightforward way to read and write files. ScharfBASIC's sequential file commands manipulate text files: files of ANSI or WIDE characters with carriage-return/lin

Kind | Keyword
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Quite possibly, the best reason for using sequential files is their degree of portability to other programs, programming languages, and computers. Because of this, you can often look at sequential files as the common denominator of data processing, since they can be read by word-processing programs and editors (such as ScharfBASIC's), absorbed by other applications (such as database managers), and sent over the Internet to other computers.

The idea behind sequential files is simplicity itself: write to them as though they were the screen and read from them as though they were the keyboard.

Create a sequential file using the following steps:

OUTPUT: If a file does not exist, a new file is created. If a file already exists, its contents are erased, and the file is then treated as a new file.

APPEND: If a file does not exist, a new file is created. If a file already exists, ScharfBASIC appends (adds) data at the end of that file.

To read a sequential file:

The drawback to sequential files is, not surprisingly, that you only have sequential access to your data. You access one line at a time, starting with the first line. This means if you want to get to the last line in a sequential file of 23,000 lines, you will have to read the preceding 22,999 lines.

Sequential files, therefore, are best suited to applications that perform sequential processing (for example, counting words, checking spelling, printing mailing labels in file order) or in which all the data can be held in memory simultaneously. This allows you to read the entire file in one fell swoop at the start of a program and to write it all back at the end. In between, the information can be stored in an array (in memory) which can be accessed randomly.

Although the SEEK statement can be used to change the point in the file where the next read or write will occur, the calculations required to determine the position of the start of each record in a sequential file would add considerable overhead. Sequential files typically consist of records of varying sizes. Either you would have to maintain a separate index file indicating the starting byte position of each record, or you would have to seek randomly until you found the correct position. However, SEEK does have its uses with sequential files. For instance, after reading an entire file, you could use SEEK to reposition the file pointer to the start of the file, in order to process the data a second time. This is certainly quicker than closing and re-opening the file.


SETEOF - ScharfBASIC Help

SETEOF

Truncate or extend an

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SETEOF [#] filenum&

Description

SETEOF will truncate or extend an open file to its current file pointer (read/write) position, which may be set explicitly with the SEEK statement.

Unlike 16-bit Windows and DOS BASIC , Win32 will not truncate a file if you simply write an empty string to it, so the SETEOF statement is provided to cater for this need.

See Also

  • CLOSE
  • FILEATTR
  • FLUSH
  • OPEN
  • SEEK function
  • SEEK statement


TCP LINE INPUT - ScharfBASIC Help

TCP LINE INPUT

Receive a line of text from a specified

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP LINE [INPUT] [#] fNum& , Buffer$

Description

Receive a line of text from the fNum& TCP/IP port, and place the data in Buffer$ . If no bytes are available, Buffer$ will be empty (a null string). If TCP LINE did not receive a complete line of text (terminated by a $CRLF character pair), EOF ( fNum& ) will return TRUE (non-zero).

If a time-out occurs, ERR will be set to indicate a run-time Error 24 ("Device timeout"). See TCP OPEN to specify the TCP socket timeout value.

The EOF function may also be used with TCP LINE (and COMM LINE ) to detect that an incomplete line was received. Normally, the TCP LINE statement reads data until a $CRLF character pair is found, and in that case, EOF will return false (zero). However, even if no $CRLF has been found, TCP LINE will return if no additional data is available. In that case, TCP LINE will return whatever data has been accumulated, and set EOF to logical TRUE (non-zero).

In many cases, it would be prudent to test EOF after every TCP LINE statement to verify that a full line has been received. In some cases, you may wish to execute the statement one or more additional times, combining the data, in order to obtain a full line of text.

See Also

  • TCP and UDP communications
  • EOF
  • TCP ACCEPT
  • TCP CLOSE
  • TCP NOTIFY
  • TCP OPEN
  • TCP PRINT
  • TCP RECV
  • TCP SEND
  • UDP RECV


UNLOCK - ScharfBASIC Help

UNLOCK

Remove

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UNLOCK [#] filenum& [, { record&& | start&& TO finish && }]

Description

UNLOCK restores access to a record, range of records , byte , or range of bytes locked by the LOCK statement, in file opened as file number filenum& .

If the file was opened in random-access mode, record&& , start&& , and finish && specify record numbers.

When used with binary mode files, record&& , start&& , and finish && specify byte positions, starting from either one (the default) or zero, depending on the BASE setting given when the file was Opened.

If a record is specified, only that record (or byte) is unlocked. Otherwise, a range of records (or bytes) is unlocked, from start&& to finish && . If no records are specified, or if the file was opened in sequential mode, the entire file is unlocked.

All records (or bytes) to be unlocked must have been previously locked using the LOCK statement. Multiple locks may be placed on a file, and locks may be unlocked in any order. However, the parameters used for each UNLOCK statement must exactly match those used for the previous corresponding LOCK statement.

All locked records (or bytes) must be unlocked using the UNLOCK statement before the file can be closed.

If an unlock attempt fails, ScharfBASIC sets the ERR system variable to reflect a run-time Error 70 ("Permission denied"), or Error 75 ("Path/file access error").

See Also

  • LOCK
  • OPEN


WRITE# - ScharfBASIC Help

WRITE#

Output data to a

Kind | Statement
Category | File I/O
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

WRITE # filenum&
WRITE # filenum& , [ expression [{;|,} expression ] ...] [;|,]

Description

WRITE# is similar to PRINT# , except WRITE# inserts a comma in the output file between each expression. It encloses

data within quotation marks, and adds no leading or trailing spaces around numeric values.

WRITE# is the preferred method of writing data to a sequential file, since it formats the output to be readable by the INPUT# statement. In other words, INPUT# respects the delimiter characters that separate items in a line of text, as created by WRITE#.

WRITE# with a file number and a comma but no expressions, outputs a carriage return to the file.

To read a delimited file without regard to the delimiter characters, use the LINE INPUT# statement.

Restrictions

For best results, strings should not contain quotation marks, as these may interfere with the expected output format.

Each expression in the WRITE# statement must be separated from other expressions by a comma or semicolon. If you include a trailing comma or semicolon, the final carriage return / line feed is suppressed and replaced with a comma delimiter. This allows you to append data to the sequential record by executing another WRITE statement.

See Also

  • GET
  • GET$
  • GET$$
  • INPUT#
  • LINE INPUT#
  • OPEN
  • PRINT#
  • PUT
  • PUT$
  • PUT$$
  • SETEOF


CHDIR - ScharfBASIC Help

CHDIR

Change the current (default) directory on the default drive, or any other drive (similar to the DOS CHDIR command). CHDIR affects only the default drive for the current program.

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CHDIR path

Description

path is a string expression containing either a relative or an explicit directory name. The directory name can be constructed from a (DOS-Style) Short File Name (SFN) directory name, a Long File Name (LFN) directory name, or a combination of the two. Also, path may be prefixed with a drive letter and colon (i.e., "D:") to change the current directory on a non-default drive.

The current directory is the location where your program will perform file operations by default. Thus:

CHDIR "\DATA"

changes to the \DATA subdirectory on the current drive, and:

CHDIR "..\DATA2"

changes the current directory to a directory whose parent is also the parent to the original directory. The double-period implies the parent directory.

CHDIR "J:\Program Files\Internet Explorer"

changes the current directory of Drive J. Drive J need not be the current default drive.

If path does not specify a valid directory on the target drive, a run-time Error 76 occurs ("Path not found").

A program that changes the current directory on the default drive also changes its active directory.

path may also be used with UNC names (i.e., \\server\share), but their use is subject to operating system restrictions.

Restrictions

CHDIR is not intended to change the current default drive. Use CHDRIVE instead.

See Also

  • CHDRIVE
  • CURDIR$
  • MKDIR
  • RMDIR


CHDRIVE - ScharfBASIC Help

CHDRIVE

Change the current default drive.

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CHDRIVE drive

Description

drive is a string expression whose first character is a letter from A to the highest logical drive letter. The trailing colon (:) that DOS uses is optional in ScharfBASIC. If drive does not indicate a valid drive, a run-time Error 76 occurs ("Path not found").

See Also

  • CHDIR
  • CURDIR$
  • MKDIR
  • RMDIR


CURDIR$ - ScharfBASIC Help

CURDIR$

Return the current directory path for the specified drive.

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = CURDIR$[( drive$ )]

Description

drive$ is an optional string expression , containing the drive letter of the target disk drive. If drive$ is not specified or is an empty string , the current directory path is returned for the default drive.

See Also

  • CHDRIVE
  • CHDIR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x202078
call   0x201ad4
call   0x2019de
lea   ebx,[ebp-0xa0]
call   0x201a9c
call   0x201ffb
call   0x201f2c


DIR$ - ScharfBASIC Help

DIR$

Return a filename and/or directory entry that matches a file name mask and an optional attribute.

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

file$ = DIR$( mask$ [, [ONLY] attribute& , TO DirDataVar ])
file$ = DIR$([NEXT] [TO DirDataVar ])

Description

There are two forms to the DIR$() function. The first form, which includes a mask string and optional attribute, is used to find the first filename which matches. The second form, without those parameters, returns subsequent matching filenames. When the returned string is null (zero-length), there are no further matching filenames.

The second form may optionally specify the key-word NEXT to aid in self-documentation of the source code.

mask$ specifies a filename or path which can include a drive name and system wildcard characters (* and ?). If the numeric attribute parameter is zero (or not specified), DIR$ returns only "Normal" files. If mask$ is a null (zero-length) string, the function call is equivalent to the second form of the function to find subsequent matching filenames. In that case, an optional attribute is ignored.

If an attribute& is specified, it must use a standard operating system numeric attribute code. This causes DIR$ to include filenames with specific attributes in the search, in addition to normal files. "Normal" files are those which are not hidden or system files, nor are they a directory or a volume label.

Attribute

Description

Equate

Normal

%NORMAL

Hidden

%HIDDEN

System

%SYSTEM

Volume Label

%VLABEL

Directory

%SUBDIR

You can search for filenames with multiple attributes set by adding the attribute codes together. For example, to search for hidden and system files, you'd add those codes together (2 and 4) to get 6. All other attribute codes (except for volume label) are normally inclusive. For example, specifying both hidden and system results in DIR$ returning all hidden files, system files, normal files, and files that are both hidden and system.

If the ONLY option is included, normal files are excluded from the file search. For example: DIR$( mask$ , ONLY 16) just the directory entries which match mask$ are returned. Another useful search attribute is 6, which returns normal, hidden, and system file, but no directories.

An attribute of 8 will return the volume label, if one exists. In this case, mask$ must reference the drive letter of the target drive, and additional path information is ignored. Additionally, you may specify a UNC name for a shared drive (subject to operating system restrictions), and retrieve the volume label, if one exists, and you have suitable access rights. You can also obtain the volume label for a 'hidden' share with NT/2000/XP by appending a trailing dollar symbol to the share name.

' Retrieve volume for share \\server\drive0

A$ = DIR$("\\server\drive0", 8)

' Retrieve volume for hidden share D: (\d$)

A$ = DIR$("\\server\d$", %VLABEL)

The DIR$ function may optionally assign the complete directory entry to an appropriate UDT variable if you include the TO clause as a parameter. The complete directory entry contains 592 bytes of data, corresponding to the following TYPE definition. This definition (DIRDATA) is built into ScharfBASIC, and need not necessarily be included in your source code. The DirData UDT is identical to the Unicode version of the Win32_Find_Data structure used by the Windows API for this purpose.

TYPE DirData

FileAttributes AS DWORD

CreationTime AS QUAD

LastAccessTime AS QUAD

LastWriteTime AS QUAD

FileSizeHigh AS DWORD

FileSizeLow AS DWORD

Reserved0 AS DWORD

Reserved1 AS DWORD

FileName AS WSTRINGZ * 260

ShortName AS WSTRINGZ * 14

END TYPE

You can declare a variable as DIRDATA for this purpose, or use any other user-defined type of at least 592 data bytes. The additional data may be used for any other purpose in your program.

CreationTime, LastAccessTime, and LastWriteTime members of the DIRDATA can be assigned to a PowerTime object to convert the QUAD integer (FILETIME) values for easy calculations and conversions.

LOCAL f AS STRING

LOCAL d AS DIRDATA

LOCAL t AS IPOWERTIME

t = CLASS "PowerTime"

f = DIR$("c:\*.*" TO d)

t.FileTime = d.CreationTime ' t contains the file creation time in a localized format.

Previous versions of ScharfBASIC used an ANSI version of DirData which was only 318 bytes in size. However, if you utilized the built-in form of DirData, your program should execute correctly under this version with no changes needed.

Restrictions

ScharfBASIC performs file matching with both the long (LFN) and short (SFN) filename versions of filenames. This means that DIR$ will also return filenames that start with the specified extension (as per standard Windows operating system behavior).

For example, A$ = DIR$("*.htm") will match filenames such as "Index.htm", "Default.html", "Homepages.htmb", "cgilib.htmlpages", etc. Similarly, A$ = DIR$("*.h??") and DIR$("*.ht*") will match the same filenames.

DIR$ is thread-safe, so DIR$ operations in one thread do not interfere with DIR$ operations in another thread. However, you should be aware that specifying a new mask$ parameter always starts an entirely new DIR$ search loop.

See Also

  • CURDIR$
  • DIR$ CLOSE
  • DISPLAY BROWSE
  • DISPLAY OPENFILE
  • FILEATTR
  • GETATTR
  • ISFILE
  • PATHNAME$
  • PATHSCAN$
  • SETATTR


DISKFREE - ScharfBASIC Help

DISKFREE

Return the amount of available space on a disk, in bytes.

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

bytes&& = DISKFREE( drive$ )

Description

drive$ specifies the drive letter or UNC share name (subject to operating system restrictions) of the disk to examine. If drive$ is an empty string , information on the default drive is returned.

Restrictions

With Windows 95 versions before OSR2, and Windows NT versions before 4.0, DISKFREE may return a negative or inaccurate value for drives larger than 2 GB.

See Also

  • DISKSIZE


DISKSIZE - ScharfBASIC Help

DISKSIZE

Return the total amount of space on a disk, in

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

bytes&& = DISKSIZE( drive$ )

Description

drive$ specifies the drive letter or UNC share name (subject to operating system restrictions) of the disk to examine. If drive$ is an empty string , information on the default drive is returned.

Restrictions

With Windows 95 versions before OSR2, and Windows NT versions before 4.0, DISKSIZE may return a negative or inaccurate value for drives larger than 2 GB.

See Also

  • DISKFREE


FILECOPY - ScharfBASIC Help

FILECOPY

Copy a file.

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FILECOPY sourcefile , destfile

Description

Copy the file sourcefile to the file destfile . Both sourcefile and destfile must be filenames, not merely drives or directories (although it's OK to include drive and directory specifications along with the filenames). Wildcards are not supported. If you attempt to copy a file that is read locked (preventing read access), a run-time Error 70 will occur ("Permission denied").

If the destination file already exists, it will be overwritten. If it is not possible to overwrite the existing destination file (for example, it is marked as read-only or in use by another program), the result will be a run-time Error 70 ("Permission denied").

The attributes of the source file are inherited by the destination file, with the exception of the Archive attribute, which is always set ON for the destination file. File attributes may be examined or modified with the GETATTR and SETATTR statements.

See Also

  • FILEATTR
  • GETATTR
  • SETATTR


Files - ScharfBASIC Help

Files

ScharfBASIC offers three distinct ways to store and retrieve information from disk: sequential, random, and binary file input and output. Each has its advantages and disadvantages; the one that works b

Kind | Keyword
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Back to command index


GETATTR - ScharfBASIC Help

GETATTR

Return the file-system attribute(s) of a disk file or directory.

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x& = GETATTR( filespec$ )

Description

filespec$ specifies a filename or directory (optionally, including a drive letter and directory path). The attribute code returned in x& is a standard operating system attribute code, or a combination of several codes ORed together:

Attribute

Description

Equate

Normal*

%NORMAL

Read-only

%READONLY

Hidden

%HIDDEN

System

%SYSTEM

Volume Label

%VLABEL

Directory

%SUBDIR

Archived

%ARCHIVE

Normal*

( synonym of %NORMAL)

* Some operating systems may return either 0 or 128 for normal files.

If GETATTR returns an attribute of 0 (or 128), filespec$ is a regular file: not read-only, not hidden, not system, and not archived.

Additional file attributes may be supported on some file systems. See the %FILE_ATTRIBUTE equates in your WinNT.inc file for a full list.

If you want to test for a single attribute, use the bitwise AND operator to strip out any other attributes that might be set. See the example below.

GETATTR can also be used to verify the existence of a file or directory, taking advantage of the fact that ERR will be set if the file/directory does not exist. See the example below.

Restrictions

If filespec$ cannot be found, a run-time Error 53 ("File not found") occurs. You cannot obtain the attributes of the root directory (i.e., "C:\"). Windows prevents this particular operation, triggering an Error 53.

See Also

  • DIR$
  • FILEATTR
  • ISFILE
  • PATHSCAN$
  • SETATTR


ISFILE - ScharfBASIC Help

ISFILE

Determine whether or not a file exists.

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FileExists& = ISFILE( FileName )

Description

The file subsystem is checked to determine whether the file specified by FileName currently exists. If it is found in any form (hidden, system, read-only, etc.), the value true (-1) is returned. Otherwise, the value false (0) is returned.

Filename is an unambiguous file name, which may not contain an asterisk (*) or query (?). If it contains one or more of those characters, the function always returns false (0).

See Also

  • DIR$
  • DISPLAY BROWSE
  • DISPLAY OPENFILE
  • DISPLAY SAVEFILE
  • ISFOLDER
  • PATHSCAN$


ISFOLDER - ScharfBASIC Help

ISFOLDER

Determine whether or not a folder exists.

Kind | Function
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FolderExists& = ISFOLDER( FolderName )

Description

The file subsystem is checked to determine whether the folder specified by FolderName currently exists. If it is found in any form (hidden, system, read-only, etc.), the value true (-1) is returned. Otherwise, the value false (0) is returned.

The root directory (for example, "C:\") is considered to be a folder, and returns the value true (-1).

FolderName is an unambiguous file name, which may not contain an asterisk (*) or query (?). If it contains one or more of those characters, the function always returns false (0).

See Also

  • DIR$
  • DISPLAY BROWSE
  • DISPLAY OPENFILE
  • DISPLAY SAVEFILE
  • ISFILE
  • PATHSCAN$


KILL - ScharfBASIC Help

KILL

Delete a disk file.

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

KILL filespec

Description

filespec is a string expression specifying the file or files to be deleted, and can include a path name and/or "wildcard" characters. filespec may be either a Short File Name (SFN) or a Long File Name (LFN). For example:

KILL "TEST.DOC"

KILL "C:\MY APPLICATION DATA\INCOME.?87"

MyFile$ = "*.BAS"

KILL MyFile$ ' Potentially dangerous!

If filespec does not exist, Error 53 ("File not found") is generated. If filespec is read only, Error 70 ("Permission denied") occurs. You should not attempt to KILL an open file.

Files with the HIDDEN or SYSTEM attribute can not be deleted with KILL. An attempt to do so is ignored, with no error generated.

KILL is analogous to the DOS "DEL" and "ERASE" commands. KILL cannot delete a directory - use RMDIR instead, after first deleting all the files in the directory.

See Also

  • FILEATTR
  • FILECOPY
  • FILENAME$
  • GETATTR
  • NAME
  • RMDIR
  • SETATTR
  • SETEOF

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x201f9c
call   0x201f1f
mov   edx,0x203a60
call   0x201f9c
call   0x201908
call   0x201d60
call   0x201e50


MKDIR - ScharfBASIC Help

MKDIR

Create a subdirectory/folder (like the DOS MKDIR command).

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MKDIR path$

Description

path$ is a string expression describing the directory to be created.

MKDIR (make directory) creates the subdirectory specified by path$ . If you try to create a directory that already exists, a run-time Error 75 occurs ("Path/file access error"). If path$ includes an parent folder that does not exist, a run-time Error 76 occurs ("Path not found").

MKDIR can use Long File

Names (LFNs).

See Also

  • CHDIR
  • RMDIR


NAME - ScharfBASIC Help

NAME

Rename a file or a directory (like the DOS REN command).

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

NAME filespec1$ AS filespec2$

Description

The NAME statement comprises the following elements:

filespec1$

The current name of a file or directory. The file must not be currently opened or locked . filespec1$ may be either a Short File Name (SFN) or a Long File Name (LFN).

filespec2$

The desired name of the file or directory, and may use Long File Name (LFN) naming conventions.

Each filespec may contain drive and path specifications as well as a file or directory name.

If filespec1 does not exist, run-time Error 53 ("File not found") occurs. If filespec2 already exists, run-time Error 58 occurs ("File already exists"). If filespec1 has been opened or locked by your application and not closed, an Error 51 can occur ("Internal system error"). You should never rename a file that has been opened by your code and not (yet) closed.

Restrictions

It is possible to move a file from one directory, drive, or partition, to another. It is not possible to move directories between drives or partitions. Wildcard characters are not permitted in the file names.


RMDIR - ScharfBASIC Help

RMDIR

Delete a disk directory (like the DOS RMDIR command).

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

RMDIR path

Description

path is a directory path, which may include a drive specification. RMDIR deletes the directory indicated by path .

This statement works like the DOS "RMDIR" or "RD" commands. As with the DOS commands, the path must specify a valid, empty directory, other than the default (current) directory. Otherwise, a run-time Error 75 occurs ("Path/file access error").

RMDIR can use Long File Names (LFNs).

See Also

  • CHDIR
  • KILL
  • MKDIR


SETATTR - ScharfBASIC Help

SETATTR

Set the file system attribute(s) of a disk file or directory.

Kind | Statement
Category | File Management
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SETATTR filespec$ , attribute

Description

filespec$ specifies a filename (optionally including a drive letter and directory path). attribute is a standard operating system attribute code:

Attribute

Description

Equate

Normal

%NORMAL

Read-only

%READONLY

Hidden

%HIDDEN

System

%SYSTEM

Archived

%ARCHIVE

The attribute code of a given file or directory may be constructed from a combination of individual attribute values. For example, if you use an attribute of 0, filespec$ will be a regular file: not read-only, not hidden, not system, and not archived.

See Also

  • DIR$
  • FILEATTR
  • GETATTR


%DEF - ScharfBASIC Help

%DEF

Determine if an equate

Kind | Operator
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

%DEF({ %numeric_equate | $string_equate })

Description

The %DEF operator tests whether or not an equate has been defined. If the equate has been defined, %DEF returns TRUE (non-zero); or FALSE (zero) if it has not be defined.

ScharfBASIC automatically defines the equates in the following table according to the ScharfBASIC compiler being used. Please note the references to other ScharfBASIC compilers are included for those writing programs that may be compilable by more than one ScharfBASIC compiler.

Equate

Definition

%PB_CC32

Pre-defined as TRUE (non-zero) in PB/CC for Windows, but is not defined in other compilers.

%PB_DLL16

Pre-defined as TRUE (non-zero) in PB/DLL 16-bit, but is not defined in other compilers.

%PB_DLL32

Synonym of %PB_WIN32

%PB_WIN32

Pre-defined as TRUE (non-zero) in PB/Win 32-bit, but is not defined in other compilers.

%PB_REVISION

Pre-defined as the hex revision (10.00 = &H1000).

%PB_REVLETTER

Pre-defined as the ASCII code of the revision letter (a = &H61), or &H20 if there is no revision letter.

%PB_EXE

Pre-defined as TRUE (non-zero) if compiling to EXE or as FALSE (zero) if compiling to DLL (PB/Win only) or SLL format.

The equate %PB_EXE is always defined in ScharfBASIC, so %DEF(%PB_EXE) will always be evaluated as TRUE. The difference being the value assigned to the equate by the compiler. See the examples below.

These can be used in conjunction with #IF as a compiler directive to selectively include or exclude code from the compiled file.

See Also

  • #IF
  • Numeric Equates
  • Built-in numeric equates
  • String Equates
  • Built-in string equates


%PB_COMPILETIME numeric equate - ScharfBASIC Help

%PB_COMPILETIME numeric equate

Helps to determine the date/time of compilation.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

Each time you compile your program, this equate is filled with the current date and time of the compilation in PowerTime binary format. You can use the PowerTIME Class to convert it to a text equivalent for use in your application.

Details

Helps to determine the date/time of compilation.

Each time you compile your program, this equate is filled with the current date and time of the compilation in PowerTime binary format. You can use the PowerTIME Class to convert it to a text equivalent for use in your application.

LOCAL Built AS IPowerTime

LET Built = CLASS "PowerTime"

Built.FileTime = %PB_COMPILETIME

MSGBOX Built.DateString

MSGBOX Built.TimeString


ACCEL ATTACH - ScharfBASIC Help

ACCEL ATTACH

Attach a table of keyboard accelerators to a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ACCEL ATTACH hDlg , AccelTbl() TO hAccelHandle

Description

ACCEL ATTACH permits you to attach one table of accelerator key definitions to each DDT dialog in your application.

The keyboard accelerator itself is a specific keystroke combination, which results in a %WM_COMMAND or %WM_SYSCOMMAND message being placed into the application's message queue.

Keyboard accelerators are very similar to command accelerators, and often permit the same action selections as menus offer. Since keyboard accelerators can be used directly, they negate the need to navigate a menu in order to perform a specific action.

Typically, application menu items inform users of available keyboard accelerators so expert users can work more efficiently without using the actual menus, but can still use the menu if required. The following image shows a menu showing command accelerator and keyboard accelerators for menu items (the command accelerators are underscored):

On Windows XP and Windows 2000 you may need to press the ALT key before Command Accelerators are made visible. You can set if Command Accelerators are visible when using the ALT key or all the time in the Windows Display Settings.

For a command accelerator to operate, the specific menu item must be visible and enabled. Conversely, keyboard accelerators can be used without the menu being open. In the example above, the CTRL+X keystroke combination will perform the CUT action, but the accelerator letter t will only perform the Cut action if the EDIT menu is opened first.

AccelTbl()

To utilize ACCEL ATTACH, you must first build the array AccelTbl() of ACCELAPI User-Defined Types (UDTs). This ACCELAPI structure is a 6-byte structure with the following definition:

TYPE ACCELAPI WORD

FVIRT AS BYTE ' Flags: One or more of %FVIRTKEY, %FSHIFT, %FALT and %FCONTROL

KEY AS WORD ' Accelerator key: ASCII code, or virtual key code {%FVIRTKEY}

CMD AS WORD ' Accelerator ID code gets passed in CB.CTL {LO(WORD, WPARAM)}

END TYPE

You must build the array of ACCELAPI types yourself, then attach it to a dialog by executing an ACCEL ATTACH statement. There must be no empty elements in the array, so it must be sized accurately.

.FVIRT

The .FVIRT flags can be combined together with the OR operator to combine the actions of the individual flags, as follows:

The ALT key must be pressed along with the accelerator key.

%FCONTROL

The CTRL key must be pressed along with the accelerator key.

%FSHIFT

The SHIFT key must be pressed along with the accelerator key.

%FVIRTKEY

The .KEY member specifies a virtual-key code. If this flag is not specified, the key member is assumed to specify an ASCII character code. %FVIRTKEY permits case-insensitive accelerator keystroke definitions - the Capslock state is ignored. For example, ALT+A and ALT+a (as determined by the Capslock key) produce the same accelerator event. If %FVIRTKEY is not used, the accelerator ALT+A would not trigger if Capslock were inactive.

If the %FVIRTKEY flag is specified in the .FVIRT member, the .KEY field contains the virtual key code for the accelerator key. Virtual key equates are defined in the WIN32API.INC file, starting with the prefix %VK_.

If %FVIRTKEY is not specified, the accelerator key code in the .KEY member is the ASCII code of the accelerator key. In this case, alphanumeric keystrokes become case-sensitive and the state of the Capslock key state becomes important. For example, if an accelerator were defined for ALT+A, it would be activated only if the Capslock key was on. Conversely, if an accelerator were defined for ALT+a then it would only be activated Capslock was off.

The .CMD member should contain the user-defined numeric ID code of the accelerator. When an accelerator keystroke occurs, a WM_COMMAND message is sent to the dialog Callback Function, with the accelerator identifier returned by the CB.CTL function.

It is usual practice to use the ID of a control that is to be activated by an accelerator. Accelerator notification codes sent to the Callback Function have CB.CTLMSG set to 1 (as opposed to button click events messages where CB.CTLMSG = %BN_CLICKED).

The handle of the dialog to attach the accelerator table to.

AccelHandle

Double-word or Long-integer variable where the handle of the attached accelerator table will be stored, or zero if the attach operation was unsuccessful.

Restrictions

If a previous table was attached to the target dialog, the table is automatically destroyed when the new table is attached in its place. The accelerator table is also destroyed automatically when the dialog is closed.

You can destroy the current accelerator table by executing ACCEL ATTACH with an array which is not dimensioned, but there is little or no reason to ever perform this action.

Accelerator tables can only run correctly when they are created in the same module that creates the dialog to which each table is attached.

See Also

  • DIALOG NEW
  • MENU ADD STRING
  • MENU ATTACH


Accessing ScharfBASIC variables by name - ScharfBASIC Help

Accessing ScharfBASIC variables by name

Most variables in a ScharfBASIC module are visible to Inline Assembler code created with the ASM statement. You can reference LOCAL , STATIC , and GLOBAL variables by name by simply using the name as a

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

SUB DoStuff (BYVAL c&)

a% = 7 ' Local variable a%

! MOV AX, a% ; Move value to AX

! ADD a%, AX ; Add value back to a%

b$ = "LINDA" ' Local variable b$

! MOV EBX, b$ ; Address of b$

! MOV [EBX], "l" ; Put lowercase "l" in first position

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fild   DWORD PTR ds:0x202a54
fld   QWORD PTR [ebp-0xa0]
call   0x201b1d
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


Add-on Libraries, Utilities and Tools - ScharfBASIC Help

Add-on Libraries, Utilities and Tools

Third Party libraries, utilities, and tools can be found on the Add-on's section on the ScharfBASIC web site.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Additional Source Code and Examples


Additional Source Code and Examples - ScharfBASIC Help

Additional Source Code and Examples

Additional source code, example files, and utilities can be found on the ScharfBASIC web site. Click the following links to go to those web pages:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Add-on Libraries, Utilities and Tools


Addressing and pointers - ScharfBASIC Help

Addressing and pointers

An important distinction in assembler is the difference between the address of a variable and the value of a variable. The address of a variable is where it is located in memory; the value of a variab

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

This is the ADDRESS of the variable in memory:

This is the VALUE at that address:

The method used in assembler to get the value at an address is a technique called dereferencing .

! MOV EAX, lpvar ; Copy address into EAX

! MOV EAX, [EAX] ; Dereference it

! MOV nuvar, EAX ; Copy EAX into new variable

Using square brackets around EAX gives access to the information at the address in EAX. This is the case with any 32-bit register . A register enclosed in square brackets is effectively a memory operand. The size of the data accessed at the address is determined by the size of the register used to receive it. In the above example, it would be a 32-bit value since it uses a 32 bit register for the destination operand. Naturally, it can be done with 8 and 16-bit values as well using the correct size register.

Pointers are a useful high-level language abstraction for passing addresses between procedures and performing other types of complex data manipulation.


Are there other important "Buzz-Words"? - ScharfBASIC Help

Are there other important "Buzz-Words"?

See Also

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

What is an object, anyway?

What are the parts of an object?

What does a Class look like?

What is a Base Class?


ARRAY ASSIGN - ScharfBASIC Help

ARRAY ASSIGN

Allow the assignment of a number of values to successive elements of an

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ARRAY ASSIGN array() = param1 [, param2 ] [, ]

Description

ARRAY ASSIGN allows the assignment of a number of values to successive elements of an array. The assignment always starts with the first array element, and continues sequentially as the elements appear in memory. The values to be assigned must match the array type, and may be literals , variables , or expressions. ARRAY ASSIGN cannot be used on an array of Interfaces .

See Also

  • ARRAY DELETE
  • ARRAY INSERT
  • ARRAY SCAN
  • ARRAY SORT
  • DIM
  • LBOUND
  • PowerArray
  • REDIM
  • UBOUND


ARRAY DELETE - ScharfBASIC Help

ARRAY DELETE

Delete a single item from a given

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ARRAY DELETE array ([ index ]) [FOR count ] [, expression ]

Description

ARRAY DELETE deletes the data stored at the nominated element in array , an n-dimensional array. You can specify the index of the element which is to have its data deleted, how many elements ( count ) are to be automatically shifted down by one position, and what data value to give the last element after the rest of the elements have been shifted ( expression ).

All of these parameters are optional. If index is not specified, the data stored in the element at the beginning of the array is deleted. If expression is not present, the last element that the data is shifted out of will contain zero if array is a numeric array, or an empty string if array is a string array . If a shift count is given, when shifting the rest of the array to eliminate the element, only count elements will be shifted.

By default, ARRAY DELETE throws away the data at the element index of array , shifting the data in the appropriate portion of the array to cover the old element:

DIM A(1 TO 4) AS LONG

ARRAY DELETE A(2), 17&

makes A(2) = A(3) , A(3) = A(4) , and A(4) = 17 . The original value of A(1) remains in place. Use count to "protect" a portion of the array from the shift:

DIM A(1 TO 4) AS LONG

ARRAY DELETE A(2) FOR 2, 17&

makes A(2) = A(3) and A(3) = 17 because you told it to shift only 2 elements. The original values of A(4) and A(1) remain in place.

DELETE with multi-dimensional arrays

count can also be used with a multi-dimensional array (stored in linear column-major order; see ARRAY SORT ), to prevent shifting element data from one dimension into another dimension, thus preserving the organization of the array. For example:

DIM A(0 TO 1,0 TO 1) AS INTEGER

A(0,0)=0

A(1,0)=100

A(0,1)=200

A(1,1)=300

ARRAY DELETE A(0,0) FOR 2, 17%

makes A(0,0) = 100 and A(1,0) = 17 . The original values of A(0,1) and A(1,1) remain in place since you told it to shift only 2 elements. Without count :

ARRAY DELETE A(0,0), 17%

makes A(0,0) = 100 , A(1,0) = 200 , A(0,1) = 300 , and A(1,1) = 17 . The original value of A(0,0) is lost.

Restrictions

ARRAY DELETE cannot be used on arrays within UDT structures. However, ARRAY DELETE can be used with arrays of UDT structures - simply treat them as if they were an array of fixed-length strings .

To use ARRAY DELETE on an embedded UDT array, use DIM..AT to dimension a regular array (of the same type) directly "over the top" of the UDT array, and use ARRAY DELETE on that array. For example:

TYPE SalesType

OrderNum AS LONG

PartNumber(1 TO 20) AS STRING * 20

END TYPE

[ statements ]

DIM Sales AS SalesType

[ statements ]

DIM Temp(1 TO 20) AS STRING * 20 AT VARPTR(Sales.Partnumber(1))

ARRAY DELETE Temp(5), "string"

ERASE Temp()

See Also

  • ARRAY ASSIGN
  • ARRAY INSERT
  • ARRAY SCAN
  • ARRAY SORT
  • DIM
  • LBOUND
  • PowerArray
  • REDIM
  • UBOUND

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Array Delete

call   0x201918
sub   esp,0x58
sub   esp,0x1c
sub   esp,0x14
call   0x20376c
add   esp,0x58
call   0x202480

Variant 2: Let

call   0x201e3c


ARRAY INSERT - ScharfBASIC Help

ARRAY INSERT

Insert a single item into a given

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ARRAY INSERT array ([ index ]) [FOR count ] [, expression ]

Description

ARRAY INSERT inserts a single data item into array , an n-dimensional array. You can specify the index at which the new element data is to be inserted, how many elements ( count) are to be shifted up by one position to make room for the new element data, and what data value to give the new element ( expression ).

All of these parameters are optional. If index is not specified, the element data is inserted at the beginning of the array If e xpression is not present, the new element will contain zero if array is a numeric array, or an empty string if array is a string array .

If a shift count is given, when shifting the rest of the array to make way for the new element data, only count elements will be shifted.

By default, ARRAY INSERT throws away the data in last element of array , then shifts the appropriate portion of the array to make way for the new element data:

DIM A(1 TO 4) AS LONG

ARRAY INSERT A(2), 17

makes A(4) = A(3) , A(3) = A(2) , and A(2) = 17 . The original value of A(4) is lost, while the original value of A(1) remains in place. Use count to "protect" a portion of the array from the shift:

DIM A(1 TO 4) AS LONG

ARRAY INSERT A(2) FOR 2, 17

makes A(3) = A(2) and A(2) = 17 because you told it to shift only 2 elements. The original values of A(4) and A(1) remain in place.

INSERT with multi-dimensional arrays

count can also be used with a multi-dimensional array (stored in linear column-major order; see ARRAY SORT ), to prevent shifting data from one dimension into another dimension, and thus preserving the organization of the array. For example:

DIM A(0 TO 1,0 TO 1) AS SINGLE

A(0,0)=0

A(1,0)=100

A(0,1)=200

A(1,1)=300

ARRAY INSERT A(0,0) FOR 2, 17

makes A(0,0) = 17 and A(1,0) = 0 . The original values of A(0,1) and A(1,1) remain in place since you told it to shift only 2 elements. Without count :

ARRAY INSERT A(0,0), 17

makes A(0,0) = 17 , A(1,0) = 0 , A(0,1) = 100 , and A(1,1) = 200 . The original value of A(1,1) is lost.

Restrictions

ARRAY INSERT cannot be used on arrays within UDT structures or on an array of Interfaces . However, ARRAY INSERT can be used with arrays of UDT structures - simply treat them as if they were an array of fixed-length strings.

To use ARRAY INSERT on an embedded UDT array, use DIM..AT to dimension a regular array (of the same type) directly "over the top" of the UDT array, and use ARRAY INSERT on that array. For example:

TYPE SalesType

OrderNum AS LONG

PartNumber(1 TO 20) AS STRING * 20

END TYPE

[ statements ]

DIM Sales AS SalesType

[ statements ]

DIM Temp(1 TO 20) AS STRING * 20 AT VARPTR(Sales.Partnumber(1))

ARRAY INSERT Temp(5), "string"

ERASE Temp()

See Also

  • ARRAY ASSIGN
  • ARRAY DELETE
  • ARRAY SCAN
  • ARRAY SORT
  • DIM
  • LBOUND
  • PowerArray
  • REDIM
  • UBOUND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201918
sub   esp,0x58
sub   esp,0x1c
sub   esp,0x14
call   0x203a59
add   esp,0x58
call   0x202480


Array operations - ScharfBASIC Help

Array operations

The following functions can be used to manipulate and manage arrays:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Control generation of error checking code

Specify if variables must be declared before use

Assign a number of values to successive elements of an array

Delete a single item from a given array


ARRAY SCAN - ScharfBASIC Help

ARRAY SCAN

Scan all or part of an

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ARRAY SCAN array ([ index ]) [FOR count ], expression , TO lvar&
ARRAY SCAN array ([ index ]) [FOR count ] [, FROM startChar TO endChar ] [, COLLATE {UCASE |
cstring }], expression , TO lvar&

Description

ARRAY SCAN scans all or part of array, an n-dimension array, for the first element that satisfies expression . expression consists of a relational operator (=, >, <, <>, >=, =>, <=, =<) followed by an expression of the same data type as array . The relative index of the first match is stored in lvar& , which must be a Long-integer variable:

ARRAY SCAN A&(), > 5, TO I&

This line of code identifies the relative index of the first element of array A&() that is greater than 5, and stores the relative index in I& . The match index ranges from 1 to the last element of the scan + 1.

Since it is a relative index:

DIM A(1 TO 10) AS SINGLE

ARRAY SCAN A(), > 17.42!, TO I&

will store 2 in I& if A(2) > 17.42, but:

DIM A(5 TO 20) AS SINGLE

ARRAY SCAN A(), > 17.42!, TO lvar&

will store 2, not 6, in lvar& if A(6) > 17.42.

If none of the scanned elements satisfy expression , zero will be stored in lvar& .

Together, index and count specify the portion of array to be scanned. index specifies the element at which the scan is to begin, while count specifies the number of consecutive elements to be scanned. If index is not specified, the scan begins at the first element of array . If count is not specified, the array is scanned from element index to the last element of array . If neither is specified, the entire array is scanned:

DIM A&(1 TO 100)

ARRAY SCAN A&(5), =1, TO I& 'scans 5..100

ARRAY SCAN A&() FOR 10, =1, TO I& 'scans 1..10

ARRAY SCAN A&(10) FOR 20, =1, TO I& 'scans 10..29

ARRAY SCAN A&(), =1, TO I& 'scans 1..100

Scanning a string array

When scanning a string array , COLLATE UCASE treats all lowercase letters as uppercase during the scan (for example, element "Bob" would satisfy the condition = "BOB"):

ARRAY SCAN A$(), COLLATE UCASE, = "BOB", TO I&

' scans A$() for "BOB"; all letters treated as

' uppercase

COLLATE string is used to specify a non-standard scanning order. cstring must contain exactly 256 characters, in the order in which they should be compared, from lowest to highest. For example, the normal ascending ASCII scan order (where "A" is considered less than "B", etc.) would be described by a string containing ASCII codes 0 through 255 in order:

C$ = CHR$(0 TO 255)

ARRAY SCAN A$(), COLLATE C$, > "BOB", TO I&

The normal descending ASCII scan order would be described by a string containing the reverse of the above:

C$ = STRREVERSE$(CHR$(0 TO 255))

ARRAY SCAN A$(), COLLATE C$, > "BOB", TO I&

The COLLATE string option is provided as a flexible means with which to specify a descending scan, or to specify the scanning order for strings containing international characters or other special symbols.

See ARRAY SORT for more information on building collating strings.

When scanning a string array, all characters of each element of the array are normally considered when performing comparisons. To limit the comparison to a specific subset of characters, use FROM to specify the startChar position, and TO to specify the endChar position that ARRAY SCAN will consider within each array element. For example, you could scan based on the zip code contained in the last 5 characters of a 40-character address string:

ARRAY SCAN A$(), = "90210", TO I&

' considers all characters when scanning for "90210"

ARRAY SCAN A$(), FROM 36 TO 40, = "90210", TO I&

' considers positions 36..40 only when scanning

Scanning a multi-dimensional array

When scanning a multi-dimensional array , the array is treated as a single-dimension array containing all of the elements of the multi-dimensional array, in linear column-major order. That is, all elements where all dimensions (except the first), are held at their minimum bounds, will come first in memory. These are immediately followed by the elements where the second dimension is set to its next consecutive index value, etc.

For example, the elements of a two-dimensional array (DIM A(0 TO n, 0 TO x)) would be stored in consecutive memory locations as follows:

A(0,0), A(1,0), , A(n,0) ' The first n+1 elements,

A(0,1), A(1,1), , A(n,1) ' The next n+1 elements,

[ statements ] ' Subsequent elements,

A(0,x), A(1,x), , A(n,x) ' The last n+1 statements.

or more clearly:

A(0,0), A(1,0) , A(n,0), A(0,1), A(1,1) , A(n,1), A(0,x),

A(1,x) , A(n,x)

In this case, ARRAY SCAN A(0,0) FOR n+1, >5, TO I& would scan only elements (0,0)...(n,0), while ARRAY SCAN A(0,0), >5, TO I& would scan the entire array: elements (0,0)...(n,x). As mentioned earlier, since ARRAY SCAN records the relative index of the matched element, ARRAY SCAN A(0,0), >5, TO I& would store 2 in I& if A(1,0) > 5.

Restrictions

ARRAY SCAN cannot be used on arrays within UDT structures or on an array of Interfaces . However, ARRAY SCAN can be used with arrays of UDT structures - simply treat them as if they were an array of fixed-length strings.

To use ARRAY SCAN on an embedded UDT array, use DIM..AT to dimension a regular array (of the same type) directly "over the top" of the UDT array, and use ARRAY SCAN on that array. For example:

TYPE SalesType

OrderNum AS LONG

PartNumber(1 TO 20) AS STRING * 20

END TYPE

[ statements ]

DIM Sales AS SalesType

[ statements ]

DIM Temp(1 TO 20) AS STRING * 20 AT VARPTR(Sales.Partnumber(1))

ARRAY SCAN Temp(), FROM 1 TO LEN(Search$), = Search$, TO lResult&

ERASE Temp()

See Also

  • ARRAY ASSIGN
  • ARRAY DELETE
  • ARRAY INSERT
  • ARRAY SORT
  • DIM
  • LBOUND
  • PowerArray
  • REDIM
  • UBOUND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201938
sub   esp,0x58
push   DWORD PTR [ebx+0x18]
push   DWORD PTR [ebx+0x24]
push   DWORD PTR [ebx+0x30]
push   DWORD PTR [ebx+0x3c]
push   DWORD PTR [ebx+0x48]
push   DWORD PTR [ebx+0x54]
push   DWORD PTR [ebx+0x60]
push   DWORD PTR [ebx+0x6c]
sub   esp,0x10
call   0x203fe6
add   esp,0x58
call   0x2024a0


ARRAY SORT - ScharfBASIC Help

ARRAY SORT

Sort all or part of a given

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ARRAY SORT darray ([ index ]) [FOR count ] [,TAGARRAY tarray() ] [,{ASCEND | DESCEND}]
ARRAY SORT dArray ([ index ]) [FOR count ] [,FROM startChar TO endChar ] [,COLLATE {UCASE |
cstring }] [,TAGARRAY tarray() ] [,{ASCEND | DESCEND}]
ARRAY SORT darray ([ index ]) [FOR count ] [,TAGARRAY tarray() ] ,CALL custfunc()

Description

ARRAY SORT sorts all or part of darray , an n-dimensional array, in ascending or descending order. tarray is a tag-along array whose elements are swapped in the same order as those in darray as the sort proceeds (you could sort an array of names and have an array of corresponding addresses tag along, for example). tarray must have at least as many elements as darray , since corresponding elements of tarray will be swapped during the sort.

Note that tarray does not have to be of the same type as darray . For example, you could have a numeric array containing account numbers tag along with a string array containing user names:

DIM Users$(100 TO 500), AcctNum&(100 TO 500)

ARRAY SORT Users$(), TAGARRAY AcctNum&()

Together, index and count specify the portion of darray to be sorted. index specifies the element at which the sort is to begin, while count specifies the number of consecutive elements to be sorted. If index is omitted, the sort begins at the first element of darray . If count is omitted or is zero, the array is sorted from element index to the last element of darray . If both are omitted, the entire array is sorted:

DIM A&(1 TO 99)

ARRAY SORT A&(5) 'sorts elements 5..99 of A&

ARRAY SORT A&() FOR 10 'sorts elements 1..10 of A&

ARRAY SORT A&(9) FOR 20 'sorts elements 9..28 of A&

ARRAY SORT A&() 'sorts elements 1..99 of A&

Sorting numeric arrays

By default, arrays are sorted in ascending order. To sort in descending order, include the DESCEND keyword:

ARRAY SORT A&(), DESCEND ' descending order

ARRAY SORT A&(), ASCEND ' ascending order

ARRAY SORT A&() ' ascending order

Sorting string arrays

When sorting a string array, the sort is performed in ascending order by default. In addition to DESCEND, ARRAY SORT provides the COLLATE UCASE and COLLATE string options.

COLLATE UCASE treats all lowercase letters as equal to their uppercase counterparts during the sort (elements "Bob" and "BOB" would be considered equal, for example):

DIM A$(1 TO 5)

A$(1) = "Bob"

A$(2) = "Jan"

A$(3) = "Linda"

A$(4) = "Ann"

A$(5) = "Jerry"

ARRAY SORT A$(), COLLATE UCASE, DESCEND

'sorts A$() in descending order; case-insensitive

COLLATE cstring is used to specify an entirely new sorting order. This can be used for a variety of purposes, the most obvious of which is the case of international character sets. The collate string cstring must contain exactly 256 characters, one for each of the ASCII codes 0-255, in the order that they would be sorted (from lowest to highest, if an ascending sort were performed on them).

Each position in the string represents the ASCII code of that value. The contents of the byte at that position tells ScharfBASIC the "weight" or importance factor of that particular ASCII code. The default is that position 0 has a weight of 0, position 1 has a weight of 1, etc, so that CHR$ (0) sorts first, CHR$(1) sorts next, and so on through CHR$(255).

Suppose you want the special character "ä" to have the same weight as the standard character "a". It's easy: construct a string of 256 characters, 0-255; then go to the position of "ä" (ASCII code 132), and change the contents of that byte so it is exactly equal to the code for "a" (97). The following code fragment constructs just such a collate string:

' Create a 256-character string:

FOR ix = 0 TO 255

C$ = C$ + CHR$(ix)

MID$(C$, 132 + 1) = CHR$(97)

We add one to the ASC value for MID$ because string positions start at 1, not 0. We can also use the expanded CHR$ function to create the same collating string using less code:

C$ = CHR$(0 TO 131, 97, 133 TO 255)

It is most important to remember the rule for creating a collating string, as it is easy to make an intuitive jump to the wrong conclusion. Each position in the string (1-256) represents the ASCII code with that value minus one (CHR$(0) to CHR$(255)). The contents of the byte at that position tell the ARRAY SORT procedure the new "weight" or importance factor for that particular code. This is exactly the technique used by the 80x86-assembler opcode XLAT.

Suppose you want CHR$(0) to sort at the very end of the sequence. To do that, you would set the byte at position 0+1 to CHR$(255) and the bytes at positions 0+2 to 0+256 to the values 0 to 254. The ASCII sequence in the collating string would appear like this: 255,0,1,2,3,4 254. Using the expanded CHR$ function, this is straightforward:

C$ = CHR$(255, 0 TO 254)

To sort upper case and lower case alphabetic characters as exactly equal, just set positions 97 to 122 (a-z) to the values 65-90 (A-Z). This is precisely how COLLATE UCASE is handled. With the collating method implemented by this procedure in ScharfBASIC, it is possible for two or more ASCII codes to have equal "weight".

As mentioned earlier, many programmers make a common, fatal mistake by intuitively creating a collating string that is simply a list of ASCII codes, in the sequence they wish to sort. That is, they expect the byte which appears first in the string to sort first, the byte which appears next to sort second, so that creating a collate string from the BASIC code:

CHR$(65) + CHR$(66) + CHR$(67) + ...

might cause the characters "ABC..." to be sorted first. This technique will never work with the ARRAY statement and must be carefully avoided . We describe it here only because it is a common error. While it is arguably more intuitive than the technique implemented in ScharfBASIC, the reason it does not work is that it doesn't allow two or more ASCII codes to have the same "weight".

The following code builds a collating string compatible with the American OEM ASCII character set. For the fastest operation, this code should be run only once and the collating string should be made global .

GLOBAL cu AS STRING

FOR x = 0 TO 255

cu = cu + CHR$(x)

MID$(cu, 97+1, 26) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

MID$(cu, 129+1, 6) = "ueaaaa" ' üéâäàã

MID$(cu, 136+1, 9) = "eeeiiiAAE" ' ëèïîìÄÂÉ

MID$(cu, 147+1, 8) = "ooouuyOU" ' ôöòûùÿÖÜ

MID$(cu, 161+1, 5) = "iounN" ' ìòùñÑ

MID$(cu, 168+1, 1) = "?" ' ¿

[ your code goes here ]

ARRAY SORT MyArray$(), COLLATE cu

An alternative arrangement using the expanded CHR$ function may look like this:

cu = CHR$(0 TO 96, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", _

123 TO 128, "ueaaaa", _ ' üéâäàã

135, "eeeiiiAAE", _ ' ëèïîìÄÂÉ

145 TO 146, "ooouuyOU", _ ' ôöòûùÿÖÜ

155 TO 160, "iounN", _ ' ìòùñÑ

166 TO 167, "?", _ ' ¿

169 TO 255)

For example, the normal ascending ASCII sort order would be described by a string containing ASCII codes 0 through 255 in order:

C$ = CHR$(0 TO 255)

ARRAY SORT A$(), COLLATE C$

The normal descending ASCII sort order would be described by a collating string containing the reverse of the above:

C$ = STRREVERSE$(CHR$(0 TO 255))

ARRAY SORT A$(), COLLATE C$

COLLATE string can also be used with the ASCEND or DESCEND option. With ASCEND, the sort is performed in the order specified by COLLATE string ; DESCEND sorts using the reverse of the order specified by COLLATE string :

ARRAY SORT A$(), COLLATE C$, DESCEND

The COLLATE string option is provided as a flexible means with which to specify the sorting order for strings containing international characters or other special symbols. Please keep in mind that the characters with ASCII code above CHR$(127) may have different meanings in different countries. The examples here assume that the default American OEM ASCII code page is in use.

When sorting a string array, all characters of each element of the array are normally considered when performing comparisons. To limit the comparison to a specific subset of characters, use FROM to specify the startChar position, and TO to specify the endChar position that ARRAY SORT will consider within each array element. For example, you could sort based on the zip code contained in the last 5 characters of a 40-character address string:

ARRAY SORT A$() ' sorts all chars

ARRAY SORT A$(), FROM 36 TO 40 ' sorts 36 - 40 only/p>

By using the FROM..TO keywords, it also becomes possible to sort an array of User-Defined Types. In this case, ARRAY SORT can sort the array as if it were an array of fixed-length strings .

Sorting custom arrays:

In most cases, the standard numeric and string sorts should serve your needs very well. However, in the case of more complex data, it is frequently necessary to create multi-key sorts, or other unusual data sequences. Generally speaking, a multi-key sort is used when you wish to order data based upon multiple sections of a string or UDT. For example, you may wish to have customers sequenced by name -- but in the case of duplicate names, order each set of duplicates by ZIP code. With the custom array option, you can sort by any number of keys, in any sequence you may desire.

A custom array may be user-defined types, fixed-length strings, or nul-terminated strings. With a custom array sort, you can write your own simple function to tell ScharfBASIC the correct sequence for any two array elements. In the following example, the array MyType() is sorted based upon the code you write in the user-written function named MyFunc().

ARRAY SORT MyType(), CALL MyFunc()

As ScharfBASIC proceeds through the sort, each time it needs to compare two array elements, it calls your custom function (in this case named MyFunc) to determine the correct sequence of the two elements. The custom function you write must always have exactly two ByRef parameters with precisely the same data type as the sorted array, for nul-terminated and FIELD strings, they must contain the length. These are the two variables which you must compare to determine the correct sequence. Your custom function must return a long integer to tell the correct sequence. It returns -1 if the first parameter should precede the second parameter. It returns +1 if the second parameter should precede the first. It returns 0 if the parameters are equal. This affords the ScharfBASIC programmer the ultimate tool in sorting capabilities. You can have any number of keys. You can sort ascending, descending, or some other special sequence. The conditions are now totally under your control. The following example show how easy it is to create a multi-key sort, even those based upon non-string members of a UDT.

Type TheType

LastName as String * 40

FirstName as String * 20

BalanceDue as Currency

End Type

[ statements ]

Dim MyType(100) as TheType

[ statements ]

Array Sort MyType(), Call MyFunc()

[ statements ]

Function MyFunc(Param1 as TheType, Param2 as TheType) As Long

If Param1.LastName < Param2.LastName Then

Function = -1 : Exit Function

End If

If Param1.LastName > Param2.LastName Then

Function = +1 : Exit Function

End If

If Param1.FirstName < Param2.FirstName Then

Function = -1 : Exit Function

End If

If Param1.FirstName > Param2.FirstName Then

Function = +1 : Exit Function

End If

If Param1.BalanceDue < Param2.BalanceDue Then

Function = +1 : Exit Function

End If

If Param1.BalanceDue > Param2.BalanceDue Then

Function = -1 : Exit Function

End If

End Function

Notice that this function first sorts by last name in ascending sequence. If the last names are equal, it then sorts by first name in ascending sequence. If both names are equal, it then sorts by Balance Due in descending sequence so that the accounts with the highest balance appear first. This descending sequence is accomplished by switching the values -1/+1 in the final tests.

The array to be sorted, and the function parameters, must be fixed-length strings, nul-terminated strings, or user-defined types. ScharfBASIC verifies that the size of the data and parameters are identical. However, to allow maximum flexibility, it does not require that the data types be the same. Therefore, for example, it's possible to sort an array of fixed-length strings using a function with UDT parameters as long as the data size is identical. It is the programmer's responsibility to ensure accuracy.

Sorting a multi-dimensional array

When sorting a multi-dimensional array , the array is treated as a single-dimension array containing all of the elements of the multi-dimensional array, in linear column-major order. That is, all elements where all dimensions (except the first), are held at their minimum bounds, will come first in memory. These are immediately followed by the elements where the second dimension is set to its next consecutive index value, etc.

For example, the elements of a two-dimensional array (i.e., DIM A( n , x )) would be stored in consecutive memory locations like this:

(0,0), , (n,0), (0,1), , (n,1), , (0,x), , (n,x)

In this case, ARRAY SORT A(0,0) FOR n+1 would sort only elements (0,0)...(n,0), while ARRAY SORT A(0,0) would sort the entire array: elements (0,0) (n,x).

Be very careful when using ARRAY SORT with multi-dimensional arrays so as not to disrupt the organization of the data in the arrays.

Restrictions

ARRAY SORT cannot be used on arrays within UDT structures or on an array of Interfaces . However, ARRAY SORT can be used with arrays of UDT structures - simply treat them as if they were an array of fixed-length strings.

To use ARRAY SORT on an embedded UDT array, use DIM..AT to dimension a regular array (of the same type) directly "over the top" of the UDT array, and use ARRAY SORT on that array. For example:

TYPE SalesType

OrderNum AS LONG

PartNumber(1 TO 20) AS STRING * 20

END TYPE

[ statements ]

DIM Sales AS SalesType

[ statements ]

DIM Temp(1 TO 20) AS STRING * 20 AT VARPTR(Sales.Partnumber(1))

ARRAY SORT Temp()

ERASE Temp()

See Also

  • ARRAY ASSIGN
  • ARRAY DELETE
  • ARRAY INSERT
  • ARRAY SCAN
  • CHR$
  • DIM
  • LBOUND
  • PowerArray
  • REDIM
  • UBOUND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201938
sub   esp,0x58
push   DWORD PTR [ebx+0x18]
push   DWORD PTR [ebx+0x24]
push   DWORD PTR [ebx+0x30]
push   DWORD PTR [ebx+0x3c]
push   DWORD PTR [ebx+0x48]
push   DWORD PTR [ebx+0x54]
push   DWORD PTR [ebx+0x60]
push   DWORD PTR [ebx+0x6c]
call   0x202cb4
call   0x202d34
add   esp,0x58
call   0x2024a0


ARRAYATTR - ScharfBASIC Help

ARRAYATTR

Return descriptive attributes of a given

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = ARRAYATTR( Arr() , AttrNum )

Description

ARRAYATTR returns various descriptive attributes of an array, depending upon the value of AttrNum

AttrNum

Definition

Returns TRUE (-1) if the array is currently dimensioned, FALSE (0) if not.

Returns the data type , as defined in the following table. Note that the numeric equates listed on the right of the table are built into ScharfBASIC, but the numeric values they represent are subject to change. Therefore, application code should always use the numeric equates rather than the numeric value, to ensure compatibility with future versions of ScharfBASIC. The current data type definitions are:

Array type

Keyword

Equate

%VARCLASS_BYT

%VARCLASS_WRD

Double-word

%VARCLASS_DWD

Integer

INTEGER

%VARCLASS_INT

Long-integer

%VARCLASS_LNG

Quad-integer

%VARCLASS_QUD

Single-precision

SINGLE

%VARCLASS_SNG

Double-precision

DOUBLE

%VARCLASS_DBL

Extended-precision

%VARCLASS_EXT

Currency

CURRENCY

%VARCLASS_CUR

Extended Currency

CURRENCYX

%VARCLASS_CUX

Variant

VARIANT

%VARCLASS_VRNT

Interface

INTERFACE

%VARCLASS_IFAC

%VARCLASS_GUID

UDT or Union

TYPE/UNION

%VARCLASS_TYPE

ANSI NulTrm string

ASCIIZ/STRINGZ * n

%VARCLASS_STRZ

Fixed-length string

STRING * n

%VARCLASS_FIX

Dynamic string

STRING

%VARCLASS_STR

Field string

%VARCLASS_FLD

Wide NulTrm string

WSTRINGZ

%VARCLASS_WSTRZ

Wide FixLen string

WSTRING * n

%VARCLASS_WFIX

Wide Dynamic string

WSTRING * n

%VARCLASS_FLD

Wide Field string

WFIELD

%VARCLASS_WFLD

Returns TRUE (-1) if it is an array of pointers, FALSE (0) if not.

Returns the number of dimensions of the array. The lower and upper boundaries of each dimension can be retrieved with the LBOUND and UBOUND functions respectively

Returns the total number of elements in the array. For example, the array DIM A&(3,4,5) would comprise 120 elements (4 x 5 x 6 = 120).

Returns the array element size. For example, an array of Double-precision variables would be 8 bytes. For dynamic strings, the size of the string handle (4 bytes) is returned. For DISPATCH and INTERFACE arrays, ARRAYATTR returns the size of a pointer variable (4 bytes).

See Also

  • DIM
  • LBOUND
  • UBOUND
  • PowerArray
  • REDIM


Balancing the stack - ScharfBASIC Help

Balancing the stack

An important consideration when using the stack is to be symmetrical in the byte count of what is pushed and what is popped.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

If the stack is not balanced on exit from an assembly code block (i.e., you POP too few or too many registers ), your routine will return to the wrong location in your code. This is because ScharfBASIC must assume that the last item on the stack is the address to which it should return.

In other words, if the stack is not balanced on exit from an assembly code block, program execution is likely to resume at the wrong address and instantly crash the program. In most instances, if you PUSH a given data size onto the stack, you must POP the same data size.


Built-in numeric equates - ScharfBASIC Help

Built-in numeric equates

The compiler provides a convenient set of built-in numeric equates .

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The first to consider should be the group which determines the compiler version and the supported feature level. Additional information may be found with the %DEF equate operator.

%PB_CC32, %PB_DLL32, %PB_EXE, %PB_REVISION, %PB_REVLETTER, %PB_WIN32

Compile-Time information:

At each compile, this equate is filled with the current date and time of the compilation in PowerTime binary format. You can use the PowerTime Class to convert it to a text equivalent for use in your application.

For use with #RESOURCE FILEFLAGS :

%VS_FF_DEBUG, %VS_FF_INFOINFERRED, %VS_FF_PATCHED, %VS_FF_PRERELEASE, %VS_FF_PRIVATEBUILD, %VS_FF_SPECIALBUILD

For use with ARRAYATTR :


Built-in string equates - ScharfBASIC Help

Built-in string equates

The compiler also provides a set of built-in string equates . These offer convenience as well as self-documentation.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The following table shows the ANSI form, each of which begins with a single dollar-sign ($). The compiler also includes and offers a wide Unicode version of each of them, identified by a double dollar-sign ($$). For example, $NUL returns a byte with the character code zero (0), while $$NUL returns a word with the character code zero (0).

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Str

mov   edx,0x203a54
call   0x201de0
call   0x201d63
mov   edx,0x203a68
call   0x201de0
call   0x201d63
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
call   0x201b74
lea   ebx,[ebp-0xa0]
call   0x201d63
call   0x201c94

Variant 2: String

call   0x201d78
call   0x201cfb
call   0x201d78
call   0x201cfb
mov   ebx,0x5
mov   edx,0x202a74
call   0x201d78
call   0x201913
lea   ebx,[ebp-0xa0]
call   0x201cfb
call   0x201c2c


Built-in User Defined Types - ScharfBASIC Help

Built-in User Defined Types

The compiler provides a set of built-in User-Defined Types, including:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

VariantArgs AS VARIANT

NamedDispID AS VARIANT

DispParams is used internally by the compiler to send parameters to Dispatch methods and properties.

FileAttributes AS DWORD


CALL DWORD - ScharfBASIC Help

CALL DWORD

Invoke a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CALL DWORD TargetPtr
CALL DWORD TargetPtr USING abc ([ arguments ]) [TO result_var ]

Description

CALL DWORD is an essential ingredient for implementing run-time (explicit) dynamic linking of DLLs , rather than the more common load-time (implicit) linking. This provides a way of constructing calls to APIs and DLLs that may not be present in all versions of Windows. This technique ensures that an application can start up successfully, even if Windows cannot resolve the location of the API or DLL function.

The first (simplified) form of CALL DWORD may be used if the target Sub/Function takes no parameters and offers no return value. It also requires STDCALL (SDECL ) calling conventions, which is used by the vast majority (99%+) of import procedures. In all other cases, you must use the second form, with a USING clause to define the signature of the target Sub/Function.

TargetPtr

A Double-word , Long-integer , or pointer variable that contains the address of the entry point of a procedure (Sub or Function). If the target Sub/Function is located in the same module, you can retrieve the address with the CODEPTR function. If it's located in an external DLL, use IMPORT ADDR to load it and get the address.

This option is used to define a model procedure declaration which matches all of the calling conventions desired to be used to invoke the target Sub/Function. For example, the following two calls to the function MySubCall are equivalent:

DECLARE SUB MySubCall

DIM PtrMySubCall AS DWORD

PtrMySubCall= CODEPTR(MySubCall)

[ statements ]

CALL MySubCall

CALL DWORD PtrMySubCall USING MySubCall

arguments

An optional, comma-delimited list of variables , expressions, and constants to be passed to the procedure as parameters. In the CALL DWORD context, enclosing parentheses are required. The number and type of parameters passed must agree with the arguments of the procedure named by the USING clause. See CALL for more information on parameter passing methods.

TO result_var

When calling a Function which returns a value, the TO keyword offers a way to assign the function return value to result_var .

Restrictions

Thread Functions and Callback Functions may not be invoked with CALL DWORD. The DECLARE model for the USING clause may not specify a LIB or IMPORT option.

See Also

  • CALL
  • CODEPTR
  • DECLARE
  • FASTPROC
  • FUNCTION/END FUNCTION
  • IMPORT
  • SUB/END SUB
  • THREAD CREATE


CALLSTK$ - ScharfBASIC Help

CALLSTK$

Retrieve the details of a specific

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

sfname$ = CALLSTK$( n )

Description

CALLSTK$(1) returns the name of the current Sub , Function , Method , or Property , and the value of each of the parameters at the time it was called. CALLSTK$(2) returns the name of the procedure which called the current one, as well as its parameters. Likewise, CALLSTK$(3) returns the one above it, and so forth.

If the CALLSTK$( n ) parameter is outside the range of one (1) through the number of stack frames identified by CALLSTKCOUNT , an empty string is returned. parameters are displayed in decimal, while pointer and array parameters display a decimal representation of the offset of the target value.

Restrictions

The CALLSTK$ function can be invaluable during debugging , but it generates substantial extra code which should be avoided in a final release version of an application. If the source code contains #TOOLS OFF , all CALLSTK$ functions which remain in the program return an empty string.

The CALLSTK$ function is "thread-aware", returning only stack frame details from the thread in which it was referenced.

See Also

  • #TOOLS
  • CALLSTK
  • CALLSTKCOUNT
  • FUNCNAME$
  • PROFILE
  • TRACE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x20108d
call   0x201b7a
call   0x201d4e
mov   edx,0x204a54
call   0x2031c4
call   0x202c1c
call   0x201ea1
call   0x20310c
call   0x201df1


CALLSTKCOUNT - ScharfBASIC Help

CALLSTKCOUNT

Retrieve the number of

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

count& = CALLSTKCOUNT

Description

CALLSTKCOUNT returns a Long-integer value that represents the total number of stack frames that currently exist on the application call stack.

Retrieve individual stack frame details with the CALLSTK$ function, or write them all to a disk file with the CALLSTK statement.

Restrictions

The CALLSTKCOUNT function, when used in conjunction with the CALLSTK$ function, can be invaluable during debugging , but its use generates substantial extra code which should be avoided in a final release version of an application. If the source code contains #TOOLS OFF , all CALLSTKCOUNT functions which remain in the program return zero.

The CALLSTKCOUNT function is "thread-aware", returning only the stack frame count from the thread in which it was referenced.

See Also

  • #TOOLS
  • CALLSTK$
  • CALLSTK
  • FUNCNAME$
  • PROFILE
  • TRACE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x20108d
call   0x201b6a
call   0x201d3e
call   0x201dca
call   0x2030fc
call   0x201de1


CBYT - ScharfBASIC Help

CBYT

Convert a value to specific

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

bytevar? = CBYT( numeric_expression )
currencyvar@ = CCUR( numeric_expression )
currencyextvar@@ = CCUX( numeric_expression )
doublevar# = CDBL( numeric_expression )
doublewordvar??? = CDWD( numeric_expression )
extendedvar## = CEXT( numeric_expression )
integervar% = CINT( numeric_expression )
longintvar& = CLNG( numeric_expression )
quadintvar&& = CQUD( numeric_expression )
singlevar! = CSNG( numeric_expression )
wordvar?? = CWRD( numeric_expression )

Description

Each of these functions converts a numeric expression to a particular variable type. In each case, numeric_expression must be within the legal range for the result type. The numeric_expression will be rounded if necessary.

Function

Result type

Currency

Extended-currency

Double-precision floating-point

Double-word

Extended-precision floating-point

Integer

Long-integer

Quad-integer

Single-precision floating-point

These conversion functions are rarely needed as ScharfBASIC automatically performs any necessary conversions when executing an assignment statement or passing parameters. For example:

e% = f#

is equivalent to:

e% = CINT(f#)

In the case of the functions that convert to integral class values, the fractional part of the number is rounded. If the fractional part is exactly .5 then it rounds to the nearest even integral value. For example, CINT(1.5) returns 2, CINT(.5) returns 0, and CLNG(-0.6) returns -1.

Restrictions

CSNG limit string display to 7 significant digits.

See Also

  • CEIL
  • CVI and associated functions
  • FIX
  • INT
  • MKI$ and associated functions

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Cbyt

mov   ecx,0xe
call   0x201c6c
call   0x201bef
and   eax,0xff
mov   BYTE PTR [ebp-0xbc],al
call   0x201b20

Variant 2: Ccur

mov   ecx,0xf
call   0x201d58
call   0x201cdb
fld   QWORD PTR [ebp-0xa8]
mov   eax,0x4
call   0x201b54
lea   ebx,[ebp-0xc0]
call   0x201b26
call   0x201c0c

Variant 3: Cdbl

call   0x201c6c
call   0x201bef
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
fstp   QWORD PTR [ebp-0xb0]
call   0x201b20

Variant 4: Cint

mov   ecx,0xe
call   0x201c7c
call   0x201bff
fld   QWORD PTR [ebp-0xa8]
fistp   QWORD PTR [ebp-0x6c]
mov   eax,DWORD PTR [ebp-0x6c]
mov   WORD PTR [ebp-0xbc],ax
call   0x201b30

Variant 5: Clng

call   0x201c6c
call   0x201bef
fld   QWORD PTR [ebp-0xa8]
call   0x201c84
call   0x201b20

Variant 6: Csng

mov   ecx,0xe
call   0x201c7c
call   0x201bff
fld   QWORD PTR [ebp-0xa8]
fstp   DWORD PTR [ebp-0x6c]
mov   eax,DWORD PTR [ebp-0x6c]
mov   DWORD PTR [ebp-0xbc],eax
call   0x201b30


Characters, Strings, and Unicode - ScharfBASIC Help

Characters, Strings, and Unicode

A string consists of a set of zero or more characters. A character is an alphabetic letter, a number, a punctuation mark, or even non-printing control codes, which usually aid in formatting the text.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

This representation is convenient, since a string of text characters can be readily stored as a series of small integral numbers. For example, the word "Hello" is stored as 72, 105, 108, 108, 111. Couldn't be any simpler. How are the numbers assigned and associated? It's just a matter of mutual consent by those who use them. As long as everyone agrees on the associations, the system works well. That said, we have experienced a certain amount of growing pains over the years. With the global growth of computer use, larger character sets are needed to represent the necessary characters. We have clearly reached the point where every programmer must consider alternate character sets for his applications. Failure to do so can carry severe penalties. When you find you can no longer read data files from an outside source, or can no longer read text from the Internet, it will be too late. The following sections describe the most-common and most-used character sets.

ASCII was the first character set to be used on small computers. In fact, all of the other sets described here use ASCII codes as-is for a base. ASCII is a set of 128 characters, numbered from 0 to 127. It was designed for American English, so it defines only unaccented letters, numbers, punctuation, and control codes. As long as you only need English text, ASCII works fairly well.

ASCII needs just 7 bits of storage per character, so it was convenient to store each character in a byte . The last bit was simply ignored. Of course, that meant that the values from 128 to 255 were unused. That void wouldn't last long.

OEM is the acronym for "Original Equipment Manufacturer". IBM introduced the IBM PC in 1981. Along with it came their version of an expanded character set. It's been known as the OEM character set ever since. In fact, that character set is still the default for the Windows Console Device on the very latest version of Windows.

The first 128 characters are identical to ASCII. However, IBM decided to use the remaining 128 characters for other purposes. They defined them for the most common accented characters, line drawing characters, and special symbols and punctuation. Of course, this was an improvement, but many characters in non-English languages were unavailable. This led to new OEM character sets (German, Cyrillic...), with many different interpretations for that second set of character codes. Of course, this caused a good amount of confusion trying to understand the contents of strings from an external source. Not an ideal solution.

Some time later, the ANSI character set evolved. Once again, the first 128 characters are the same as ASCII. But there are many ways to handle the second set. The decoding system, called "code pages", handles these items accurately, even if cumbersome. In reality, many languages need hundreds or thousands of characters. Clearly, the character codes can't possibly be squeezed into a byte. The solution? Multi-byte characters. Some characters are one byte, and some are more. If a particular character needs a multi-byte representation, a special ID byte is inserted, followed by the identifying data. A multi-byte character may consist of two, three, or even more bytes. That special ID byte determines what data will follow.


ChrToOem$ - ScharfBASIC Help

ChrToOem$

Translates a string

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

o$ = ChrToOem$( AnsiOrWide$ )

Description

AnsiOrWide$ contains a series of ANSI characters or WIDE (16-bit) characters, ChrToOem$ translates it into OEM byte characters.

See Also

  • OemToChr$
  • ChrToUtf8$
  • Utf8ToChr$


ChrToUtf8$ - ScharfBASIC Help

ChrToUtf8$

Translates a string of

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

o$ = ChrToUtf8$( AnsiOrWide$ )

Description

AnsiOrWide$ contains a series of ANSI characters or WIDE (16-bit) characters, ChrToUtf8$ translates it into UTF-8 byte characters.

See Also

  • ChrToOem$
  • OemToChr$
  • Utf8ToChr$


CLIP$ - ScharfBASIC Help

CLIP$

Delete characters from a string

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = CLIP$(LEFT StringExpression , Count& )
s$ = CLIP$(RIGHT StringExpression , Count& )
s$ = CLIP$(MID StringExpression , Start& , Count& )

Description

Returns the contents of StringExpression with Count& characters removed from the left side.

Returns the contents of StringExpression with Count& characters removed from the right side.

Returns the contents of StringExpression with Count& characters removed starting at position Start& . The first character is considered position 1, the second position 2...

If Count& is negative, or Start& is less than one, the return value is undefined.

Restrictions

If Count& is less than one, the entire string is returned. If Start& is less than one, the results are undefined.

See Also

  • EXTRACT$
  • LTRIM$
  • MID$
  • REMOVE$
  • REPLACE
  • RTRIM$
  • SHRINK$
  • STRINSERT$
  • STRDELETE$
  • TRIM$
  • UNWRAP$


CLIPBOARD GET BITMAP - ScharfBASIC Help

CLIPBOARD GET BITMAP

Copy data to/from the Windows ClipBoard.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CLIPBOARD GET BITMAP TO ClipVar [, ClipResult ]
CLIPBOARD GET OEMTEXT TO AnsiStrgVar [, ClipResult ]
CLIPBOARD GET TEXT TO StrgVar [, ClipResult ]
CLIPBOARD GET UNICODE TO StrgVar [, ClipResult ]
CLIPBOARD RESET [, ClipResult ]
CLIPBOARD SET BITMAP ClipHndl [, ClipResult ]
CLIPBOARD SET OEMTEXT StrgExpr [, ClipResult ]
CLIPBOARD SET TEXT StrgExpr [, ClipResult ]
CLIPBOARD SET UNICODE StrgExpr [, ClipResult ]


Command Summary - ScharfBASIC Help

Command Summary

The following is a list of the commands built into the compiler and separated into 18 groups of related commands, which can assist with identifying the best command for the task at hand. Some commands

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Communication Control

Debugging and Error Control


Constants and Literals - ScharfBASIC Help

Constants and Literals

A string literal is simply a group of characters surrounded by quotation marks. It may optionally be followed by a TypeID of a single $ to specify ANSI characters, or a double $$ for wide , Unicode ch

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

MyAnsi$ = "This is a string"$

MyWide$$ = "This is a UniCode string"$$

A string literal can include the double-quote character, simply by doubling the character within the string. For example:

A$ = "This is a ""string"""

Numeric literals represent numeric values. They consist primarily of the digits 0 through 9 and a decimal point. Negative values need a leading minus sign (-); a plus sign (+) is optional for positive values. The amount of precision you supply determines the internal representation ( Integer , Long-integer , Quad-integer , Byte , Word , Double-word , Single-precision , Double-precision , Extended-precision , and Currency ) which ScharfBASIC will use in processing that literal value.

You can also force a literal value to be stored with a given precision by following the constant with one of the variable type-specifiers (%, &, &&, ?, ??, ???, !, #, ##, @, @@). This ability becomes very important when working with Currency and other floating-point numbers.

For example, the statement eVar## = 1.1 stores the Single-precision representation of 1.1 (which is 1.10000002384185791) in the Extended-precision variable eVar## . In order to store the exact quantity 1.1 in eVar## , you must follow 1.1 with the Extended-precision type-specifier (##). For example

DIM x1 AS EXT, x2 AS EXT

x1 = 1.1 ' Single-precision literal


Converting a .RC to a .RES - ScharfBASIC Help

Converting a .RC to a .RES

Using the IDE

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Firstly, ensure that the ScharfBASIC IDE's OPTIONS dialog is configured to correctly point to the RC.EXE and PBRES.EXE files. Once configured, the IDE can automatically compile a .RC into a .RES file. When the "Create a .PBR when compiling .RC files" option on the compiler options tab is selected the IDE will also produce a .PBR file from the .RES file. This is achieved in one simple step: simply load the .RC file into the IDE and select Compile.

Using the command-line Resource Compiler

To compile the .RC file, we need to run the Resource Compiler from a DOS box (command-line) to create the binary (.RES) resource file.

The resource compiler takes the filename of your modified (.RC) resource script file as a parameter, and produces a new 32-bit .RES file. For example:

C:\PB\BIN\RC.EXE MYAPP.RC

Note that you may need to change the path name to suit your individual settings. At this point, you should have a compiled binary resource file (i.e., MYAPP.RES), ready to be used with the #RESOURCE metastatement.

What is a Resource File?


Creating a Dynamic Link Library - ScharfBASIC Help

Creating a Dynamic Link Library

A DLL contains one or more exported Classes , Subs , or Functions that may be called by applications or other DLLs. A DLL may also contain any number of private Subs or Functions that can only be call

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The first step is to identify the sections of your application that are used in multiple programs, or in the case of Visual Basic, Subs and Functions that you need to execute faster.

Save those Subs and Functions as text, and change the file extension to .BAS. This will become the source module that will be compiled into a DLL with ScharfBASIC. You could also create the source file from scratch, if you so wish.

Launch PBEDIT.EXE (the ScharfBASIC IDE) and add the EXPORT keyword to any Sub or Function in the DLL source code (that you wish to be made accessible to external applications). Add #COMPILE DLL to the top of the source code file, and make any other changes to your .BAS source module. See the SUB/END SUB and FUNCTION/END FUNCTION topics for more information on the exact syntax.

Click the compile button on the ScharfBASIC IDE toolbar.

Any compile-time error s will be flagged at this point. Repeat steps 3 to 4 above until no more errors are reported. You are then ready to start testing and debugging your DLL. Debugging is done using the ScharfBASIC symbolic Debugger built into the ScharfBASIC IDE (PBEDIT.EXE). See the section on Debugging for more information.


Creating a Static Link Library - ScharfBASIC Help

Creating a Static Link Library

Creation of an SLL couldn't be easier. All it takes is a single metastatement at the top of your module source code:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

If your source code file is named "ABC.BAS", then your Static Link Library will automatically be named "ABC.SLL". (You can check the #COMPILE section for additional naming options.) When you wish to use the SLL code in a host program, you use:

and the contents are automatically embedded in the new .EXE or .DLL. It's just that simple.

Common Subs and Functions

A COMMON Sub or Function is one which is visible between the primary host program and one or more SLL unit modules. A Sub / Function is defined as COMMON by inserting that word as one of the descriptors:

FUNCTION MyFunc(Parm AS LONG) COMMON AS DOUBLE


DATACOUNT - ScharfBASIC Help

DATACOUNT

Return the total count of the number of local

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

Count% = DATACOUNT

Description

DATACOUNT only returns the number of DATA items in the Sub , Function , Method , or Property in which it appears (i.e., local DATA statements). While it is not possible to directly read data from outside of the scope of current procedure, global data can be emulated easily by placing it inside a procedure returns data to the calling code. There is a limit of 64 Kilobytes and 16384 separate data items per procedure.

See Also

  • DATA
  • READ$


DATE$ system variable - ScharfBASIC Help

DATE$ system variable

Set or retrieve the system date.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DATE$ = s$ ' sets system date according to s$
s$ = DATE$ ' s$ now contains system date

Description

Assigning a properly formatted string value to DATE$ sets the system date. You can also assign DATE$ to a string variable, which stores 10 characters in the form "mm-dd-yyyy", where mm represents the month, dd the day, and yyyy the year.

To change the date, your date string must be formatted in one of the following ways:

mm-dd-yy

mm/dd/yy

mm-dd-yyyy

mm/dd/yyyy

For example, DATE$ = "11-09-84" sets the system date to November 9, 1984.

Restrictions

The year assigned to the DATE$ system variable must be within the range 1980 to 2099. DATE$ never returns locale-specific date formats. When assigning a two digit year, any value less than 81 will be assumed to be in the 2000's and any value greater than 80 will be assumed to be in the 1900's.

See Also

  • DAYNAME$
  • MONTHNAME$
  • POWERTIME
  • TIME$


DAYNAME$ - ScharfBASIC Help

DAYNAME$

Converts a Day-of-Week number to the associated name.

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = DAYNAME$( DayNumber& )

Description

The DAYNAME$ function converts a Day-of-Weeek number into a string representing its associated name. The argument must be in the range of 0 through 6, representing the names Sunday, Monday, etc.

See Also

  • DATE$
  • MONTHNAME$
  • POWERTIME


DEC$ - ScharfBASIC Help

DEC$

Convert an integral value to a decimal string

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = DEC$( IntVal [, Digits , LeadSpaces , TrailSpaces ])

Description

IntVal is a numeric expression in the range of a 64-bit Quad Integer (-9223372036854775808 to +9223372036854775807). Any fractional part of the value is rounded. If the value is negative, the leading minus sign occupies one digit position. The result string is always formatted as an integral number using all the significant digits in IntVal. It is never expressed in scientific notation.

If Digits is 0 (or not given), no leading characters will be added to the numeric field. If Digits is a positive number greater than 0, the result string will be prepended with leading zeros to achieve the desired length. If Digits is a negative number, leading spaces are added to reach the absolute length. Digits may be in the range of -20 to +20.

LeadSpaces specifies additional leading spaces to be prepended, regardless of the length of the numeric portion of the string.

TrailSpaces specifies additional trailing spaces to be appended to the end of the string.

See Also

  • BIN$
  • FORMAT$
  • HEX$
  • OCT$
  • STR$
  • TRIM$
  • USING$
  • VAL


DECR - ScharfBASIC Help

DECR

Decrement a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DECR variable

Description

variable can be a numeric variable or a pointer variable. When DECR is used with a numeric variable, 1 is subtracted from the numeric variable.

If DECR is used on the target of a numeric pointer variable (i.e., DECR @IntPtr), the target numeric variable is decremented by one. However, when using DECR on a pointer variable, the value of the pointer variable is decremented by the size of its target.

For example, given a pointer to element 1000 of an Integer array, DECR of the pointer variable itself would result in a decrement of 2, which should point to the previous element in the array (element 999). This is because an Integer is two bytes wide, so the pointer value is reduced by 2 bytes.

See Also

  • INCR
  • LET

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201b00


DEFBYT - ScharfBASIC Help

DEFBYT

Declare the default type for

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DEFtype letter_range [, letter_range ] [, ...]

Description

type represents one of ScharfBASIC's variable types: INT ( Integer ), LNG ( Long-integer ), QUD ( Quad-integer ), SNG ( Single-precision floating-point ), DBL ( Double-precision floating-point ), EXT ( Extended-precision floating-point ), CUR ( Currency ), CUX ( Extended-currency ), STR ( String ), BYT ( Byte ), WRD ( Word ), and DWD ( Double-word ).

letter_range

is either a single alphabetic character (A through Z, case insignificant), or a range of letters (two letters separated by a hyphen, for example, A-M).

DEFtype

Tells the compiler that variables and user-defined functions , whose names begin with the specified letter or range of letters, are of the specified type.

Normally, when the compiler finds a variable name without a type specifier, a compile-time error is generated. If however, there was a preceding DEF type statement such as DEFINT A-Z, the variable would default to that type (in this case, an Integer variable).

You may use multiple DEF type statements. If there is overlap between two DEF type statements, no error is generated; but the definition of the latter DEF type statement overrides the former where the two overlap.

The DEF type statement may not be supported in future editions of ScharfBASIC, so we recommend explicit variable declarations, using DIM , INSTANCE , LOCAL , STATIC , THREADED , or GLOBAL .

Restrictions

Def type only applies to implicitly-defined variables. It has no effect on variables that are defined explicitly. If a #DIM ALL statement exists in the application then Deftype statements will have no effect, #DIM ALL requires all variables to be defined explicitly

Usage Examples

  1. DEFINT A-E, G, Q, Y-Z
  2. DEFCUX B, F, H-P, R-X
  3. FUNCTION PBMAIN
  4. A = 1 ' A is Integer
  5. B = 2 ' B is Extended-currency.
  6. [ statements ]
  7. END FUNCTION

See Also

  • #DIM ALL
  • DIM
  • INSTANCE
  • LOCAL
  • STATIC
  • THREADED
  • GLOBAL


Defining Constants - ScharfBASIC Help

Defining Constants

PB/Win constants (also known as equates) are defined by prefixing the name of the constant with a "%" character. MSBASIC and VB define constants with the CONST keyword. The MSBASIC/VB compiler then do

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

However, the MACRO facilities in PB/Win offer a way to retain the CONST syntax in your code, while maintaining the low overhead advantage of ScharfBASIC. For example:

CONST Something_Else = 2???

CONST AppTitle = "My Application"

MSGBOX FORMAT$(Something), ,AppTitle

During compilation, the CONST keyword is replaced by the MACRO word, which dynamically creates a new macro that, in turn, defines a constant.


DIR$ CLOSE - ScharfBASIC Help

DIR$ CLOSE

Force the release of the operating system FindNext handle.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIR$ CLOSE

Description

DIR$ CLOSE will cause the operating system FindNext handle to be closed. Each time a new DIR$() sequence is initiated within a thread, or DIR$() returns an empty string , ScharfBASIC automatically closes the FindNext handle to avoid overuse of system resources.

However, in unusual circumstances (such as a recursive directory scan with delete or rename), it may be necessary to close the FindNext handle sooner, through the use of this explicit statement, so that a directory can be removed or renamed.

Restrictions

It is never necessary to execute DIR$ CLOSE to simply avoid a "System Handle Leak".

See Also

  • DIR$


Dll example - ScharfBASIC Help

Dll example

A very simple example is a DLL with a function that will add one to any Long-integer passed to it as a parameter:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

FUNCTION AddOne ALIAS "AddOne" (BYVAL x AS LONG) EXPORT AS LONG

The ALIAS keyword is used to indicate the capitalization that ScharfBASIC will assign the function. In Win32, all exported (and imported) Sub and Function names are case-sensitive. If the ALIAS keyword was omitted, ScharfBASIC will capitalize the exported name and this could cause " Missing DLL entry point" errors if the calling code did not match the capitalization exactly.

By default, all Subs and Functions in ScharfBASIC are private, which means they cannot be seen outside of the DLL. The EXPORT keyword is used on the Sub or Function definition line to indicate that the routine is to be exported, i.e., made accessible to applications and other DLLs.

When compiled into a DLL, AddOne is visible to outside applications. A Visual Basic program needs only include a prototype, or a DECLARE statement for the function, in order to call it as if it were a VB function:

DECLARE FUNCTION AddOne LIB "ADDONE.DLL" ALIAS "ADDONE" (BYVAL x&) AS LONG

AddOne is then accessible from within your Visual Basic code:


ERL system variable - ScharfBASIC Help

ERL system variable

Return the last

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

nline = ERL

Description

Return the last (most recent) line number that was encountered before the most recent run-time error , within the current Sub , Function , Method , or Property . With ERL, line numbers are of the traditional-basic line numbering variety, not the physical source code line.

See Also

  • ERL$
  • ERR
  • ERRCLEAR
  • ERROR
  • ERROR$
  • Error Overview
  • Error Trapping
  • ON ERROR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201ae4


ERL$ - ScharfBASIC Help

ERL$

Return the last

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

position$ = ERL$

Description

Return a string containing the name of the last (most recent) label, line number, or procedure that was executed prior to the most recent run-time error , within the current Sub , Function , Method , or Property . In order to maintain high efficiency levels, the returned name is limited to the first 8 characters of the actual name.

See Also

  • ERL
  • ERR
  • ERRCLEAR
  • ERROR
  • ERROR$
  • Error Overview
  • Error Trapping
  • ON ERROR


ERR system variable - ScharfBASIC Help

ERR system variable

Return the error code of the most recent ScharfBASIC run-time error.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = ERR
ERR = ErrNum
y = ERRCLEAR
ERRCLEAR

Description

ERR and ERRCLEAR return the error code of the most recent run-time error in the current Sub , Function , Method , or Property . This number can be tested after any critical operation, so that appropriate error-handling code can be executed.

You can also assign a value to ERR. This is similar to executing an ERROR statement , except that no branch to an error trap routine is generated. Instead, subsequent tests of ERR and ERRCLEAR reflect ErrNum .

ERRCLEAR returns the error code of the most recent run-time error. In addition, it resets ScharfBASIC's internal error code variable ERR to zero after you reference it. Finally, it emulates RESUME FLUSH so that no RESUME execution is needed or allowed. This ensures that the next time you test ERR or ERRCLEAR, you are guaranteed to get a zero, unless a new error has actually occurred in the interim.

ERRCLEAR can also be used as a statement to reset ERR to zero.

IMPORTANT: Be sure to study the Errors and Error Trapping .

Restrictions

Valid run-time error values are in the range 0 through 255. A value of 0 indicates no error. Attempting to set an error value (with the ERROR statement) outside of that range will convert the value to a run-time Error 5 ("Illegal function call").

See Also

  • ERROR
  • ERROR$
  • Error Overview
  • Error Trapping
  • ON ERROR

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Err

call   0x20171d

Variant 2: Errclear

call   0x201735


Evaluating a variable - ScharfBASIC Help

Evaluating a variable

To see the value of position right-click on the variable and choose the Evaluate variable item from the context-menu - since this is a context-sensitive menu, it will actually read "Evaluate position"

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The next few lines are supposed to remove the word from the beginning of the line and put the word into SecondString$ . To check if that routine functions correctly, you should examine the values of FirstString$ and SecondString$ before and after the routine alters them. The debugger should display:

To be or not to be; that is the question.

From the appearance of the string, you can see that the first blank should appear in position 3, and that the program has correctly determined that position. The variable SecondString$ ought to contain the last word processed and should have no value yet. You can check that by entering SecondString$ in the Variable Name field; if you do, you will find no error.

Everything seems normal so far. Press ESCAPE to return to the main part of the debugger, then press F8 to step the program one more line. Since you already know position is not 0, you'll find out what you need to know by pressing F8 several more times, stopping when the execution bar is over the final END IF of that routine. At that point, both FirstString$ and SecondString$ have been processed.

Once more, evaluate SecondString$ . This time, SecondString$ does contain data: the word "To". This seems correct. When you ask to see the value of FirstString$ , though, you get a surprise: FirstString$ has not been changed at all! This explains the lockup for the first line; subroutine GetAWord was correctly supplying the first word, but was not removing that first word from the entry string. Therefore, the first line never actually became shorter, so it was being processed and reprocessed endlessly.

To correct the bug, exit the debugger and insert a routine in the editor that shortens FirstString$ by the length of SecondString$ . Insert a line reading something like:

FirstString$ = MID$(FirstString$, position + 1)

immediately before the END IF in GetAWord . Make this correction, then save it. Click on the Compile and Debug icon in the toolbar and run the program through the debugger again.


EXE.Inst member - ScharfBASIC Help

EXE.Inst member

Return information about the executing program.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

h& = EXE.Inst
f$ = EXE.Extn$
f$ = EXE.Full$
f$ = EXE.Name$
f$ = EXE.Namex$
f$ = EXE.Path$

Description

You can use EXE to retrieve information about the executing program, including the complete path and file name, or just a selected part of it. If the reference is physically located within a DLL, the returned data describes the executable program which loaded it.

EXE.Inst

This returns the instance handle (a DWord ) of the program which is currently executing.

EXE.Extn$

This returns the extension (with a leading period) of the program which is currently executing.

EXE.Full$

This returns the complete drive, path, file name, and extension of the program which is currently executing.

EXE.Name$

This returns just the file name of the program which is currently executing.

EXE.Namex$

This returns the file name and the extension of the program which is currently executing.

EXE.Path$

This returns the complete drive and path of the program which is currently executing.

See Also

  • COMMAND$
  • PATHNAME$
  • PATHSCAN$


FASTPROC/END FASTPROC statements - ScharfBASIC Help

FASTPROC/END FASTPROC statements

Define a FastProc code section.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FASTPROC ProcName [([ arguments ])] [THREADSAFE] [AS LONG]
[ statements ...]
END FASTPROC [= ReturnValue ]

Description

Return value: ]

A Fast Procedure (FASTPROC) is a highly simplified form of SUB or FUNCTION which executes much faster than its fully-featured counterparts. It allows a maximum of two numeric LONG arguments, and may optionally return a LONG result. The arguments are always processed as register variables for maximum execution speed. No stack frame is ever created, so there are other limitations detailed below. The programmer may then decide when it is appropriate to accept these trade-offs in exchange for maximum efficiency.

All executable code must reside in a Sub , Function , Method , FastProc, or Property block. You cannot define a procedure inside another procedure. A FASTPROC is a subroutine-like block of statements which is invoked with the CALL statement. A FASTPROC may also be invoked without the word CALL, which is then implied. If the CALL word is omitted, the parentheses around the argument list must also be omitted.

ProcName must be unique: no variable, Function, Sub, Method, FastProc, Property or label can share the same name.

THREADSAFE

If you include the option THREADSAFE, ScharfBASIC automatically establishes a semaphore which allows only one thread to execute it at a time. Others must wait until the first thread exits the THREADSAFE procedure before they are allowed to begin.

Restrictions

Most of the restrictions of a FASTPROC stem from the fact that no stack frame is created.

See Also

  • DECLARE
  • EXIT
  • FUNCNAME$
  • GLOBAL
  • INSTANCE
  • ISMISSING
  • LOCAL
  • METHOD
  • PROPERTY
  • STATIC
  • SUB
  • THREAD CREATE
  • THREADID
  • THREADSAFE


File Commands - ScharfBASIC Help

File Commands

The following functions can be used to manipulate files , standard I/O and disk services:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Change the current (default) directory on a given drive.

Change the current default drive.

Conclude I/O (input/output) to/from a file or device.

Return the current directory for a given drive.


GET$ - ScharfBASIC Help

GET$

Read an

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GET$ [#] filenum& , Count& , StrgVar

Description

GET$ reads Count& characters from file number filenum& , and assigns them to StrgVar . GET$ and PUT$ provide a low-level alternative to sequential and random-access file-processing techniques, allowing you to deal with files on a byte-by-byte basis.

File filenum& must have been opened in binary mode. Characters are read starting at the current file pointer position, which can be set with the SEEK statement. When the file is first opened, the pointer is at the beginning of the file (position 1, by default, unless BASE=0 was specified in the OPEN statement). After GET$, the file pointer position is automatically advanced to the position immediately following the data read.

See Also

  • EOF
  • GET
  • GET$$
  • INPUT#
  • LINE INPUT#
  • LOF
  • OPEN
  • PRINT#
  • PUT
  • PUT$
  • PUT$$
  • SEEK
  • WRITE#


GET$$ - ScharfBASIC Help

GET$$

Reads

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GET$$ [#] Filenum& , Count& , StrgVar

Description

GET$$ reads Count& WIDE characters from file number filenum& , and assigns them to StrgVar . GET$$ and PUT$$ provide a low-level alternative to sequential and random-access file-processing techniques, allowing you to deal with files on a character-by-character basis.

File filenum& must have been opened in binary mode. Characters are read starting at the current file pointer position, which can be set with the SEEK statement. When the file is first opened, the pointer is at the beginning of the file (position 1, by default, unless BASE=0 was specified in the OPEN statement). After GET$$, the file pointer position is automatically advanced to the position immediately following the data read.

See Also

  • EOF
  • GET
  • GET$
  • INPUT#
  • LINE INPUT#
  • LOF
  • OPEN
  • PRINT#
  • PUT
  • PUT$
  • PUT$$
  • SEEK
  • WRITE#


GOTO - ScharfBASIC Help

GOTO

Transfer program execution to the statement identified by a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GOTO { label | linenumber }
GOTO DWORD dwpointer

Description

GOTO causes program flow to jump unconditionally to the code identified by label or linenumber . The label or linenumber must be local to the Sub , Function , Method , or Property where the GOTO statement is located. GOTO differs from GOSUB and other similar control statements, in that after execution of a GOTO, the program retains no memory of where it was before it executed the jump.

Labels and line numbers are private. You cannot GOTO a label outside of the current procedure.

GOTO DWORD causes execution to jump unconditionally to address stored in dwpointer . dwpointer must be a Double word , Long integer , or pointer variable that contains the address of a label which is local to the procedure where the GOTO DWORD statement is located.

See Also

  • CALL
  • CALL DWORD
  • DO/LOOP
  • EXIT
  • FOR/NEXT
  • FUNCTION
  • GOSUB
  • IF block
  • METHOD
  • PROPERTY
  • RETURN
  • SELECT
  • SUB
  • WHILE/WEND


IMPORT ADDR - ScharfBASIC Help

IMPORT ADDR

Load or free a library (

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

IMPORT ADDR ProcName$ , LibName$ TO AddrVar& [, HndlVar& ]
IMPORT CLOSE LibHndl

Description

In most cases, libraries are implicitly loaded automatically when you list an IMPORT or LIB option in a DECLARE statement. While that's the easiest approach, it can cause a fatal problem if the DLL is missing, or it's a version which does not include the Sub / Function you need. In that case, your program will fail at startup, and not execute at all.

IMPORT ADDR allows you to load a DLL explicitly, by name, so that you can handle a problem gracefully if the operation fails for any reason. With IMPORT ADDR, ProcName$ specifies the name of the SUB or Function you wish to access, while LibName$ specifies the name of the DLL and where it is located. ProcName$ must use the correct upper/lower case for all alphabetic characters or it will fail. If the load is successful, the address of the entry point of the Sub/Function is assigned to the variable AddrVar& , and the handle of the DLL is assigned to the optional variable HndlVar& . Both of these variables must be Long Integers or DWords . If the load fails for any reason, the value zero (0) is assigned to both.

After the library (DLL) is loaded successfully, you can access the Sub/Function with CALL DWORD AddrVar& .

Once you are through using the library, you can release it and regain the memory used by executing IMPORT CLOSE. The expression LibHndl must specify the value returned in HndlVar& when the DLL was loaded. If you do not execute an IMPORT CLOSE, the DLL will be automatically released when your program terminates.

See Also

  • CALL DWORD
  • DECLARE


INCR - ScharfBASIC Help

INCR

Increment a variable by 1; increment a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

INCR variable

Description

variable can be a pointer or a pointer variable . When INCR is used with a numeric variable, 1 is added to the numeric variable.

When INCR is used with a pointer variable itself, the value of the pointer is incremented by the size of the pointer's target.

When INCR is used on a numeric pointer's target (i.e., INCR @IntPtr) the value of the target is incremented by 1.

For example, given a pointer to an array where the pointer targets element 1000, applying INCR to the pointer would result in the pointer aiming at element 1001. The actual address held by the pointer would have risen by two, because the target of the pointer is an Integer which is two bytes wide.

Conversely, if INCR was used on the target of this Integer pointer, the value of the element itself would be incremented by 1.

See Also

  • DECR
  • LET

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201b00


Internal representations of arrays - ScharfBASIC Help

Internal representations of arrays

ScharfBASIC stores arrays in column-major order: Array (0,0) is first (lowest) in memory, then Array (1,0), then Array (2,0), and so on through all the rows of the array. After the rows are taken care

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

While ScharfBASIC supports lower boundary values that are non-zero, ScharfBASIC generates the most efficient code if the lower boundary parameter is omitted (i.e., the array uses the default lower boundary of zero).

Array boundary values can be obtained at run-time via the LBOUND and UBOUND functions. Descriptive attributes of an array can be retrieved with the ARRAYATTR function. These attributes include such information as the data type and the number of dimensions , etc.

Multidimensional arrays

Array storage requirements

Arrays within User-Defined Types


ISFALSE - ScharfBASIC Help

ISFALSE

Return the logical truth or falsity of a given expression.

Kind | Operator
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ISFALSE expr
ISTRUE expr

Description

ISTRUE returns -1 (TRUE) when expr evaluates as non-zero; otherwise, it returns zero (FALSE). ISFALSE returns -1 when expr evaluates as 0 (FALSE); otherwise, it returns zero.

Truth table

operator

Result

ISTRUE

ISTRUE

ISFALSE

ISFALSE

ScharfBASIC's NOT operator serves a double duty: it returns the one's-complement of an integer class expression and "reverses" the value of a TRUE/FALSE (Boolean) expression. Usually, these two functions do not conflict, but since ScharfBASIC accepts any non-zero value as TRUE, the following condition can arise:

test1 = 0 ' test1 is FALSE (zero)

IF NOT test1 THEN ' TRUE (-1 is non-zero)

[ statements ]

test2 = 1 ' test2 is TRUE (1 is non-zero)

IF NOT test2 THEN ' still TRUE (-2 is non-zero)

[ statements ]

In this case, NOT does not reverse the TRUE/FALSE value of test2. ISFALSE ensures that the test is performed exactly as you would expect:

test2 = 1 ' test2 is TRUE (non-zero)

IF ISFALSE test2 THEN ' ISFALSE detects test2 is

[ statements ] ' TRUE so the IF test fails

This problem does not exist when you're testing for logical truth. ScharfBASIC considers that an expression is TRUE in every case except when the expression is zero. However, ISTRUE converts all non-zero values to the "most true" value, -1, which provides the most consistent results with both boolean and arithmetic expressions.

Restrictions

ISTRUE and ISFALSE operators evaluate the "whole" expression following the keyword, subject to their Operator Precedence level. For example, parentheses contained within the expression are regarded as an integral part of the expression, and do not act as delimiters for the ISTRUE and ISFALSE operators.

With this in mind, combining a logical test result into a further expression means that the expressions must be separated to ensure the correct evaluation.

Consider the following statement:

IF ISTRUE (x&) + y& THEN

ScharfBASIC evaluates the entire expression (x&) + y& and then calculates the logical truth from the overall result of that expression. That is, the parentheses around the first part of the expression do not stop ISTRUE from evaluating the whole expression. To demonstrate this, the statement can be rewritten to concisely demonstrate the scope of the logical evaluation:

IF ISTRUE (x& + 2) THEN

or it could be simplified even further:

IF ISTRUE x& + 2 THEN

If you wish to utilize the numeric result of the logical test in a further expression, parentheses must be added to separate the expressions correctly:

IF (ISTRUE x&) + 2 THEN

See Also

  • Arithmetic Operators
  • NOT
  • Short-circuit evaluation

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201c6c
lea   ebx,[ebp-0xa4]
call   0x201bef
mov   eax,0xffffffff
mov   eax,0xffffffff
call   0x201b20


Keyword Reference - ScharfBASIC Help

Keyword Reference

This section contains an alphabetical listing of all of the ScharfBASIC keywords. Each entry goes into specific detail about each command, and is cross-references to other relevant commands. The Progra

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The commands can be classified into four primary categories, according to their syntactic class: functions, statements, system variables, and metastatements:

These are predefined ScharfBASIC functions, as opposed to user-defined functions. Functions generally return either a s tring or a numeric value, and these can be used within a more complex expression. Most functions require the program pass one or more arguments to them; these arguments being numeric or string, or combinations thereof, depending on the function. For example:

A$ = CHR$(123, "hello", 65, 66, 67, 65 TO 97)

Statements are building blocks that make up programs. They instruct the compiler to perform specific actions, such as opening a file, setting the date, sending data to a device, etc. Statements do not return a value, but often take one or more arguments. Each statement must appear on a line by itself; or be separated from other program elements with a delimiting colon (:) character. For example:

A& = A& + 10& : B$ = "ScharfBASIC"


LBOUND - ScharfBASIC Help

LBOUND

Return the smallest possible

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y& = LBOUND( array [( dimension )])
y& = LBOUND( array , dimension )

Description

LBOUND can be used in combination with UBOUND to determine the size of an array. LBOUND of an undimensioned array returns zero. The LBOUND function has the following parts:

Name of the array of interest.

dimension

An integer indicating which dimension's lower bound is returned. If not specified, the first dimension is assumed.

Restrictions

LBOUND cannot be used on arrays within User-Defined Types .

See Also

  • ARRAYATTR
  • DIM
  • REDIM
  • UBOUND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201908
call   0x201c10
call   0x201e84


LET statement (with Types) - ScharfBASIC Help

LET statement (with Types)

Assign data to a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

[LET] TypeVar = TypeVar
[LET] TypeVar = VARIANT$( VrntVar )

Description

Typevar is a user-defined type variable. In order to perform direct assignment of data from one user-defined type variable to another, they must be dimensioned to the same type. To assign data between two different types, you should use the TYPE SET statement instead.

The word LET is optional in assignment statements. It is allowed to provide compatibility BASIC source files written for early versions of BASIC. In practice, the word LET is very rarely used.

When User-Defined Type data is stored in a variant variable, it may be extracted as in the second syntax example. The Variant$() function understands that UDT data is stored as a byte string.

To allow easy conversion, ScharfBASIC allows a User-Defined Type in a string expression . The User-Defined Type is simply copied, byte for byte, into the expression. To assign a string back to a User-Defined Type, you may also use the TYPE SET statement. Generally speaking, if a UDT is used in a WIDE string expression (Unicode), it will give unpredictable results from the character conversions.

DIM abc as MyType

MyString$ = abc

See Also

  • LET
  • LET (with Objects)
  • LET (with Variants)
  • TYPE SET
  • VARIANT$


Line numbers and Labels - ScharfBASIC Help

Line numbers and Labels

Line numbers are integers in the range 1 to 65535, which serve to identify program lines. ScharfBASIC takes a relaxed stance toward line numbers. They can be freely interspersed with labels, and used i

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

Return value: The following is illegal, however: ExitPoint: a = a + 1 ' a label must be on a line by itself Finally, it should be noted that symbol names must be unique: a label may not share the name of any other symbol ( Sub name, Function name, Method name, Property name, user-defined type or union definition, variable name, etc), and they are local to the Sub, Function, Method, or Property in which they appear.

Details

While line numbers and labels serve the same purpose, their usage is slightly different. Line numbers are just a concession to compatibility with Interpretive BASIC. Line numbering can lead to bad programming style. Since the numbers themselves can be in any order, they give a false sense of structure to a program. We recommend that you avoid line numbers, and use labels instead.

Using labels instead of numbers allows you to make the flow of your program much more readable. For example:

tells you much more than

Each label must appear on a line by itself (though a comment may follow) and it serves to identify the statement immediately following it. Labels must begin with a letter and contain any number of letters, digits, and an underscore. Case is insignificant - THISLABEL , thislabel , and ThisLabel are all the same. A colon must follow a label, however, and statements that refer to the label must not include the colon.

MSGBOX "Now Sorting Invoices"


MAT - ScharfBASIC Help

MAT

To simplify Matrix Algebra calculations.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MAT a1() = CON 'Set all elements of a1() to one
MAT a1() = CON( expr ) 'Set all elements of a1() to value of expr
MAT a1() = IDN 'Establish a1() as an identity matrix
MAT a1() = ZER 'Set all elements of a1() to zero
MAT a1() = a2() + a3() 'Addition
MAT a1() = a2() 'Assignment
MAT a1() = INV( a2() ) 'Inversion
MAT a1() = ( expr ) * a2() 'Scalar Multiplication
MAT a1() = a2() - a3() 'Subtraction
MAT a1() = a2() * a3() 'Multiplication
MAT a1() = TRN( a2() ) 'Transposition

Description

Array names with the MAT statements may optionally include a set of empty parentheses. The following are both equally valid, but the inclusion of the parentheses improves clarity of the code:

MAT a1 = CON

MAT a1() = CON

MAT CON, IDN ZER + - = and TRN operations are valid with Byte , Word , Double-word , Integer , Long-integer , Quad-integer , Single-precision , Double-precision and Extended-precision arrays .

Matrix * and INV operations support all numeric types.

It is the programmer's responsibility to ensure that arrays used with MAT are of the appropriate size and type. All operations involving two or more arrays require that they be of exactly the same size and type, without exception. Failure to adhere causes undefined results. In the interest of execution speed, no error checking is performed at run-time.

Every scalar value denoted here as 'expr' must be enclosed in parentheses. Although Matrix operations tend to imply a two-dimensional array , unless otherwise noted (such as with MAT IDN, *, TRN), MAT may be used with arrays of one to eight dimensions. It is permissible to specify one array for multiple MAT parameters.


ME pseudo-variable - ScharfBASIC Help

ME pseudo-variable

A pseudo

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ME. Method1 ( param )

Description

ME is a pseudo-variable, which ScharfBASIC automatically defines in every Method and Property . It is treated as a reference to the current object. Using ME, it's possible to call any other Method or Property which is a member of the class: var = ME. Method1 ( param )

ME can also be assigned to an appropriate object variable, or used as a Sub / Function /Method/Property parameter.

See Also

  • CLASS
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • METHOD
  • PROPERTY
  • What is an object, anyway?


METRICS - ScharfBASIC Help

METRICS

Retrieves information or dimensions of system elements.

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MetricVar = METRICS( MetricName )


Misc Operations - ScharfBASIC Help

Misc Operations

Miscellaneous functions:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Identify an assembly-language statement.

Rounds up the instruction location to a power of two address

Define a block where primitive read-only data is stored.

Play the default Windows sound through the computer speaker(s).


MKBYT$ - ScharfBASIC Help

MKBYT$

.

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

AnsiStringVar$ = MKBYT$( byte_expr )
AnsiStringVar$ = MKCUR$( currency_expr )
AnsiStringVar$ = MKCUX$( extended_currency_expr )
AnsiStringVar$ = MKD$( double_precision_expr )
AnsiStringVar$ = MKDWD$( double_word_expr )
AnsiStringVar$ = MKE$( extended_precision_expr )
AnsiStringVar$ = MKI$( integer_expr )
AnsiStringVar$ = MKL$( long_integer_expr )
AnsiStringVar$ = MKQ$( quad_integer_expr )
AnsiStringVar$ = MKS$( single_precision_expr )
AnsiStringVar$ = MKWRD$( word_expr )

Description

The MKx functions return the binary representations of a number as a set of bytes in an ANSI string. Do not confuse these functions with the STR$ or FORMAT$ functions, which return a printable string.

In all but the most extreme cases, the returned string should only be stored as an ANSI string or UDT which consist of single bytes. WIDE (Unicode) strings consist of a series of 2-byte words which will generally yield undefined results.

The CV x functions are complementary to the MK x functions. They convert the binary representation in a string to an actual numeric value:

Function

Converts to

MKBYT$

1-byte string

MKCUR$

8-byte string

Currency

MKCUX$

8-byte string

Extended-currency

8-byte string

Double-precision

MKDWD$

4-byte string

Double-word

10-byte string

Extended-precision

2-byte string

Integer

4-byte string

Long-integer

8-byte string

Quad-integer

4-byte string

Single-precision

MKWRD$

2-byte string

See Also

  • CVI and associated functions

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Mkbyt

call   0x201d00
call   0x201c83
call   0x2018d8
lea   ebx,[ebp-0xb8]
call   0x201c83
call   0x201bb4

Variant 2: Mkc

push   0x20108f
mov   ecx,0x2c
call   0x201fb8
call   0x201f3b
lea   ebx,[ebp-0xc0]
call   0x201e2c
fistp   QWORD PTR [ebp-0x6c]
mov   eax,DWORD PTR [ebp-0x6c]
mov   ebx,DWORD PTR [ebp-0x134]
mov   edx,DWORD PTR [ebx+eax*4]
call   0x201f24
lea   ebx,[ebp-0xb8]
call   0x201f3b
call   0x201e6c

Variant 3: Mkd

call   0x201d00
call   0x201c83
fld   QWORD PTR [ebp-0xa8]
call   0x201902
lea   ebx,[ebp-0xb8]
call   0x201c83
call   0x201bb4

Variant 4: Mkdwd

call   0x201d00
call   0x201c83
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
call   0x20190d
lea   ebx,[ebp-0xb8]
call   0x201c83
call   0x201bb4

Variant 5: Mki

call   0x201d00
call   0x201c83
call   0x201944
lea   ebx,[ebp-0xb8]
call   0x201c83
call   0x201bb4

Variant 6: Mkl

call   0x201d00
call   0x201c83
call   0x201923
lea   ebx,[ebp-0xb8]
call   0x201c83
call   0x201bb4

Variant 7: Mkq

call   0x201d00
call   0x201c83
fld   QWORD PTR [ebp-0xa8]
call   0x20192e
lea   ebx,[ebp-0xb8]
call   0x201c83
call   0x201bb4


Modal vs. Modeless - ScharfBASIC Help

Modal vs. Modeless

To support the different ways that applications use dialog boxes, ScharfBASIC provides two types of dialog box: modal and modeless .

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

A modal dialog box requires the user to supply information, or cancel the dialog box, before allowing the application to continue. Applications use modal dialog boxes in conjunction with commands that require additional information before they can proceed.

A modeless dialog box allows the user to supply information and return to the previous task without closing the dialog box. Modal dialog boxes are simpler to manage than modeless dialogs because they are displayed, perform their task, and are destroyed by calling a single DIALOG SHOW MODAL statement.

In the above example, we display the dialog as modal. The DIALOG SHOW MODAL statement displays the dialog and waits until your code calls DIALOG END (or if there is a Close box in the caption, the dialog will end when the Close box is clicked). When Windows displays a modal dialog box, it disables the parent window to keep the user focused on the dialog. When the dialog box is closed, the parent window is automatically re-enabled.

By comparison, a modeless dialog box does not cause your code to stop and wait while the dialog is displayed. An example of a modeless dialog box is the "Cancel" dialog displayed by many programs that print long documents on the printer. The application code sits in a loop sending data to the printer. The "Cancel" dialog allows the user to cancel printing at any time. The following is a simplistic example of this process:

DIALOG SHOW MODELESS hDlg TO lResult&

Done& = PrintNextLineFunction()

LOOP UNTIL lResult& = %IDCANCEL OR Done& = %TRUE


MONTHNAME$ - ScharfBASIC Help

MONTHNAME$

Converts a Month number to the associated name.

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = MONTHNAME$( MonthNumber& )

Description

The MONTHNAME$ function converts a Month number into a string representing its associated name. The argument must be in the range of 1 through 12, representing the names January, February, etc.

See Also

  • DATE$
  • DAYNAME$
  • POWERTIME


MYBASE pseudo-variable - ScharfBASIC Help

MYBASE pseudo-variable

A pseudo

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MYBASE. Method1 ( param )

Description

MYBASE is a pseudo-variable, which ScharfBASIC automatically defines in every Method and Property on an inherited interface . It is treated as a reference to the original, inherited object. Using MYBASE, it's possible to call the original Methods and Properties so you can modify or build upon them in the derived interface.

MYBASE may not be assigned to an object variable, nor may it be used as a Sub / Function /Method/Property parameter.

See Also

  • CLASS
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ME
  • METHOD
  • PROPERTY
  • What is an object, anyway?
  • What is inheritance?


NUL$ - ScharfBASIC Help

NUL$

Return a string

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

sResult$ = NUL$( count )

Description

NUL$ returns a count character string of $NUL characters.

See Also

  • CHR$
  • REPEAT$
  • SPACE$
  • STRING$


Numeric Operations - ScharfBASIC Help

Numeric Operations

The following functions manipulate and manage numeric data:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Return the absolute value of a numeric expression

AND works as both a logical and a bitwise arithmetic operator

Assign a number of values to successive elements of an array

Delete a single item from a given array


OBJRESULT$ - ScharfBASIC Help

OBJRESULT$

Returns a string which describes an

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

text$ = OBJRESULT$([ nexp& ])

Description

This function returns a text string which describes the hResult code specified by nexp&. If the parameter nexp& is omitted, it is replaced by the most recent OBJRESULT value. That is, OBJRESULT$() is identical to OBJRESULT$(OBJRESULT).

See Also

  • DIM
  • CLASS
  • CLSID$
  • IDISPINFO
  • GUID$
  • GUIDTXT$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • LET (with Objects)
  • METHOD
  • PROPERTY
  • OBJECT
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • PROGID$
  • What is an hResult?
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   DWORD PTR [ebp-0x98],esi


OemToChr$ - ScharfBASIC Help

OemToChr$

Translates a byte string

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = OemToChr$( OemExpr$ )
a$$ = OemToChr$(GRAPHIC, OemExpr$ )

Description

OemExpr$ contains a series of byte (8-bit) characters in OEM format. OemToChr$ translates it into either ANSI multi-byte equivalent characters or WIDE (16-bit) Unicode characters, depending upon the context of the source code. ScharfBASIC will always choose the correct form with no intervention needed by the programmer. Control codes, CHR$(0) to CHR$(31) and CHR$(127), are handled uniquely, as they are normally considered to be non-printing characters. By default, they are just copied, without any translation.

GRAPHIC

If the option GRAPHIC is included, it indicates you want to convert control codes into the codes which will display the graphic symbols defined in the original IBM OEM character set. Most of these codes are only available as wide Unicode characters.

See Also

  • ChrToOem$
  • ChrToUtf8$
  • Utf8ToChr$


Operating System - ScharfBASIC Help

Operating System

The following functions manipulate file and operating system features:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Change the current (default) directory on a given drive.

Change the current default drive.

A bitmap is copied from the CLIPBOARD and stored in a newly created GRAPHIC BITMAP .

CLIPBOARD GET OEMTEXT

A text string is retrieved from the CLIPBOARD. If necessary, it is converted to OEM Text format.


Parameters passed by reference or by copy - ScharfBASIC Help

Parameters passed by reference or by copy

When a parameter is passed by reference (the default method), ScharfBASIC passes a 32-bit pointer on the stack . That pointer is the actual 32-bit offset, or memory location, of the variable to be util

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

SUB MyProc(xyz&) ' This will increment the

' parameter variable by one

! INC DWORD PTR [EBX]

Parameters passed by copy (such as expressions or constants) also take precisely 4 bytes on the stack. In this case, just as in parameters by reference, the item on the stack is not the value of the parameter. Rather, it is the address of a temporary location in memory where the value is stored. This may seem roundabout, but it has two distinct advantages. First, assembler routines can handle p arameters BYREF and BYCOPY in precisely the same way. Second, routines can modify the value of a parameter without altering the original variable in the main program.

Suppose the first and only parameter is a Long-integer . In that case, you can put the integral value into the ECX register by writing:


Passing arrays - ScharfBASIC Help

Passing arrays

Each array in your program has an associated array descriptor . This descriptor is saved in a proprietary format, which may change from version to version of ScharfBASIC. Since most of the information

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

In addition to the LBOUND and UBOUND functions, the ARRAYATTR function can be used to obtain array attributes and information on a given array.

Parameters passed by reference or by copy

Parameters passed by value

Passing dynamic strings

Accessing ScharfBASIC variables by name


Passing dynamic strings - ScharfBASIC Help

Passing dynamic strings

A dynamic string variable is defined as a 32-bit data item, which contains a pointer (or offset) to the string characters. When passed by value , the parameter is actually a 32-bit offset of the data.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

! MOV EBX, abc$ ; EBX is a pointer to the string handle

! MOV EBX, [EBX] ; EBX is now a pointer to string data

! MOV AL, [EBX] ; AL contains the 1st char of the string

' more code could go here

If you need to determine the current length of a dynamic string, there are two ways to do so. The end of string is always followed by a nul, CHR$ (0), so it is possible to scan the string for the first occurrence. Of course, this will only work if there are no embedded nul bytes in the string data. An alternative method is to read the 32-bit Long-integer that immediately precedes the start of the string data, as the current length is always stored there.


Passing parameters - ScharfBASIC Help

Passing parameters

ScharfBASIC 32-bit compilers pass all parameters to procedures by pushing them in sequence from right to left. This is always the case when a procedure uses the default calling conventions of SDECL (an

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

By default, ScharfBASIC passes parameters by reference: a 32-bit pointer to the data. You can also pass most parameters by value , by declaring with the optional BYVAL keyword. When a parameter is passed by value, the actual value of the parameter is pushed on the stack.

Fixed-length strings , nul-terminated strings , and User-Defined Types / Unions may also be passed as BYVAL or OPTIONAL parameters, now. Try to avoid passing large items BYVAL, as it?s terribly inefficient, and there is a maximum size limit of 64 Kb for a given parameter list. Arrays cannot be passed BYVAL.

ScharfBASIC automatically sets up a local "stack frame" at the beginning of each procedure in your program. As per standard conventions, the EBP register is used to address the parameters. The lowest parameter can be found at EBP+8, and subsequent parameters will be found in adjacent locations on the stack.

In assembler routines, it is easier and safer to access parameters by name rather than calculating their locations on the stack. However, it is important to remember the difference in accessing parameters passed by value and parameters passed by reference .

Parameters passed by reference or by copy

Parameters passed by value


PATHNAME$ - ScharfBASIC Help

PATHNAME$

Parse a path/file name to extract component parts

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

fil$ = PATHNAME$( director , filespec$ )

Description

The PATHNAME$ function evaluates a text path/file text name, and returns a requested part of the name. The functionality is strictly one of string parsing alone. No attempt is made to find the file on disk. If you wish to scan for a particular file on disk, you should use the companion function PATHSCAN$ .

director

This is one of the following words which is used to specify the requested part:

Returns the full path/file name, just as given in the filespec$ parameter. This is really a non-operation, but is included for symmetry with the companion function PATHSCAN$.

Returns the path portion of the path/file name. That is the text up to and including the last backslash (\) or colon (:).

Return the name portion of the path/file name. That is the text to the right of the last backslash (\) or colon (:), ending just before the last period (.).

Returns the extension portion of the path/file name. That is the last period (.) in the string plus the text to the right of it.

Returns the NAME and the EXTN parts combined.

filespec$

A path/file name which does not necessarily exist on disk.

See Also

  • DIR$
  • EXE
  • PATHSCAN$
  • PARSE
  • PARSE$
  • PARSECOUNT


PATHSCAN$ - ScharfBASIC Help

PATHSCAN$

Find a file on disk and return the path and/or file name parts.

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

fil$ = PATHSCAN$( director , filespec$ [, pathspec$ ])

Description

The PATHSCAN$ function scans specified directories to find a particular file. If the file is found, it returns either the full path/file name, or a selected part of it. If the file is not found, a nul (zero-length) string is returned. If you wish to simply parse a text file name, without regard to its validation on disk, you should use the companion function PATHNAME$ .

director

This is one of the following words which is used to specify the requested part:

Return the full drive/path/file name.

Return the path portion of the path/file name. That is the text up to and including the last backslash (\).

Return the name portion of the path/file name. That is the text to the right of the last backslash (\), ending just before the last period (.) in the string.

Return the extension portion of the path/file name. That is the last period (.) in the string plus the text to the right of it.

Return the NAME and the EXTN parts combined.

filespec$

A file name which is expected to exist on disk. It must not be an ambiguous name -- that is, it may not include a query (?) or an asterisk (*) character.

pathspec$

An optional path string which includes one or more paths to be searched to find filespec$. If multiple path names are included in this string, they must each be separated by a semicolon (;) delimiter. If pathspec$ is not given, or it is a nul (zero-length) string, the following directories are searched:

See Also

  • DIR$
  • EXE
  • PATHNAME$
  • PARSE
  • PARSE$
  • PARSECOUNT


Pointers to arrays - ScharfBASIC Help

Pointers to arrays

In order to work with arrays created by other languages, such as VB arrays, ScharfBASIC supports an extension of the pointer syntax, called "Pointer Indexing". As noted above, a pointer allows you acce

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The address of the first element, x%(0), is the base with the remaining elements stored in memory, one after the other. To access the array using an index pointer, you simply assign the address of the first element to your base pointer:

DIM xPtr AS INTEGER POINTER

@xPtr[0] = 0 ' same as x%(0)

@xPtr[1] = 1 ' same as x%(1)

@xPtr[2] = 2 ' same as x%(2)

@xPtr[3] = 3 ' same as x%(3)

@xPtr[4] = 4 ' same as x%(4)


Pointers to arrays with dual indexes - ScharfBASIC Help

Pointers to arrays with dual indexes

Indexed pointers with dual indexes require an "OF limit " clause on both indexes. While simple arrays (arrays with one index) store data sequentially, dual indexes interleave each row of data. The OF

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

DIM DataPtr AS INTEGER PTR

DIM z%(0 TO 8, 0 TO 3)

DataPtr = VARPTR(z%(0, 0))

Value% = @DataPtr[x OF 8, y OF 3]

The following example uses a lower bound other than zero:


PREFIX/END PREFIX statements - ScharfBASIC Help

PREFIX/END PREFIX statements

Executes a series of statements, each of which utilizes pre-defined source code.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PREFIX " source code "
[ additional statements ]
END PREFIX

Description

PREFIX/END PREFIX statements enclose a set of statements, each of which has the same specified " source code " prepended. The " source code " (in languages which support it) is usually required to be the name of an object variable. However, in ScharfBASIC, this definition has been expanded greatly to allow virtually any code to be used. This reduces repetitive typing and reduces the risk of typing errors. For example:

PREFIX/END PREFIX

Compiles as:

PREFIX "MyObject."

Init(xx)

Sleep(2)

END PREFIX

MyObject.Init(xx)

MyObject.Sleep(2)

PREFIX "MyStruc."

Height = 220

Width = 345

Color = %Blue

END PREFIX

MyStruc.Height = 220

MyStruc.Width = 345

MyStruc.Color = %Blue

PREFIX "ASM "

Mov Eax, Ebx

Mov Ecx, &H14

IMul Eax, Esi

END PREFIX

ASM Mov Eax, Ebx

ASM Mov Ecx, &H14

ASM IMul Eax, Esi

If the "source code" prefix refers to an object variable or a UDT structure variable, be sure it ends with a period (.) to reference members of that item. Otherwise, be sure it contains whole words. Just as with macros and line continuations, you cannot put half a word on one line, and half a word on another. For example, the following code is illegal and will generate an exception:

PREFIX "PRI"

NT #1, "Hello World"

END PREFIX

PREFIX/END PREFIX structures may not be nested.

See Also

  • ASM ALIGN


PUT$ - ScharfBASIC Help

PUT$

Writes an

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PUT$ [#] filenum& , StrgExpr

Description

PUT$ first evaluates the string expression . If it results in a WIDE Unicode string, it is converted to ANSI byte characters. PUT$ then writes the ANSI string to the file specified by FileNum& at the current file pointer position. GET$ , PUT$ , and SEEK provide a low-level alternative to sequential and random-access file processing techniques, allowing you to deal with files on a byte by byte basis.

File filenum& must have been opened in binary mode. Bytes are written starting at the current file pointer position, which can be set with the SEEK statement. When the file is first opened, the pointer is at the beginning of the file (position 1, by default, unless BASE=0 was specified in the OPEN statement). After PUT$, the file pointer position is automatically advanced to the point which immediately follows the just written data. You can use SEEK to retrieve or change the file pointer position.

Filenum&

The file number under which the file was opened.

StrgExpr

A string expression which is written to the file.

See Also

  • GET
  • GET$
  • GET$$
  • OPEN
  • PUT
  • PUT$$
  • SEEK function
  • SEEK statement
  • SETEOF
  • WRITE#


PUT$$ - ScharfBASIC Help

PUT$$

Writes a

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PUT$$ [#] filenum& , StrgExpr

Description

PUT$$ first evaluates the string expression . If it results in an ANSI string, it is converted to WIDE Unicode characters. PUT$$ then writes the WIDE string to the file specified by FileNum& at the current file pointer position. GET$$ and PUT$$ provide a low-level alternative to sequential and random-access file processing techniques, allowing you to deal with files on a character by character basis.

File filenum& must have been opened in binary mode. Characters are written starting at the current file pointer position, which can be set with the SEEK statement. When the file is first opened, the pointer is at the beginning of the file (position 1, by default, unless BASE=0 was specified in the OPEN statement). After PUT$$, the file pointer position is automatically advanced to the point which immediately follows the just written data. You can use SEEK to retrieve or change the file pointer position.

Filenum&

The file number under which the file was opened.

StrgExpr

A string expression which is written to the file.

See Also

  • GET
  • GET$
  • GET$$
  • OPEN
  • PUT
  • PUT$
  • SEEK function
  • SEEK statement
  • SETEOF
  • WRITE#


Reading and writing data - ScharfBASIC Help

Reading and writing data

To complement the new COMM OPEN statement, ScharfBASIC introduces four new COMM statements to help you write serial communications programs:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

COMM PRINT #hComm, expr [;]

COMM SEND #hComm, expr

COMM RECV #hComm, count, expr

COMM LINE [INPUT] #hComm, expr

COMM PRINT and COMM SEND are used to send data out of the communications port (via the transmit buffer). COMM PRINT sends the data specified by expr followed by a CR/LF byte pair { $CRLF or CHR$ (13,10)}. By adding a trailing semicolon to the COMM PRINT statement , ScharfBASIC suppresses these CR/LF bytes. COMM SEND is identical to COMM PRINT with a trailing semicolon.

COMM RECV and COMM LINE [INPUT] are used to receive data from a communications port (via the receive buffer). The COMM (#hComm, RXQUE) function can be used to identify the number of bytes that can be retrieved with COMM RECV. COMM LINE is used to return a CR/LF delimited "line" of data from the receive buffer.

If your communications application is primarily dealing with binary data transmission and reception, COMM SEND and COMM RECV will suit this purpose exactly. COMM PRINT and COMM INPUT are very useful for sending "AT" commands to a modem and receiving the modem response. For example:

COMM PRINT #hComm, "AT"

SLEEP 1000 ' Give modem time to respond


REGEXPR - ScharfBASIC Help

REGEXPR

Scan a string

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

REGEXPR mask$ IN target $ [AT start& ] TO iPos& [, iLen& ]

Description

REGEXPR scans target $ for a matching expression specified in mask$ . If found, it returns the position of the match in the iPos& variable (indexed to the first character position), and optionally, the length of the matching expression in iLen& .

If a match is made, the iPos& and iLen& results can be immediately used with subsequent string operations such as MID$ to extract the matched portion of target $ , and/or to continue the search through the remainder of target $ . If no matching expression is found, both iPos& (and iLen& if specified) are set to zero.

If specified, the search begins at the character position target & in target $; however, start& must be between 1 and the length of target $ . If start& is less than 1, the start& parameter is ignored.

While it is possible for more than one match to be found in a particular target string, REGEXPR first selects one or more matches which start at the leftmost possible position, then returns the longest of those. Use the \s special escape operator to force a match on the shortest match (see below).

The ^ and $ operators match on both the actual string start/end, or the previous/next embedded line-delimiter characters ( CHR$ (13,10) or $CRLF ) in target $ . This enables REGEXPR to treat the target $ string as containing a set of "logical lines" of text. In this situation, the start& character position plays a crucial role in identifying which logical delimited line that should be examined by REGEXPR.

By default, search expressions are assumed to be case-insensitive, so capitalization is ignored.

The regular ( wildcard ) expression specified in mask$ may contain a combination of standard text characters and/or the metacharacters which are defined as follows:

Definition

(period) Matches any character, except the end-of-line.

(caret) Matches the actual beginning-of-line position or the preceding line-delimiter character pair (CHR$(13,10) or $CRLF), as taken from the start& character position. The line-delimiter characters themselves are not included in the iLen& result. (also see [^] below for usage within a character class definition).

(dollar) Matches the end-of-line position, which may be either the first line-delimiter character pair (CHR$(13,10) or $CRLF) that is encountered in the search to the right of the start& position, or the actual end of the target $ string, whichever occurs first. The line-delimiter characters themselves are not included in the iLen& result.

(stile) Specifies alternation (the OR operator), so that an expression on either side can match. Precedence is from left-to-right, as encountered in the expression.

(question mark) Specifies that zero or one match of the preceding sub-pattern is allowed. Cannot be used with a Tag.

(plus) Specifies that one or more matches of the preceding sub-pattern are allowed. Cannot be used with a Tag.

(asterisk) Specifies that zero or more matches of the preceding sub-pattern are allowed. Cannot be used with a Tag.

Character classes

(square brackets) Identifies a user-defined class of characters, any of which will match: [abc] will match a, b, or c. Only three special metacharacters are recognized within a class definition, the caret ^ for complemented characters, the hyphen - for a range of characters, or one of the following \ backslash escape sequences:

\\ \- \] \e \f \n \q \r \t \v \x##

Any other use of a backslash within a class definition yields an undefined operation that should be avoided.

(hyphen) The hyphen identifies a range of characters to match. For example, [a-f] will match a, b, c, d, e, or f.

Characters in an individual range must occur in the natural order as they appear in the character set. For example, [f-a] will match nothing.

Lists of characters, and one or more ranges of characters, may be intermixed in a single class definition. The start and end of a range may be specified by a literal character, or one of the \ backslash escape sequences:

\\ \- \] \e \f \n \q \r \t \v \x##

Any other use of a backslash within a class definition yields an undefined operation.

Multiple ranges in a class are valid. For example, [a-d2-5] matches a, b, c, d, 2, 3, 4, or 5.

When the hyphen is escaped, it is treated as a literal. For example, [a\-c] is a list, not a range, and matches a, -, or c due to the \ backslash escape sequence.

(caret) When the caret appears as the first item in a class definition, it identifies a complemented class of characters, which will not match. For example, [^abc] matches any character except a, b, or c.

A range can also be specified for the complemented class. For example, [^a-z] matches any character except a through z.

A caret located in any position other than the first is treated as a literal character.

Tags/sub-patterns

(parentheses) Parentheses are used to match a Tag, or sub-pattern, within the full search pattern, and remember the match. The matched sub-pattern can be retrieved later in the mask (or in a replace operation with REGREPL), with \01 through \99, based upon the left-to-right position of the opening parentheses.

Parentheses may also be used to force precedence of evaluation with the alternation operator. For example, "(Begin)|(End)File" would match either "BeginFile" or "EndFile", but without the Tag designations, "Begin|EndFile" would only match either "BeginndFile" or "BegiEndFile".

Escaped characters

(backslash) . The escape operator (single-character quote). The following character will be treated as a literal value rather than being interpreted as a special character. Note that the character following the backslash must actually be a special character, as follows:

A word boundary . The start or end of a word, where a word is defined as one or more characters that include an alphabetic character (A-Z or a-z), a numeric character (0-9), and an underscore. For example, "abc_123" is considered a single word and "abc-123" is considered two words.

Case-sensitive search . Without the \c operator, the default is to ignore case when matching. Unlike some other implementations of regular expressions, case-insensitivity is recognized in all operations, even a range of characters such as "[6-Z]". The \c operator may appear at any position in the mask.

Escape character : CHR$(27) or $ESC .

Formfeed character: CHR$(12) or $FF .

Linefeed (or new-line) character: CHR$(10) or $LF .

Double-quote mark ("): CHR$(34) or $DQ . \q is included for ease of inclusion within a literal string. For example: "\qHello\q".

Carriage-return character: CHR$(13) or $CR .

Shortest match character: The \s flag causes the shortest matching string to be returned, rather than the longest (the default). For example, when searching for the mask "abc.*abc" in "abcdabcabc", the default setting would return position 1 and length 10. With the \s switch set, it returns position 1 and length 7. This option may cause a slight increase in processing time. The \s flag must appear at the beginning of the mask string.

Horizontal tab character: CHR$(9) or $TAB .

Vertical tab character: CHR$(11) or $VT .

Hex character code: Indicates that an ASCII code follows, given by two hexadecimal digits. For example, \xFF = CHR$(&HFF) (which is equivalent to CHR$(255)). XX must be in the range 0 through 255.

Restrictions

To maximize performance, avoid overuse of the *, + and ? metacharacters.

See Also

  • REGREPL


REGREPL - ScharfBASIC Help

REGREPL

Scan a string

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

REGREPL mask$ IN target $ WITH repl$ [AT start& ] TO iPos& , newtarget$

Description

REGREPL scans target $ for a matching regular expression specified in mask$. If a match is made, REGREPL replaces the matched text with the contents of repl$ , and assigns the new text to newtarget$. Additionally, REGREPL sets iPos& to reflect the character position immediately following the matched text in newtarget$ , so the operation can be repeated, if desired.

If no matching expression is found, iPos& will be set to zero, and newtarget$ receives a direct copy of target$ . In either case, target$ remains unchanged.

mask$ may contain literal characters and metacharacters (wildcards) to form the regular expression, and repl$ may only contain literal characters and tags specified by \##. Each tag from \01 through \99 is replaced by the text actually matched for that tag. \00 is replaced by the entire matched text.

If specified, the search begins at the character position start& in target$ ; however, start& must be between 1 and the length of target$ . If start& is less than 1, the start& parameter is ignored.

While it is possible for more than one match to be found in a particular target string, REGREPL first selects one or more matches which start at the leftmost possible position, then returns the longest of those. Use the \s special escape operator to force a match on the shortest match (see below).

The ^ and $ operators match on both the actual string start/end, or the previous/next embedded line-delimiter characters ( CHR$ (13,10) or $CRLF ) in target$ . This enables REGREPL to treat the target$ string as containing a set of "logical lines" of text. In this situation, the start& character position plays a crucial role in identifying which logical delimited line that should be examined by REGREPL.

By default, search expressions are assumed to be case-insensitive, so capitalization is ignored.

The regular ( wildcard ) expression specified in mask$ may contain a combination of standard text characters and/or the metacharacters which are defined as follows:

Definition

(period) Matches any character, except the end-of-line.

(caret) Matches the actual beginning-of-line position or the preceding line-delimiter character pair (CHR$(13,10) or $CRLF), as taken from the start& character position. The line-delimiter characters themselves are not replaced by repl$ . (also see [^] below for usage within a character class definition).

(dollar) Matches the end-of-line position, which may be the either the first line-delimiter character pair (CHR$(13,10) or $CRLF) that is encountered in the search to the right of the start& position, or the actual end of the target$ string, whichever occurs first. The line-delimiter characters themselves are not replaced by repl$ .

(stile) Specifies alternation (the OR operator), so that an expression on either side can match. Precedence is from left-to-right, as encountered in the expression.

(question mark) Specifies that zero or one match of the preceding sub-pattern is allowed. Cannot be used with a Tag.

(plus) Specifies that one or more matches of the preceding sub-pattern are allowed. Cannot be used with a Tag.

(asterisk) Specifies that zero or more matches of the preceding sub-pattern are allowed. Cannot be used with a Tag.

Character classes

(square brackets) Identifies a user-defined class of characters, any of which will match: [abc] will match a, b, or c. Only three special metacharacters are recognized within a class definition, the caret (^) for complemented characters, the hyphen (-) for a range of characters, or one of the following \ backslash escape sequences:

\\ \- \] \e \f \n \q \r \t \v \x##

Any other use of a backslash within a class definition yields an undefined operation that should be avoided.

(hyphen) The hyphen identifies a range of characters to match. For example, [a-f] will match a, b, c, d, e, or f.

Characters in an individual range must occur in the natural order as they appear in the character set. For example, [f-a] will match nothing.

Lists of characters, and one or more ranges of characters, may be intermixed in a single class definition. The start and end of a range may be specified by a literal character, or one of the \ backslash escape sequences:

\\ \- \] \e \f \n \q \r \t \v \x##

Any other use of a backslash within a class definition yields an undefined operation.

Multiple ranges in a class are valid. For example, [a-d2-5] matches a, b, c, d, 2, 3, 4, or 5.

When the hyphen is escaped, it is treated as a literal. For example, [a\-c] is a list, not a range, and matches a, -, or c due to the \ backslash escape sequence.

(caret) When the caret appears as the first item in a class definition, it identifies a complemented class of characters, which will not match. For example, [^abc] matches any character except a, b, or c.

A range can also be specified for the complemented class. For example, [^a-z] matches any character except a through z.

A caret located in any position other than the first is treated as a literal character.

Tags/sub-patterns

(parentheses) Parentheses are used to match a Tag, or sub-pattern, within the full search pattern, and remember the match. The matched sub-pattern can be retrieved later in the mask, or in a replace operation, with \01 through \99, based upon the left-to-right position of the opening parentheses.

Parentheses may also be used to force precedence of evaluation with the alternation operator. For example, "(Begin)|(End)File" would match either "BeginFile" or "EndFile", but without the Tag designations, "Begin|EndFile" would only match either "BeginndFile" or "BegiEndFile".

Note: Parentheses may not be used with ? + * as any match repetition could cause the tag value to be ambiguous. To match repeated expressions, use parentheses followed by \01*.

Escaped characters

(backslash) . The escape operator (single-character quote). The following character will be treated as a literal value rather than being interpreted as a special character. Note that the character following the backslash must actually be a special character, as follows:

A word boundary . The start or end of a word, where a word is defined as one or more characters that include an alphabetic character (A-Z or a-z), a numeric character (0-9), and an underscore. For example, "abc_123" is considered a single word and "abc-123" is considered two words.

Case-sensitive search . Without the \c operator, the default is to ignore case when matching. Unlike some other implementations of regular expressions, case-insensitivity is recognized in all operations, even a range of characters such as "[6-Z]". The \c operator may appear at any position in the mask.

Escape character: CHR$(27) or $ESC .

Formfeed character: CHR$(12) or $FF .

Linefeed (or newline) character: CHR$(10) or $LF .

Double-quote mark ("): CHR$(34) or $DQ . \q is included for ease of inclusion within a literal string. For example: "\qHello\q".

Carriage-return character: CHR$(13) or $CR .

Shortest match character: The \s flag causes the shortest matching string to be returned, rather than the longest (the default). For example, when searching for the mask "abc.*abc" in "abcdabcabc", the default setting would return position 1 and length 10. With the \s switch set, it returns position 1 and length 7. This option may cause a slight increase in processing time. The \S flag must appear at the beginning of the mask string.

Horizontal tab character: CHR$(9) or $TAB .

Vertical tab character: CHR$(11) or $VT .

Hex character code: Indicates that an ASCII code follows, given by two hexadecimal digits. For example, \xFF = CHR$(&HFF) (which is equivalent to CHR$(255)). XX must be in the range 0 through 255.

Tag number: Evaluated as the characters matched by tag number ## (where ## is in the range 01 through 99, in decimal). Tags are implicitly numbered from 01 through 99, based upon the left-to-right position of the left parenthesis. "( )w\01" would match "abcwabc" or "456w456".

Tags cannot be forward-referenced - that is, if a reference is made to any Tag that is not yet defined, a non-match is presumed.

Restrictions

To maximize performance, avoid overuse of the *, + and ? metacharacters.

See Also

  • REGEXPR


REM - ScharfBASIC Help

REM

Indicate that the remainder of a line in source code files is to be regarded as a Remark or Comment, and excluded from the compiled code.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

REM comment text
' comment text
; comment in an Inline Assembler statement

Description

The ScharfBASIC compiler ignores Remarks; they do not take up space in your generated code, so use them abundantly - useful comments greatly increase the readability and maintainability of source code.

Comment text is any sequence of characters. A comment can appear on a line with other statements, but it must be the last thing on that line, and a colon must precede it. For example, the assignment below will not be compiled or executed because the compiler cannot tell where the comment ends and the statement begins:

REM now add the numbers: a = b + c

The following works:

a = b + c : REM now add the numbers

The apostrophe ( ' ) is an alternate form of REM. When you use an apostrophe, you do not need a colon to separate the remark from the other statements on the same line.

When using the Inline Assembler , use the semi-colon ( ; ) to indicate that the remainder of the line should be ignored. An apostrophe ( ' ) can still be used for comments, however.

In addition, the compiler treats text that appears after the line continuation character as a remark. However, we still recommend that such comments are preceded by a REM or an apostrophe ( ' ) symbol to clearly distinguish remarks from the actual code. For example:

DECLARE FUNCTION Call32& _ The prototype

LIB "CALL32.DLL" _ The DLL name

ALIAS "Call32" _ ' The exported name

(Param1 AS ANY, _ ' 1st parameter

BYVAL id&) ' 2nd parameter

For situations where a large section of code needs to be REMmed out (yet preserved within the source code file), it is often easier to enclose the code with #IF 0/#ENDIF metastatements. For example:

#IF 0 ' Exclude the following lines

Code and text in between the #IF 0 and #ENDIF

metastatements is ignored by the compiler.

DIM a$(1 TO 1000) ' This line is ignored too.

INCR x& ' As is this line!

#ENDIF

Since the #IF expression evaluates to false (zero), this forces the compiler to exclude the enclosed block of code from the compilation process, in exactly the same way as if a REM statement had been prefixed to each line.

See Also

  • Long Lines


RESOURCE$ - ScharfBASIC Help

RESOURCE$

Returns predefined

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

r $ = RESOURCE$(RCDATA, ResID )
s$$ = RESOURCE$(STRING, ResID% )

Description

You can embed data into your EXE or DLL with the #RESOURCE metastatement. While the data can be represented in several different data types, two are designed to be retrieved directly for your own purposes: RCDATA and STRING. In both cases, this data is returned as a variable-length string so you can manipulate it and use it as you wish. The specific resource you wish to retrieve is specified by the ResID . If the ID you request is not present, a nul (zero-length) string is returned.

RCDATA

This resource contains raw data of any type. It is always stored byte -by-byte, just as it was originally created at the time of compilation. Generally speaking, this type of data should be assigned to an ANSI string variable so no Unicode conversions are performed. The ResID which identifies this resource may be a numeric value between 0 and 65535, or an alphanumeric label which is passed to the function as a string expression (string literal, variable, etc.)

STRING

This resource contains predefined strings in a string table. Each string is identified by a resource ID number in the range of 0 to 65535. This number is used as the ResID% to determine which string will be retrieved. Because of the format in which Windows stores the strings in tables, only integral numeric ID's may be used. All resource strings are saved internally in wide Unicode format.

See Also

  • #RESOURCE


Saving the Source Code - ScharfBASIC Help

Saving the Source Code

To save the ScharfBASIC compatible source code, simply click the Save As button or select File -> Save As from the menu and the source code displayed in the Source Code view will be saved to disk. You

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The selected text in the Source Code window can also be save to the Windows clipboard, by selecting Edit -> Copy.

The ScharfBASIC COM Browser User Interface

What is an object, anyway?

What are Type Libraries?


SIZEOF - ScharfBASIC Help

SIZEOF

Return the total or physical length of any ScharfBASIC

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x& = SIZEOF( target )

Description

Particularly useful for determining the maximum length of a fixed-length string , nul-terminated string , or User-Defined Type . It provides similar functionality to LEN , which returns the current length of a data item.

target can be the name of any variable type (fixed-length string, nul-terminated string, User-Defined Type (UDT) variable or definition, etc).

When measuring the size of a padded (aligned) UDT variable or definition with the SIZEOF (or LEN) statement, the measured length includes any padding that was added to the structure. For example, the following UDT structure:

TYPE LengthTestType DWORD

a AS INTEGER

END TYPE

' more code here

DIM abc AS LengthTestType

x& = SIZEOF(abc) ' or use SIZEOF(LengthTestType)

Returns a length of 4 bytes in x& , since the UDT was padded with 2 additional bytes to enforce DWORD alignment. Note that the SIZEOF of individual UDT members returns the true size of the member without regard to padding or alignment. In the previous example, SIZEOF(abc.a) returns 2.

When used on a dynamic (variable length) string, SIZEOF returns 4, which is the size of the string handle. To obtain the length of the string data in the dynamic string, use the LEN function. SIZEOF also returns 4 for pointer variables, since a pointer is always stored as a DWORD .

Pointers

When used with a dereferenced pointer (i.e., SIZEOF(@p), SIZEOF returns the size of the pointer target variable type, as defined in the DIM x AS y PTR [* pSize ] statement.

For example, with a dynamic string pointer, SIZEOF returns 4. If the pointer target is a fixed-length string, UDT, Union , or nul-terminated string, SIZEOF returns the size of the target data structure. However, if the pointer is declared to reference an nul-terminated with no specific target size (i.e., DIM a AS STRINGZ PTR), SIZEOF returns 0.

Likewise, if SIZEOF is used on a BYREF STRINGZ string that does not have an explicit length specification, SIZEOF will also return 0. For example:

SUB ProcessData(BYREF szText AS STRINGZ)

' Within this Sub, SIZEOF(szText) will return 0 because there is no explicit length specification

See Also

  • CHRBYTES
  • DIM
  • LEN


SLL example - ScharfBASIC Help

SLL example

Below is a very simple example of a Static Link Library (SLL). This SLL unit module contains only one function that converts millimeters to inches.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

#COMPILE SLL "conversion.sll"

FUNCTION MillimetersToInches(BYVAL mm AS DOUBLE) COMMON AS DOUBLE

FUNCTION = mm * 0.03937#

The #COMPILE SLL metastatement tells the compiler to create an SLL named conversion.sll.

By default, all procedures in ScharfBASIC are private, which means they cannot be seen outside of the SLL. The COMMON keyword is used on the procedure definition line to indicate that the procedure is to be visible to the host application. If the COMMON keyword is not used in the procedure definition, the procedure will not be visible to the host application. If the MillimetersToInches function did not contain the COMMON keyword any attempt to reference it from a host program would result in a Missing Declaration error when the host program is compiled.

Below is a sample host program that links in the compiled conversion.sll into our program.


Storage requirements and restrictions - ScharfBASIC Help

Storage requirements and restrictions

You can determine the amount of storage required for a variable of a User-Defined Type using the LEN function. To determine the requirements for a student record, for example, use:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

RecordSize = LEN(Student)

The address of a record variable , as returned by the VARPTR function, is the address in memory of the first byte of data in the record. You can also obtain the starting address of the fields within the record by passing the full name of the field ( Student.IdNum , for example) to the VARPTR function.

A single UDT structure is limited to 16 MB (16,777,216 bytes). Locally dimensioned UDT structures are limited to the amount of free stack space available, typically less than 1 MB. If larger UDT structures are required, use a STATIC or GLOBAL declaration instead (since these are not stored on the stack). The same rules apply to Unions (and LOCAL fixed-length and nul-terminated strings).

Note that the ARRAY statements cannot be directly used on arrays within UDTs. However, you can use DIM..AT to define an array (of the same data type) at the address of the UDT array, and employ ARRAY statements on that array. The ARRAY statements can be used on arrays of UDT structures. An individual array within a UDT may occupy as much as the full 16 MB UDT size limit.

User-Defined Types (UDTs)


Storage requirements and restrictions - ScharfBASIC Help

Storage requirements and restrictions

A single Union structure is limited to 16 MB (16,777,216 bytes). Locally dimensioned Union structures are limited to the amount of free stack space available, typically less than 1 MB. If larger UDT s

Kind | Structure
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

User-Defined Types (UDTs)


Text Commands - ScharfBASIC Help

Text Commands

The following commands can be used with a Text Window:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Sets or retrieves the cursor position.

Clears the Text Window and moves to caret to the upper left corner.

Sets the foreground color

The Text Window currently attached to your program is destroyed and detached from the process.


The Stack - ScharfBASIC Help

The Stack

The stack is a range of memory addresses that can be used for temporary storage of data from either within a procedure or as the normal method of passing parameters to a procedure.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The stack is normally accessed in code by the mnemonics PUSH and POP. The stack is accessed on a last on, first off basis which means that the last value pushed onto the stack is the first one to be popped back off the stack.

The next position that can be written on the stack is called the top of the stack. When a piece of data is pushed onto the stack, the processor decrements the stack pointer ESP then writes the data to the top of the stack. When a piece of data is popped back off the stack, the processor reads the data from the top of the stack then increments the stack pointer. Therefore, the stack address decreases as more data is pushed onto it, and the address increases as data is popped back off the stack.

In the following images, each square represents 1 byte on the stack, and the different colors are intended to demonstrate the different data sizes being pushed and popped. The top of the stack is the left side of each image.

The following sequence demonstrates the stack layout as one 32-bit and two 16-bit values are pushed and popped from the stack.

Existing stack layout:

Push a 32 bit value (PUSH EAX)

Push a 16 bit value (PUSH CX)

Push another 16 bit value (PUSH DX)


Time Commands - ScharfBASIC Help

Time Commands

The following functions manipulate and manage time and the system date:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Set and retrieve the system date.

Converts a Day-of-Week number to the associated name.

Adds or subtracts a specified number of days to value of this object .

Adds or subtracts a specified number of hours to value of this object.

IPowerTime.AddMinutes


TIME$ system variable - ScharfBASIC Help

TIME$ system variable

Read and/or set the system time.

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = TIME$
TIME$ = string_expression

Description

The system variable TIME$ contains an eight-character string that represents the time of the system clock in the form "hh:mm:ss", where hh is hours (in 24-hour military form), mm is minutes, and ss is seconds.

Assigning string_expression to TIME$ resets the system clock. string_expression must contain time information in military (24-hour) format. Minutes and seconds information can be omitted. For example:

TIME$ = "12" 'set clock to 12 noon

TIME$ = "13:01" 'set clock to 1:01 PM

TIME$ = "13:01:30" 'set clock to 30 sec after 1:01 PM

TIME$ = "0:01" 'set clock to 1 min after midnight

Use the TIMER function to return the number of seconds that have elapsed since midnight.

See Also

  • DATE$
  • MONTHNAME$
  • POWERTIME
  • TIMER
  • TIX


TRACE - ScharfBASIC Help

TRACE

Capture a representation of the precise flow of execution in a module.

Kind | Statement
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TRACE NEW fname$
TRACE ON
TRACE PRINT string_expr
TRACE OFF
TRACE CLOSE

Description

The TRACE statement is used to generate a trace file detailing program flow as execution passes through Labels , plus entry and exit of all Subs , Functions , Methods , and Properties , along with details of passed parameters, etc. All trace details are written to a named disk file fname$ .

TRACE also logs ScharfBASIC run-time errors as they occur, to assist with locating program errors. TRACE can be dynamically started and stopped with the TRACE ON and TRACE OFF statements to enable the programmer to check specific portions of a program without generating volumes of irrelevant trace data.

The five general forms of the TRACE statement are described as follow:

TRACE NEW fname$

TRACE NEW causes a standard sequential trace file (of the specified file name fname$ ) to be created, deleting any previous file of the same name.

TRACE ON

When a subsequent TRACE ON is then executed, ScharfBASIC begins to write pertinent trace information to the trace file. It will contain a chronological list of every call to an internal procedure, the associated parameter values, and the point at which it was exited. Further, it will list a label name each time that program execution flows through the label position.

In a test or debugging situation, TRACE, CALLSTK , and CALLSTK$ allow you to easily answer that age-old programming question, "How did I get here?". TRACE details the entry and exit of every procedure in your program, while CALLSTK simply lists the stack frames that exist above the current level. TRACE is particularly valuable in pinpointing the area of a program where a fatal machine crash occurs.

TRACE PRINT string_expr

TRACE PRINT writes the value of string_expr to the trace file. It can be used to record the value of important variables or other information of importance.

TRACE OFF

TRACE OFF temporarily stops output to the trace file. The trace can be subsequently restarted with another TRACE ON statement. An implied TRACE OFF is performed when you exit the procedure in which the current TRACE ON was executed.

TRACE CLOSE

TRACE CLOSE permanently detaches the trace file from the stream of trace data.

The TRACE statement can easily create a huge trace file, so caution must be exercised. Use TRACE ON at the lowest procedure level possible, to keep the output size within reason.

If PBMAIN contains TRACE NEW and TRACE ON statements, and subsequently calls SUB AAA(x&), which in turn calls SUB BBB(y&,a$), which then calls SUB CCC(z&), which encounters a run-time error 5 , the trace file might look something like this:

Trace Begins...

AAA(3)

BBB(4,string data)

CCC(5)

TRACE PRINT printed this user data from CCC()

ERROR 151 was generated in this thread

CCC Exit

BBB Exit

AAA Exit

Numeric parameters are displayed in decimal, while pointer and array parameters display a decimal representation of the offset of the target value.

Restrictions

TRACE can be invaluable during debugging , but it generates substantial additional code that should be avoided in the final release version of an application. If the source code contains #TOOLS OFF , all TRACE statements which remain in the program are ignored by the compiler, and the parameters and expressions are excluded from the compiled program.

To conserve memory requirements in the code, long labels are truncated to 13 characters; however, procedure names are not truncated.

The TRACE statement is "Thread-Aware", displaying only Sub, Function, Method, Property, or Label details from the thread in which it was executed. You can execute TRACE multiple times, or even in multiple concurrent threads. However, you must use caution to ensure that each thread uses a unique name for its own trace file.

See Also

  • #TOOLS
  • CALLSTK
  • CALLSTK$
  • CALLSTKCOUNT
  • FUNCNAME$
  • PROFILE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x20108d
call   0x201b6a
call   0x201d3e
mov   edx,0x204a54
call   0x2031b4
call   0x20207a
call   0x2030fc
call   0x201de1


UBOUND - ScharfBASIC Help

UBOUND

Return the largest possible

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = UBOUND( array [( dimension )])
y = UBOUND( array , dimension )

Description

array is the array of interest. dimension is an integeral value or expression from 1 up to the number of dimensions in array; it specifies which dimension's upper bound value will be returned. If you omit dimension, it defaults to 1 (the first dimension). To find the lower bound of an array's dimension, use the LBOUND function. Use LBOUND and UBOUND together to determine an array's size. UBOUND of an undimensioned array returns -1, so that UBOUND(array) - LBOUND(array) + 1 yields zero (0) for such an array.

Restrictions

UBOUND cannot be used on arrays within User-Defined Types .

See Also

  • ARRAYATTR
  • DIM
  • LBOUND
  • REDIM

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201908
call   0x201c22
call   0x201e84


Unions - ScharfBASIC Help

Unions

If you have ever programmed in Pascal or C, you may be familiar with the concept of a Union. A Union is similar in some ways to a User-Defined Type . Both have data fields that can be made up of any o

Kind | Structure
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

While the concept may appear abstract, Unions provide an avenue to freely convert data from one format to another, simply by writing the data into the Union as one data format, and reading the data back as another. Combining the versatility of a UDT with the flexibility of a Union can extend this functionality dramatically, such as splitting data into its component parts.

For example, the following definition would create a Union called WordFld and a WordFld variable called MyVar :


Using ESP and EBP - ScharfBASIC Help

Using ESP and EBP

It is possible in ScharfBASIC to write your own procedure within an existing Sub , Function , Method , or Property by manually coding the stack entry and exit. This is a complicated area of assembler c

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

' Other ScharfBASIC code here

! JMP label ; Jump over the procedure

! PUSH EBP ; Preserve base pointer

! MOV EBP, ESP ; Stack pointer into EBP

' Write your assembler code here

! MOV ESP, EBP ; Restore stack pointer

! POP EBP ; Restore base pointer


Utf8ToChr$ - ScharfBASIC Help

Utf8ToChr$

Translates a byte string of

Kind | Function
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$$ = Utf8ToChr$( UtfExpr$ )

Description

UtfExpr$ contains a series of bytes in UTF-8 format. Utf8ToChr$ translates it into either ANSI multi-byte equivalent characters or WIDE (16-bit) Unicode characters, depending upon the context of the source code. ScharfBASIC will always choose the correct form with no intervention needed by the programmer.

See Also

  • ChrToOem$
  • ChrToUtf8$
  • OemToChr$


Variables - ScharfBASIC Help

Variables

Variables repre sent numeric or string values. Unlike constants, the value of a variable can change during program execution. Like labels , variable names must begin with a letter and can contain up t

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The Single-precision variables, EndOfMonthTotals and emt, both require exactly four bytes of run-time storage. A good rule of thumb is to preserve a balance, keeping variable names short enough so that statements can fit on one line. Many programmers use single-letter variables for loop counters (i, j, k, l and x, y, z are favorites). However, you can use names like count, total, index, and so on for greater clarity, especially if you have nested loops.

ScharfBASIC has many built-in variable types: Dynamic string ; Fixed-length string ; nul-terminated string ; Field , Integer ; Long integer ; Quad integer ; Byte , Word ; Double word ; Single ; Double ; and Extended floating point ; Currency and CurrencyX ; Variant , Object , Guid , plus Pointer , arrays , and Bit and Sbit bitfield subtypes .

Declaring a variable as a specific type:

Use the DIM statement to declare a variable and use the AS type syntax:

Appending a type-specifier to the variable name:

bat# = 1.312 ' bat# is a Double-precision variable

hat% = 3 ' hat% is an Integer variable

DEFINT c ' Variables beginning with c are now Integer


What is a Dll? - ScharfBASIC Help

What is a Dll?

A Dynamic Link Library (DLL) is a Windows executable library module containing one or more Subs , Functions , or classes that can be called by executables or other DLLs. Unlike executables, DLLs do no

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

To get a better idea of how a DLL works, it helps to understand the difference between static and dynamic linking. Static linking is the process of writing one or more modules, and then linking them, along with whatever other run-time, third-party, etc., libraries that may be needed to create a complete, stand-alone executable program. When a program uses a Sub or Function from a static-link library, a copy of that Sub or Functions code is statically linked into the programs executable file.

If two programs that are running concurrently use the same routine from a library, they would each have their own copy of that routine. It would be more efficient if the two programs could share a single copy of the routine. DLLs provide that capability by resolving your application's references to external procedures at run-time.

In contrast to a static-link library, the code in a DLL is not linked into a program that uses the DLL. Instead, a DLLs code and resources are in a separate executable file, usually with a .DLL extension. This file must be present when the application runs. You will still have to write one or more modules to implement the functions that are specific to your application.

However, the linking process is divided into two stages. You first place DECLARE statements into your application to temporarily satisfy the references your program makes to the DLL services, in order to create an EXE (or DLL) file. The second stage happens at run-time, when your program calls one of the DLLs services.

At that time, the Function calls in the program are dynamically linked to their entry points in the DLL(s). The operating system resolves external references by establishing a link between the application calls and the code, in the DLL, that implement the required functions. The Windows environment supports both static and dynamic linking.

Creating a Dynamic Link Library

Private and Exported Procedures


What is an SLL? - ScharfBASIC Help

What is an SLL?

An SLL is a Static Link Library. It consists of a set of Classes , Subs , and Functions which are compiled into a machine-code library. Since it is a library, the code cannot be executed standalone. I

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

A Static Link Library is the perfect vehicle for third-party code, because it creates a single final module while not requiring source code to be distributed. It allows you to create a group of your own libraries, which you know function correctly and don't require any further debugging. It also offers big advantages to larger group programming projects to control distribution of various elements.

Creating a Static Link Library


Why use Dlls? - ScharfBASIC Help

Why use Dlls?

There are a number of mitigating reasons to create a DLL. Among them are:

Kind | Keyword
Category | General
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Parts of your code, while functional, might not execute as fast as you would like. Once you've isolated the bottleneck area(s), a machine code DLL is an obvious choice for optimizing just those areas of your application that are running too slowly.

Unlike conventional libraries, when a DLL is loaded into memory by the operating system, its Subs and Functions are accessible by all other programs (or DLLs). Only one copy of the DLL needs to be present in memory. This is possible because the library is not linked into any one of the programs permanently. It is present, in memory, making its services available to any program (or other DLL) which may need them.

You might have a set of procedures that are common to a number of different applications. Instead of having those procedures appear in every application that needs them, it is better to put them in a DLL where they can be accessed by all the applications. This reduces the size of your executables while giving you the flexibility of updating the DLL itself, without having to re-compile every application that uses its services.

A DLL can be updated and redistributed without having to re-compile any of the applications (or other DLLs) that use its services.

Creating a Dynamic Link Library

Private and Exported Procedures


ASM - ScharfBASIC Help

ASM

Identify an assembly-language statement. ScharfBASIC's

Kind | Statement
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

{! | ASM} { opcode | label }
{! | ASM} ALIGN boundary

Description

This statement allows you to place assembly-language code within your ScharfBASIC source code. An exclamation mark (!) serves as a shortcut for the ASM keyword.

Each group of ASM statements must preserve the following CPU registers if the assembler code causes them to change: EBX, ESI, EDI, ESP, EBP, and all segment registers. See Saving Registers for more information.

No other statements may appear on the same line as an ASM statement; however, comments are acceptable.

! DB 1, 2, 3, 4, 5

! DD &H45001222, &HFFFF4327

Any variable referenced in an assembly-language statement must be defined prior to use. For example:

x% = 10

! MOV AX, x%

You cannot access the target of a pointer with a single ASM statement as you might do in BASIC source code. Instead, you must use the pointer address indirectly. To simulate the BASIC statement INCR @x, you would write:

DIM x AS INTEGER PTR

ASM MOV EAX, x ; EAX holds a pointer to an Integer

ASM INC WORD PTR [EAX] ; Add one to target value

String literals of up to four characters may be used in Inline Assembler code:

! MOV AL, "a" ; move char a into reg AL

! MOV AX, "ab" ; move chars ab into reg AX

! ; "a" into AL, "b" into AH

! MOV EAX, "abcd" ; move chars abcd into reg EAX

ScharfBASIC recognizes either an apostrophe ( ' ) or a semi-colon ( ; ) to specify a comment after a line of assembler code:

! PUSH EAX ; save the EAX register

! PUSH EBX ' save the EBX register

ASM ALIGN is used in critical situations to gain maximum efficiency from assembler code sections.

ASM ALIGN is used to round up the instruction location to a power of two address. The boundary parameter shown must be a power of two, in the range of 2 through 256.

ScharfBASIC inserts NOP instructions into the code section to bring the instruction location up to the desired address. If the instruction location is already at a multiple of boundary , ALIGN has no effect.

The #ALIGN metastatement functions in the same respect as ASM ALIGN, but the ASM ALIGN statement is more suited to being used in a PREFIX/END PREFIX block.

Restrictions

Care should be exercised to ensure registers are appropriately preserved when Inline Assembler code is intermixed with BASIC statements. See Saving Registers for more information.

Usage Examples

  1. LOCAL a&, b&, c&, z&
  2. ! MOV EAX, a&
  3. ! ADD EAX, b&
  4. ! ADD EAX, c&
  5. ! MOV z&, EAX

See Also

  • The Inline Assembler
  • ASMDATA


Commenting Assembly code - ScharfBASIC Help

Commenting Assembly code

On assembly code lines, a semi-colon ( ; ) is typically used for comments, although an apostrophe ( ' ) is still valid. For example:

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

ASM PUSH EBX ; Save EBX

ASM MOV EAX, 5 ; Put 5 into EAX

! MOV EBX, &HFF ; Put FFh into EBX

! ADD EAX, EBX ' EAX = EAX + EBX

! POP EBX ' Restore EBX


Inline Assembler code syntax - ScharfBASIC Help

Inline Assembler code syntax

The ASM statement or, for a "shortcut", the exclamation point (!), is used to insert assembler instructions (or opcodes ) into your BASIC program. They must appear at the beginning of each line that c

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The machine code generated by ASM statements is placed directly in line with the code from your BASIC statements, so execution of your program will flow just as it appears in your source code. You should never, under any circumstances, attempt to exit a Sub / Function / Method / Property early by the use of a RET instruction, as that guarantees failure. If you need to terminate a routine at some point before the End Sub/Function/Method/Property statement, jump to a label at the end of the procedure instead.

Using assembly-language in your code


Intermixing ASM and BASIC code - ScharfBASIC Help

Intermixing ASM and BASIC code

There are special conditions with register preservation that apply when writing mixed assembler and BASIC code. ScharfBASIC is a highly optimized compiler and among its optimizations are reductions in

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

This means that if your assembler algorithm uses any of the EBX, ESI, or EDI registers, you must preserve their original state from the last line of BASIC code that precedes the Inline Assembler code. This is, you must PUSH them before your ASM code, and POP them again right before the BASIC code commences.

This may appear to be more code than is necessary but it must be remembered that the internal structure of ScharfBASIC does not duplicate the stack preservation that the application programmer must apply, so in terms of the stack overhead, the code is actually very efficient.

It should be noted that if your ASM code uses the EAX, ECX, or EDX registers, you should also preserve these as the internal execution of BASIC statements can also freely modify any of these three registers too.

The overall approach to preserving the registers around intermixed ASM and BASIC code is demonstrated in the following listing:

SUB TestProc(var1&, var2&)

#REGISTER NONE ' Ensure there is no conflict with

' ScharfBASIC Register variables

' Code that uses EAX ECX and EDX goes here


Mnemonics and Operands - ScharfBASIC Help

Mnemonics and Operands

An assembly code instruction (statement) consists of a mnemonic (pronounced "nih-MON-ick"), and between zero and three operands. For a logical or arithmetic mnemonic with two operands, the right opera

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

[ASM|!] mnemonic destination, source

In the examples above, the keywords MOV and ADD are the mnemonics, EAX is the destination operand, and 1 and EBX are the source operands.

In the first line, the value 1 is "moved" into the EAX operand (register). In BASIC code, this works similarly to the statement A = 1. The second example adds the value in EBX to the value in EAX and stores the result in EAX. In BASIC code, this works similarly to A = A + B.

Using assembly-language in your code


Opcodes and Mnemonics - ScharfBASIC Help

Opcodes and Mnemonics

At the hardware level in an Intel or compatible processor, instructions are built directly into the CPU circuitry and these are represented by opcodes .

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

While assembly code can be written at the Byte level, it is a particularly complex method of writing code since it involves memorizing a very large number of opcodes. Additionally, such program code must use the Intel numeric ( little-endian ) data format. With little-endian, multi-byte numeric values are stored in reverse order to usual human representation.

For example, to copy the 32-bit value &H56A700FE into the EAX register (MOV EAX, &H56A700FE), you must first find the opcode for the MOV EAX mnemonic (&HA1) followed by the data in reverse order (&HFE, &H00, &HA7, and &H56).

In hex format, the whole instruction would look like this:

Obviously this becomes a very tedious and error prone way to write assembly code. As a result, a system was developed (many years ago) where groups of similar opcodes were given verbose names that made them a lot more convenient to use than raw numeric opcodes. These names are referred to as mnemonics , and this is the system used in ScharfBASIC's 32-bit Inline Assembler .

Each mnemonic represents a reserved name that represents a family of opcodes that perform similar tasks in the processor. The actual numeric opcodes are different depending on the size and type of operands being used. For example, with the MOV mnemonic:

! MOV EAX, VAR1 ' opcode = &HA1

! MOV VAR1, EAX ' opcode = &HA3

The use of mnemonics provides a far more intuitive way of representing opcodes; however, there is no exact correlation between what you write using mnemonics and what you get as finished opcodes. This is because the opcode you actually get for a given mnemonic can depend on whether it is using near or far addressing, the operand data types (registers or pointers or constants), etc. However, ScharfBASIC takes care of these details automatically and transparently for you, leaving you to get on with writing your actual program.


The Inline Assembler - ScharfBASIC Help

The Inline Assembler

Occasionally, you may run into a situation where the syntax and structure of the BASIC language is not the most suitable for a task at hand. ScharfBASIC addresses the need for optimal speed and flexibi

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

This chapter discusses the different ways that ScharfBASIC lets you use assembly-language code in your BASIC programs. It also discusses some design philosophies and considerations, which you should keep in mind if you decide to write your own assembly-language procedures or functions.

The technique of interfacing with assembly-language is, by its very nature, somewhat complex. You should be reasonably familiar with assembly-language concepts before tackling the information in this chapter.

Using assembly-language in your code

Inline Assembler code syntax

Protected mode programming

Mnemonics and Operands

Opcodes and Mnemonics


Using assembly-language in your code - ScharfBASIC Help

Using assembly-language in your code

ScharfBASIC provides a number of ways in which you can use assembly-language. You can write the whole program using the Inline Assembler . You can write entire Subs , Functions , Methods , and Properti

Kind | Keyword
Category | Inline Assembler
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

To write good assembler code, you must be aware of certain items:

Inline Assembler code syntax


ABS - ScharfBASIC Help

ABS

Return the absolute value of a numeric

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = ABS( numeric_expression )

Description

The absolute value of a number is its non-negative value. For example, the absolute value of -3 is 3, and the absolute value of +3 is also 3. The absolute value of 0 is 0.

See Also

  • SGN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
mov   esi,0xfffffff6
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
mov   DWORD PTR [ebp-0x98],esi
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


ATN - ScharfBASIC Help

ATN

Return the arctangent of an argument.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = ATN( numeric_expression )

Description

ATN returns the arctangent (Inverse Tangent) of numeric_expression ; that is, the angle whose tangent is numeric_expression .

The result, as with all operations involving angles in ScharfBASIC, is in radians rather than degrees . Although it is common to specify angles in degrees, the radian is a more convenient measurement for mathematical operations. One radian is defined as the angle at the center of a circle that subtends an arc equal in length to one radius. Since for all circles, using the constant ? :

Circumference / radius = 2 * ?

the length of the circumference of a circle is equal to 2 * ? * radius , and the angle of a full circle (360 degrees) is equal to 2 * ? radians.

To convert radians to degrees, just multiply the radian value by 180/ ? , or 57.29577951308232##. For example, the arctangent of 0.23456 can be converted this way:

t = ATN(.23456!) 't = 0.230395 (radians)

t = 57.29577951308232## * ATN(.23456!) 't= 13.200 (degrees)

To convert degrees to radians, multiply by 0.0174532925199433##. For example:

14 degrees = (0.0174532925199433## * 14) = 0.2443460952792062 radians

Rather than memorizing the radians/degrees conversion factors, calculate them for yourself by remembering this relationship: 2 ? radians equals a full circle (360 degrees), so 1 ? radian is 180 / ? degrees. Conversely, 1 degree equals ? / 180 radians.

? is a transcendental constant, meaning that it has an infinite number of decimal places. To 15-place accuracy, adequate for most applications, ? = 3.141592653589793##. This value can be closely approximated with the expression:

pi## = 4 * ATN(1)

Degrees-to-radians and radians-to-degrees conversions are good applications for user-defined functions.

The ATN function always returns an Extended-precision result.

The Tangent (TAN) of a value can be easily calculated with the TAN function.

The Hyperbolic Tangent (TANH) can be calculated:

TanH = (EXP(2 * Value) - 1) / (EXP(2 * Value) + 1)

The Inverse Hyperbolic Tangent (ARCTANH) of a value can be calculated:

ArcTanH = LOG((1 + Value) / (1 - Value)) / 2

' Useful Macro functions

MACRO Pi = 3.141592653589793##

MACRO DegreesToRadians(dpDegrees) = (dpDegrees*0.0174532925199433##)

MACRO RadiansToDegrees(dpRadians) = (dpRadians*57.29577951308232##)

See Also

  • COS
  • SIN
  • TAN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201ae4
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


BGR - ScharfBASIC Help

BGR

Create a BGR

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

result& = BGR( red& , green& , blue& )
result& = BGR( rgbexpr& )

Description

An RGB value is a long integer value in the range of 0 to &H00FFFFFF. It is used to specify a very precise color to various ScharfBASIC functions and Windows API functions. The lowest three bytes of the value each specify the intensity of a primary color which combine to form the resultant color. Byte 1 (lowest) represents the red component, byte 2 the green, and byte 3 the blue. They can each take on a value in the range of 0 to 255. Byte 4 (highest) is always 0.

Some Windows API functions, such as those which reference Device Independent Bitmaps (DIB), require that the colors be specified in the reverse sequence (Blue-Green-Red instead of Red-Green-Blue). In order to maximize performance and execution speed, ScharfBASIC statements and functions which reference these structures also use the BGR format. These include GRAPHIC GET BITS and GRAPHIC SET BITS . When used with 3 parameters, the BGR() function creates a BGR value from the three component values.

When used with one parameter, this function translates an RGB value to its BGR equivalent by swapping the first byte with the third byte, and returning the result.

For example, the RGB value of blue is &HFF0000. BGR() translates it to &H0000FF. Calling RGB() with that value converts it back to &HFF0000.

See Also

  • Built In RGB Color Equates
  • RGB


BIN$ - ScharfBASIC Help

BIN$

Convert an integral value to a binary string

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = BIN$( IntVal [, Digits , LeadSpaces , TrailSpaces ])

Description

IntVal is a numeric expression in the range of a 64-bit Quad Integer (-9223372036854775808 to +9223372036854775807). Any fractional part of the value is rounded. The result string is always formatted as an integral number using all the significant digits in IntVal . It is never expressed in scientific notation.

If Digits is 0 (or not given), no leading characters will be added to the numeric field. If Digits is a positive number greater than 0, the result string will be prepended with leading zeros to achieve the desired length. If Digits is a negative number, leading spaces are added to reach the absolute length. Digits may be in the range of -64 to +64.

LeadSpaces specifies additional leading spaces to be prepended, regardless of the length of the numeric portion of the string.

TrailSpaces specifies additional trailing spaces to be appended to the end of the string.

See Also

  • DEC$
  • FORMAT$
  • HEX$
  • OCT$
  • STR$
  • TRIM$
  • USING$
  • VAL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2023ec
call   0x20236f
mov   edx,0x203a68
call   0x2023ec
call   0x20236f
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
call   0x2018e8
lea   ebx,[ebp-0xa0]
call   0x201e10
call   0x20236f
call   0x2022a0


BIT CALC - ScharfBASIC Help

BIT CALC

Set or reset a bit in an integral class

Kind | Statement
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

BIT CALC intvar , bitnumber , calcexpr

Description

BIT CALC performs like a combination of the BIT SET and BIT RESET statements, offering the choice between set (1) and reset (0) according to the result of a numeric expression.

intvar

An integral class variable ( Byte , Word , Double-word , Integer , Long-integer or Quad-integer ), or a variable forming the base of an implied bit-array.

bitnumber

An integral class expression or numeric literal that specifies the bit number to adjust. Bit numbers start from zero (0), and extend to the size of the target variable or bit-array. For example, a 16-bit integer variable uses the range 0 to 15. An implied bit-array comprised of a Long-integer array with 100 elements (4 bytes * 100 = 400 bytes = 3200 bits) covers the bit range 0 to 3199.

calcexpr

The value derived from bit zero of calcexpr determines the set or reset action. If bit zero contains a zero (0), the bit in intvar is reset; if bit zero in calcexpr contains a one (1), the bit in intvar is set. This action can be more easily remembered if we consider ScharfBASIC performs an implied bitwise AND operation ( calcexpr AND 1) to derive the set or reset action.

Care must be exercised to ensure that the bit index number ( bitnumber ) does not exceed the number of bits that can be validly accessed. For example, reading the 17th bit of a 16-bit scalar variable may trigger a General Protection Fault (GPF). Similarly, adjusting the 4097th bit of a bit-array derived from a 128-element DWORD array may cause similar problems. bitnumber is always zero-based, so the 129th bit of an implied bit-array is referenced in the BIT statement with bitnumber equal to 128. For example: x& = BIT(A?(1), 128).

See Also

  • BIT function
  • BIT statement
  • BITS functions

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x3
mov   ecx,0x1
call   0x201b12


BIT - ScharfBASIC Help

BIT

Manipulate individual bits of an integral class

Kind | Statement
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

BIT {SET | RESET | TOGGLE} intvar , bitnumber

Description

intvar must be one of the integral-class variable types: Byte , Word , Integer , Double-word , Long-integer , or Quad-integer .

The allowable range for the parameter bitnumber is the same as that of a Long-integer, making it possible to have implicit bit-arrays of more than 2 billion bits in size. Bits 0 to 15 are in the first word starting at intvar , bits 16-31 are in the next word, and so forth.

Implied bit-arrays are considered to start at the memory position of the variable intvar . For example, if intvar is itself an array variable, it is possible to access bits in any of the following elements of the array. See the array examples below.

Care must be exercised to ensure that the bit index number ( bitnumber ) does not exceed the number of bits that can be validly accessed. For example, adjusting the 17th bit of a 16-bit scalar variable may cause a subtle memory corruption problem, and/or may trigger a General Protection Fault (GPF). Similarly, adjusting the 4097th bit of a bit-array derived from a 128-element DWORD array may cause similar problems. bitnumber is always zero-based, so the 129th bit of an implied bit-array is referenced in the BIT statement with bitnumber equal to 128. For example: BIT SET A?(1), 128.

Sets the indicated bit to one.

Sets the indicated bit to zero.

TOGGLE

Toggles the indicated bit: one becomes zero; zero becomes one.

See Also

  • BIT CALC statement
  • BIT function

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Bit Reset

mov   eax,0x3
call   0x201ae8

Variant 2: Bit Set

mov   eax,0x3
call   0x201af2

Variant 3: Bit Test

mov   eax,0x3
call   0x201ad4

Variant 4: Bit Toggle

mov   eax,0x3
call   0x201afa


BITS - ScharfBASIC Help

BITS

Converts an integral value into another data type, based upon the bit pattern of the value. This is particularly helpful in converting between signed and unsigned representations.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

resultvar = BITS( datatype , expression )

Description

Since the integer value -1 and word value 65535 have the identical bit pattern of 1111111111111111, BITS(WORD,-1) would return the unsigned word value of 65535. Of course, BITS(INTEGER,65535) would then return the integer value -1. Other values and data types would follow the same pattern and rules.

This newer form of BITS condenses the functionality of the older forms (BITS%, BITS&, BITS?, BITS?? and BITS???) into a single function. In particular, this provides for the addition of new data types in future version of ScharfBASIC, particularly those which may not have an associated type-specifier character.

See Also

  • BIT CALC statement
  • BIT function
  • BIT statement
  • BITS$
  • BITSE


BITSE - ScharfBASIC Help

BITSE

Compare integral values for equivalent bits regardless of sign.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x& = BITSE( nexp , nexp , bitsize )

Description

This function allows you to compare two integral values for equivalent bit patterns, regardless of whether they are signed or unsigned values. The two numeric expressions ( nexp ) are the integral values to be compared, The bitsize parameter specifies the number of bits to be compared, 8, 16, or 32.

For example, the integer value -1 and the word value 65535 both have the identical bit pattern: 1111111111111111. The difference is simply the way the bits are interpreted by a program.

x& = BITSE( -1, 65535, 16)

The above example would cause the lowest 16 bits of the expressions to be compared. Since they are equal, the value TRUE (-1) is returned.

See Also

  • BITS


CEIL - ScharfBASIC Help

CEIL

Convert a floating

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

intvar = CEIL( numeric_expression )

Description

The CEIL function rounds upward, returning the smallest integral value that is greater than or equal to numeric_expression . For example, y = CEIL(1.5) places the value 2 into y .

See Also

  • CINT
  • FIX
  • FRAC
  • INT
  • ROUND


COS - ScharfBASIC Help

COS

Return the cosine of an angle.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = COS( numeric_expression )

Description

numeric_expression is an angle specified in radians. To convert radians to degrees, multiply by 57.29577951308232##. To convert degrees to radians, multiply by 0.0174532925199433##. For more information on radians, see the ATN function.

COS returns an Extended-precision value that always ranges between -1 and +1 inclusive.

The Inverse Cosine (ARCCOS) of a value can be calculated as follows:

pi## = 3.141592653589793##

ArcCos = pi## / 2 - ATN( Value / SQR(1 - Value * Value ))

The Hyperbolic Cosine (COSH) of a value can also be calculated:

CosH = (EXP(Value) + EXP(-Value)) / 2

The Inverse Hyperbolic Cosine (ARCCOSH) of a value can also be calculated:

ArcCosH = LOG(Value + SQR(Value * Value - 1))

' Useful Macro functions

MACRO Pi = 3.141592653589793##

MACRO DegreesToRadians(dpDegrees) = (dpDegrees*0.0174532925199433##)

MACRO RadiansToDegrees(dpRadians) = (dpRadians*57.29577951308232##)

See Also

  • ATN
  • SIN
  • TAN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201ae9
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


CVBYT - ScharfBASIC Help

CVBYT

Extracts numeric

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

bytevar? = CVBYT( stringexpr [, offset ])
curvar@ = CVCUR( stringexpr [, offset ])
cuxvar@@ = CVCUX( stringexpr [, offset ])
doublevar# = CVD ( stringexpr [, offset ])
doublewordvar??? = CVDWD( stringexpr [, offset ])
extendedvar## = CVE ( stringexpr [, offset ])
integervar% = CVI ( stringexpr [, offset ])
longintvar& = CVL ( stringexpr [, offset ])
quadintvar&& = CVQ ( stringexpr [, offset ])
singlevar! = CVS ( stringexpr [, offset ])
wordvar?? = CVWRD( stringexpr [, offset ])

Description

The CVx functions return a number corresponding to a binary pattern stored in a ANSI string value. The binary pattern is the internal format used by ScharfBASIC to store these values in memory. This format follows the IEEE standard wherever it applies. The MKx$ functions are complementary to the CVx functions. Do not confuse these functions with the VAL function, which converts a number stored as a printable text string (such as "123.45") into a numeric expression.

In all but the most extreme cases, StringExpr must be an ANSI string or UDT which consists of single bytes . WIDE (Unicode) strings consist of a series of 2-byte words which will generally yield undefined results.

The CVx functions allow you to retrieve values beyond the first byte of the StringExpr . In this case, the optional offset parameter tells the byte position where the conversion should begin. This is the byte position, not the character position, even with a WIDE StringExpr . If Offset is not given, it is presumed to be one (1).

For example: "Value& = CVL(x$, 3)" would extract the 3rd through 6th bytes of x$ and convert these 4 bytes to the corresponding Long-integer value. In this example, x$ must be at least 6 bytes long.

Function

Variable

Converts to

1-byte string

8-byte string

Currency

8-byte string

Extended-currency

8-byte string

Double-precision float

4-byte string

Double-word

10-byte string

Extended-precision float

2-byte string

Integer

4-byte string

Long-integer

8-byte string

Quad-integer

4-byte string

Single-precision float

2-byte string

Restrictions

Expressions involving Numeric Equates and conditional compilation ( #IF ) may also include the CVQ function. This allows you to easily assign numeric values to an equate, based upon a meaningful mnemonic. In this context, the CVQ expression is limited to a length of eight bytes. For example:

%Mode = CVQ("DEBUG")

%Style = CVQ("Cool")

CVS limits string display to seven significant digits.

See Also

  • MKBYT$ and associated functions

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Cvbyt

call   0x201d4c
call   0x201ccf
mov   edx,DWORD PTR [ebp-0xb4]
call   0x201cb8
mov   eax,0x1
call   0x2018d8
call   0x201c00

Variant 2: Cvd

call   0x201d4c
call   0x201ccf
mov   edx,DWORD PTR [ebp-0xb4]
call   0x201cb8
mov   eax,0x1
call   0x201903
fstp   QWORD PTR [ebp-0xb0]
call   0x201c00

Variant 3: Cvi

call   0x201d4c
call   0x201ccf
mov   edx,DWORD PTR [ebp-0xb4]
call   0x201cb8
mov   eax,0x1
call   0x201929
call   0x201c00

Variant 4: Cvl

call   0x201d4c
call   0x201ccf
mov   edx,DWORD PTR [ebp-0xb4]
call   0x201cb8
mov   eax,0x1
call   0x201934
call   0x201c00

Variant 5: Cvs

mov   ecx,0xe
call   0x201d4c
call   0x201ccf
mov   edx,DWORD PTR [ebp-0xb4]
call   0x201cb8
mov   eax,0x1
call   0x201948
fstp   DWORD PTR [ebp-0xbc]
call   0x201c00


EXP - ScharfBASIC Help

EXP

Return a base number raised to a power. The base is

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = EXP( n )
y = EXP2( n )
y = EXP10( n )

Description

EXP returns e to the n th power, where n is a numeric variable or expression and e is the base for natural logarithms, approximately 2.718282. Among other uses, this provides a simple way to obtain the value of e itself:

e = EXP(1)

EXP2( n ) returns 2 to the n th power, where n is a numeric variable or expression.

EXP10( n ) returns 10 to the n th power, where n is a numeric variable or expression.

The EXP functions provide a convenient alternative to the ^ operator, which works with any base. The EXP functions return results in Extended-precision.

See Also

  • LOG
  • LOG2
  • LOG10
  • SQR
  • Arithmetic Operators

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201aec
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


FIX - ScharfBASIC Help

FIX

Syntax

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = FIX( numeric_expression )

Description

FIX strips off the fractional part of its argument, and returns the integer part. Unlike CINT and INT , FIX does not perform any form of rounding or scaling.

See Also

  • CEIL
  • CINT
  • INT
  • FRAC
  • ROUND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201af3
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


FRAC - ScharfBASIC Help

FRAC

Return the fractional part of a floating point

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

h = FRAC( float_expression )

Description

FRAC returns the number after the decimal point of a floating-point number or expression. FRAC rounds the result of fit the precision of the target h , as per IEEE specifications.

See Also

  • CEIL
  • CINT
  • FIX
  • INT
  • ROUND


HEX$ - ScharfBASIC Help

HEX$

Convert an integral value to a hexadecimal string

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = HEX$( IntVal [, Digits [, LeadSpaces [, TrailSpaces ]]])

Description

IntVal is a numeric expression in the range of a 64-bit Quad Integer (-9223372036854775808 to +9223372036854775807). Any fractional part of the value is rounded. The result string is always formatted as an integral number using all the significant digits in IntVal . It is never expressed in scientific notation.

If Digits is 0 (or not given), no leading characters will be added to the numeric field. If Digits is a positive number greater than 0, the result string will be prepended with leading zeros to achieve the desired length. If Digits is a negative number, leading spaces are added to reach the absolute length. Digits may be in the range of -16 to +16.

LeadSpaces specifies additional leading spaces to be prepended, regardless of the length of the numeric portion of the string.

TrailSpaces specifies additional trailing spaces to be appended to the end of the string.

See Also

  • BIN$
  • DEC$
  • FORMAT$
  • OCT$
  • STR$
  • TRIM$
  • USING$
  • VAL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2023ec
call   0x20236f
mov   edx,0x203a68
call   0x2023ec
call   0x20236f
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
call   0x201a0f
lea   ebx,[ebp-0xa0]
call   0x201e10
call   0x20236f
call   0x2022a0


HI - ScharfBASIC Help

HI

Extract the most significant (high-order) portion of an integral

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

result = HI( DataType , value )

Description

The value returned by HI is unsigned if DataType is BYTE , WORD , or DWORD , and signed if DataType is INTEGER or LONG . value may be up to twice the size of the data type specified by DataType . In the following example, n may be up to a 16-bit value (twice the size of a BYTE):

b = HI(BYTE, n )

Restrictions

HI replaces HIBYT, HIWRD, and HIINT. Note that those functions are no longer supported, so update your code to use the new syntax.

See Also

  • LO
  • MAK

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   esi,0x12345678
call   0x201c6c
lea   ebx,[ebp-0xa4]
call   0x201bef
mov   eax,0xffff
idiv   DWORD PTR ds:0x202a60
call   0x201b20


INT - ScharfBASIC Help

INT

Convert a numeric expression to an integral

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = INT( numeric_expression )

Description

INT rounds numeric_expression to the largest integral value that is less than or equal to numeric_expression .

See Also

  • CEIL
  • CINT
  • FIX
  • FRAC
  • ROUND

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201b15
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


ISWIN - ScharfBASIC Help

ISWIN

Determine whether a Control

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DialogExists& = ISWIN( hDlg& )
ControlExists& = ISWIN( hParentDlg& , Ident& )

Description

The Window subsystem is checked to determine whether the specified Dialog or Control currently exists. This function may be used for a wide range of purposes, but it's particularly valuable when you want to be sure that a CONTROL was created successfully with the control add statement.

If you use a single parameter, it must specify the handle of a Window, Dialog, or Control you are checking. If you use two parameters, you would specify the handle of the parent and the identifier of the Control you are checking.

If the target of the function currently exists, TRUE (-1) is returned. If it does not exist, the return value is FALSE (0).

See Also

  • CONTROL HANDLE
  • DIALOG NEW


LO - ScharfBASIC Help

LO

Extract the least significant (low-order) portion of an integral

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

result = LO( DataType , value )

Description

The value returned by LO is unsigned if DataType is BYTE , WORD , or DWORD , and signed if DataType is INTEGER or LONG . value may be up to twice the size of the data type specified by DataType . In the following example, n may be up to a 16-bit value (twice the size of a BYTE):

b = LO(BYTE, n )

Restrictions

LO replaces LOBYT, LOWRD, and LOINT. Note that those functions are no longer supported, so update your code to use the new syntax.

See Also

  • HI
  • MAK

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   esi,0x12345678
call   0x201c5c
lea   ebx,[ebp-0xa4]
call   0x201bdf
mov   eax,0xffff
call   0x201b10


LOG - ScharfBASIC Help

LOG

LOG returns the natural (base

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = LOG( numeric_expression )
y = LOG2( numeric_expression )
y = LOG10( numeric_expression )

Description

A logarithm of a number is the power to which the base would have to be raised to yield the number. Thus:

logarithm (base b) of n = x if b^x = n

(base)^log(n) = n

The EXP functions complement the LOG functions. For example, if s = LOG(t) , then t = EXP(s) .

By definition, the logarithm (any base) of 1 is 0. LOG returns the natural logarithm (base e , where e = 2.718282...) of its argument. LOG2 and LOG10 return the logarithm for base 2 and 10, respectively.

numeric_expression must be a value greater than zero.

LOG, LOG2, and LOG10 return Extended-precision values.

See Also

  • EXP
  • EXP2
  • EXP10
  • SQR
  • Arithmetic Operators

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201b08
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


MAK - ScharfBASIC Help

MAK

Create an integral class

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

resultvar = MAK( datatype , loworderval , highorderval )

Description

Create an integral class value of a specified data type ( WORD , DWORD , PTR , INTEGER , LONG , QUAD ) from a low-order and a high-order part.

The complements to this function are the HI and LO functions, which may be used to split a single 32-bit value into two 16-bit components.

Restrictions

MAK supercedes the MAKWRD, MAKDWD, and MAKPTR functions. Those functions are no longer supported, so update your code to use the new syntax.

See Also

  • HI
  • LO


MAX - ScharfBASIC Help

MAX

Return the argument with the largest (maximum) value.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = MAX( arg [, arg ] ...)
y& = MAX&( arg& [, arg& ] ...)
y$ = MAX$( arg$ [, arg$ ] ...)

Description

These functions take any number of arguments and return the argument with the largest (maximum) value. MAX handles arguments of any numeric type.

MAX& handles arguments which evaluate to Long-integers (MAX& is more efficient than MAX).

MAX$ handles string arguments.

If any arguments of MAX& are outside of the range of Long-integers, the result is undefined. Any floating point arguments of MAX& will be rounded to Long-integers before the comparison begins.

MAX% is recognized as a valid synonym for MAX&.

See Also

  • CHOOSE
  • CHOOSE&
  • CHOOSE$
  • IIF
  • IIF&
  • IIF$
  • MIN
  • MIN&
  • MIN$
  • SWITCH
  • SWITCH&
  • SWITCH$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201918
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
fild   DWORD PTR ds:0x202a60
call   0x201e7c
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
call   0x201e90


MIN - ScharfBASIC Help

MIN

Return the argument with the smallest (minimum) value.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = MIN( arg , arg [, arg ] ...)
y& = MIN&( arg& , arg& [, arg& ] ...)
y$ = MIN$( arg$ , arg$ [, arg$ ] ...)

Description

These functions take any number of arguments and return the argument with the smallest (minimum) value. MIN handles arguments of any numeric type.

MIN& handles arguments that evaluate to Integers and Long-integers (MIN& is more efficient than MIN).

MIN$ handles string arguments.

If any arguments of MIN& are outside of the range of Long-integers, the result is undefined. Any numeric arguments of MIN& will be rounded to Long-integers before the comparison begins.

MIN% is recognized as a valid synonym for MIN&.

See Also

  • CHOOSE
  • CHOOSE&
  • CHOOSE$
  • IIF
  • IIF&
  • IIF$
  • MAX
  • MAX&
  • MAX$
  • SWITCH
  • SWITCH&
  • SWITCH$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201918
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
fild   DWORD PTR ds:0x202a60
call   0x201e63
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
call   0x201e90


OCT$ - ScharfBASIC Help

OCT$

Convert an integral value to an octal string

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = OCT$( IntVal [, Digits , LeadSpaces , TrailSpaces ])

Description

IntVal is a integral expression in the range of a 64-bit Quad Integer (-9223372036854775808 to +9223372036854775807). Any fractional part of the value is rounded. The result string is always formatted as an integral number using all the significant digits in IntVal. It is never expressed in scientific notation.

If Digits is 0 (or not given), no leading characters will be added to the numeric field. If Digits is a positive number greater than 0, the result string will be prepended with leading zeros to achieve the desired length. If Digits is a negative number, leading spaces are added to reach the absolute length. Digits may be in the range of -22 to +22.

LeadSpaces specifies additional leading spaces to be prepended, regardless of the length of the numeric portion of the string.

TrailSpaces specifies additional trailing spaces to be appended to the end of the string.

See Also

  • BIN$
  • DEC$
  • FORMAT$
  • HEX$
  • STR$
  • TRIM$
  • USING$
  • VAL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2023ec
call   0x20236f
mov   edx,0x203a68
call   0x2023ec
call   0x20236f
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
call   0x201b48
lea   ebx,[ebp-0xa0]
call   0x201e10
call   0x20236f
call   0x2022a0


RANDOMIZE - ScharfBASIC Help

RANDOMIZE

Seed the random number generator.

Kind | Statement
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

RANDOMIZE [ number ]

Description

number is a seed value that may be any numeric type. If number is not specified, the value returned by the TIMER function is used.

Values returned by the random number generator ( RND ) depend on an initial seed value. For a given seed value, RND always returns the same sequence of values, yielding a predictable pseudo-random number sequence. Thus, any program that depends on RND will run exactly the same way each time unless a different seed is given.

The default seed can be duplicated with the following statement:

RANDOMIZE CVS(CHR$(255,255,255,255))

Note that each thread has its own, independent random number seed.

See Also

  • RND
  • TIMER

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201e70
call   0x201df3
call   0x201bf8
call   0x2018b8
call   0x201d24


REMAIN$ - ScharfBASIC Help

REMAIN$

Return the portion of a string

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = REMAIN$([ Start ,] MainStr , [ANY] MatchStr )

Description

REMAIN$ is a complement to the EXTRACT$ function. MainStr is searched for the string specified in MatchStr . If found, all characters after MatchStr are returned. If MatchStr is not present in MainStr , or either string parameter is nul, then a nul (zero-length) is returned.

Start is an optional starting position to begin searching. If Start is not specified, position 1 will be used. If Start is zero, a nul string is returned. If Start is negative, the starting position is counted from right to left: if -1, the search begins at the last character; if -2, the second to last, and so forth.

If the ANY keyword is included, MatchStr specifies a list of single characters to be searched for individually. A match on any one of them will cause the operation to be performed up to that character.

See Also

  • EXTRACT$
  • LEFT$
  • LTRIM$
  • MID$
  • REMOVE$
  • REPLACE
  • RIGHT$
  • RTRIM$
  • TALLY
  • TRIM$
  • VERIFY


RGB - ScharfBASIC Help

RGB

Create an RGB

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

result& = RGB( red& , green& , blue& )
result& = RGB( bgrexpr& )

Description

An RGB value is a long integer value in the range of 0 to &H00FFFFFF. It is used to specify a very precise color to various ScharfBASIC functions and Windows API functions. The lowest three bytes of the value each specify the intensity of a primary color which combine to form the resultant color. Byte 1 (lowest) represents the red component, byte 2 the green, and byte 3 the blue. They can each take on a value in the range of 0 to 255. Byte 4 (highest) is always 0. When used with 3 parameters, the RGB() function creates an RGB value from the three component values.

Some Windows API functions, namely those which reference Device Independent Bitmaps (DIB), require that the colors be specified in the reverse sequence (Blue-Green-Red instead of Red-Green-Blue). In order to maximize performance and execution speed, ScharfBASIC statements and functions which reference these structures also use the BGR format. These include GRAPHIC GET BITS and GRAPHIC SET BITS .

When used with one parameter, this function translates a BGR value to its RGB equivalent by swapping the first byte with the third byte, and returning the result.

For example, the BGR value of red is &HFF0000. RGB() translates it to &H0000FF. Calling BGR() with that value converts it back to &HFF0000.

See Also

  • Built In RGB Color Equates
  • BGR


RND - ScharfBASIC Help

RND

Return a random number.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = RND
y = RND( a , b )
y = RND( numeric_expression )

Description

Floating point mode: RND returns a random value that is less than 1, but greater than or equal to 0. Numbers generated by RND aren't really random, but are the result of applying a pseudo-random transformation algorithm to a starting ("seed") value. Given the same seed, ScharfBASIC's RND algorithm always produces the same sequence of "random" numbers. The pseudo-random value is calculated internally as a single precision value, but returned as an extended precision representation so it can be readily used in any situation.

Integral Range mode: RND( a , b ) returns a Long-integer in the range of a to b inclusive. a and b can each be a numeric literal or a numeric expression that evaluates within the range of a Long-integer (-2,147,483,648 to 2,147,483,647).

Special effects mode: When used with a single numeric expression argument, the value returned by RND depends on the optional numeric value you supply as the argument, as follows:

With no argument, or with a positive argument, RND generates the next number in sequence based on the initial seed value. With an argument of 0, RND repeats the last number generated. A negative argument causes the random number generator to be re-seeded, so subsequent uses of RND with no argument or with a positive argument result in a new sequence of values.

Do not use 0 or negative value arguments in special effects mode unless you are looking for the special effects those argument values produce.

The random number generator can be reset back to the default seed using the following statement:

RANDOMIZE CVS(CHR$(255,255,255,255))

Note that each thread has its own, independent random number seed. See the discussion under RANDOMIZE for additional information on seeding the random number generator.

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
call   0x20189f
fstp   QWORD PTR [ebp-0xa0]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


ROTATE - ScharfBASIC Help

ROTATE

Rotate the bits in an integral class

Kind | Statement
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ROTATE {LEFT | RIGHT} ivar , count

Description

ivar must be one of the integral-class variable types: Byte , Word , Integer , Double-word , Long-integer , or Quad-integer . count is the number of bits by which to rotate ivar . ROTATE rotates all the bits in ivar without special regard to the sign bit of a signed integral-class variable.

See Also

  • BIT function
  • BIT statement
  • BITS
  • SHIFT

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Rotate Left

mov   ecx,0x2
mov   eax,0x4
call   0x201b89

Variant 2: Rotate Right

mov   ecx,0x2
mov   eax,0x4
call   0x201bad


ROUND - ScharfBASIC Help

ROUND

Round a numeric value to a specified number of decimal places.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x = ROUND( numeric_expression , n )

Description

n is an integral expression specifying the number of decimal places required in the result. ROUND is especially useful in cases where you have a variable in Single , Double , or Extended-precision , and you want to put it into a Currency variable or display it, rounded to a specific number of decimal places.

Rounding is done according to the "banker's rounding" principle: if the fractional digit being rounded off is exactly five, with no trailing digits, the number is rounded to the nearest even number. This provides better results, on average, than the simple "round up at five" approach.

A% = ROUND(0.5, 0) ' 0

A% = ROUND(1.5, 0) ' 2

A% = ROUND(2.5, 0) ' 2

A% = ROUND(2.51, 0) ' 3

See Also

  • CEIL
  • FIX
  • FORMAT$
  • INT
  • USING$


SGN - ScharfBASIC Help

SGN

Return the sign of a numeric expression.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = SGN( numeric_expression )

Description

If numeric_expression is positive, SGN returns 1. If numeric _ expression is zero, SGN returns 0. If numeric_expression is negative, SGN returns -1.

In conjunction with the ON GOTO and ON GOSUB statements, SGN can produce a FORTRAN-like three-way branch:

ON SGN(balance) + 2 GOTO InTheRed, BreakingEven, InTheMoney

See Also

  • ABS
  • IF
  • ON GOSUB
  • ON GOTO
  • SELECT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
mov   esi,0xfffffff6
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
call   0x201ad4
mov   DWORD PTR [ebp-0x98],esi
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


SHIFT - ScharfBASIC Help

SHIFT

Shift the bits in an integral

Kind | Statement
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SHIFT [SIGNED] {LEFT | RIGHT} ivar , countexpr

Description

ivar must be one of the integral-class variable types: Byte , Word , Integer , Double-word , Long-integer , or Quad-integer . countexpr is an integral-class expression specifying the number of bits by which to shift ivar .

SHIFT shifts all the bits in ivar without special regard to the sign bit of a signed integral-class variable.

SIGNED

The SIGNED option shifts everything, but does not allow the sign (positive or negative) of the value to change.

LEFT | RIGHT

The LEFT or RIGHT option determines the direction of the bit SHIFT operation. SHIFT LEFT shifts the bits toward the high-order end of ivar , and SHIFT RIGHT shifts bits toward the low-order end of ivar .

See Also

  • AND
  • BIT function
  • BIT statement
  • NOT
  • OR
  • ROTATE
  • XOR


SIN - ScharfBASIC Help

SIN

Return the sine of its argument.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = SIN( numeric_expression )

Description

numeric_expression is an angle specified in radians. SIN returns an Extended-precision value between -1 and +1.

To convert radians to degrees, multiply by 57.29577951308232##. To convert degrees to radians, multiply by 0.0174532925199433##. For more information on radians, see the ATN function.

The Inverse Sine (ARCSIN) of a value can be calculated as follows:

ArcSin = ATN( Value / SQR(1 - Value * Value ))

The Hyperbolic Sine (SINH) of a value can also be calculated:

SinH = (EXP(Value) - EXP(-Value)) / 2

The Inverse Hyperbolic Sine (ARCSINH) of a value can also be calculated:

ArcSinH = LOG(Value + SQR(Value * Value + 1))

' Useful Macro functions

M ACRO Pi = 3.141592653589793##

MACRO DegreesToRadians(dpDegrees) = (dpDegrees * 0.0174532925199433##)

MACRO RadiansToDegrees(dpRadians) = (dpRadians * 57.29577951308232##)

See Also

  • ATN
  • COS
  • TAN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201c12
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


SQR - ScharfBASIC Help

SQR

Return the square root of its argument.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = SQR( numeric_expression )

Description

numeric_expression must be greater than or equal to zero. SQR calculates square roots using an optimized algorithm. That is, y = SQR(x) takes less time to execute than y = x^0.5.

Attempting to take the square root of a negative number does not produce any run-time errors , but the results of such an operation are undefined.

SQR returns an Extended-precision result.

See Also

  • EXP
  • EXP2
  • EXP10
  • LOG
  • LOG2
  • LOG10

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201c15
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


SWAP - ScharfBASIC Help

SWAP

Exchange the values of two

Kind | Statement
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SWAP var1 , var2

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201c5c
lea   ebx,[ebp-0xa4]
call   0x201bdf
mov   edi,0x0
call   0x201b10


TAN - ScharfBASIC Help

TAN

Return the tangent of its argument.

Kind | Function
Category | Math & Numeric
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = TAN( numeric_expression )

Description

numeric_expression is an angle specified in radians. To convert radians to degrees, multiply by 57.29577951308232##. To convert degrees to radians, multiply by 0.0174532925199433##. For more information on radians, see ATN .

TAN returns an Extended-precision result.

TAN is approximated with the expression:

TAN = SIN( Value ) / COS( Value )

The Inverse Tangent (ARCTAN) of a value can be easily calculated with the ATN function.

The Hyperbolic Tangent (TANH) of a value can be calculated:

TanH = (EXP(2 * Value) - 1) / (EXP(2 * Value) + 1)

The Inverse Hyperbolic Tangent (ARCTANH) of a value can be calculated:

ArcTanH = LOG((1 + Value ) / (1 - Value )) / 2

' Useful Macro functions

MACRO Pi = 3.141592653589793##

MACRO DegreesToRadians(dpDegrees) = (dpDegrees * 0.0174532925199433##)

MACRO RadiansToDegrees(dpRadians) = (dpRadians * 57.29577951308232##)

See Also

  • ATN
  • COS
  • SIN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
fld   DWORD PTR ds:0x202a50
fstp   QWORD PTR [ebp-0xa0]
fld   QWORD PTR [ebp-0xa0]
call   0x201c22
fstp   QWORD PTR [ebp-0xa8]
mov   DWORD PTR [ebp-0x98],0x1
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


#STACK - ScharfBASIC Help

#STACK

Set the maximum potential

Kind | Directive
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#STACK num_expr

Description

The literal numeric expression is expressed in bytes, and is rounded up to the next 64 Kb boundary. The minimum allowable stack size is 128 Kb, and a typical stack size of at least 1 Megabyte (the default) is usually recommended.

Upon program startup, an initial block of 128 Kb of physical memory is allocated to the stack. As the stack grows, additional memory is automatically added, as necessary, up to the specified maximum. Since physical memory is only committed as required, it is usually prudent to overestimate potential stack needs.


CODEPTR - ScharfBASIC Help

CODEPTR

Obtain a 32-bit address of a

Kind | Function
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

AddrVar = CODEPTR( Label )
AddrVar = CODEPTR( ProcName )

Description

CODEPTR retrieves the address of a Label, Sub, Function, or FastProc. The first form may be used to get the address of a label located within the same procedure. The second form is used to obtain the address of a Sub, Function, or FastProc.

CODEPTR is particularly useful when it is necessary to pass the address of a SUB or FUNCTION to ScharfBASIC or Windows to specify a Callback Function.

Restrictions

CODEPTR cannot obtain the address of a METHOD or PROPERTY as direct access to them would constitute an illegal operation.

See Also

  • STRPTR
  • VARPTR
  • CALL DWORD

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x201083


Effective Addressing - ScharfBASIC Help

Effective Addressing

The notation to calculate the effective address of data in memory can look complicated but it is in fact very clear and precise notation. In the range of allowable notation for Intel 80x86 assembler,

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

! MOV EAX, lpArray ; Copy address into EAX

! MOV ECX, [EAX] ; Copy 1st item in array into ECX

! ADD EAX, 4 ; Increment the array location by 4 bytes

! MOV ECX, [EAX] ; Copy 2nd item in array into ECX

This works fine in simple situations where the register that has the address is manually incremented or decremented by the data size each time it is accessed, but there is a much more powerful and flexible technique available by using the standard Intel notation that is available.

The Intel 80x86 allows the following format to calculate the effective address of a value in memory:

[ Base Address + Index * Scale + Displacement ]

Base Address The register that has the starting address or base address of the array (or buffer) in memory.

Index The register used to determine the offset from the base address.


GLOBALMEM ALLOC - ScharfBASIC Help

GLOBALMEM ALLOC

Allocate or release a block of global memory

Kind | Statement
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GLOBALMEM ALLOC count TO vHndl
GLOBALMEM FREE mHndl TO vHndl
GLOBALMEM LOCK mHndl TO vPtr
GLOBALMEM SIZE mHndl TO vSize
GLOBALMEM UNLOCK mHndl TO vLocked

Description

GLOBALMEM allocates a block of global system memory of the requested size. This is always allocated as "moveable" memory, so it can be used with any facilities of Windows. It is the programmer's responsibility to release the allocated memory block when it's no longer needed.

There are five general forms of the GLOBALMEM statement:

GLOBALMEM ALLOC

A moveable memory block of the size in bytes specified by count is allocated. A unique handle is assigned to this memory object (for later identification). This handle is assigned to the LONG or DWORD variable specified by vHndl . If the requested allocation fails for any reason, the value zero (0) is assigned to vHndl instead.

GLOBALMEM FREE

A memory block is de-allocated and released for re-use. The mHndl parameter is a variable or expression which evaluates to the handle returned by GLOBALMEM ALLOC when the memory block was created. If the de-allocation operation was successful, the result variable vHndl is set to zero (0) to indicate that the original handle is no longer valid. If the operation fails for any reason, the value of the mHndl parameter is assigned to vHndl . It may be convenient to use the same variable for both the parameter and the result, as it will then be automatically cleared to zero when the memory block is released.

GLOBALMEM LOCK

The moveable memory block referenced by mHndl is locked at a specific memory location. A pointer to this location is assigned to the variable specified by vPtr . You may only read or write the memory block while it is locked, and you use the current pointer to its location.

GLOBALMEM SIZE

The size of the memory block referenced by mHndl is retrieved and assigned to the LONG or DWORD variable specified by vSize . The mHndl parameter is the handle originally returned by GLOBALMEM ALLOC.

GLOBALMEM UNLOCK

The moveable memory block referenced by mHndl is unlocked, and the previous memory pointer is invalidated. If the memory block remains locked (perhaps because it had been locked more than once), the value TRUE (non-zero) is assigned to the result variable vLocked . If the memory block is now unlocked, or the parameter mHndl was invalid, the value FALSE (0) is assigned to vLocked instead.

See Also

  • MEMORY

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Globalalloc

push   0x400
call   DWORD PTR ds:0x20311c
fldcw   WORD PTR [ebp-0x10]

Variant 2: Globalfree

call   DWORD PTR ds:0x20311c
fldcw   WORD PTR [ebp-0x10]

Variant 3: Heapalloc

push   0x400
call   DWORD PTR ds:0x203120
fldcw   WORD PTR [ebp-0x10]
call   DWORD PTR ds:0x203124
fldcw   WORD PTR [ebp-0x10]

Variant 4: Heapfree

call   DWORD PTR ds:0x203120
fldcw   WORD PTR [ebp-0x10]
call   DWORD PTR ds:0x203124
fldcw   WORD PTR [ebp-0x10]


MEMORY COPY - ScharfBASIC Help

MEMORY COPY

Copy, Swap, or Fill blocks of memory.

Kind | Statement
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MEMORY COPY Source& , Dest& , Count&
MEMORY SWAP Source& , Dest& , Count&
MEMORY FILL Dest& , Count& , BYTE|WORD|DWORD IntegralExpr
MEMORY FILL Dest& , Count& , StrgExpr

Description

The MEMORY statement may be used to copy, swap, or fill a block of memory with very high efficiency. ScharfBASIC will automatically take into account the possibility that the source and destination blocks overlap and avoid corruption from that fact.

In the first form, Count& bytes of memory at the address specified by Source& is copied to the address specified by Dest& . In the second form, Count& bytes of memory at the address specified by Source& is exchanged with the data at the address specified by Dest& .

In the third form, Count& bytes of memory at Dest& are filled with one or more copies of the BYTE, WORD, or DWORD value specified by the value of IntegralExpr .

In the fourth form, Count& bytes of memory at Dest& are filled with one or more copies of the string StrgExpr .

See Also

  • GLOBALMEM
  • PEEK$
  • POKE$
  • STRPTR
  • VARPTR


MMX registers - ScharfBASIC Help

MMX registers

According to the Intel documentation, all MMX registers require parentheses around the register number. These were compulsory in early versions of ScharfBASIC, but the parentheses are now optional.

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

! PXOR mm(7), mm(7) ' PB/DLL 5.0, PB/CC 1.0 format

! PXOR mm7, mm7 ' PB/DLL/WIN 6.0+, PB/CC 2.0+ format

Data types in registers

Saving Registers at the Procedure level

Tricks in preserving registers


OBJPTR - ScharfBASIC Help

OBJPTR

Return an

Kind | Function
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ObjectPointer??? = OBJPTR( objectvar )

Description

OBJPTR returns the object pointer as a Double-word ( DWORD ) value.

See Also

  • DIM
  • CLSID$
  • GUID$
  • GUIDTXT$
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISOBJECT
  • LET (with Objects)
  • OBJECT
  • OBJACTIVE
  • OBJEQUAL
  • OBJRESULT
  • PROGID$
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

lea   ebx,[ebp-0xa8]
call   0x201b10


PEEK - ScharfBASIC Help

PEEK

Returns a

Kind | Function
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

numvar = PEEK([ datatype ,] address??? )
ansivar = PEEK$([STRINGZ,] address??? , count& )
widevar = PEEK$$([WSTRINGZ,] address??? , count& )

Description

The PEEK functions and complementary POKE statements are low-level methods of accessing individual bytes in memory. The data is retrieved from memory, starting at the specified 32-bit address??? .

PEEK retrieves a numeric value starting at a specified memory address.

PEEK$ retrieves count& consecutive bytes and returns them as a string . If STRINGZ (or ASCIIZ) is specified, PEEK$ reads successive characters from memory, up to the specified size, until a terminating $NUL ( CHR$ (0)) byte is found. Since STRINGZ strings must contain a terminating $NUL, the maximum length of the returned string is 1 character less than count&.

PEEK$$ retrieves count& consecutive 2-byte wide characters, and returns them as a wide character string. If WSTRINGZ is specified, PEEK$$ reads successive characters from memory, up to the specified size, until a terminating $NUL (CHR$(0)) character is found. Since WSTRINGZ strings must contain a terminating $NUL, the maximum length of the returned string is 1 character less than count& .

Contrary to intuitive notions, PEEK and POKE execute at the same high performance levels as pointer variables. They offer an excellent alternative to pointers in many situations.

datatype

The numeric data type to retrieve, which may be any one of BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , EXT , CUR , CUX . If a data type is not specified, BYTE is assumed.

address???

A valid 32-bit memory address specifying the location in memory where data retrieval should begin.

count&

A numeric expression that specifies the number of consecutive characters to be read from memory.

Restrictions

If address??? (or any memory in the range covered by count& ) references an invalid address (memory that is not allocated to the application), Windows will generate a General Protection Fault (GPF) and terminate the application. GPFs cannot be trapped with an ON ERROR error handler.

See Also

  • POKE
  • STRPTR
  • VARPTR

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Peek Byte

movzx   eax,BYTE PTR [ebx]
call   0x201b10

Variant 2: Peek Long

call   0x201b10

Variant 3: Peek String

call   0x201e20
call   0x201da3
mov   eax,0x5
call   0x201bc8
call   0x201da3
call   0x201cd4

Variant 4: Peek Word

movzx   eax,WORD PTR [ebx]
call   0x201b10


POKE - ScharfBASIC Help

POKE

Store a

Kind | Statement
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

POKE [ DataType ,] Address??? , DataValue [, DataValue ...]
POKE$ [STRINGZ,] Address??? , StringExpr
POKE$$ [WSTRINGZ,] Address??? , StringExpr

Description

The POKE statements and complementary PEEK functions are low-level methods of accessing individual bytes in memory. The data is stored to memory starting at the specified 32-bit address.

In its classic form, the POKE statement stores a single byte (8 bits) whose value ranges from 0 to 255. In its enhanced form, POKE provides the functionality of a dynamic pointer: the DataType parameter specifies the data type and hence the size of the target data to write to the target memory address. DataType can be any one of BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , EXT , CUR , CUX . If a DataType is not specified, BYTE is assumed. If you specify more than one DataValue , they are stored in successive memory locations.

POKE$ stores the bytes of StringExpr in consecutive bytes of memory. If STRINGZ (or ASCIIZ) is specified, POKE$ writes successive characters to memory, up to the specified size, until a terminating $NUL byte is found in the source string. If no $NUL is found in the string, one is automatically appended. It is the programmer's responsibility to ensure that POKE$ does not overrun the target memory area to avoid data corruption or protection faults.

POKE$$ stores the characters of StringExpr as consecutive 2-byte words of memory. If WSTRINGZ is specified, POKE$$ writes successive wide characters, up to the specified size, until a terminating $NUL is found in the source string. If no $NUL is found in the string, one is automatically added. It is the programmer's responsibility to ensure that POKE$$ does not overrun the target memory area to avoid data corruption or protection faults.

Contrarary to intuitive notions, PEEK and POKE execute at the same high performance levels as pointer variables. They offer an excellent alternative to pointers in many situations.

Address???

A valid 32-bit memory address specifying the location in memory where data storage should begin.

Datavalue

The data value to be stored at A ddress??? .

StringExpr

A string constant , literal or expression that specifies the sequence of characters to be stored in memory, starting at by Address??? .

Restrictions

If POKE attempts to access memory that is not allocated to the application, Windows will generate a General Protection Fault (GPF) and terminate the application. GPFs cannot be trapped.

See Also

  • GLOBALMEM ALLOC
  • MEMORY
  • PEEK
  • STRPTR
  • VARPTR

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Poke Byte

mov   BYTE PTR [ebx],0x41
call   0x201b10

Variant 2: Poke Long

mov   DWORD PTR [ebx],0x2a
call   0x201b10


Registers - ScharfBASIC Help

Registers

Registers are a special working area within the processor. Registers are faster than memory operands , and are designed to work with the processor's opcodes .

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Registers in an Intel or compatible processor are a very limited resource when writing assembler. In essence, there are eight general-purpose registers, EAX, EBX, ECX, EDX, ESI, EDI, ESP, and EBP . In most instances, ESP and EBP should remain unused as ScharfBASIC uses them for entry and exit of procedures.

This means that you have six 32-bit registers to use in your assembly code, plus any other memory locations that are useful in the procedure. ESI and EDI can be used in the normal manner in most instances but neither can be accessed at a Byte level. You can read the low WORD of ESI as SI and the low WORD of EDI as DI.

Understanding the size of registers and the data that you can place in them is very important when using assembler. A 32-bit Intel or compatible processor has three native data sizes that can be used by the normal integral instructions, BYTE , WORD , and DWORD corresponding to 8-bit, 16-bit and 32-bit.

This can be shown in HEX notation.

In terms of registers, this corresponds to the three sizes that can be addressed with the normal integral registers. Intel and compatible processors are backwards compatible with older code that uses 8 and 16-bit registers, and it is done by accessing any of the general purpose registers in three different ways. Using the EAX register as an example:


Saving registers - ScharfBASIC Help

Saving registers

When writing assembler code in 32-bit Windows, there is a convention that governs the use of registers so programmers can interact with the Windows API functions in a predictable and completely reliab

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

However, the registers available with an 80x86 processor are a very limited resource, and they are used by every application (process) running and also by the operating system itself. Therefore, a reliable method of using registers is very important to the process of writing reliable assembler code.

An 80x86 processor has eight general-purpose integral registers, EAX, EBX, ECX, EDX, ESI, EDI, ESP, and EBP . Of these, ESP and EBP are almost exclusively used to manage the entry and exit to a procedure, so there are effectively just six general-purpose registers available for application level programming.

Following on, the Windows convention splits the remaining registers so that 3 can be freely modified (EAX, ECX, and EDX) within the Sub / Function / Method / Property that uses them, while the other 3 must be preserved (EBX, ESI, and EDI) by the procedure. For the sake of this discussion, we'll refer to these two sets as scratch and volatile registers respectively.

In summary, ScharfBASIC automatically preserves EBX, ESI, and EDI at the procedure level, but the programmer is responsible for preserving both the scratch and volatile registers within the procedure.

"Preserving the registers" does not necessarily mean that you must push all the registers on the stack, though that is the usual way of ensuring their safety. Simple routines might not modify any of the registers; in which case, you may not need to take any precautions. We use may because it's best to avoid making assumptions, especially with assembler programming. It is better to be safe than sorry. When in doubt, preserve (save and restore) all of the registers.

Saving Registers at the procedure level


Saving Registers at the Procedure level - ScharfBASIC Help

Saving Registers at the Procedure level

To conform to the Windows programming conventions, ScharfBASIC must provide a "safe" environment for the range of functions that are available. This is achieved by transparently preserving the three vo

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

! PUSH EBX ' Automatically added by ScharfBASIC

' the actual SUB code is placed here

! POP EDI ' Automatically added by ScharfBASIC


Saving the FPU registers - ScharfBASIC Help

Saving the FPU registers

Whereas the CPU has registers with fixed names (EAX, etc), the FPU (Floating-Point Unit or co-processor) has stack -like registers which are numbered according to their position in the stack: ST(0) {t

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Note the term loading is used to describe placing a value on the FPU stack, yet it operates more like a PUSH operation. In ScharfBASIC, it is not a question of which FPU registers are available, but that four registers (or stack slots) are usually available for use by the programmer. If more are required, the stack should be saved and restored accordingly.

To preserve the entire FPU stack, the mnemonics FSAVE and FRSTOR take care of preserving, and restoring, the FPU stack (respectively). These work in a similar way to the PUSHFD and POPFD CPU, but are notoriously slow to execute and FPU programmers often avoid their use unless necessary. However, they can be useful when starting to write FPU code since they guarantee the preservation and restoration of the FPU stack.

Saving Registers at the Procedure level

Tricks in preserving registers


Stack Overhead Reduction - ScharfBASIC Help

Stack Overhead Reduction

There may be some instances where you wish to repeatedly call a very small SUB and this may produce a situation where the normally modest stack overhead may actually become a factor in the speed of th

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

To help boost performance in such cases, ScharfBASIC offers the often-overlooked GOSUB/RETURN statements, which can be used in place of a call to a SUB/END SUB block . Where stack overhead reduction is critical, you can create a Label in the code below the end of your normal code (but still within the current Sub/ Function / Method / Property block).

You may then take the Inline Assembler code from the target SUB, and place it right after the Label. Finally, a RETURN statement is added so that execution resumes at the next instruction after the GOSUB. Such code would look something like this:

FUNCTION MyFunc() AS LONG

' Inline Assembler code

' More Inline Assembler code

EXIT FUNCTION ' or EXIT SUB

' Your Inline Assembler code


STRPTR - ScharfBASIC Help

STRPTR

Return the 32-bit

Kind | Function
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

xPtr = STRPTR( StringVar )

Description

StringVar is the name of a string variable. STRPTR returns the 32-bit address in memory, where the contents of StringVar are stored.

Note that STRPTR differs from VARPTR . When used with a string variable, VARPTR returns the address of the string's handle , while STRPTR returns the address of the actual string data . Similarly, a STRING POINTER (or STRING PTR) is a pointer to a string handle - this important distinction should be recognized when working with the VARPTR and STRPTR operations.

STRPTR may not be used with fixed-length or nul-terminated strings, because they do not use string handles. Use VARPTR with fixed-length and nul-terminated strings.

When a dynamic string content is changed, the address of the string data will also change, but the string handle will remain in the same location. Therefore, it is important that your code refresh any pointers that target the string data memory locations directly.

See Also

  • CODEPTR
  • POKE$
  • PEEK$
  • VARPTR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201c6c
call   0x201bef
call   0x201c91
call   0x201b20


Tricks in preserving registers - ScharfBASIC Help

Tricks in preserving registers

When you are developing mixed assembler /API code, and you do not know what registers are used in the API functions, you can draw upon two pairs of assembler instructions that preserve all of the usua

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The first pair of mnemonics, PUSHAD and POPAD, save and restore the registers in a block. These mnemonics allow you to do things like display the value of a register in the middle of assembler code with a MessageBox API call.

MessageBox hWnd&,BYCOPY STR$(var&),"Test Value",%MB_OK

' ...More assembler code


Tricks of the stack - ScharfBASIC Help

Tricks of the stack

The stack is very flexible in what can be pushed and popped. There are a few tricks that are very useful when using the stack, you can push a 32-bit value and then pop two 16-bit values.

Kind | Keyword
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

' Push a 32 bit value onto the stack

' Now pop two 16 bit values off the stack

Even though the pushed data size is different to the popped data size, four bytes have been pushed onto the stack and four bytes have been popped back off the stack so the stack is balanced .

The stack can be used for many different things, you can push a register and pop it later when you need it so that you do not need to allocate a memory variable to put it in. You can use the stack to move a piece of data between memory operands and registers.


VARPTR - ScharfBASIC Help

VARPTR

Return the 32-bit address of a

Kind | Function
Category | Memory & Pointers
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = VARPTR( variable )

Description

VARPTR returns a complete 32-bit address to the specified variable as a Double-word (DWORD) value. variable is any string , numeric , structure variable ( User-Defined Type or Union ), or element of an array . VARPTR returns a pointer (32-bit address in memory) where the variable data is stored.

VARPTR may also be used to locate an array descriptor, as well as the array data itself. To find the address of an array descriptor, use the array name with empty parentheses: VARPTR( x( ) ).

When you use VARPTR to get the address of a dynamic (variable length) string , keep in mind that the value being returned is the address of the string handle , not the actual data in the string. This can be useful for manipulating a dynamic string array using indexed-pointers, For example:

DIM A$(100), b$, pA AS STRING PTR, x&

' Assume A$() is filled here

pA = VARPTR(a$(0)) ' 1st element handle

FOR X& = 0 TO 100

B$ = B$ + @pA[x&] + ","

NEXT x&

You can use STRPTR to find the address of the string's data. When used with pointers, VARPTR returns the address of the pointer itself.

Restrictions

VARPTR cannot be used on Register variables , because Register variables are stored in internal processor registers rather than application memory. VARPTR can be used on UDT and Union variables, but not the UDT definition name. For example:

TYPE MyType

ABC AS LONG

END TYPE

' more code here

DIM x AS MyTYPE, y&

y& = VARPTR(x) ' This is legal

y& = VARPTR(MyType) ' This is not

See Also

  • CODEPTR
  • PEEK
  • Pointers
  • POKE
  • STRPTR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   DWORD PTR [ebp-0x9c],0x0
call   0x201c5c
call   0x201bdf
lea   ebx,[ebp-0x9c]
call   0x201b10


AND - ScharfBASIC Help

AND

The AND operator works as both a logical and a bitwise arithmetic operator.

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

p AND q

See Also

  • Arithmetic Operators
  • EQV
  • IMP
  • ISFALSE
  • ISTRUE
  • NOT
  • OR
  • XOR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0xff


Arithmetic Operators - ScharfBASIC Help

Arithmetic Operators

Arithmetic operators perform normal mathematical operations. Several of these operators merit a word of explanation. The backslash (\) represents integral division. Integral division rounds its operan

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The remainder of an integral division can be determined with the MOD (modulo) operator (MOD is valid for all numeric types). MOD is similar to integer division except that it returns the remainder of the division rather than the quotient. For example, 5 MOD 2 returns the value 1, and 9 MOD 10 returns the value 9.

The ISTRUE operator returns TRUE only if its operand is TRUE (non-zero). ISTRUE is guaranteed to return -1 as its TRUE value, whereas the operators can return any non-zero value.

The ISFALSE operator returns TRUE only if its operand is FALSE (zero). ISFALSE is guaranteed to return -1 as its TRUE value, where the operators can return any non-zero value.

ScharfBASIC arithmetic operators


EQV - ScharfBASIC Help

EQV

The EQV operator works as both a logical and a bitwise

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

p EQV q

Description

Using EQV as a logical operator

EQV returns TRUE (non-zero) if at least one bit in one operand contains the same value as the identical bit position in the other operand. Further, EQV will return zero if and only if there are no matching bit values between the two operands. This can occur when one operand is equal to the bitwise NOT value of the other operand. For example:

IF x EQV y = 0 THEN statement

is equivalent to:

IF x = NOT y THEN statement

The EQV operator can be used for comparing signed and unsigned values of the same bit size, such as Long-integer and Double-word . This use of EQV is similar to using the BITS functions; however, care must be exercised to test the return value of EQV correctly, since EQV will return an unsigned value with all bits set only if the bit patterns of the two operands are an exact match .

The EQV truth table looks like this:

Truth table

x EQV y

See Also

  • Arithmetic Operators
  • AND
  • IMP
  • ISFALSE
  • ISTRUE
  • LET
  • NOT
  • OR
  • XOR


IMP - ScharfBASIC Help

IMP

The IMP operator works as both a logical and a bitwise

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

p IMP q

Description

IMP as a logical operator

The IMP operator returns FALSE (zero) if and only if its first operand is TRUE (non-zero), and its second operand is FALSE. In all other cases, it returns TRUE.

Truth table

x IMP y

See Also

  • Arithmetic Operators
  • AND
  • EQV
  • ISFALSE
  • ISTRUE
  • NOT
  • OR
  • XOR


ISFALSE - ScharfBASIC Help

ISFALSE

Return the logical truth or falsity of a given expression.

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ISFALSE expr
ISTRUE expr

Description

ISTRUE returns -1 (TRUE) when expr evaluates as non-zero; otherwise, it returns zero (FALSE). ISFALSE returns -1 when expr evaluates as 0 (FALSE); otherwise, it returns zero.

Truth table

operator

Result

ISTRUE

ISTRUE

ISFALSE

ISFALSE

ScharfBASIC's NOT operator serves a double duty: it returns the one's-complement of an integer class expression and "reverses" the value of a TRUE/FALSE (Boolean) expression. Usually, these two functions do not conflict, but since ScharfBASIC accepts any non-zero value as TRUE, the following condition can arise:

test1 = 0 ' test1 is FALSE (zero)

IF NOT test1 THEN ' TRUE (-1 is non-zero)

[ statements ]

test2 = 1 ' test2 is TRUE (1 is non-zero)

IF NOT test2 THEN ' still TRUE (-2 is non-zero)

[ statements ]

In this case, NOT does not reverse the TRUE/FALSE value of test2. ISFALSE ensures that the test is performed exactly as you would expect:

test2 = 1 ' test2 is TRUE (non-zero)

IF ISFALSE test2 THEN ' ISFALSE detects test2 is

[ statements ] ' TRUE so the IF test fails

This problem does not exist when you're testing for logical truth. ScharfBASIC considers that an expression is TRUE in every case except when the expression is zero. However, ISTRUE converts all non-zero values to the "most true" value, -1, which provides the most consistent results with both boolean and arithmetic expressions.

Restrictions

ISTRUE and ISFALSE operators evaluate the "whole" expression following the keyword, subject to their Operator Precedence level. For example, parentheses contained within the expression are regarded as an integral part of the expression, and do not act as delimiters for the ISTRUE and ISFALSE operators.

With this in mind, combining a logical test result into a further expression means that the expressions must be separated to ensure the correct evaluation.

Consider the following statement:

IF ISTRUE (x&) + y& THEN

ScharfBASIC evaluates the entire expression (x&) + y& and then calculates the logical truth from the overall result of that expression. That is, the parentheses around the first part of the expression do not stop ISTRUE from evaluating the whole expression. To demonstrate this, the statement can be rewritten to concisely demonstrate the scope of the logical evaluation:

IF ISTRUE (x& + 2) THEN

or it could be simplified even further:

IF ISTRUE x& + 2 THEN

If you wish to utilize the numeric result of the logical test in a further expression, parentheses must be added to separate the expressions correctly:

IF (ISTRUE x&) + 2 THEN

See Also

  • Arithmetic Operators
  • NOT
  • Short-circuit evaluation

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201c6c
lea   ebx,[ebp-0xa4]
call   0x201bef
mov   eax,0xffffffff
mov   eax,0xffffffff
call   0x201b20


ISMISSING - ScharfBASIC Help

ISMISSING

Determine whether an optional parameter

Kind | Function
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ParamStatus = ISMISSING( ParamVar )

Description

The ISMISSING function may be used to test certain optional parameters to determine whether or not the parameter was actually passed by the calling code. It may be used to test ByVal/ByRef VARIANT parameters, or other variable types passed ByRef. An attempt to test a ByVAL parameter other than VARIANT will generate an error 579 (BYREF variable or BYVAL/BYREF variant expected) to be generated during compilation.

A ByRef parameter is considered to be missing when the pointer has the value zero. A variant parameter is considered to be missing when it has a type of %VT_ERROR and an error value of %DISP_E_PARAMNOTFOUND.

If the specified optional parameter is missing, the value true (-1) is returned. Otherwise, the value false (0) is returned.

Restrictions

The ISMISSING function may only be used within the procedure which uses the specified optional parameter.

See Also

  • DECLARE
  • FUNCTION
  • METHOD
  • PROPERTY
  • SUB


ISNOTHING - ScharfBASIC Help

ISNOTHING

Determine the current status of a given

Kind | Function
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

oStatus = ISNOTHING( objectvar )

Description

ISNOTHING is particularly useful in determining the success or failure of a LET statement. It returns TRUE (-1) if the object variable contains nothing, or FALSE (0) if it contains a valid current reference to an object interface.

ISNOTHING is the complement to the ISOBJECT function.

Restrictions

objectvar mu st be an Interface or IDispatch object variable.

See Also

  • DIM
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISOBJECT
  • LET (with Objects)
  • OBJECT
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

lea   ebx,[ebp-0xa8]
call   0x2021dd
call   0x203028


ISNOTNULL - ScharfBASIC Help

ISNOTNULL

Determine if a string

Kind | Function
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ResultVar& = ISNOTNULL( StrgExpr )

Description

The StrgExpr is examined to determine if it is null, or if it contains one or more characters. The value true (-1) is returned if the StrgExpr contains characters, or false (0) if it is null (zero-length).

The complementary function is ISNULL .

See Also

  • ISNULL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201c7c
call   0x201bff
mov   eax,0x1
call   0x201cf4
lea   ebx,[ebp-0xb8]
call   0x201bff
call   0x201b30


ISNULL - ScharfBASIC Help

ISNULL

Determine if a string

Kind | Function
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ResultVar& = ISNULL( StrgExpr )

Description

The StrgExpr is examined to determine whether it is null (has zero characters). The value true (-1) is returned if the StrgExpr is null, or false (0) if it contains characters.

The complementary function is ISNOTNULL .

See Also

  • ISNOTNULL


ISOBJECT - ScharfBASIC Help

ISOBJECT

Determine the current status of a given

Kind | Function
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

oStatus = ISOBJECT( objectvar )

Description

ISOBJECT is particularly useful in determining the success or failure of a LET (with Objects) statement. It returns TRUE (-1) if the object variable contains a valid current reference to an object interface, or FALSE (0) if it contains nothing.

ISOBJECT is the complement to the ISNOTHING function.

Restrictions

objectvar must be an interface or IDispatch object variable.

See Also

  • DIM
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISNOTHING
  • LET (with Objects)
  • OBJECT
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

lea   ebx,[ebp-0xa8]
call   0x2021d2
call   0x203028


MOD - ScharfBASIC Help

MOD

Return the remainder of the division between two numbers.

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

p MOD q

Description

The MOD operator divides the two operands, p and q , and returns the remainder of that division. The result of the initial division is truncated to an integral value, before the remainder is calculated. See the example below.

The remainder may be a floating point value. MOD is often considered to complement integral division.

See Also

  • LET

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x133f
sub   esp,0x70
push   0x201083
mov   esi,0x14
mov   edi,0x3
mov   DWORD PTR [ebp-0xa4],eax
mov   DWORD PTR [ebp-0x98],esi
mov   eax,DWORD PTR [ebp-0x98]
lea   esp,[ebp-0xc]


NOT - ScharfBASIC Help

NOT

The NOT operator works as a bitwise

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

NOT p

Description

ScharfBASIC's NOT operator returns the one's-complement of an integral expression. When dealing with the absolute values 0 and -1, the NOT operator "reverses" the two values, performing a Boolean-like operation.

ScharfBASIC accepts any non-zero value as a logical TRUE value; therefore, subtle logic problems can arise in a program when the NOT operator is used to perform Boolean logic tests with operand values that are not limited to just 0 and -1.

Consider the following two test conditions:

test1 = 0 ' test1 is FALSE (zero)

IF NOT test1 THEN ' TRUE (-1 is non-zero)

test2 = 1 ' test2 is TRUE (1 is non-zero)

IF NOT test2 THEN ' still TRUE (-2 is non-zero)

Because NOT performs a bitwise operation on test2 , it does not reverse the logical TRUE/FALSE value of test2 , rather, it returns -2 (the one's-complement of 1) and this is evaluated as a logical TRUE value.

In cases where a proper logical (Boolean) evaluation is required, and the operand may be a value other than 0 and -1, the ISFALSE operator should be used in place of the NOT operator:

test3 = 1 ' test3 is TRUE (non-zero)

IF ISFALSE test3 THEN ' ISFALSE detects test3 is

[ statements ] ' TRUE so the IF test fails

The two's-complement of a value can be obtained with the following algorithm:

y = (NOT x) + 1

Using NOT as a logical operator

NOT returns 0 (FALSE) if and only if its operand is exactly -1 (TRUE). Generally, you should use the ISFALSE operator instead of NOT, when you are testing for logical falsity.

Truth table

See Also

  • Arithmetic Operators
  • AND
  • EQV
  • IMP
  • ISFALSE
  • ISTRUE
  • OR
  • Short-circuit evaluation
  • XOR


Operator Precedence - ScharfBASIC Help

Operator Precedence

For example, the expression 3+6 / 3 evaluates to 5, not 3. Division has a higher priority than addition, so the division operation (6 / 3) is performed first. Even though the compiler will not get con

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

To handle operations of the same priority, ScharfBASIC proceeds from left to right. For example, in the expression 4 - 3 + 6, the subtraction (4 - 3) is performed before the addition (3 + 6), producing the intermediate expression 1 + 6.

Operations inside parentheses are of the highest priority and are always evaluated first. Within parentheses, standard precedence is used. Use parentheses like garlic: generously, but not to excess.

Another example of the effect of Order of Precedence on an expression follows:

At first glance, the result of 1 may be the expected result (since -1 * -1 = 1); however, the unary negation operator has a lower precedence than exponentiation, so the expression is evaluated as x& = -(1^2) which gives a result value of -1. As noted above, the use of parentheses can clarify the intended expression:


OR - ScharfBASIC Help

OR

The OR operator works as both a logical and a bitwise

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

p OR q

Description

Using OR as a logical operator

OR returns TRUE (non-zero) if and only if either or both of its operands is TRUE. Here is OR's truth table:

Truth table

x OR y

See Also

  • Arithmetic Operators
  • AND
  • EQV
  • IMP
  • ISFALSE
  • ISTRUE
  • LET
  • NOT
  • XOR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x1


Relational Operators - ScharfBASIC Help

Relational Operators

Relational operators allow you to compare the values of two expressions, to obtain a Boolean result of TRUE or FALSE . Although they can be used in any numeric expression (for example, a = (b > c) / 1

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Usage Examples

  1. a$ = "CAT"
  2. x1% = (a$ = "CAT") : x2% = (a$ = "CATS") : x3% = (a$ = "cat")
  3. city1$ = "Seattle"
  4. city2$ = "Tucson"
  5. IF UCASE$(city1$) > UCASE$(city2$) THEN
  6. city$ = city1$
  7. ELSE
  8. city$ = city2$
  9. END IF
  10. city1$ = UCASE$(city1$)
  11. city2$ = UCASE$(city2$)
  12. IF city1$ > city2$ THEN

Details

ScharfBASIC relational operators


XOR - ScharfBASIC Help

XOR

The XOR operator works as both a logical and a bitwise

Kind | Operator
Category | Operators
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

p XOR q

Description

XOR as a logical operator

XOR returns FALSE (zero) if and only if both its operands have the same value. Here is XOR's truth table:

Truth table

x XOR y

See Also

  • Arithmetic Operators
  • AND
  • EQV
  • IMP
  • NOT
  • OR

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0xff


#ALIGN - ScharfBASIC Help

#ALIGN

Align the next instruction to a boundary.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#ALIGN boundary

Description

The #ALIGN metastatement is primarily used by advanced assembler programmers to gain ultimate efficiency from critical code sections.

#ALIGN is used to round up the instruction location to a power of two address. The boundary parameter shown must be a power of two, in the range of 2 through 256.

ScharfBASIC inserts NOP instructions into the code section to bring the instruction location up to the desired address. If the instruction location is already at a multiple of boundary, #ALIGN has no effect.

See Also

  • #OPTIMIZE
  • ASM
  • ASM ALIGN
  • TIX


#BLOAT - ScharfBASIC Help

#BLOAT

Artificially inflate the disk image size of a compiled program.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#BLOAT size_expression

Description

#BLOAT allows the creation of artificially bloated program files on disk, in order to match or exceed that generated by competing " BloatWare " compilers. #BLOAT does not affect the memory image size (running size) of a compiled program.

size_expression

The size_expression parameter is a simple Long-integer expression that specifies the total desired size of the compiled programs disk image, but is ignored if it is smaller than the actual program size. #BLOAT uses sections of the actual compiled code to fill and obfuscate the portion added to the file.

While #BLOAT adds no true merit to the technical efficiency of the compiled code, there are a number of reasons for its use, including:

See Also

  • #COMPILE EXE
  • #OPTIMIZE


#COM - ScharfBASIC Help

#COM

Declare information to be included in a COM

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#COM CLASS ClassName [, ClassName ...]
#COM DOC "This is specific information to be used in the Help String"
#COM HELP "MyProg.chm"[, &H1E00]
#COM NAME "LibName", 3.32
#COM GUID GUID$("{20000000-2000-2000-2000000000000002}")
#COM TLIB {ON|+ | OFF|-}

Description

The #COM metastatement establishes information about the COM library or application which can be extracted by COM client programs.

#COM CLASS allows you to add the COM attribute to a class defined elsewhere. The COM attribute can even be added to a class in an SLL which was compiled separately. A class which is declared AS COM makes it available to external programs through the COM services of Windows. When you define a class as COM, it is automatically considered to be COMMON as well.

#COM DOC specifies a help string which usually provides a general description of the COM server.

#COM HELP specifies the name of the associated help file and the help context code. The name must appear as a string literal , while the context code is an unsigned DWORD value greater than zero. The context code may be specified in decimal or radix format.

#COM NAME specifies the name of the server and the version number. The name must consist of only letters, numbers, and underscore characters, and may contain no punctuation nor spaces. If no name is specified, ScharfBASIC substitutes the module name. If no version is specified, ScharfBASIC uses version number 0.0.

#COM GUID specifies the GUID which identifies the entire application or library (APPID or LIBID). If no GUID is specified, ScharfBASIC substitutes a random GUID for this purpose.

#COM TLIB ON specifies that the compiler should create a type library for the compiled EXE or DLL. The type library will be the same name and destination directory as the compiled EXE or DLL, with a .TLB extension.

#COM TLIB OFF (default) specifies that the compiler should not create a type library for the compiled EXE or DLL.

Type Libraries only support the following data types: BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , CURRENCY , OBJECT , STRING , and VARIANT . If any Methods or Properties use data types not supported by Type Libraries, you will receive a Error 581 - Type Library creation error , when using the #COM TLIB ON metastatement.

See Also

  • CLASS
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • Just what is COM?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

lea   ebx,[ebp-0xa8]
push   0x46000000
push   0xc0
mov   edx,0x204a54
call   0x203100
mov   eax,0x1
call   0x201bc8
call   0x203048


#COMPILE - ScharfBASIC Help

#COMPILE

Determine what type of file will be created by the compiler.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#COMPILE {EXE | DLL | SLL} [" filename { .exe | .dll|.sll }"]

Description

This metastatement is used to specify whether a module is to be compiled as an EXE, DLL , or SLL file. The #COMPILE metastatement can only be used once per program, and must be placed before any executable code.

You may, optionally, specify the target name and path of the file. If the optional equal sign (=) is included, the name given is considered to be an exact name, and nothing is appended or changed. Otherwise, the file type is forced to be EXE, DLL, or SLL by the compiler.

If the filename clause is omitted, the compiled file is given the name of the main source code file with an appropriate extension.

If a path is included, the compiled file is placed in the named directory; otherwise, it is placed in the current directory.

If the named directory does not exist, the filename is invalid or locked, if the EXE is still running, or if the file cannot be successfully stored in that location for some other reason, a compile-time Error 496 ("Destination file write error") occurs.

A related item is the built-in numeric equate %PB_COMPILETIME . Each time you compile your program, this equate is filled with the current date and time of the compilation in PowerTime binary format. You can use the PowerTIME Class to convert it to a text equivalent for use in your application.

Restrictions

If #COMPILE is not specified, the default is #COMPILE EXE.

Examples

#COMPILE EXE ' Same name as source, i.e., ABC.EXE

#COMPILE DLL ' Same name as source, i.e., ABC.DLL

#COMPILE SLL "ABC" ' Compiles to ABC.SLL

#COMPILE EXE "ABC.BAS" ' Compiles to ABC.BAS.EXE

See Also

  • %PB_COMPILETIME
  • #COMPILER
  • DLLMAIN
  • LIBMAIN
  • PBLIBMAIN
  • PBMAIN
  • WINMAIN


#DEBUG CODE - ScharfBASIC Help

#DEBUG CODE

Compiler directive to suppress generation of debugging code.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#DEBUG CODE {ON|+ | OFF|-}

Description

When a program is compiled for debugging in the ScharfBASIC IDE, the compiler must generate some additional code to facilitate setting of breakpoints and some other debug operations. In most cases, this does not affect the execution of your program. However, in the case of code repetition in a tight loop , or for certain assembler code or data which must not be altered, it may be very important that some debugging code be suppressed so that code will execute correctly, and at full speed.

#DEBUG CODE OFF suppresses generation of debug code, from that line, until a subsequent #DEBUG CODE ON (or the end of the Sub / Function / Method / Property ) is reached. Of course, when debug code is suppressed, it is not possible to set breakpoints on those lines.

#DEBUG CODE metastatements are ignored if not compiling for debug.

See Also

  • Error Trapping
  • Errors
  • Debugging
  • #DEBUG DISPLAY
  • #DEBUG ERROR
  • #DEBUG PRINT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   esi,0x2a


#DEBUG DISPLAY - ScharfBASIC Help

#DEBUG DISPLAY

Display a message when an untrapped run-time error occurs.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#DEBUG DISPLAY {ON|+ | OFF|-}

Description

#DEBUG DISPLAY ON enables error display mode within a compiled ScharfBASIC program. In this mode, whenever an untrapped error occurs (without the benefit of ON ERROR GOTO , TRY/CATCH , etc.), program execution is suspended, and a descriptive message is displayed. This message includes the error number, a brief description of the error, and a position descriptor word to help you find the location of the error. The position descriptor word is the first 8 characters of the name of the last (most recent) label, line number, or procedure that was executed. This mode should only be used during program development and debugging. It should never be used in a production program.

When the descriptive message is displayed, it is accompanied by two buttons marked "OK" and "Cancel". If "OK" is selected, program execution continues despite the error condition. If "Cancel" is selected, program execution is stopped. However, if any child processes were started, it is possible they will continue running until ended normally.

#DEBUG DISPLAY OFF suppresses display mode, and is the default condition.

Restrictions

#DEBUG DISPLAY ON|OFF can only be executed once and must precede all executable code. If #DEBUG DISPLAY is omitted, the default condition is #DEBUG DISPLAY OFF.

See Also

  • Error Trapping
  • Errors
  • Debugging
  • #DEBUG CODE
  • #DEBUG ERROR
  • #DEBUG PRINT


#DEBUG ERROR - ScharfBASIC Help

#DEBUG ERROR

Control generation of

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#DEBUG ERROR {ON|+ | OFF|-}

Description

#DEBUG ERROR option specifies whether the compiler should generate code that checks for array boundary and null- pointer errors wherever they may occur. The default setting is OFF.

When #DEBUG ERROR mode is ON, any attempt to access an array outside of its boundaries, or attempting to use a null-pointer will generate a run-time Error 9 ("Subscript/Pointer out of range"), and the statement itself is not executed.

When OFF, all statements are executed "as-is" and no errors are generated. However, accessing an array outside its boundaries or using a null-pointer can cause a General Protection Fault (GPF) or Exception error.

It is best to enable #DEBUG ERROR error checking when developing a program. Once all of the more obvious bugs have been eradicated, you will want to return to the default setting (OFF), as this will make your code smaller and faster. Depending on the type of application being developed, the final (production) version of a program may not need to contain any error-checking code.

Restrictions

#DEBUG ERROR is always enabled when code is running within the Debugger, regardless of any explicit #DEBUG ERROR metastatement.

Disk I/O errors are always caught, regardless of the state of #DEBUG ERROR.

#DEBUG ERROR ON does not trap array boundary errors of arrays within User-Defined Types and Unions . Pointers are only tested for null (zero) values. Non-zero pointer target addresses are not tested for readability or writeability.

See Also

  • Error Trapping
  • Errors
  • Debugging
  • #DEBUG CODE
  • #DEBUG DISPLAY
  • #DEBUG PRINT


#DEBUG PRINT - ScharfBASIC Help

#DEBUG PRINT

Display information in the

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#DEBUG PRINT string_expression

Description

The PRINT option allows the programmer to display arbitrary information in the IDE's Debug Output Window during a debugging session. The output window is provided by debugger to display status information about the state of the debugging session; however, #DEBUG PRINT provides a convenient way of creating a "process log" of a Sub / Function / Method / Property / Variable as the program runs. Combined with FUNCNAME$ , #DEBUG PRINT can be a useful tool for debugging application code. See the Example below.

This is possible because the Debugger Output Window has a scrollable range somewhat like a console window, whereas the Watch Window shows only the instantaneous value of a variable .

#DEBUG PRINT statements are ignored when code is compiled into a standalone (EXE/ DLL ) file; they are only included when using the Debugger. Control codes in the string are translated into hex format in the output window. For example, embedded CHR$ (0) or $NUL bytes are displayed as "<00>".

Restrictions

You may use Unicode strings with #DEBUG PRINT, but the results will always be converted to ANSI by Windows. This is a Windows design limitation, not a limitation of ScharfBASIC.

See Also

  • Debugging
  • #DEBUG ERROR
  • FUNCNAME$


#EXPORT - ScharfBASIC Help

#EXPORT

Declare a Sub/Function to have the EXPORT attribute.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#EXPORT SubFuncName [, SubFuncName ...]

Description

#EXPORT allows you to add the EXPORT attribute to a Sub / Function defined elsewhere. The EXPORT attribute can even be added to a Sub/Function in an SLL which was compiled separately.

The EXPORT descriptor identifies a Sub/Function which may be accessed between Dynamic Link Libraries ( DLLs ), and/or the main executable which links them. If a procedure is not marked EXPORT, it is hidden from these other modules. Generally speaking, it's best not to mark a Sub/Function in an SLL as EXPORT. While it is syntactically acceptable, it may limit your future options when linking the SLL into host modules. ScharfBASIC recommends that you mark them as COMMON in the SLL, and add the EXPORT attribute in the host module.

It's easy to create an SLL which can be linked into an executable program or a dedicated DLL for the same purpose. To add the EXPORT attribute to a linked Sub/Function, just add the word EXPORT to the DECLARE statement in the host module or add an #EXPORT metastatement.

Using this technique, your SLL can be linked directly into an application executable without publishing the Subs/Functions as EXPORT. However, you can also link the same SLL into a DLL host module which adds the EXPORT attribute with #EXPORT.

For example, let's say you want to make a library which publishes the SUB named XXX. You want to provide it in two forms, a linkable SLL and an industry standard DLL. So, first just create the SLL:

#COMPILE SLL = "XXXLib.SLL"

SUB xxx() COMMON

MSGBOX "Hello"

END SUB

Just compile it, and you're ready to link it into your application. But now you want to create a DLL, too, since it might be used with other applications. It's just this easy:

#COMPILE DLL = "XXXLib.DLL"

#EXPORT xxx

#LINK "XXXLib.SLL"

That's all there is to it. You now have an SLL and an equivalent DLL to do the job of the XXX procedure.

See Also

  • #LINK
  • DECLARE


#IF - ScharfBASIC Help

#IF

Define sections of source code to be compiled or ignored, depending on a certain condition. This is often referred to as conditional compilation.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#IF [NOT] { %equate | %DEF({ %numeric_equate | $string_equate }) | expression }
[ statements ]
[#ELSEIF [NOT] { %equate | %DEF({ %numeric_equate | $string_equate }) | expression }
[ statements ]]
[#ELSE
#ENDIF

Description

%equate is a named constant or constant value. The %DEF operator allows you to test whether an equate has been defined. %DEF returns TRUE or FALSE . Typical usage: #IF %DEF(%PB_DLL16) or #ELSEIF NOT %DEF(%PB_WIN32). expression may be a simple numeric expression using the arithmetic operators +, -, *, /, and \, and the relational operators >, <, >=, <=, <>, and =, and may also include the CVQ function.

ScharfBASIC automatically defines the equates in the following table according to the ScharfBASIC compiler being used. Please note the references to other ScharfBASIC compilers are included for those writing programs that may be compilable by more than one ScharfBASIC compiler.

Equate

Definition

%PB_CC32

Pre-defined as TRUE (non-zero) in PB/CC for Windows, but is not defined in other compilers.

%PB_DLL16

Pre-defined as TRUE (non-zero) in PB/DLL 16-bit, FALSE (zero) in other compilers.

%PB_DLL32

Synonym of %PB_WIN32

%PB_WIN32

Pre-defined as TRUE (non-zero) in PB/Win 32-bit, but is not defined in other compilers.

%PB_REVISION

Pre-defined as the hex revision (10.00 = &H1000).

%PB_REVLETTER

Pre-defined as the ASCII code of the revision letter (a = &H61), or &H20 if there is no revision letter.

%PB_EXE

Pre-defined as TRUE (non-zero) if compiling to EXE or as FALSE (zero) if compiling to DLL format (PB/Win only). The equate %PB_EXE is always defined in ScharfBASIC, so %DEF(%PB_EXE) will always be evaluated as TRUE. The difference being the value assigned to the equate by the compiler.

Examples of valid expressions can include:

#IF %DEBUG = -1&

#IF %DEBUG AND (NOT %RELEASE)

#IF NOT %DEBUG

#IF %VERSION <> CVQ("DemoMode")

Note that the AND , OR and NOT operators work as bitwise operators, rather than logical operators, in #IF metastatements.

If the value of %equate or if %DEF ( %equate|$equate ) is TRUE (non-zero) or if the result of expression is TRUE, the statements between #IF and #ELSE or #ELSEIF are compiled, and the statements between #ELSE or #ELSEIF and #ENDIF are ignored.

If the value of %equate or %DEF ( %equate|$equate ) is FALSE (zero) or the result of expression is FALSE, the statements between #IF and #ELSE or #ELSEIF are ignored, and those between #ELSE or #ELSEIF and #ENDIF are compiled.

The #ELSE or #ELSEIF clause and associated statements are optional, but #ENDIF is required.

Conditional compilation statements can be nested up to 16 levels deep. A primary use of conditional compilation is to include test code in your programs that will be compiled during program development (but not in the final product), and to facilitate building special editions of an application from a single source code file.

It is possible to perform bitwise operations on equates to produce a TRUE/FALSE result. For example:

#IF (%PB_REVISION AND &H0FF00) - &H0700

SoftwareVersion$ = "not 7.x"

SoftwareVersion$ = "7.x"

#ENDIF

See Also

  • %DEF operator
  • IF statement
  • IF block


#INCLUDE - ScharfBASIC Help

#INCLUDE

Instruct the compiler to read a text file from disk and treat it as an integral part of the source code.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#INCLUDE "FileSpec"
#INCLUDE ONCE "FileSpec"
#INCLUDE THIS ONCE

Description

Use #INCLUDE to compile the text of another file along with the current file. The first form causes FileSpec to be included in every case it is encountered. The second form causes FileSpec to be included only once, the first time it is encountered. This is particularly useful when including common declaration files like WIN32API.INC to avoid redundant code, and the resulting errors. To be effective, the ONCE option must appear on every #INCLUDE of a particular file. Effectively, #INCLUDE ONCE means: "Include this file only if it has not already been included."

The third form (#INCLUDE THIS ONCE) is placed in the file to be included, and produces an end result similar to form two. It tells the compiler to "Include me only one time, no matter how many times it is requested". Depending upon the content and context, this may be a simpler and more readable method to achieve the desired result.

FileSpec is a string constant that follows normal LFN file-naming conventions, and which names a ScharfBASIC source code file. If FileSpec does not include an extension, the compiler looks for that file name with the default extension of .BAS.

If FileSpec does not include a path, the compiler scans the search path for each #INCLUDE file before checking the current (default) directory. For the IDE, the search path can be set in the Compiler Preferences tab in the Options dialog . The search path can also be specified when compiling from the command-line by using the /I Include option. The search path can contain one path or multiple paths to scan. If multiple paths are used, they are separated by a semicolon (;).

When the compiler encounters an #INCLUDE metastatement, it reads FileSpec from disk and continues compilation with the source code in FileSpec . When the end of FileSpec is reached, compilation continues with the statement immediately following the #INCLUDE in the original source file. The result is the same as if the contents of the included file were physically present within the original text. This allows large source files to be broken into smaller sections that are more manageable.

#INCLUDE metastatements can be nested as many as twelve levels deep. That is, an included file can have #INCLUDE metastatements of its own, including files that also have #INCLUDE metastatements, and so on, for a total of twelve levels of files (including the primary file). Note that macros count as #include files for nesting purposes.

See Also

  • WIN32API.INC Updates


#LINK - ScharfBASIC Help

#LINK

LINK a pre-compiled

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#LINK " filespec.SLL "
#LINK " filespec.PBLIB "

Description

The #LINK metastatement is used to link pre-compiled Unit files (SLL or PBLIB) into your primary host program. The host program must compile to an EXE or DLL module. You cannot link a unit file into another unit file.

If a specified SLL unit file (or a component SLL in a PBLIB) is not needed by other compiled code, it is ignored entirely. This allows the host program to be compiled to the smallest possible size.

The filespec may include an optional path name, and must include the extension ".SLL" or ".PBLIB". The #LINK metastatement may be placed at any location in your source file, as long as it is outside of any block structure, such as Sub , Function , Method , Class , etc.

#LINK shares the file search path with #INCLUDE . If filespec does not include a path, the compiler scans the search path for each #LINK file before checking the current (default) directory. For the IDE, the search path can be set in the Compiler Preferences tab in the Options dialog. The search path can also be specified when compiling from the command-line by using the /I Include option. The search path can contain one path or multiple paths to scan. If multiple paths are used, they are separated by a semicolon (;).

See Also

  • #COMPILE
  • #EXPORT


#MESSAGES - ScharfBASIC Help

#MESSAGES

Specify which messages should be sent to a Control Callback Function.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#MESSAGES COMMAND
#MESSAGES NOTIFY

Description

#MESSAGES COMMAND specifies that only %WM_COMMAND messages be sent to Control Callback Functions, just as in earlier versions of ScharfBASIC

#MESSAGES NOTIFY specifies that %WM_NOTIFY messages (as well as %WM_COMMAND messages) be sent to Control Callback Functions. This is the default condition, and need not be explicitly stated.

There are two general types of CallBack Functions. The first is the DIALOG CALLBACK , which is specified with the CALL DLGPROC clause of the DIALOG SHOW statement. It receives all messages which are directed to the dialog , including certain messages regarding its child controls. Specifically, this would include both %WM_COMMAND and %WM_NOTIFY messages. The second is the CONTROL CALLBACK, which is specified with the CALL CTLPROC clause of the CONTROL ADD statement. If specified, it receives all %WM_COMMAND and %WM_NOTIFY messages sent to the parent dialog.

Prior to version 9.0 of ScharfBASIC for Windows, Control Callback Functions received only %WM_COMMAND messages. Beginning with PB 9.0, %WM_NOTIFY messages are sent as well. There are many situations where these added messages will prove to be very important to you. If your existing callback functions are written with complete error checking (ensuring that CB.MSG = %WM_COMMAND), this minor addition will cause no problems. It just presents additional information which can be acted upon, or just ignored. However, if callbacks were written without complete error checking, some ambiguity is possible. In this case, you should either update your Control Callback code, or suppress %WM_NOTIFY messages with a #MESSAGES Command metastatement.

See Also

  • Callbacks
  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • FUNCTION/END FUNCTION


#OPTIMIZE - ScharfBASIC Help

#OPTIMIZE

Choose the optimization which should be applied to your program.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#OPTIMIZE CODE [ON | OFF]
#OPTIMIZE {SIZE | SPEED}

Description

The #OPTIMIZE metastatement is used to tell the compiler your preferences in regards to the optimization of generated code. You can specify optimization for either execution speed or smaller code size.

The first form of the directive (CODE) tells the compiler whether unreferenced code should be removed from the compiled program to minimize the executable file size. This option defaults to ON as there are few reasons to disable it (other than curiosity as to the effectiveness). Regardless of the compiled module type ( SLL , DLL , or EXE), ScharfBASIC removes every unneeded:

Function

FastProc

Method

Property

String Literal

Numeric Literal

Static Link Library

Extraction is always performed on a procedure basis, not an entire class. If you have a CLASS with 50 Methods, but only one is ever called, the other 49 are removed entirely. This level of granularity is particularly important with your personal code library of general purpose functions. You can include them all, and ScharfBASIC will use just the minimum necessary. If you generate a log file (using the /L command line option), a list of the extracted procedures, classes, and SLL modules is provided.

The second form of the directive (SIZE/SPEED) tells the compiler whether you want additional optimization for execution speed or smaller total code size. If not used, the default is to choose faster code speed.

If you choose the SPEED option, one of the primary actions of the compiler is to align heavily used code sections on an address boundary which is most beneficial to the CPU/FPU.

In some cases, the speed of loop mechanisms ( FOR/NEXT , DO/UNTIL ...) can be improved by as much as 100%, and occasionally even more.

Restrictions

#OPTIMIZE SIZE | SPEED can only be executed once and must precede all executable code. If #OPTIMIZE is omitted, the default condition is #OPTIMIZE SPEED.

See Also

  • #ALIGN
  • ASM ALIGN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   esi,0x2a
mov   eax,0x2


#OPTION - ScharfBASIC Help

#OPTION

Establish various compiler options.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#OPTION {LARGEMEM32 | VERSION3 | VERSION4 | VERSION5 | WIN95 | ANSIAPI}

Description

#OPTION LARGEMEM32

For 32-bit Windows applications, this option sets the "Large Memory Model" flag. This allows your application to use more than the original limit of 2 Gigabytes of memory. Depending upon the version of Windows in use, and the installed memory, the exact increase may vary from computer to computer. In most cases, you will likely be limited to a total of approximately 3 Gigabytes.

#OPTION VERSION3, VERSION4, VERSION5

When the #OPTION metastatement is used with any one of the VERSION directives, it controls the "minimum Windows version" tag that is written into your compiled code. If the version you select is equal or lower to the version of Windows that is running, the application will be executed. In turn, Windows will tailor the messages it sends to your program according to this version number, so your program will not need to handle messages from a later Windows version. The version tag may also affect the appearance and behavior of Windows common dialogs.

Conversely, if the version tag you select is higher than the version of Windows that is running, Windows will display an error message instead of running your application. For example, running a VERSION5 application on a VERSION4 platform would fail. It is your responsibility to make sure that your program only uses the Windows features that are present in the specified version of Windows. For example, don't call an API that's present only in Windows XP, if you want your program to run under Windows 98.

#OPTION VERSION3

Use #OPTION VERSION3 to make the compiled output file require a minimum of Windows 95 or NT 3.1. That includes Windows 95, 98, ME, Windows NT 3.1-4.0, Windows 2000, XP, Windows 2003, Windows Vista, Windows 7, and later.

#OPTION VERSION4

Use #OPTION VERSION4 (default) to make the compiled output file require a minimum of Windows 95 or NT4. That includes Windows 95, 98, ME, Windows NT 4.0, Windows 2000, XP, Windows 2003, Windows Vista, Windows 7, and later.

#OPTION VERSION5

Use #OPTION VERSION5 to make the compiled output file require a minimum of Windows 2000. That includes Windows 2000, XP, Windows 2003, Windows Vista, Windows 7, and later.

#OPTION WIN95

Windows95, Windows98, and Windows ME do not offer Unicode support for Windows API functions. Normally, that would make it possible to execute your compiled programs on these operating systems, as this version of ScharfBASIC offers complete support for Wide Unicode text. However, if you specify #OPTION WIN95 in your source code, ScharfBASIC will include a complete Unicode emulation package in your executable or DLL to allow them to run properly on these operating systems, This option will cause your code to be a bit larger, so it should only be used where necessary.

#OPTION ANSIAPI

This version of ScharfBASIC offers complete support for Wide Unicode text, so it follows that the internal runtime library would call Unicode versions of functions in the Windows API. In some fairly rare cases, this could cause an incompatibility with code you have written, if your code calls ANSI functions in the Windows API. If you specify #OPTION ANSIAPI in your source code, ScharfBASIC will call only ANSI versions of these functions. This option will cause your code to be a bit larger, so it should only be used when needed.


#PAGE - ScharfBASIC Help

#PAGE

Sets a page boundary for the ScharfBASIC

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#PAGE
Back to command index


#PBFORMS - ScharfBASIC Help

#PBFORMS

Compiler directive to mark named blocks of generated

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

#PBFORMS metastatements are generated by the ScharfBASIC Forms? visual design tool, and placed automatically into the generated source code. #PBFORMS metastatements identify named blocks of code that have special meaning to both the compiler and the ScharfBASIC Forms? visual design tool.

#PBFORMS metastatements should not be removed or utilized - they should only be created and positioned by ScharfBASIC Forms? . For more information, please refer to the documentation supplied with ScharfBASIC Forms? .

ScharfBASIC Forms? is a visual design environment that enables rapid visual design of GUI application dialogs. ScharfBASIC Forms generates compilable Dynamic Dialog Tools ( DDT ) source code, directly from the dialogs created in the designer. ScharfBASIC Forms product information can be found at http://www.scharfbasic.com/products/pbforms .

An example ScharfBASIC Forms? template and completed project can be found in the PB\SAMPLES\DDT\INTERFACE EXPLORER folder installed with ScharfBASIC for Windows.


#RESOURCE - ScharfBASIC Help

#RESOURCE

Embed a ScharfBASIC

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#RESOURCE BITMAP, ResID , " filespec.BMP "
#RESOURCE ICON, ResID , " filespec.ICO "
#RESOURCE MANIFEST, 1, "filespec.XML"
#RESOURCE RCDATA, ResID, " filespec.DAT "
#RESOURCE STRING, ResID, " YourWideText "$$ [, LangID ]
#RESOURCE TYPELIB, 1, " filespec.TLB "
#RESOURCE WAVE, ResID , " filespec.WAV "
#RESOURCE VERSIONINFO <>
#RESOURCE RES, " filespec.RES "
#RESOURCE PBR, " filespec.PBR "

Description

This metastatement is used to include ScharfBASIC Resource data into your program or DLL. Resource data may consist of bitmaps , icons , strings , COM Type Libraries , Version Information, and more. You can even embed custom binary data for your personal, specialized needs.

Resource data can be a very valuable tool. While you can certainly load bitmaps and icons from separate files, wouldn't it be better to just embed them in your application? When you need the bitmap, it's always right there for your use! You don't have to deal with scads of files. Now it's all at your fingertips.

The parameter ResID is a unique identifier which you create to reference this item. It can be a numeric or an alphanumeric literal. If numeric, it must be an integral value from 0 to 65535. If alphanumeric, it must begin with a letter, and consist of letters and numbers. Alphanumeric labels are not case sensitive. The filespec parameter must always be expressed as a string literal which tells the location of the resource data.

If a resource file's path is not specified, then the compiler will look in the default directory.

With most programming languages, creation and embedding of resource data is a cumbersome process. First you create a resource script (an .RC file) with a text editor. Then you save the .RC file. Now, compile the .RC file with a resource compiler to get a .RES file. Next, you convert it to a linkable file using Microsoft's CVTRES.EXE or another converter program like PBRES.EXE. Finally, you link it into your .EXE or .DLL with a compiler or linker program. What if you find you need to make a tiny change? Do it all over again, from the beginning. Even older versions of ScharfBASIC suffered from this problem.

Isn't there a better way? Yes, ScharfBASIC now handles the entire process in a single line of code. Need an embedded bitmap?

#RESOURCE BITMAP, 123, "MyPicture.BMP"

ScharfBASIC finds your bitmap in the file MyPicture.BMP and embeds it in your executable. When you need to use it, you can reference it by the ID you chose for it (123). The ID can be an integral numeric value or a text name of your choice. So, to display the bitmap on a graphic window , it's as simple as:

GRAPHIC RENDER "#123", (100,100)-(160,140)

String Resources

The String resource contains string data which is always created and stored as Wide Unicode characters. It is retrieved at run-time with the RESOURCE$ function. Due to the manner in which Windows stores string resources in a string table, the ResID must be numeric.

The string data must be from 1 to 127 characters in length, and may not contain any embedded nuls ( CHR$ (0)). The string data may be specified as a quoted wide string literal ("MyText"$$), or as a wide string literal expression. A string literal expression can be constructed from combinations of wide string equates or wide quoted string literals, the CHR$ function, SPACE$ function, and the STRING$ function when used with numeric parameters.

VersionInfo Resources

The VersionInfo resource contains information about the file, such as its version number, its intended operating system, its original file name, and much more. This resource is intended to be used with the Version Information API functions, so that Windows Explorer, and other programs, can display the relevant information about your EXE. The VersionInfo resource cannot be embedded in a Static Link Library (SLL).

The VersionInfo resource is unique in that it requires several #RESOURCE metastatements which are interpreted as a complete block. They must be placed consecutively in the correct sequence in order be processed correctly.

#RESOURCE VERSIONINFO

#RESOURCE FILEFLAGS FlagValue&

#RESOURCE FILEVERSION HiNum1& , LoNum1& , HiNum2& , LoNum2&

#RESOURCE PRODUCTVERSION HiNum1& , LoNum1& , HiNum2& , LoNum2&

#RESOURCE STRINGINFO " LangID ", " CharSet "

#RESOURCE VERSION$ " Comments ", " Additional info "

#RESOURCE VERSION$ " CompanyName ", " ScharfBASIC Inc. "

#RESOURCE VERSION$ " FileDescription ", " Presented to users "

#RESOURCE VERSION$ " FileVersion ", " Readable VerNum 1.02 "

#RESOURCE VERSION$ " InternalName ", " Private "

#RESOURCE VERSION$ " LegalCopyright ", " Copyright 2012 PB Inc "

#RESOURCE VERSION$ " LegalTrademarks ", " xx is a... "

#RESOURCE VERSION$ " OriginalFilename ", " Original name w/o path "

#RESOURCE VERSION$ " PrivateBuild ", " Private info "

#RESOURCE VERSION$ " ProductName ", " Product distributed with "

#RESOURCE VERSION$ " ProductVersion ", " Version distributed with "

#RESOURCE VERSION$ " SpecialBuild ", " Special info "

FILEFLAGS

FlagValue&

Description

%VS_FF_DEBUG

File contains debugging information or is compiled with debugging features enabled.

%VS_FF_PATCHED

File has been modified and is not identical to the original shipping file of the same version number.

%VS_FF_PRERELEASE

File is a development version, not a commercially released product.

%VS_FF_PRIVATEBUILD

File was not built using standard release procedures. If this value is given, you must include a PrivateBuild string item.

%VS_FF_SPECIALBUILD

File was built by the original company using standard release procedures, but is a variation of the standard file of the same version number. If this value is given, you must include a SpecialBuild string item.

STRINGINFO

LangID

Language

LangID

Language

&H0401

Arabic

&H0415

Polish

&H0402

Bulgarian

&H0416

Portuguese (Brazil)

&H0403

Catalan

&H0417

Rhaeto-Romanic

&H0404

Traditional Chinese

&H0418

Romanian

&H0405

&H0419

Russian

&H0406

Danish

&H041A

Croato-Serbian (Latin)

&H0407

German

&H041B

Slovak

&H0408

&H041C

Albanian

&H0409

U.S. English

&H041D

Swedish

&H040A

Castilian Spanish

&H041E

&H040B

Finnish

&H041F

Turkish

&H040C

French

&H0420

&H040D

Hebrew

&H0421

Bahasa

&H040E

Hungarian

&H0804

Simplified Chinese

&H040F

Icelandic

&H0807

Swiss German

&H0410

Italian

&H0809

U.K. English

&H0411

Japanese

&H080A

Spanish (Mexico)

&H0412

Korean

&H080C

Belgian French

&H0413

&H0816

Portuguese (Portugal)

&H0414

Norwegian - Bokmal

&H081A

Serbo-Croatian (Cyrillic)

&H0810

Swiss Italian

&H0C0C

Canadian French

&H0813

Belgian Dutch

&H100C

Swiss French

&H0814

Norwegian - Nynorsk

STRINGINFO

CharSet

Character Set

&H0000

7-bit ASCII

&H03A4

Japan (Shift - JIS X-0208)

&H03B5

Korea (Shift - KSC 5601)

&H03B6

Taiwan (Big5)

&H04B0

Unicode

&H04E2

Latin-2 (Eastern European)

&H04E3

Cyrillic

&H04E4

Multilingual

&H04E5

&H04E6

Turkish

&H04E7

Hebrew

&H04E8

Arabic

RES/PBR Resources

The second group of syntax examples show how you can embed resources which have been pre-compiled used a resource compiler. Standard resource compilers output a binary resource with a .RES extension. ScharfBASIC will embed this resource just as it is given in the file. This form will always be supported to support resource forms which are typically not needed for most ScharfBASIC programs, or which usually require the use of a resource editor.

The final example, using a .PBR file, will only be supported for a limited period of time. This is the form created by the ScharfBASIC PBRES utility in older versions of the compiler. It is recommended that you change to the .RES version soon, as it is more efficient, and needs less effort from the programmer. It should be noted that prior versions of ScharfBASIC allowed the descriptor "PBR" to be omitted. While this option will be supported for a limited period of time, we recommend that you always insert "PBR" for clarity.

Restrictions

Windows 95, 98, and ME offer limited support for resources. When compiling on one of these versions of Windows, only #RESOURCE RES and #RESOURCE PBR may be used. Other forms of the #RESOURCE metastatement are not functional.

RES and PBR resources cannot be mixed with any other resources. Once you add a PBR or RES resource, you cannot add any other #RESOURCE metastatements in your program.

See Also

  • RESOURCE$
  • Resource Files


#TOOLS - ScharfBASIC Help

#TOOLS

Enable or disable integrated development tool code in compiled code.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#TOOLS [ON|+ | OFF|-]

Description

The #TOOLS metastatement allows integrated development tools like TRACE , PROFILE , and CALLSTK to be readily disabled, ensuring that extra code and data is not compiled into the final (distribution) version of an application. #TOOLS defaults to ON, and may appear only once in the source code, before any statement that generates executable code.

See Also

  • CALLSTK
  • CALLSTK$
  • CALLSTKCOUNT
  • FUNCNAME$
  • PROFILE
  • TRACE


#UNIQUE - ScharfBASIC Help

#UNIQUE

Specify whether unique

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#UNIQUE VAR [ON|OFF]

Description

By default (#UNIQUE VAR OFF), it is possible to use the same name for more than one variable in your program. For example, you might use abc%, abc#, and abc$ in the same function using default typing defined by the Type ID character. You could even create a local variable named "counters" and a global variable also named "counters".

So, when you reference a variable name in your program, which variable is actually used? Depending upon location of the reference, the compiler chooses the variable with the smallest scope. The precedence of variable scopes is:

1- Local or Static

2- Instance

3- Global or Threaded

When #UNIQUE VAR is OFF, ScharfBASIC first tries to find a LOCAL or STATIC . Next, an INSTANCE , and finally a GLOBAL or THREADED . It selects the first one it finds, in that sequence. Of course, you cannot use the same name for a LOCAL and a STATIC, unless you use a Type ID character to differentiate them. You can never use the same name for a GLOBAL and a THREADED, as it would be impossible to tell them apart. While this offers the most flexibility, it can be confusing, and can lead to the creation of insidious, hard-to-find errors in your program. When you reference the wrong variable by accident, the results can be disastrous. If #UNIQUE VAR is enabled, ScharfBASIC will require that all variable names be unique. The can make your job a good deal easier, as it removes the ambiguity found with identifier reuse. There are a few exceptions to the uniqueness rule, which are designed to improve readability in your code:

1- Local, Static, and Parameter names may be reused in other Subs, Functions, and Methods.

2- Instance names may reused in other Classes.

3- Scalar and array names may co-exist if they they are the same data type and scope.

See Also

  • #DIM
  • DEFtype
  • DIM
  • GLOBAL
  • LOCAL
  • REDIM
  • STATIC
  • OPTION EXPLICIT


#UTILITY - ScharfBASIC Help

#UTILITY

Compiler directive to allow external utility programs to read text inserted on the #UTILITY line.

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

#UTILITY "any text for an external program"


Metastatements - ScharfBASIC Help

Metastatements

The following functions control compiler and debugger behavior:

Kind | Directive
Category | Preprocessor
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Align the next instruction to a boundary.

Determine if an equate has been previously defined.

Specifies a help string which usually provides a general description of the COM server.

Specifies the name of the associated help file and the help context code.


CALL - ScharfBASIC Help

CALL

Invoke a procedure (

Kind | Statement
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CALL ProcName [([ arguments ])] [TO result_var ]

Description

The CALL statement has the following parts:

ProcName

The name of a Sub, Function, Method, Property, or FastProc defined elsewhere in the program.

arguments

An optional, comma-delimited list of variables , expressions, and constants to be passed to the procedure as parameters, for up to 32 parameters. If the CALL keyword is used, the arguments must be enclosed in parentheses.

You can omit the CALL keyword. If you do so, you may also omit the parentheses surrounding arguments. For example, the following lines are equivalent:

CALL MyProc(parm1, parm2)

MyProc(parm1, Parm2)

MyProc parm1, parm2

However, if the first parameter argument is enclosed in parentheses for any reason, the entire parameter list must be enclosed in parentheses. For example:

MyProc (3+z, b) ' Valid syntax

MyProc ((3+z), b) ' Valid syntax

MyProc (3+z), b ' Invalid syntax

This updated syntax now permits macros to be called using the SUB-style convention if/when the macros expand directly to Function calls. For example:

MACRO sm(Msg) = SendMessage(a, Msg, b, c)

can be called like this (when the return value is not required):

In all cases, the number and type of parameters passed must agree with the arguments in procedure definition.

V ariant Arguments

Y ou can think of a Variant as a kind of container, which can hold a variable of most any data type. If you call a procedure which requires a variant for one or more of its arguments, ScharfBASIC will automatically convert a standard data type into a variant data type.

While a variant may not normally contain a UDT , ScharfBASIC offers a special methodology to do so. At programmer direction, a TYPE may be assigned to a variant (as a byte string ) by using:

[LET] VrntVar = TypeVar AS STRING

In the same manner, a UDT argument can be auto-converted to the variant type by appending AS STRING:

CALL ProcName(UDTVar AS STRING)

The data contained in the User-Defined Type variable (UDT) is stored in the variant argument as a dynamic string of bytes (vt_bstr). When you retrieve that UDT data (with Variant$ ), ScharfBASIC understands the content and handles it accurately. However, other programming languages may not understand this technique, so it should be limited to ScharfBASIC applications. This methodology is implemented in all of the ScharfBASIC COLLECTION objects as it greatly enhances ease of coding and performance of the final executable.

Passing Parameters

In a procedure definition, every parameter is described by the data type, and the format used to pass it. The type may be any normal variable type, such as long, string, User-Defined Type, etc. The passing format describes how the value is presented to the procedure: by reference (BYREF), by value (BYVAL), or by reference to a copy (BYCOPY).

When a parameter is passed by reference, it consists of a 4-byte address of the data. In this case, the original data can be modified by the procedure.

When a parameter is passed by value, it consists of an actual copy of the data. Since the parameter is a copy, the original data cannot be modified by the procedure.

When you pass parameters from the calling code with an explicit BYVAL, you effectively switch off the compilers type-checking for that parameter. This can be useful in cases where the called code is expecting a BYREF parameter, and you wish to pass an address of another data type that would trigger a compile-time error without the BYVAL method. For example:

SUB TheSub(x AS STRINGZ) ' Address of x expected

[ statements ]

END SUB

[ statements ]

DIM a$

a$ = "Dynamic string data"

CALL TheSub(BYVAL STRPTR(a$)) ' Pass data address

BYCOPY

A parameter passed by copy is a special case; somewhat of a hybrid of the other two methods. When a procedure expects a parameter to be passed by reference, it expects to see a pointer to the data. In some cases, such as when the parameter is a calculated expression, it is not precisely possible to pass a pointer, since an expression result is a temporary value that does not exist in a permanent memory location. On the other hand, if you wish to ensure that the original data is not modified by the procedure, you can place a BYCOPY override in the arguments list.

In both cases, a copy of the data is stored in a temporary memory location, and the parameter consists of a 4-byte address of this temporary location. Another way to force BYCOPY is to enclose a variable name in parentheses, so it will appear to the compiler as an expression, rather than just a single variable.

Unless declared otherwise, parameters default to BYREF passing method. Expressions and constants are always passed BYCOPY. Fixed length strings , User-Defined Types , and full arrays are always passed BYREF.

CALL MySub (i&) ' i& is passed by reference

CALL MySub (BYREF i&) ' i& is passed by reference

CALL MySub (BYCOPY i&) ' i& is passed by copy

CALL MySub ((i&)) ' i& is passed by copy

Unless declared otherwise, parameters default to the BYREF passing method. Expressions and constants are always passed BYCOPY. Full arrays are always passed BYREF.

Entire arrays are specified by using an empty set of parentheses after the array, while individual array elements are specified by subscript index number. For example:

CALL SumArray(a()) ' pass entire array 'a'

CALL SumArray(a(3)) ' pass element 3 of array 'a'

The CALL statement can be used to invoke functions, subs, methods, properties, or fastprocs. In this case, the return value of the function is simply discarded, unless the TO keyword is used to specify a return variable.

If a procedure expects a parameter by reference, it is possible to substitute a pointer by value, for the identical result. This is particularly useful with Fixed-length strings and Types:

DECLARE SUB a(z%)

DIM MyInt AS INTEGER, x AS INTEGER PTR

x = VARPTR(MyInt)

CALL a(MyInt)

CALL a(BYVAL x)

CALL a(BYVAL VARPTR(MyInt))

Of course, if the procedure is expecting a parameter by value, you may not pass the pointer, but rather the pointer target (i.e., CALL a(@x)).

ScharfBASIC compilers have a limit of 32 parameters per SUB, FUNCTION, METHOD, and PROPERTY. To pass more than 32 parameters, construct a User-Defined Type (UDT) and pass (the address of) the UDT by reference (BYREF) instead.

Fixed-length strings, STRINGZ strings, and User-Defined Types/Unions may also be passed as BYVAL or OPTIONAL parameters, now. Try to avoid passing large items BYVAL, as it's terribly inefficient, and there is a maximum size limit of 64 Kb for a given parameter list. Arrays cannot be passed BYVAL.

When a procedure definition specifies either a BYREF parameter or a pointer variable parameter, the calling code may freely pass a BYVAL DWORD or a Pointer instead. While the use of the explicit BYVAL override in the calling code is optional, it is recommended for clarity. It is necessary to explicitly declare all pointer parameters as BYVAL (i.e., BYVAL X AS BYTE PTR). Failure to do so will generate a compile-time Error 549 ("BYVAL required with pointers").

A procedure may also be imported and exported within the same module. That is, a function in the module may be stated as EXPORT, while a DECLARE in the same module specifies it as an imported function by the option LIB "XXX.DLL", provided that XXX.DLL is the name of the module. This may be particularly valuable when you wish to build an #INCLUDE file with all of the DECLARE statements for a project.

For information on using OPTIONAL parameters, please see DECLARE , FUNCTION , METHOD , PROPERTY and SUB topics.

NOTHING

The reserved word NOTHING can be used to replace any OBJECT variable parameter. In this case, the compiler passes a null object (or a pointer to a null object if BYREF) in place of a typical parameter. While this simplifies some programming issues, the technique must be used with caution. If the target METHOD or FUNCTION is not expecting a null parameter, it could cause a fatal error condition.

TO result_var

This offers an optional way to assign a function return value to result_var . For example, the following code assigns the return value to x% in two different ways:

x% = MyFunCall

CALL MyFunCall TO x%

Restrictions

A thread Function may not be directly called or executed, except by a THREAD CREATE statement.

See Also

  • CALL DWORD
  • DECLARE
  • FASTPROC
  • FUNCTION/END FUNCTION
  • METHOD
  • PROPERTY
  • SUB/END SUB
  • THREAD CREATE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   esi,DWORD PTR [ebp+0x8]
ret   0x4


Callbacks - ScharfBASIC Help

Callbacks

A callback is a Function called by Windows when an event occurs. In the previous modal dialog example , when the OK button is clicked by the user, Windows calls the OkButton() function. ScharfBASIC's D

Kind | Keyword
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

If you've used Visual Basic, you'll be familiar with the concept of a Control Callback even though it's not called by that name. A Control Callback is a function that is called when a %WM_COMMAND or %WM_NOTIFY event is generated for a particular control. In the earlier example , we arranged it so the OkButton() function was called when the OK button was clicked. Further, when the Cancel button was clicked, the CancelButton() function was called. A Control Callback function is enabled when you execute a CONTROL ADD statement using the CALL CtlProc option at the end.

CONTROL ADD BUTTON, hDlg, %IDOK, "OK", 34, 32, 40, 14, %BS_DEFAULT OR %WS_TABSTOP CALL OkButton

CONTROL ADD BUTTON, hDlg, %IDCANCEL, "Cancel", 84, 32, 40, 14 CALL CancelButton

Some controls, like text boxes , list boxes , and combo boxes , can generate more than one type of event. In VB, each separate event on each control is handled by a new function. For example, if your VB form includes a list box, it may include a Callback Function such as List1_Change() that is called whenever the current selected item changes. In ScharfBASIC, only a single Callback Function is needed for each control. When an event occurs, the Callback Function just chooses which events to handle, and which events to ignore. If your ScharfBASIC callback wanted to process the Change event for a list box, your code would look like this:

CALLBACK FUNCTION List1() AS LONG

IF CB.MSG = %WM_COMMAND THEN

IF CB.CTLMSG = %LBN_SELCHANGE THEN


CB Callback functions - ScharfBASIC Help

CB Callback functions

In a

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CtlID = CB.CTL
CtlMsg = CB.CTLMSG
WinHndl = CB.HNDL
Value = CB.LPARAM
Msg = CB.MSG
Value = CB.WPARAM
CodeMsg = CB.NMCODE
NmPtr = CB.NMHDR
NmStruc = CB.NMHDR$
NmHndl = CB.NMHWND
NmID = CB.NMID

Description

When an event occurs (like a user clicking on a button , a character typed into a text box , etc.) Windows sends a message to the control Callback Function, or the Dialog Callback Function. The CB functions are used to easily retrieve information about the message. These CB functions can only be used within a callback function.

Callback functions in Windows have a standard set of four parameters. For this reason, ScharfBASIC allows you to ignore them and save some typing in your source code. The implied parameters are:

FUNCTION DlgCallback(BYVAL hDlg AS DWORD _

BYVAL wMsg AS LONG _

BYVAL wParam AS LONG _

BYVAL lParam AS LONG)

Generic Callback Functions

CB.HNDL

This function returns the window handle of the parent dialog. This is the value specified by the hDlg parameter above.

CB.MSG

Each type of message sent to your callback function has a unique numeric value, such as %WM_COMMAND, %WM_NOTIFY, etc. CB.MSG will return the actual numeric message value of the message being processed. The definitions of the numeric values in other CB functions (CB.LPARAM, CB.WPARAM, CB.CTL, etc.) can only be ascertained once CB.MSG is identified. Therefore, callback functions usually test the value of CB.MSG first.

CB.WPARAM

When Windows sends a message to a callback function, the wParam value contains different values, depending on the nature of the particular message (CB.MSG). In other words, CB.WPARAM returns a message-dependent value.

CB.LPARAM

When Windows sends a message to a callback function, the lParam value contains different values, depending on the nature of the particular message (CB.MSG). In other words, CB.LPARAM returns a message-dependent value.

%WM_COMMAND Specific Callback Functions

CB.CTL

If CB.MSG = %WM_COMMAND, this function returns the ID number assigned to the control with the CONTROL ADD statement. For other values of CB.MSG, it returns message-dependent values. This value is sent as the low-order word of the wParam parameter. It's functionally equivalent to LO (WORD, wParam&) in a conventional function, or LO(WORD, CB.WPARAM) in a DDT Callback Function.

CB.CTLMSG

If CB.MSG = %WM_COMMAND, this function returns the specific control message describing the event which occurred. For example, CB.CTLMSG returns %BN_CLICKED when the user clicks a button. For other values of CB.MSG, it returns message-dependent values. This value is sent as the high-order word of the wParam parameter. It's functionally equivalent to HI (WORD, wParam&) in a conventional function, or HI(WORD, CB.WPARAM) in a DDT Callback Function.

%WM_NOTIFY Specific Callback Functions

CB.NMCODE

If CB.MSG = %WM_NOTIFY, this function returns the specific notification message describing the event which occurred. For example, CB.NMCODE retu rns %NM_SETFOCUS when the described control gains the focus . For other values of CB.MSG, the value returned is meaningless.

CB.NMHDR

If CB.MSG = %WM_NOTIFY, this function returns the address ( a pointer ) to the NMHDR UDT for this notification message. NMHDR is defined as:

Type NMHDR

hwndFrom as DWord ' Handle of the control sending the message

idfrom as DWord ' Identifier of the control sending the message

code as Long ' Notification code

End Type

Some notification messages (%NM_CHAR, %NM_CLICK, etc.) require an extended version of the NM structure. However, all NM structures begin with an NMHDR UDT, so the pointer returned here is always accurate. For other values of CB.MSG, the pointer returned by CB.NMHDR is meaningless.

CB.NMHDR$

If CB.MSG = %WM_NOTIFY, this function returns the contents of the NMHDR UDT as a dynamic string . If the notification message is one which requires an extended version of the NM structure, the string returned contains all of the data for the extended UDT. However, in all cases, the first 12 bytes of the returned string will be the contents of NMHDR. You can use TYPE SET to assign the string data to an appropriate user-defined type. For other values of CB.MSG, the string returned by CB.NMHDR$ is meaningless.

The following notification messages use the extended NM structures as listed, so an appropriately longer string is returned:

Message

%NM_CLICK

NMMOUSE

%NM_RCLICK

NMMOUSE

%NM_NCHITTEST

NMMOUSE

%NM_KEYDOWN

%NM_SETCURSOR

NMMOUSE

%NM_CHAR

NMCHAR

%NM_TOOLTIPSCREATED

NMTOOLTIPSCREATED

Other special notify messages may use a different extended NM structure than those listed above. To ensure compatibility, you can include an optional numeric parameter to specify the size of the special UDT you are using:

TYPE SET NotifyUDT = CB.NMHDR$(sizeof(NotifyUDT))

CB.NMHWND

If CB.MSG = %WM_NOTIFY, this function returns the handle of the control which sent this message. For other values of CB.MSG, the value returned is meaningless.

CB.NMID

If CB.MSG = %WM_NOTIFY, this function returns the ID number assigned to this control. For other values of CB.MSG, the value returned is meaningless.

Restrictions

These functions are only valid inside a Callback Function. The CB Callback functions replace CBMSG, CBHNDL, CBLPARAM, CBWPARAM, CBCTL, and CBCTLMSG . Note these functions are no longer supported, so update your code to use the new syntax.

See Also

  • Callbacks
  • Dynamic Dialog Tools


DECLARE - ScharfBASIC Help

DECLARE

Explicitly declare a

Kind | Statement
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DECLARE SUB ProcName [ALIAS " AliasName "] [( arguments )] < Descriptors >
DECLARE FUNCTION ProcName [ALIAS " AliasName "] [( arguments )] < Descriptors > AS RetType
DECLARE CALLBACK FUNCTION ProcName [[()] AS LONG]
DECLARE THREAD FUNCTION ProcName (BYVAL var AS (LONG | DWORD}) AS {LONG | DWORD}

Description

The DECLARE statement has the following parts:

ProcName

The name of the Sub or Function to be declared. For Functions, a type-specifier may be appended (just like an ordinary variable name) to specify the data type of the Function's return value, in place of the [AS RetType] clause.

Future versions of ScharfBASIC will not support type-specifier symbols for the Function return type. Specify the return data type with an explicit AS RetType clause in all DECLARE and FUNCTION definitions to ensure future compatibility.

An alias clause may be used to specify an alternate name to be used for imported or exported procedures. This allows you to interact with outside modules ( DLL or EXE) using a different procedure name. The alias name must be specified by a string literal which provides the name and capitalization of the procedure in the external DLL.

This option is particularly useful if you want to abbreviate a long name, or if the original name of a function contains characters that are illegal in ScharfBASIC. The alias name is the actual name used in the other module, while the ProcName is the word you use in your ScharfBASIC program. For example:

DECLARE SUB ShortName ALIAS "VeryLongProcName"()

DECLARE FUNCTION LegalName ALIAS "Illegal$Name"()

Although a Proc Name must be unique, you may use the same AliasName in multiple declarations. This is particularly useful for avoiding AS ANY in cases where a procedure is designed to receive several different types of parameters.

DECLARE FUNCTION AddAtom LIB "KERNEL32.DLL" ALIAS "AddAtomA" (lpString AS STRINGZ) AS WORD

DECLARE FUNCTION AddIntAtom LIB "KERNEL32.DLL" ALIAS "AddAtomA" (BYVAL lpString AS DWORD) AS WORD

The ALIAS clause is very important when importing or exporting Subs and Functions from DLLs. Omitting the ALIAS clause or incorrectly capitalizing the alias name are common causes of DLL load failure problems. Please refer to the SUB and FUNCTION sections for more information.

Descriptors

You may optionally add one or more descriptor words (Import, Export, Common, Private, ThreadSafe, BDecl, CDecl, SDecl) to provide specific functionality. They may be added to the DECLARE as a comma delimited list. You should note that some of them are mutually exclusive.

IMPORT

A string literal or equate that specifies the name of the module in which an imported procedure is located. This allows you to call Subs or Functions that reside in DLLs. The legacy word LIB may be substituted for IMPORT.

EXPORT

This descriptor identifies a Sub or Function which may be accessed between Dynamic Link Libraries (DLLs), and/or the main executable which links them. If a procedure is not marked EXPORT, it is hidden from these other modules. The EXPORT attribute may be added to a Sub/Function defined elsewhere, by specifying EXPORT in a DECLARE statement. EXPORT can even be added to a Sub/Function in an SLL with a DECLARE in the host module.

COMMON

A COMMON Sub/Function is one which may be called between linked unit modules (Host or SLL ). If the Common Sub/Function is not present in this module, it is presumed to be found in a separate linked module (Host or SLL). It is not necessary to DECLARE a COMMON Sub or Function in the Host Module. If you choose to do so, it is generally advisable to omit the COMMON descriptor, as its presence will force the SLL to be linked, whether needed or not.

PRIVATE

A PRIVATE Sub/Function is one which may only be accessed from within the current ScharfBASIC program or library. Even if not specified, this is the default mode of operation.

THREADSAFE

With the THREADSAFE option, ScharfBASIC automatically establishes a semaphore which allows only one thread to execute the Sub/Function at a time. Other callers must wait until the first thread exits the THREADSAFE procedure before they are allowed to begin.

Specifies that the declared procedure uses the legacy BASIC/Pascal calling convention. Parameters are pushed on the stack from left to right, and the called procedure is responsible for removing them. BDECL should only be used when necessary to match outside modules.

Specifies that the declared procedure uses the C calling convention. Parameters are pushed on the stack from right to left, and the calling code is responsible for removing them. CDECL should only be used when necessary to match outside modules.

When a procedure is imported or exported, ScharfBASIC automatically creates a lowercase ALIAS, prefixed with an underscore. The following two declarations are equivalent, indicating how the default ALIAS name would be created by ScharfBASIC:

DECLARE SUB C_Function CDECL ()

DECLARE SUB C_Function CDECL ALIAS "_c_function" ()

This is the default convention, and should be used whenever possible. SDECL (and its synonym STDCALL), specifies the "Standard Calling Convention" for Windows. Parameters are pushed on the stack from right to left, and the called procedure is responsible for removing them.

CALLBACK

Callback Functions are reserved for use with Dynamic Dialog Tools (DDT) functions. No parameters should be specified, as data is retrieved with the CALLBACK ( CB ) functions. Parentheses and the AS LONG return type may be added for clarity.

THREAD

Thread functions are reserved for use with the THREAD CREATE statement. It must take exactly one Long Integer parameter by value (BYVAL LONG), and must return a Long Integer value (AS LONG). It is permissible to substitute DWORD for both of these items.

Passing parameters

Arguments

Contains the name(s) or the type of each parameter, in the order they are passed, for up to 32 parameters. If you wish to call a SUB or FUNCTION in a DLL, you must describe the target SUB or FUNCTION with an explicit DECLARE statement. The DECLARE must physically precede any reference to the target procedure.

Previous versions of ScharfBASIC required that you create an explicit DECLARE statement if you wished to execute a SUB or function which did not physically precede the reference to it. This extra work is no longer required, as ScharfBASIC resolves all forward references to internal procedures automatically.

The complete arguments list must be specified for each routine. Each parameter may be defined in one of three ways:

Legal type names for arguments include ANY, ASCIIZ , BYTE , CUR , CUX , DOUBLE , DWORD , EXT , INTEGER , LONG , PTR , QUAD , SINGLE , STRING , STRINGZ , WORD , WSTRING , WSTRINGZ and ARRAY . The ARRAY keyword is used in conjunction with one of the other types to specify an entire array of that type. For example:

DECLARE SUB KerPlunk(INTEGER ARRAY, DOUBLE)

declares a procedure called KerPlunk , which takes an entire Integer array and a Double-precision variable as parameters. You can also name the parameters using the AS keyword:

DECLARE SUB KerPlunk(iArray() AS INTEGER, dVar AS DOUBLE)

The following four declare statements are equivalent:

DECLARE SUB KerPlunk(x) ' if DEFINT A-Z is in effect

DECLARE SUB KerPlunk(x%)

DECLARE SUB Plunk(x AS INTEGER)

DECLARE SUB KerPlunk(INTEGER)

When parameters are passed by reference (BYREF), the address of the variable passed to the routine is placed on the stack. When they are passed by value (BYVAL), the actual data is placed on the stack. You can use the BYVAL or BYREF keywords to specify that a parameter should always be passed in a known format.

Using ANY disables type checking for a particular parameter, and passes the address of the variable on the stack. Since the internal format of variables differ greatly by type, you must use caution to be certain your code knows the data type in each invocation. Normally, a second parameter is used to specify the actual type of the ANY parameter.

When a Sub/Function definition specifies either a BYREF parameter or a pointer variable parameter, the calling code may freely pass a BYVAL DWORD or a pointer instead. While the use of the explicit BYVAL override in the calling code is optional, it is recommended for clarity. It is necessary to explicitly declare all pointer parameters as BYVAL (BYVAL x AS BYTE PTR). Failure to do so will generate compile-time Error 549 ("BYVAL required with pointers").

Additional information on BYVAL/BYREF/BYCOPY parameter passing can be found in the CALL statement topic.

Using OPTIONAL/OPT

DECLARE statements may specify one or more parameters as optional by preceding the parameter with either the keyword OPTIONAL (or the abbreviation OPT). Optional parameters are only allowed with CDECL or SDECL calling conventions, not BDECL.

When a parameter is declared optional, all subsequent parameters in the declaration are optional as well, whether or not they specify an explicit OPTIONAL or OPT directive. The following two lines are equivalent, with both second and third parameters being optional:

DECLARE SUB sABC(a&, OPTIONAL BYVAL b&, OPTIONAL BYVAL c&) AS LONG

DECLARE SUB sABC(a&, OPT BYVAL b&, BYVAL c&) AS LONG

VARIANT variables are particularly well suited for use as an optional parameter. If the calling code omits an optional VARIANT parameter, (BYVAL or BYREF), ScharfBASIC (and most other compilers) substitute a variant of type %VT_ERROR which contains an error value of %DISP_E_PARAMNOTFOUND (&H80020004). In this case, you can check for this value directly, or use the ISMISSING() function to determine whether the parameter was physically passed or not.

When optional parameters (other than VARIANT) are omitted in the calling code, the stack area normally reserved for those parameters is zero-filled.

If the parameter is defined as a BYVAL parameter, it will have the value zero. For TYPE or UNION variables passed BYVAL, the compiler will pass a string of binary zeroes of length SIZEOF ( Type _or_ union _var).

If the parameter is defined as a BYREF parameter , VARPTR ( Varname ) will equal zero; when this is true, any attempt to use Varname in your code will result in a General Protection Fault or memory corruption. You should use the ISMISSING() function first to determine whether it is safe to access the parameter.

AS type

You may specify the type of data returned by a Function to the calling code. If you do not specify a type, ScharfBASIC assumes that the Function returns the data type specified by a DEF type statement. However, if no DEF type or AS type has been specified, a compile-time error is generated.

Therefore, there are two ways to specify the return type of a Function:

For example, the following statements are equivalent:

DECLARE FUNCTION aFunction?()

DECLARE FUNCTION aFunction() AS BYTE

While most FUNCTION calling conventions are fairly well defined throughout the industry, there are a few exceptions. In the case of functions which return a Quad Integer value, some programming languages (including ScharfBASIC) return the quad value in the FPU, while others return it in EDX:EAX. ScharfBASIC automatically detects the method used by imported functions and adjusts accordingly for you, but that's not a feature found in other compilers. Therefore, we recommend that you do not EXPORT QUAD FUNCTIONS unless they will only be accessed by ScharfBASIC programs. A simple equivalent functionality would be to return the quad-integer value to the caller in a BYREF QUAD parameter.

Restrictions

A Sub/Function may be imported and exported within the same module. That is, a function in the module may be stated as EXPORT, while a DECLARE in the same module specifies it as an imported function by the option LIB "filename.dll", as long as FILENAME.DLL is the name of the module. This may be particularly valuable when you wish to build an #INCLUDE file with all of the DECLARE statements for a project.

See Also

  • #EXPORT
  • #LINK
  • CALL
  • CALL DWORD
  • FASTPROC
  • FUNCTION/END FUNCTION
  • IMPORT
  • ISMISSING
  • SUB/END SUB
  • THREAD CREATE

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Bycopy

mov   eax,DWORD PTR [ebp+0xc]
add   eax,DWORD PTR [ebp+0x8]
ret   0x8

Variant 2: Byref

mov   eax,0x1
mov   ebx,DWORD PTR [ebp+0x8]
mov   ebx,DWORD PTR [ebp+0x8]
ret   0x4

Variant 3: Byval

mov   eax,0x2
imul   DWORD PTR [ebp+0x8]
mov   DWORD PTR [ebp-0x98],eax
ret   0x4


DLLMAIN - ScharfBASIC Help

DLLMAIN

LIBMAIN (or its synonym DLLMAIN) is an optional user-defined function called by Windows each time a

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FUNCTION { LIBMAIN | DLLMAIN } ( _
BYVAL hInstance AS DWORD, _
BYVAL lReason AS LONG, _
BYVAL lReserved AS LONG ) AS LONG

Description

Return value: If LIBMAIN is called with %DLL_PROCESS_ATTACH, your LIBMAIN function should return a zero (0) if any part of your initialization process fails, or a one (1) if no errors were encountered. If a zero is returned, Windows will abort and unload the DLL from memory. When LIBMAIN is called with any other value than %DLL_PROCESS_ATTACH, the return value is ignored.

The LIBMAIN / DLLMAIN function provides the following parameters:

hInstance

The unique instance handle of the DLL. This handle is used by the calling application to identify the DLL. The instance handle value is commonly used to load resources embedded within the DLL, and to obtain the actual file name of the DLL (via the GetModuleFilename API function). In these cases, it is common to copy the hInstance value to a global variable, allowing the instance handle value to be utilized elsewhere in the DLL.

lReason

This flag indicates why the DLL entry-point is being called. It can be one of the following values (as defined in WIN32API.INC ):

%DLL_PROCESS_ATTACH

Indicates that the DLL is being loaded by a process (another DLL or EXE is loading the DLL). DLLs can use this opportunity to initialize any instance or global data, such as arrays . lReserved is zero if the DLL is being loaded explicitly (run-time linking) using LoadLibrary(), or non-zero if the DLL is being loaded implicitly (load-time linking) during process initialization.

%DLL_PROCESS_DETACH

Indicates that the DLL is being cleanly unloaded or detached from the calling application. DLLs can take this opportunity to clean up all resources for all threads attached and known to the DLL. This is functionally equivalent to the WEP function in 16-bit DLLs. lReserved is zero if LIBMAIN was executed via the FreeLibrary API and the DLLs reference count reached zero (no further instances of the DLL are loaded), or non-zero if LIBMAIN is executed during process termination. A %DLL_PROCESS_DETACH does not generate %DLL_THREAD_DETACH for active threads.

%DLL_THREAD_ATTACH

Indicates that the DLL is being loaded by a new thread in the calling application. DLLs can use this opportunity to initialize any Thread Local Storage (TLS). This execution occurs in the context of the new thread.

%DLL_THREAD_DETACH

Indicates that the thread is exiting cleanly. If the DLL has allocated any thread-specific storage (Thread Local Storage or TLS), it should be released. This may occur even if there was no matching %DLL_THREAD_ATTACH call. A %DLL_PROCESS_DETACH does not generate %DLL_THREAD_DETACH for active threads.

lReserved

The lReserved parameter specifies further aspects of the DLL initialization and cleanup. If lReason is %DLL_PROCESS_ATTACH, lReserved is zero (0) for explicit (dynamic) loads and non-zero for implicit loads. If lReason is %DLL_PROCESS_DETACH, lReserved is zero if LIBMAIN has been called by using the FreeLibrary API call, and non-zero if LIBMAIN has been called during process termination.

Return value

If LIBMAIN is called with %DLL_PROCESS_ATTACH, your LIBMAIN function should return a zero (0) if any part of your initialization process fails, or a one (1) if no errors were encountered. If a zero is returned, Windows will abort and unload the DLL from memory. When LIBMAIN is called with any other value than %DLL_PROCESS_ATTACH, the return value is ignored.

Restrictions

Note that Windows does not guarantee that LIBMAIN will be called in a "balanced" manner. For example, a %DLL_PROCESS_ATTACH is not followed by a %DLL_THREAD_ATTACH for the primary thread. In some conditions, %DLL_THREAD_DETACH may not occur at all. Further discussion on these Windows traits are beyond the scope of this documentation; however, an excellent source of information can be found in "Win32 Programming", Rector/Newcomer, ISBN 0-201-63492-9.

At the point where a DLL is loaded into memory during process startup, Windows only guarantees that the KERNEL32.DLL system library will be loaded in memory. On this basis, API calls made from within LIBMAIN must be restricted to the range of API functions present in KERNEL32.DLL, with the exception of the LoadLibrary, LoadLibraryEx, and FreeLibrary API functions.

In addition, code within LIBMAIN must not call API functions in any other DLL (for example, USER32.DLL, SHELL32.DLL, ADVAPU32.DLL, GDI32.DLL, etc), because some API functions in those DLLs may attempt to load other libraries via LoadLibrary, etc. For example, never call the MessageBox API function from within LIBMAIN, nor use the related MSGBOX function or MSGBOX statement.

Failure to observe these restrictions will result in Access Violation or General Protection Faults (GPFs), typically caused by the execution of code in DLLs that has yet to be initialized.

See Also

  • DLLMAIN
  • PBLIBMAIN
  • PBMAIN
  • THREAD CREATE
  • WINMAIN


FUNCNAME$ - ScharfBASIC Help

FUNCNAME$

Return the name of the current

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

f$ = FUNCNAME$

Description

FUNCNAME$ returns the name of the procedure in which it is located. If an ALAIS is specified, FUNCNAME$ returns the ALIAS name; otherwise, it returns the primary name capitalized. Returning the ALIAS name provides a mechanism to disguise sensitive internal procedure names even when reporting error conditions to a user.

FUNCNAME$ can be useful as a debugging tool, or in situations where an error handler in a procedure passes error information on to a "central" procedure for logging and handling. FUNCNAME$ does not require #TOOLS ON .

See Also

  • #TOOLS
  • CALLSTK
  • CALLSTK$
  • CALLSTKCOUNT
  • FILENAME$
  • FUNCTION
  • METHOD
  • PROFILE
  • PROPERTY
  • SUB
  • TRACE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x20108d
call   0x2018ca
lea   ebx,[ebp-0xa4]
call   0x201da7
call   0x201cd8


FUNCTION/END FUNCTION statements - ScharfBASIC Help

FUNCTION/END FUNCTION statements

Define a Function block.

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FUNCTION ProcName [ALIAS " AliasName "] [( arguments )] < Descriptors > AS Type
[ statements ]
[{ FuncName | FUNCTION} = ReturnValue ]
END FUNCTION
CALLBACK FUNCTION ProcName [AS LONG]...
THREAD FUNCTION ProcName (BYVAL var AS LONG) AS LONG...

Description

Return value: ] END FUNCTION CALLBACK FUNCTION ProcName [AS LONG]... THREAD FUNCTION ProcName (BYVAL var AS LONG) AS LONG...

All executable code must reside in a Sub , Function, Method , Property , or FastProc block. Functions may not be nested. That is, you cannot define a code block (Sub, Function, Method, Property) inside another code block.

Previous versions of ScharfBASIC required that you create an explicit DECLARE statement if you wished to execute a SUB or FUNCTION which did not physically precede the reference to it. This extra work is no longer required, as ScharfBASIC resolves all forward references to internal procedures automatically.

DECLARE statements for a Sub/Function imported from a DLL must still precede any reference to the procedure.

FuncName

The name of the Function. A type-specifier may be appended (just like an ordinary variable name) to specify the data type of the Function's return value, in place of the [AS type ] clause. FuncName must be unique: no other variable, Function, Sub, Method, Property, or label can share it. Also see ALIAS below.

Future versions of ScharfBASIC will not support type-specifier symbols for the Function return type, so specify the return data type with an explicit AS type clause in all DECLARE and FUNCTION definitions, to ensure future compatibility.

String literal that identifies an case-sensitive alternative name for the function. This lets you export a Function by a different unique name. This can be useful if you want to abbreviate a long name, provide a more descriptive name, or if the exported name needs to contain characters that are illegal in ScharfBASIC. AliasName is the routine's actual name as it appears in the export table, and FuncName is the title that you can use in ScharfBASIC. For example:

FUNCTION ShortName ALIAS "LongFuncName"() EXPORT STATIC AS LONG

The ALIAS clause is very important when exporting procedures. Omitting the ALIAS clause or incorrectly capitalizing the alias name are common causes of "Missing Export" errors. Please refer to the DECLARE topic for more information.

Descriptors

EXPORT

This descriptor identifies a Sub or Function which may be accessed between Dynamic Link Libraries (DLLs ), and/or the main executable which links them. If a procedure is not marked EXPORT, it is hidden from these other modules. The EXPORT attribute may be added to a Sub/Function defined elsewhere, by specifying EXPORT in a DECLARE statement. EXPORT can even be added to a Sub/Function in an SLL with a DECLARE in the host module.

COMMON

A COMMON Sub/Function is one which may be referenced by and between linked unit modules (Host or SLL). If you DECLARE a Common Sub or Function which is not present in this module, it is presumed to be found in a separate linked module (Host or SLL).

PRIVATE

A PRIVATE Sub/Function is one which may only be accessed from within the current ScharfBASIC program or library. Even if not specified, this is the default mode of operation.

THREADSAFE

With the THREADSAFE option, ScharfBASIC automatically establishes a semaphore which allows only one thread to execute the Sub/Function at a time. Other callers must wait until the first thread exits the THREADSAFE procedure before they are allowed to begin.

This descriptor specifies that all undeclared variables in a function are LOCAL . This is the default condition if neither LOCAL nor STATIC is specified.

Local variables and arrays variables are automatically deallocated when the procedure terminates. LOCAL scalar variables (except dynamic strings) are stored on the stack, and visible only within the function.

STATIC

This descriptor specifies that all undeclared variables in a function are STATIC . Static variables retain their values as long as the program is running. They are visible only within the function.

Specifies that the declared procedure uses the legacy BASIC/Pascal calling convention. Parameters are pushed on the stack from left to right, and the called procedure is responsible for removing them. BDECL should only be used when necessary to match outside modules.

Specifies that the declared procedure uses the C calling convention. Parameters are pushed on the stack from right to left, and the calling code is responsible for removing them. CDECL should only be used when necessary to match outside modules.

This is the default convention, and should be used whenever possible. SDECL (and its synonym STDCALL), specifies the "Standard Calling Convention" for Windows. Parameters are pushed on the stack from right to left, and the called procedure is responsible for removing them.

CALLBACK

Specifies that this is a callback function, which is used only to receive messages from the operating system. It may never be called directly from your code. Details about the message sent to the callback are retrieved using the CB group of ScharfBASIC functions. Callback functions may not include parameters, and always return a long integer result. For example:

CALLBACK FUNCTION DlgProc AS LONG

' Callback code goes here

END FUNCTION

Callback functions have the unique ability to optionally return two distinct values when necessary for certain Windows messages. This allows them to return the value zero (0) as a function result, while still specifying that the message has been processed. See the section CALLBACK RETURN VALUE (below) and the CALLBACKS page for more details.

THREAD

Specifies that this is a thread function, which is the point where execution of a new thread begins. It may never be called directly from your code. Thread functions must take exactly one long-integer or double-word parameter by value (BYVAL), and must return either a long-integer or double-word result. For example:

THREAD FUNCTION MyThreadFunction(BYVAL x AS LONG) AS LONG

' Thread code goes here

END FUNCTION

The THREAD CREATE statement creates and begins execution of a new thread Function.

Passing parameters

arguments

An optional, comma-delimited sequence of formal parameters. The parameters used in the arguments list serve only to define the Function; they have no relationship to other variables in the calling code with the same name.

Normally, ScharfBASIC passes parameters to a Function either by reference (BYREF) or by value (BYVAL). If you do not need to modify the parameters (true in many cases), you can speed up your calls by passing the parameters by value using the BYVAL keyword. You can clarify that a parameter is passed by reference by using the optional BYREF keyword.

The type of the parameter is specified either by appending a type-specifier character to the name or by using an AS clause. For example:

FUNCTION Test&(A AS INTEGER) 'integer passed by ref

FUNCTION Test&(A%) 'integer passed by ref

FUNCTION Test&(BYREF A%) 'integer passed by ref

FUNCTION Test&(BYVAL A%) 'integer passed by val

Parameter restrictions

ScharfBASIC compilers have a limit of 32 parameters per FUNCTION. To pass more than 32 parameters to a FUNCTION, construct a User-Defined Type (UDT) and pass the UDT by reference (BYREF) instead.

Fixed-length strings , Nul-Terminated Strings , and User-Defined Types / Unions may also be passed as BYVAL or OPTIONAL parameters. Try to avoid passing large items BYVAL, as it?s terribly inefficient, and there is a maximum size limit of 64 Kb for a given parameter list.

ScharfBASIC Functions cannot return an array or Variant variable as a Function return value. Pass these variable types as BYREF parameters instead. For example:

lResult& = ProcessData(TheArray&(), iSize%)

[ statements ]

FUNCTION ProcessData(lArr() AS LONG, iSize%) AS LONG

REDIM lArr(iSize%) AS LONG

lArr(iSize%) = 1&

FUNCTION = -1&

END FUNCTION

Pointer parameters

When a Function definition specifies either a BYREF parameter or a pointer variable parameter, the calling code may freely pass a BYVAL DWORD or a Pointer instead. Pointer variable parameters must always be declared as BYVAL parameters.

' Integer Pointer (passed by value)

FUNCTION Test(BYVAL A AS INTEGER PTR) AS LONG

@A = 56

END FUNCTION

Additional information on BYVAL/BYREF/BYCOPY parameter passing can be found in the CALL statement topic.

Optional parameters

ScharfBASIC supports two syntax formats for optional parameters: the classic optional parameter syntax using brackets "[..]", and the new syntax using the OPTIONAL (or OPT) keyword. We'll discuss each one in turn.

Using OPTIONAL/OPT

FUNCTION statements may specify one or more parameters as optional by preceding the parameter with either the keyword OPTIONAL or OPT. Optional parameters are only allowed with CDECL or SDECL calling conventions, not BDECL.

When a parameter is declared optional, all subsequent parameters in the declaration are optional as well, whether or not they specify an explicit OPTIONAL or OPT directive. The following two lines are equivalent, with both second and third parameters being optional:

FUNCTION sABC(a&, OPTIONAL BYVAL b&, OPTIONAL BYVAL c&) AS LONG

FUNCTION sABC(a&, OPT BYVAL b&, BYVAL c&) AS LONG

VARIANT variables are particularly well suited for use as an optional parameter. If the calling code omits an optional VARIANT parameter, (BYVAL or BYREF), ScharfBASIC (and most other compilers) substitute a variant of type VT_ERROR which contains an error value of %DISP_E_PARAMNOTFOUND (&H80020004). In this case, you can check for this value directly, or use the ISMISSING() function to determine whether the parameter was physically passed or not.

When optional parameters (other than a VARIANT) are omitted in the calling code, the stack area normally reserved for those parameters is zero-filled. This allows you to test if an optional parameter was passed or not:

If the parameter is defined as a BYVAL parameter, it will have the value zero. For TYPE or UNION variables passed BYVAL, the compiler will pass a string of binary zeroes of length SIZEOF (Type_or_union_var).

If the parameter is defined as a BYREF parameter, VARPTR ( varname ) will equal zero; when this is true, any attempt to use Var_name in your code will result in Error #9 (null pointer); failure to detect this error using error-trapping may result in a General Protection Fault or memory corruption. You should use the ISMISSING() function first to determine whether it is safe to access the parameter.

Because the FUNCTION, SUB, FASTPROC, METHOD, or PROPERTY being called does not know how many parameters are being passed at the time it is called, you should pass the number of parameters as one of the required parameters in the list.

AS type

Function blocks are constructed very much like Subs (see SUB/END SUB statement). However, Functions differ from Subs in that they always return a result, so they can be used in assignments and expressions. Therefore, there are two ways to specify the return type of a Function:

You may specify the type of data returned by a Function to the calling code. If you do not specify a type, ScharfBASIC assumes that the Function returns the data type specified by a DEFtype statement. However, if no DEFtype or AS type has been specified, a compile-time error is generated.

Therefore, there are two ways to specify the return type of a Function:

For example, the following statements are equivalent:

FUNCTION aFunction?()

FUNCTION aFunction() AS BYTE

While most FUNCTION calling conventions are fairly well defined throughout the industry, there are a few exceptions. In the case of functions which return a Quad Integer value, some programming languages (including ScharfBASIC) return the quad value in the FPU, while others return it in EDX:EAX. ScharfBASIC automatically detects the method used by imported functions and adjusts accordingly for you, but that's not a feature found in other compilers. Therefore, we recommend that you do not EXPORT QUAD FUNCTIONS unless they will only be accessed by ScharfBASIC programs. A simple equivalent functionality would be to return the quad-integer value to the caller in a BYREF QUAD parameter.

Assigning a return value

You can specify the return value of the Function by explicitly setting the value, either by assigning a value to the FUNCTION keyword, or by assigning a value to the function name. For example, the two lines within the following Function block are equivalent:

FUNCTION AddData() AS LONG

[ statements ]

AddData = 123& ' Assign value to function name

FUNCTION = 123& ' Assign value to the function

END FUNCTION

Default return value

If the code within the Function does not explicitly set a return value, the default return value will be zero if the function returns a numeric data type, or an empty string if the function returns a string. For example:

FUNCTION AddData() AS LONG

[ statements ]

IF condition THEN

EXIT FUNCTION ' No assignment, will return 0&

FUNCTION = -1& ' An explicit return value

END IF

END FUNCTION

ScharfBASIC Functions cannot return an array as a Function return value. Pass the array as a parameter instead. For example:

lResult& = CheckTheData(InTheArray&())

[ statements ]

FUNCTION CheckTheData(lArr() AS LONG) AS LONG

[ statements ]

END FUNCTION

CALLBACK Return Value

Callback functions always return a long integer result. The primary purpose of this return value is to tell the ScharfBASIC DDT engine and the Windows operating system whether your Callback Function has processed this particular message. If you return the value TRUE (any non-zero value), you are asserting that the message was processed and no further handling is needed. If you return the value FALSE (zero), the ScharfBASIC DDT engine will manage the message for you, using the default message procedures in Windows. If you do not specify a return value in the function, ScharfBASIC chooses the value FALSE (zero) for you.

The term "process a message" may have many meanings. If it's a simple notification of a change in focus or style, which has no impact on your program, you may decide to consider it processed, yet do nothing. In other cases, your reaction could be quite complex and involved. As the programmer, that's your decision to make. But, regardless of your reaction, you should consider a message "processed" (returning a true value) whenever no further handling of the message (by DDT or Windows) is needed.

In some cases, especially when dealing with Common Controls and custom controls, you may be required to return a second result value through a special Windows data area named DWL_MSGRESULT. When you complete a Callback Function, ScharfBASIC automatically copies any non-zero return value to DWL_MSGRESULT, if you haven't done so already. Therefore, it's generally safe to ignore this requirement in your code.

In most cases, when you process a message, you'll return a generic value for TRUE, such as: FUNCTION = 1. However, some messages require that you return a special value for TRUE, such as a graphical brush handle. As long as the value is non-zero, you can return it in the normal manner (with FUNCTION = n ), since any non-zero value automatically implies that the message was processed.

That said, there are a few unique messages which may require special handling. Luckily, they're rare, but some just "break all the rules" listed above. For example, you might find one which requires a zero result, even when you have processed the message. You may find another which requires the return value be different from DWL_MSGRESULT. For these very special cases, you can simply specify two return values:

FUNCTION = 1, BrushHandle&

In this form, the first numeric expression specifies the value to be returned from the Callback Function. The second numeric expression tells the value to be assigned to DWL_MSGRESULT. When you use this double parameter assignment, the results are absolute. ScharfBASIC assumes you have processed the message, regardless of the values given. ScharfBASIC makes no other assumptions of any kind about these values. A double parameter function assignment is only allowed in a Callback Function.

Previous versions of ScharfBASIC did not offer a double parameter form of function return. This caused some difficulty with a few Windows messages which required a special return value of zero. If you return a value of zero (0) with the single parameter form, it implies the message was not processed at all by the Callback. This issue is totally circumvented by the double parameter form.

Variables within functions

LOCAL variables are created within the procedures stack frame. If a LOCAL variable exceeds the amount of stack space available, it may become necessary to use a STATIC or GLOBAL variable instead. For example, creating a LOCAL Nul-Terminated string or LOCAL fixed-length string that is very large (say, approaching 1 MB) can trigger a General Protection Fault (GPF) because it may overrun the stack frame.

See Also

  • DECLARE
  • EXIT
  • FASTPROC
  • FUNCNAME$
  • GLOBAL
  • INSTANCE
  • ISMISSING
  • LOCAL
  • METHOD
  • PROPERTY
  • STATIC
  • SUB
  • THREAD CREATE
  • THREADID


LibMain - ScharfBASIC Help

LibMain

In addition to the functions you want to export (plus any supporting private routines), a DLL can contain an optional function called LIBMAIN (or its synonyms DLLMAIN and PBLIBMAIN ). Windows calls LI

Kind | Keyword
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Creating a Dynamic Link Library

Private and Exported Procedures

What is an object, anyway?

What is a COM component?


METHOD / END METHOD statements - ScharfBASIC Help

METHOD / END METHOD statements

Define a

Kind | Statement
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

[CLASS|OVERRIDE] METHOD name [< DispID >] [ALIAS " altname "] (var AS type ...) [THREADSAFE] [AS type ]
[ statements ]
METHOD = expression
END METHOD

Description

METHOD/END METHOD is used to define a METHOD procedure within a class. Standard methods can only be called through a virtual function table on a valid object .

A METHOD is a block of code, very similar to a user-defined function. Optionally, it can return a value, like a FUNCTION , or merely act as a subroutine, like a SUB . If the optional "AS type" is included, the method returns a value set by " Method = expr ", or defaults to a return value of zero (0) or nul string , depending upon the type. METHOD parameters may be any variable type, including VARIANT variables. Methods may be called using any of the five following forms:

DIM ObjVar AS MyInterface

LET ObjVar = NEWCOM Prgid$

1. ObjVar.Method1(param)

2. CALL ObjVar.Method1(param)

3. ObjVar.Method1(param) TO var

4. CALL ObjVar.Method1(param) TO var

5. var = ObjVar.Method1(param)

Forms 1 and 2 assume that the Method does not return a value, or you simply wish to discard it. Forms 3, 4, and 5 require that the Method return a value compatible with the type of variable specified as var . Parentheses enclosing parameters are optional in forms 1 and 3.

Methods may be declared (using AS type ...) to return a string, any of the numeric types, a specific class of object variable (AS MyClass), a Variant, or a user defined Type .

Type Libraries only support the following data types: BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , CURRENCY , OBJECT , STRING , and VARIANT . If any Methods or Properties use data types not supported by Type Libraries, you will receive a Error 581 - Type Library creation error , when using the #COM TLIB ON metastatement.

In addition to the explicit return value which you declare, all Methods and Properties on an IAutomation or IDispatch interface have another "Hidden Return Value", which is cryptically named hResult. While the name would imply a handle for a result, it's really not a handle at all, but just a long integer value, used to indicate success or failure of the Method. After calling a Method or Property, you can retrieve the hResult value with the ScharfBASIC function OBJRESULT . The most significant bit of the value is known as the severity bit. That bit is 0 (value is positive) for success, or 1 (value is negative) for failure. The remaining bits are used to convey error codes and additional status information. If you call any object Method/Property (either Dispatch or Direct ), and the severity bit of hResult is set, ScharfBASIC generates Run-Time error 99 : Object error. When you create a Method or Property, ScharfBASIC automatically returns an hResult of zero, which implies success. You can return a non-zero hResult value by executing a METHOD OBJRESULT = expr within a Method, or PROPERTY OBJRESULT = expr within a Property.

Class Methods

A CLASS METHOD is one which is private to the class in which it is located. That is, it may only be called from a METHOD or PROPERTY in the same class. The CLASS METHOD must be located within a CLASS block, but outside of any INTERFACE blocks. This shows it is a direct member of the class, rather than a member of an interface .

CLASS MyClass

INSTANCE MyVar AS LONG

CLASS METHOD MyClassMethod(BYVAL param AS LONG) AS STRING

METHOD = "My" + STR$(param + MyVar)

END METHOD

INTERFACE MyInterface

INHERIT IUNKNOWN

METHOD MyMethod()

Result$ = ME.MyClassMethod(66)

END METHOD

END INTERFACE

END CLASS

In the above example, MyClassMethod() is a CLASS METHOD, and is always accessed using the pseudo-object ME (in this case ME.MyClassMethod). Class methods are never accessible from outside a class, nor are they ever described or published in a type library. By definition, there is no reason to have a private PROPERTY, so ScharfBASIC does not offer a CLASS PROPERTY structure.

Constructors and Destructors

There are two special class methods which you may optionally add to a class. They meet a very specific need: automatic initialization when an object is created, and cleanup when an object is destroyed. Technically, they are known as constructor and destructor methods, and can perform almost any functionality needed by your object: initialization of variables, reading/writing data to/from disk, etc. You do not call these methods directly from your code. If they are present in your class, ScharfBASIC automatically calls them each time an object of that class is created or destroyed. If you choose to use them, these special class methods must be named CREATE and DESTROY. They may take no parameters, and may not return a result. They are defined at the class level, so they may never appear within an INTERFACE definition.

CLASS MyClass

INSTANCE MyVar AS LONG

CLASS METHOD CREATE()

' Do initialization

END METHOD

CLASS METHOD Destroy()

' Do cleanup

END METHOD

INTERFACE MyInterface

INHERIT IUNKNOWN

METHOD MyMethod()

' Do things

END METHOD

END INTERFACE

END CLASS

As displayed above, CREATE and DESTROY must be placed at the class level, but outside of any interface block. You should note that it's not possible to name any standard method (one that's accessible through an interface) as CREATE or DESTROY. That's just to help you remember the rules for a constructor or destructor. However, you may use these names as needed to describe a method external to your program.

A very important caution: You must never create an object of the current class in a CREATE method. To do so will cause CREATE to be executed again and again until all available memory is consumed. This is a fatal error, from which recovery is impossible.

Override Methods

You can add to, or replace, the functionality of a particular method or property of an inherited base class by coding a replacement which is preceded by the word OVERRIDE. The overriding method must have the same name and signature (parameters, return value, etc.) as the one it replaces.

Dispatch ID

Every method and property in a dual interface needs a positive, long integer value to identify it. That integer value is known as a DispID (Dispatch ID), and it's used internally by COM services to call the correct function on a Dispatch interface. You can optionally specify a particular DispID by enclosing it in angle brackets immediately following the Method/Property name:

METHOD MethodOne <76> ()

If you don't specify a DispID, ScharfBASIC will assign a random value for you. This is fine for internal objects, but may cause a failure for published COM objects, as the DispID could change each time you compile your program. It is particularly important that you specify a DispID for each Method/Property in a COM Event Interface .

BYREF and BYVAL attributes

Just like a SUB or FUNCTION, ScharfBASIC uses BYREF parameters as the default form, unless you specify a BYVAL override. Either key word can be placed before the parameter name, along with IN, OUT, and INOUT, as described later.

A copy of the data value is placed on the stack as a parameter. The copy is destroyed when the METHOD ends. BYVAL parameters default to an IN parameter, if no explicit direction is specified.

A pointer to the data is placed on the stack as a parameter. If the data is a variable, any changes to the parameter are passed back to the caller in the variable. If the data is an expression, it is destroyed when the METHOD ends. BYREF parameters default to an INOUT parameter, if no explicit direction is specified.

Direction attributes

METHOD parameters may also specify the direction in which data is passed between the caller and callee:

Data is passed from the caller to the METHOD. Generally speaking, you'll find that almost all IN parameters are passed BYVAL, and that is highly recommended. However, it is possible to pass them BYREF if necessary.

Data is passed from the METHOD back to the caller. All OUT parameters must be passed BYREF.

Data is passed from the caller to the METHOD, and results are returned to the caller in the same parameter. All INOUT parameters must be passed BYREF.

In many cases, the direction of a parameter can be inferred directly from the BYVAL/BYREF attribute (BYVAL=IN, BYREF=OUT). However, we recommend that you include the direction attribute as an added means of self-documentation. Each METHOD parameter name may be preceded by one of BYVAL/BYREF, and one of IN/OUT/INOUT, in any sequence.

You should note an interesting rule of COM objects: IN parameters are read-only. They may not be altered.

IN parameters are considered by COM rules to be "constant" which may not be altered, because they are values which are not returned to the caller. However, since this is not a rule normally applied to a standard SUB or FUNCTION, it can allow programming bugs which are most difficult to find and correct. For this reason, ScharfBASIC automatically protects you from this issue with no action needed on your part. When writing METHOD or PROPERTY code in ScharfBASIC, you may freely assign new values to BYVAL/IN parameters. They will simply be discarded when the METHOD exits. Of course, not every programming language protects you in this way, so you must use caution if you create a COM METHOD in another compiler.

Using OPTIONAL/OPT

METHOD statements may specify one or more parameters as optional by preceding the parameter with either the keyword OPTIONAL (or the abbreviation OPT). When a parameter is declared optional, all subsequent parameters in the declaration are optional as well, whether or not they specify an explicit OPTIONAL or OPT directive.

VARIANT variables are particularly well suited for use as an optional parameter. If the calling code omits an optional VARIANT parameter, (BYVAL or BYREF), ScharfBASIC (and most other compilers) substitute a variant of type %VT_ERROR which contains an error value of %DISP_E_PARAMNOTFOUND (&H80020004). In this case, you can check for this value directly, or use the ISMISSING function to determine whether the parameter was physically passed or not.

When optional parameters (other than VARIANT) are omitted from the calling code, the stack area normally reserved for those parameters is zero-filled.

If the parameter is defined as a BYVAL parameter, it will have the value zero. For TYPE or UNION variables passed BYVAL, the compiler will pass a string of binary zeroes of length SIZEOF ( Type_or_union_var ).

If the parameter is defined as a BYREF parameter, VARPTR ( Varname ) will equal zero; when this is true, any attempt to use Varname in your code will result in a General Protection Fault or memory corruption. You should use the ISMISSING() function first to determine whether it is safe to access the parameter.

THREADSAFE Option Descriptor

If you include the option THREADSAFE, ScharfBASIC automatically establishes a semaphore which allows only one thread to execute it at a time. Others must wait until the first thread exits the THREADSAFE procedure before they are allowed to begin.

See Also

  • #COM
  • CLASS
  • INSTANCE
  • INTERFACE (Direct)
  • ISMISSING
  • Just what is COM?
  • ME
  • PROPERTY
  • What is an object, anyway?


PBLIBMAIN - ScharfBASIC Help

PBLIBMAIN

PBLIBMAIN performs a similar task to

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FUNCTION PBLIBMAIN [()] [AS LONG]

Description

See LIBMAIN / DLLMAIN for more information.

See Also

  • DLLMAIN
  • LIBMAIN
  • PBMAIN
  • THREAD CREATE
  • WINMAIN


PBMAIN - ScharfBASIC Help

PBMAIN

PBMAIN is a user-defined function called by Windows to begin running an executable application. Every ScharfBASIC executable (EXE) must contain either a PBMAIN or a

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FUNCTION PBMAIN [()] [AS LONG]

Description

Return value: The return value of PBMAIN has an effective range of 0 to 255. Batch files may act on the result through the IF [NOT] ERRORLEVEL batch command.

Either a PBMAIN or WINMAIN function is required in every ScharfBASIC application (.EXE). If you use PBMAIN, no parameters are passed, and you cannot directly obtain the instance handle of your application or the pointer to any command-line parameters.

However, you can use COMMAND$ to get the command-line passed to your program, and the GetModuleHandle API function to get the application instance handle.

Restrictions

DLLs created with ScharfBASIC should contain a DLLMAIN , LIBMAIN , or PBLIBMAIN function instead of PBMAIN/WINMAIN.

See Also

  • COMMAND$
  • DLLMAIN
  • LIBMAIN
  • PBLIBMAIN
  • WINMAIN


Private and Exported Procedures - ScharfBASIC Help

Private and Exported Procedures

There are two basic types of procedures in a DLL : private and exported. Exported procedures are those which are made available to applications and other DLLs. Private, or local, procedures are suppor

Kind | Keyword
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

In the following example, the first procedure defines an exported Sub that accepts two arguments: a string and an Integer . The second procedure defines an exported function that accepts a single string argument, and returns an Integer. Finally, the third procedure defines a private Sub that accepts a single Integer argument. The first two routines are callable from an external .EXE or another DLL. The third one is not.

SUB MySub (sArg AS STRING, BYVAL iArg AS INTEGER) EXPORT

FUNCTION MyFunc (sArg AS STRING) EXPORT AS INTEGER

SUB MyPrivateSub(BYVAL iArg AS INTEGER)


PROPERTY / END PROPERTY - ScharfBASIC Help

PROPERTY / END PROPERTY

Define a

Kind | Statement
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

[OVERRIDE] PROPERTY GET|SET name [< DispID >] [ALIAS " altname "] ( var AS type ...) [THREADSAFE] [AS type ]
[ statements ]
PROPERTY = expression
END PROPERTY

Description

PROPERTY/END PROPERTY is used to define a PROPERTY procedure within a class. Properties can only be called through a virtual function table on an active object . A PROPERTY is a special type of METHOD , which is only used to set or retrieve data in an object. While the work of a PROPERTY could readily be accomplished with a standard METHOD, this distinction is convenient to emphasize the concept of encapsulation of instance data within an object. There are two forms of PROPERTY procedures: PROPERTY GET and PROPERTY SET. As implied by the names, the first form is used to retrieve a data value from the object, while the second form is used to assign a value. Properties must be defined within a CLASS Block , and may only be declared within a DECLARE CLASS Block. Properties are defined:

PROPERTY GET name [ALIAS "altname"] (BYVAL var AS type...) [THREADSAFE] AS type

[ statements ]

PROPERTY = expression

END PROPERTY

PROPERTY SET name [ALIAS "altname"] (BYVAL var AS type...) [THREADSAFE]

[ statements ]

variable = value

END PROPERTY

When you use PROPERTY SET, the value to be assigned is passed to the right of an equal sign, just like a normal assignment to a variable:

Properties can only be called through a virtual function table on an active object. Property parameters may be of any variable type.

ObjVar.Prop1 = NewValue

A PROPERTY may be considered "Read-Only" or "Write-Only" by simply omitting one of the two definitions. However, if both GET and SET forms are defined for a particular property, all parameters and the property data type must be identical in both forms, and they must be paired. That is, the PROPERTY SET must immediately follow the PROPERTY GET.

Property parameters may be of any variable type.

You can access a PROPERTY GET with:

DIM ObjVar AS MyInterface

LET ObjVar = NEWCOM Prgid$

1. ObjVar.Prop1(param) TO var

2. CALL ObjVar.Prop1(param) TO var

3. var = ObjVar.Prop1(param)

You can access a PROPERTY SET with:

DIM ObjVar AS MyInterface

LET ObjVar = NEWCOM Prgid$

1. ObjVar.Prop1(param) = expr

2. CALL ObjVar.Prop1(param) = expr

Note that the choice of Property procedure is syntax directed. In other words, depending upon the way you use the name, ScharfBASIC will automatically decide whether the GET or SET PROPERTY should be called.

In every Method and Property, ScharfBASIC automatically defines a pseudo-variable named ME , which is treated as a reference to the current object. Using ME, it's possible to call any other Method or Property which is a member of the class: var = ME. Method1 ( param )

Methods may be declared (using AS type ...) to retu rn a string , any of the numeric types, a specific class of object variable (AS MyClass), a Variant , or a user defined Type .

Type Libraries only support the following data types: BYTE , WORD , DWORD , INTEGER , LONG , QUAD , SINGLE , DOUBLE , CURRENCY , OBJECT , STRING , and VARIANT . If any Methods or Properties use data types not supported by Type Libraries, you will receive a Error 581 - Type Library creation error , when using the #COM TLIB ON metastatement.

In addition to the explicit return value which you declare, all COM Methods and Properties have another "Hidden Return Value", which is cryptically named hResult . While the name would imply a handle for a result, it's really not a handle at all, but just a long integer value, used to indicate success or failure of the Method. After calling a Method or Property, you can retrieve the hResult value with the ScharfBASIC function OBJRESULT . The most significant bit of the value is known as the severity bit. That bit is 0 (value is positive) for success, or 1 (value is negative) for failure. The remaining bits are used to convey error codes and additional status information. If you call any object Method/Property (either Dispatch or Direct ), and the severity bit in the returned hResult is set, ScharfBASIC generates Run-Time error 99 : Object error. When you create a Method or Property, ScharfBASIC automatically returns an hResult of zero, which implies success. You can return a non-zero hResult value by executing a METHOD OBJRESULT = expr within a Method, or PROPERTY OBJRESULT = expr within a Property.

Every method and property in a dual interface needs a positive, long integer value to identify it. That integer value is known as a DispID (Dispatch ID), and it's used internally by COM services to call the correct function on a Dispatch interface. You can optionally specify particular DispID by enclosing it in angle brackets immediately following the Method/Property name:

METHOD MethodOne <76> ()

If you don't specify a DispID , ScharfBASIC will assign a random value for you. This is fine for internal objects, but may cause a failure for published COM objects , as the DispID could change each time you compile your program. It is particularly important that you specify a DispID for each Method/Property in a COM Event Interface .

Override Properties

You can add to, or replace, the functionality of a particular method or property of an inherited base class by coding a replacement which is preceded by the word OVERRIDE. The overriding method must have the same name and signature (parameters, return value, etc.) as the one it replaces.

BYREF and BYVAL parameters

A copy of the data value is placed on the stack as a parameter. The copy is destroyed when the PROPERTY ends. BYVAL parameters default to an IN attribute, if no explicit direction is specified.

A pointer to the data is placed on the stack as a parameter. This option may not be used with an internal PROPERTY parameter.

Direction attributes

PROPERTY parameters also specify the direction in which data is passed between the caller and callee:

Data is passed from the caller to the PROPERTY. Generally speaking, you'll find that almost all IN parameters are passed BYVAL, and that is highly recommended. However, it is possible to pass them BYREF if necessary.

Data is passed from the PROPERTY back to the caller. All OUT parameters must be passed BYREF.

Data is passed from the caller to the PROPERTY, and results are returned to the caller in the same parameter. All INOUT parameters must be passed BYREF.

In many cases, the direction of a parameter can be inferred directly from the BYVAL/BYREF attribute (BYVAL=IN, BYREF=OUT). However, we recommend that you include the direction attribute as an added means of self-documentation. Each METHOD parameter name may be preceded by one of BYVAL/BYREF, and one of IN/OUT/INOUT, in any sequence.

You should note an interesting rule of COM objects: IN parameters are read-only. They may not be altered.

IN parameters are considered by COM rules to be "constant" which may not be altered, because they are values which are not returned to the caller. However, since this is not a rule normally applied to a standard SUB or FUNCTION , it can allow programming bugs which are most difficult to find and correct. For this reason, ScharfBASIC automatically protects you from this issue with no action needed on your part. When writing METHOD or PROPERTY code in ScharfBASIC, you may freely assign new values to BYVAL/IN parameters. They will simply be discarded when the METHOD exits. Of course, not every programming language protects you in this way, so you must use caution if you create a COM METHOD in another compiler.

Using OPTIONAL/OPT

PROPERTY statements may specify one or more parameters as optional by preceding the parameter with either the keyword OPTIONAL (or the abbreviation OPT). When a parameter is declared optional, all subsequent parameters in the declaration are optional as well, whether or not they specify an explicit OPTIONAL or OPT directive.

VARIANT variables are particularly well suited for use as an optional parameter. If the calling code omits an optional VARIANT parameter, (BYVAL or BYREF), ScharfBASIC (and most other compilers) substitute a variant of type %VT_ERROR which contains an error value of %DISP_E_PARAMNOTFOUND (&H80020004). In this case, you can check for this value directly, or use the ISMISSING function to determine whether the parameter was physically passed or not.

When optional parameters (other than VARIANT) are omitted from the calling code, the stack area normally reserved for those parameters is zero-filled.

If the parameter is defined as a BYVAL parameter, it will have the value zero. For TYPE or UNION variables passed BYVAL, the compiler will pass a string of binary zeroes of length SIZEOF ( Type_or_union_var ).

If the parameter is defined as a BYREF parameter, VARPTR ( Varname ) will equal zero; when this is true, any attempt to use Varname in your code will result in a General Protection Fault or memory corruption. You should use the ISMISSING() function first to determine whether it is safe to access the parameter.

THREADSAFE Option Descriptor

If you include the option THREADSAFE, ScharfBASIC automatically establishes a semaphore which allows only one thread to execute it at a time. Others must wait until the first thread exits the THREADSAFE procedure before they are allowed to begin.

See Also

  • #COM
  • CLASS
  • INSTANCE
  • INTERFACE (Direct)
  • INTERFACE (IDBind)
  • ISINTERFACE
  • ISNOTHING
  • ISMISSING
  • ISOBJECT
  • Just what is COM?
  • LET (with Objects)
  • ME
  • METHOD
  • OBJACTIVE
  • OBJPTR
  • OBJRESULT
  • What is an object, anyway?


RETURN - ScharfBASIC Help

RETURN

Return from a (

Kind | Statement
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

Return value: RETURN FLUSH

RETURN terminates the execution of a subroutine, and passes control to the statement directly following the calling GOSUB statement.

RETURN FLUSH removes the most recent return address from the system stack and program flow continues normally after the RETURN FLUSH.

Performing either form of RETURN without a corresponding GOSUB can cause unpredictable behavior and difficult-to-track errors. This includes the possibility of a General Protection Fault (GPF).

See Also

  • CALL
  • GOSUB
  • GOTO
  • ON ERROR
  • SUB/END SUB

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   DWORD PTR [ebp-0x98],esi


SUB/END SUB statements - ScharfBASIC Help

SUB/END SUB statements

Define a Sub code section.

Kind | Statement
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SUB ProcName [ALIAS " AliasName "] [( arguments )] < Descriptors >
[ statements ]
END SUB

Description

All executable code must reside in a Sub, Function . Method , Property , or FastProc block. Subs may not be nested. That is, you cannot define a code block (Sub, Function, Method, FastProc, Property) inside another code block.

SUB and END SUB define a subroutine-like block of statements called a procedure (or subprogram), which is invoked with the CALL statement, and may be passed parameters by value or by reference. A Sub may also be invoked without the use of the CALL statement. If the CALL word is omitted, the parentheses around the arguments list must also be omitted.

Previous versions of ScharfBASIC required that you create an explicit DECLARE statement if you wished to execute a SUB or FUNCTION which did not physically precede the reference to it. This extra work is no longer required, as ScharfBASIC resolves all forward references to internal procedures automatically.

DECLARE statements for a Sub/Function imported from a DLL must still precede any reference to the procedure.

ProcName

The name of the Sub. ProcName must be unique: no other variable, Function, Sub, Method, Property, FastProc or label can share it.

String literal that identifies a case-sensitive alternative name for the sub. This lets you export a Sub by a different unique name. This can be useful if you want to abbreviate a long name, provide a more descriptive name, or if the exported name needs to contain characters that are illegal in ScharfBASIC. AliasName is the routines actual name as it appears in the export table, and ProcName is the title that you can use in ScharfBASIC. For example:

SUB ShortName ALIAS "LongProcName" () EXPORT STATIC

The ALIAS clause is very important when exporting procedures. Omitting the ALIAS clause or incorrectly capitalizing the alias name are common causes of "Missing Export" errors. Please refer to the DECLARE topic for more information.

Descriptors

You may optionally add one or more descriptor words (Export, Common, Private, ThreadSafe, Local, Static, BDecl, CDecl, SDecl) to provide specific functionality. They may be added to the SUB as a comma delimited list. You should note that some of them are mutually exclusive.

EXPORT

This descriptor identifies a Sub or Function which may be accessed between Dynamic Link Libraries (DLLs), and/or the main executable which links them. If a procedure is not marked EXPORT, it is hidden from these other modules. The EXPORT attribute may be added to a Sub/Function defined elsewhere, by specifying EXPORT in a DECLARE statement. EXPORT can even be added to a Sub/Function in an SLL with a DECLARE in the host module.

COMMON

A COMMON Sub/Function is one which may be referenced by and between linked unit modules (Host or SLL ). If you DECLARE a Common Sub or Function which is not present in this module, it is presumed to be found in a separate linked module (Host or SLL).

PRIVATE

A PRIVATE Sub/Function is one which may only be accessed from within the current ScharfBASIC program or library. Even if not specified, this is the default mode of operation.

THREADSAFE

With the THREADSAFE option, ScharfBASIC automatically establishes a semaphore which allows only one threa d to execute the Sub/Function at a time. Other callers must wait until the first thread exits the THREADSAFE procedure before they are allowed to begin.

This descriptor specifies that all undeclared variables in a sub are LOCAL . This is the default condition if neither LOCAL nor STATIC is specified.

Local variables and arrays variables are automatically deallocated when the procedure terminates. LOCAL scalar variables (except dynamic strings ) are stored on the stack , and visible only within the sub.

STATIC

This descriptor specifies that all undeclared variables in a sub are STATIC. Static variables retain their values as long as the program is running. They are visible only within the sub.

Specifies that the declared procedure uses the legacy BASIC/Pascal calling convention. Parameters are pushed on the stack from left to right, and the called procedure is responsible for removing them. BDECL should only be used when necessary to match outside modules.

Specifies that the declared procedure uses the C calling convention. Parameters are pushed on the stack from right to left, and the calling code is responsible for removing them. CDECL should only be used when necessary to match outside modules.

This is the default convention, and should be used whenever possible. SDECL (and its synonym STDCALL), specifies the "Standard Calling Convention" for Windows. Parameters are pushed on the stack from right to left, and the called procedure is responsible for removing them.

Passing Parameters

Arguments

An optional, comma-delimited sequence of formal parameters. The parameters used in the arguments list serve only to define the Function; they have no relationship to other variables in the calling code with the same name.

Normally, ScharfBASIC passes parameters to a Sub either by reference (BYREF) or by value (BYVAL). If you do not need to modify the parameters (true in many cases), you can speed up your calls by passing the parameters by value using the BYVAL keyword. You can clarify that a parameter is passed by reference by using the optional BYREF keyword.

The type of the parameter is specified either by appending a type-specifier character to the name or by using an AS clause. For example:

SUB Test(A AS INTEGER) ' integer passed by reference

SUB Test(A%) ' integer passed by reference

SUB Test(BYREF A%) ' integer passed by reference

SUB Test(BYVAL A%) ' integer passed by value

Parameter Restrictions

ScharfBASIC compilers have a limit of 32 parameters per Sub. To pass more than 32 parameters to a FUNCTION, construct a User-Defined Type (UDT) and pass the UDT by reference (BYREF) instead.

Pointer Parameters

When a Sub definition specifies either a BYREF parameter or a pointer variable parameter, the calling code may freely pass a BYVAL DWORD or a Pointer instead. Pointer variable parameters must always be declared as BYVAL parameters.

' Integer Pointer (passed by value)

SUB Test(BYVAL A AS INTEGER PTR)

@A = 56

END SUB

Additional information on BYVAL/BYREF/BYCOPY parameter passing can be found in the CALL statement topic.

Using OPTIONAL/OPT

SUB statements may specify one or more parameters as optional by preceding the parameter with either the keyword OPTIONAL or OPT. Optional parameters are only allowed with CDECL or SDECL calling conventions, not BDECL.

When a parameter is declared optional, all subsequent parameters in the declaration are optional as well, whether or not they specify an explicit OPTIONAL or OPT directive. The following two lines are equivalent, with both second and third parameters being optional:

SUB sABC(a&, OPTIONAL BYVAL b&, OPTIONAL BYVAL c&)

SUB sABC(a&, OPT BYVAL b&, BYVAL c&)

VARIANT variables are particularly well suited for use as an optional parameter. If the calling code omits an optional VARIANT parameter, (BYVAL or BYREF), ScharfBASIC (and most other compilers) substitute a variant of type VT_ERROR which contains an error value of %DISP_E_PARAMNOTFOUND (&H80020004). In this case, you can check for this value directly, or use the ISMISSING() function to determine whether the parameter was physically passed or not.

When optional parameters (other than a VARIANT) are omitted in the calling code, the stack area normally reserved for those parameters is zero-filled. This allows you to test if an optional parameter was passed or not.

If the parameter is defined as a BYVAL parameter, it will have the value zero. For TYPE or UNION variables passed BYVAL, the compiler will pass a string of binary zeroes of length SIZEOF ( Type _or_ union_var ).

If the parameter is defined as a BYREF parameter, VARPTR ( varname ) will equal zero; when this is true, any attempt to use varname in your code will result in Error #9 (null pointer); failure to detect this error using error-trapping may result in a General Protection Fault or memory corruption. You should use the ISMISSING() function first to determine whether it is safe to access the parameter.

Because the FUNCTION, SUB, FASTPROC, METHOD, or PROPERTY being called does not know how many parameters are being passed at the time it is called, you should pass the number of parameters as one of the required parameters in the list.

Variables within Subs

LOCAL variables are created within the procedure stack frame. If a LOCAL variable exceeds the amount of stack space available, it may become necessary to use a STATIC or GLOBAL variable instead. For example, creating a LOCAL nul-terminated or LOCAL fixed-length string that is very large (say, approaching 1 MB) can trigger a General Protection Fault (GPF) because it may overrun the stack frame.

Procedure definitions and program flow

The position of procedure definitions is mostly immaterial. They are usually grouped together in one region of the source code, but you cannot nest procedure definitions. That is, you cannot define a procedure within another procedure (although a procedure definition can contain calls to other procedures). Unlike subroutines (see GOSUB ), program execution cannot accidentally "fall into" a procedure, even if it is located before the PBMAIN or WINMAIN Function in your code. For example:

#COMPILE EXE

SUB DisplayInfo(a$)

' Code goes here

END SUB

FUNCTION PBMAIN

' Main program code goes here

END FUNCTION

When this program is executed, the code in DisplayInfo is only executed if the procedure is explicitly called, even though it is located earlier in the source code file. Procedure definitions should be treated like isolated islands of code; do not jump in or out of them with GOTO , GOSUB or RETURN . Within a procedure block, such statements are legal.

See Also

  • CALL
  • DECLARE
  • EXIT SUB
  • FASTPROC
  • FUNCNAME$
  • FUNCTION/END FUNCTION
  • GLOBAL
  • GOSUB
  • ISMISSING
  • LOCAL
  • RETURN
  • STATIC

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   esi,DWORD PTR [ebp+0x8]
ret   0x4


WINMAIN - ScharfBASIC Help

WINMAIN

WINMAIN (or its synonym

Kind | Function
Category | Procedures
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FUNCTION {WINMAIN | MAIN} ( _
BYVAL hInstance AS DWORD, _
BYVAL hPrevInst AS DWORD, _
BYVAL lpszCmdLine AS WSTRINGZ PTR, _
BYVAL nCmdShow AS LONG ) AS LONG

Description

Return value: The return value assigned to WINMAIN is optional, but by convention, the return value is derived from the wParam& parameter of a %WM_QUIT message. Typically, a GUI-based application uses the WINMAIN function to create the initial GUI application window, and then enters a message loop. This loop should terminate when a %WM_QUIT message is received, and the wParam& parameter of that message should be passed on as the return value for WINMAIN. If WINMAIN terminates before entering the message loop, WINMAIN should return zero. Console applications may use the return value to set an error level that can be passed back to the calling application, in the range 0 to 255 inclusive. Batch files may act on the result through the IF [NOT] ERRORLEVEL batch command. If the parameters passed to WINMAIN are not required by the application itself, the PBMAIN function may be used in place of WINMAIN.

The WINMAIN function is called by Windows when an executable application first loads and begins to run. It is often referred to as the "entry point" for the application. When the execution of WINMAIN is completed, the application is deemed to be finished, and Windows releases the application memory back to the heap. WINMAIN receives the following parameters:

hInstance

The executable's (EXE) instance handle . Each instance of a Windows application has a unique handle. It is used as a parameter to a number of Windows API functions which may need to distinguish between multiple instances of an application.

hPrevInst

Not used by 32-bit Windows. It is present merely for compatibility with existing 16-bit code, and always returns zero in 32-bit applications.

lpszCmdLine

A pointer to an nul-terminated string that contains a command-line. Note that the string passed in lpszCmdLine is not the same as the string returned by the GetCommandLine API call. The string in lpszCmdLine contains the command-line arguments only (like COMMAND$ ), but GetCommandLine returns the program name (including path) followed by the arguments.

nCmdShow

Specifies how to display the application's main window. For example, the calling application can specify %SW_NORMAL or %SW_MINIMIZE, etc. It is up to the programmer to honor this parameter, and to do so is recommended.

Restrictions

Pointers may not be passed BYREF , so the lpszCmdLine parameter of WINMAIN must be declared to be passed BYVAL .

See Also

  • PBMAIN


ACODE$ - ScharfBASIC Help

ACODE$

Translates

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = ACODE$( UnicodeStrExpression [, CodePage& ])

Description

This version of ScharfBASIC handles all conversions between ANSI strings and UNICODE strings automatically. For example:

MyAnsiString$ = MyWideString$$

In this case, the wide characters are transparently converted to byte characters when they are stored in MyAnsiString$ . You should not insert an ACODE$ function here. The simple fact that the variables are of differing types (ANSI/WIDE) causes the compiler to make all conversions for you, whenever they are needed.

Of course, this automatic conversion was not available in previous versions of the compiler. In the past, there were no WIDE UNICODE variables offered, so it was necessary to force wide characters into standard byte strings when UNICODE was needed. The ACODE$ and UCODE$ functions are used for this purpose alone: to support legacy programs which calculated strings in this fashion.

New ScharfBASIC programs and updates to your older ScharfBASIC programs should use the new WIDE UNICODE variables which are now available.

ACODE$ presumes that the UnicodeStrExpression contains WIDE UNICODE characters stored in an ANSI byte string. It converts them into ANSI byte characters and returns them as an ANSI string. To convert an ANSI byte string into a UNICODE byte string, use the UCODE$ function.

If the optional parameter CodePage& is present, it represents the code page to be used for the conversion process. If not given, the default code page for the locale of the executing computer is used.

Unicode strings require two bytes to represent a Unicode character, whereas ANSI strings (the native ScharfBASIC string format) use one byte to represent a character. Therefore, ACODE$ returns a string that has half of the byte count of the Unicode string, yet represents the same number of characters.

See Also

  • UCODE$
  • UCODEPAGE


ASC - ScharfBASIC Help

ASC

Replaces one character in a string

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ASC( stringvar , position& ) = CharCode&

Description

The ASC statement replaces one character in a string variable. The position& parameter determines which character is replaced. The first character is one, the second two, etc. If position& is negative, ASC counts from the end of the string in reverse. That is, -1 specifies the last character, -2 specifies the second to last character, etc.

If the stringVar is ANSI , the CharCode must be in the range of 0 to 255. If Unicode , the CharCode must be in the range of 0 to 65535.

Restrictions

The ASC statement cannot be used to extend the length of a string. If string is null (zero-length), or position is zero or greater than the length of stringvar , the operation is ignored.

See Also

  • ASC function
  • CHR$
  • MID$ statement

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201e3c
call   0x201dbf
call   0x201e3c
call   0x201dbf
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201da8
mov   eax,0x1
call   0x201be8
call   0x201cf0


BUILD$ - ScharfBASIC Help

BUILD$

Build or concatenate

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x$ = BUILD$( a$ , b$ , c$ , d$ ...)

Description

In some cases, string concatenation using the classic string operators can be a slow process. This is particularly true when there are many operands using longer strings. The BUILD$ function passes all the typical bottlenecks to create a new string at the greatest possible speed. The following 2 lines are functionally identical, but the BUILD$ version will execute substantially faster.

x$ = a$ + "bb" + c$ + y$(7) + y$(i&) + z$

x$ = BUILD$(a$, "bb", c$, y$(7), y$(i&), z$)

It's interesting to note that this string function could have been named APPEND$ or PREPEND$ because it performs these functionalities so well. For example, to prepend a topic number to text$ while also adding a period at the end, you could execute:

text$ = BUILD$( "1) ", text$, ".")

In order to extract the utmost efficiency, BUILD$() was designed to work with a very narrow definition. The component parameters must be dynamic string variables, either scalar or array , string literals , or string equates . They may not be expressions . There is virtually no limit as to the number of parameters.

The BUILD$() function is most valuable when you are concatenating numerous strings all at the same time. However, when you must add many string sections, in many separate operations, the StringBuilder object is much faster, and a more appropriate choice.

Generally speaking, the greater the number of parameters, the greater the increase in execution speed.

See Also

  • LET
  • CHR$
  • CSET
  • CSET$
  • JOIN$
  • LSET
  • LSET$
  • REPEAT$
  • RSET
  • RSET$
  • STRING$
  • STRINGBUILDER
  • STRINSERT$
  • WRAP$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x202a5c
call   0x201dd0
call   0x201d53
mov   edx,0x202a70
call   0x201dd0
call   0x201d53
push   DWORD PTR [ebp-0x9c]
push   DWORD PTR [ebp-0xa4]
mov   eax,0x3
call   0x2019b9
lea   ebx,[ebp-0xa0]
call   0x201d53
call   0x201c84


CHR$ - ScharfBASIC Help

CHR$

Converts one or more numeric character codes (

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = CHR$( expression [, expression ] [,...])
s$ = CHR$( string_expression [,...])
s$$ = CHR$$( x& TO y& , ...)

Description

The CHR$() form of the function creates a string of ANSI (1- byte ) characters. Arguments must be ANSI (1-byte) characters, or codes in the range of 0 to 255. The CHR$$() form of the function creates a string of WIDE (2-byte) characters. Arguments must be WIDE (2-byte) characters, or codes in the range of 0 to 65535.

Generally speaking, ScharfBASIC handles ANSI/WIDE conversions for you, automatically and transparently. However, there are just a few functions (CHR$, PEEK$ , POKE$ , STRING$ , etc.) which are ambiguous, by definition, and require that the programmer choose the appropriate result type (ANSI or WIDE). Use CHR$ for ANSI results, or use CHR$$ for Unicode results. In the remainder of these remarks, CHR$ is used to represent both CHR$ and CHR$$.

CHR$ creates and returns a string. There are three forms of arguments available, and they may be intermixed in a single CHR$ function. The created string may contain no characters, one character, or multiple characters, depending upon the arguments you use. You may specify any number of arguments for this function.

If the argument is a numeric expression, it is translated into the character defined by that number. A character code of -1 is treated as a special case. If you use it as an argument, CHR$ returns an empty (zero length) string for that character. For example, CHR$(65, -1, 66) returns "AB".

CHR$(x& TO y&) returns a sequence of all characters from CHR$(x&) through CHR$(y&) inclusive. The characters may be ascending or descending in sequence. For example, CHR$(65 TO 70) returns the string "ABCDEF". CHR$(52 T0 50) returns the string "432", and CHR$(65 TO 65) returns the string "A".

If the argument is a string expression, the characters are simply copied into the newly created string at the specified position. The expanded CHR$ definition is intended to assist in the encoding of longer strings, to avoid the need for concatenation operations.

For example, the CHR$ function can be used to create COLLATE strings for the ARRAY SORT and ARRAY SCAN statements at run-time, and can be used to create string equates at compile time:

$colstring = CHR$(0 TO 131, 97, 133 TO 255)

The following lines are functionally equivalent, and return the same string result:

a$ = CHR$("Line1", 13, 10, "Line2")

a$ = "Line1" & CHR$(13) & CHR$(10) & "Line2"

a$ = "Line1" & $CRLF & "Line2"

CHR$ complements the ASC function, which returns the numeric character code of a nominated character in a string.

See Also

  • ARRAY SCAN
  • ARRAY SORT
  • ASC function
  • ASC statement
  • NUL$
  • SPACE$
  • STRING$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201dc0
call   0x201d43
call   0x201dc0
call   0x201d43
mov   eax,0x41
call   0x201937
call   0x2018e8
lea   ebx,[ebp-0xa0]
call   0x201d43
call   0x201c74


CHRBYTES - ScharfBASIC Help

CHRBYTES

Determine the size of a single character in a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

siz& = CHRBYTES( MyStringVar )

Description

This function is used to determine whether a particular string variable contains ANSI characters or Unicode (wide) characters, ANSI characters are stored in 1 byte , so the function returns 1 if the variable is a dynamic string , stringz , string*n , or field string . Unicode characters are stored in 2 bytes, so the function returns 2 if the variable is a wstring , wstringz , wstring*n , or wfield string . This function may be particularly valuable in some macros which use string variables.

See Also

  • LEN
  • SIZEOF


CSET$ - ScharfBASIC Help

CSET$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

result_var = CSET$( string_expression , strlen& [USING ustring_expression ])

Description

CSET$ centers the string string_expression into a string of strlen& characters.

If ustring_expression is null (empty) or is not specified, CSET$ pads string_expression with space characters. Otherwise, CSET$ pads the string with the first character of ustring_expression .

If string_expression is shorter then strlen& , CSET$ centers string_expression within result_var, padding both sides as described above; otherwise, CSET$ returns the left-most strlen& bytes of string_expression .

See Also

  • CSET
  • GET
  • LET
  • LSET
  • LSET$
  • PUT
  • RESET
  • RSET
  • RSET$
  • STRINSERT$
  • TYPE SET


EXTRACT$ - ScharfBASIC Help

EXTRACT$

Extract characters from a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x$ = EXTRACT$([ start ,] MainStr , [ANY] MatchStr )

Description

E XTRACT$ returns a sub-string of MainStr , starting with its first character (or the character specified by start ) and up to (but not including) the first occurrence of MatchStr . If MatchStr is not present in MainStr , or either string parameter is nul, all of MainStr is returned.

start is the optional starting position to begin extracting. If start is not specified, it will start at position 1. If start is zero, or beyond the length of MainStr , a nul string is returned. If start is negative, the starting position is counted from right to left: if -1, the search begins at the last character; if -2, the second to last, and so forth.

MainStr is the string expression from which to extract. MatchStr is the string expression to extract up to. EXTRACT$ is case-sensitive.

If the ANY keyword is included, MatchStr specifies a list of single characters to be searched for individually, a match on any one of which will cause the extract operation to be performed up to that character.

EXTRACT$ is especially useful when parsing a string containing arguments to a program, or when manipulating nul-terminated or delimited strings received from a routine written in another language.

The complementary function to EXTRACT$ is REMAIN$ , which returns the part of the string that EXTRACT$ leaves behind. A similar function to EXTRACT$ is PARSE$ , which extracts delimited substrings from a string.

See Also

  • CLIP$
  • INSTR
  • JOIN$
  • LEFT$
  • LTRIM$
  • MID$
  • PARSE
  • PARSE$
  • PARSECOUNT
  • REMAIN$
  • REMOVE$
  • RETAIN$
  • RIGHT$
  • RTRIM$
  • TALLY
  • TRIM$
  • UNWRAP$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a5c
call   0x2020ac
call   0x20202f
mov   edx,0x203a70
call   0x2020ac
call   0x20202f
mov   edx,DWORD PTR [ebp-0x9c]
call   0x202018
mov   eax,0x1
mov   edx,0x203a54
call   0x2020ac
call   0x201b50
lea   ebx,[ebp-0xa0]
call   0x20202f
call   0x201f60


FORMAT$ - ScharfBASIC Help

FORMAT$

Format string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x$ = FORMAT$( num_expression [, [ digits& | fmt$ ]])

Description

FORMAT$ has the following parts:

num_expression

The numeric expression, variable , or literal value to be formatted. This argument is converted to full ( Extended ) precision before formatting commences.

digits&

The maximum number of significant digits, in the range of 1 to 18. If not included, ScharfBASIC supplies a default value of 7 for single precision values, or 16 for more precise values. This form of the function is very similar to the STR$() function, except that it never supplies any leading or trailing spaces. Use care that digits& is large enough to contain the whole part of a number, or scientific notation must be used to estimate it. For example, FORMAT$(123.456, 2) returns the string "1.2E+2", while FORMAT$(123.456, 5) returns the string "123.45".

Format characters that will determine how the numeric expression should be formatted. This expression is termed the mask . There may be up to 18 digit-formatting digits on either side of the decimal point. The mask may not contain literal characters unless each character is preceded with a backslash (\) escape character, or the literal characters are enclosed in quotes.

fmt$ may contain one, two or three formatting masks, separated by semicolon (;) characters:

One mask

If fmt$ contains just one format mask, the mask is used to format all possible values of num_expression . For example:

x$ = FORMAT$(z!, "000.00")

Two masks

If fmt$ contains two format masks, the first mask is used for positive values (=> 0), and the second mask is used for negative values (< 0). For example:

x$ = FORMAT$(-100, "+00000.00;-000")

Three masks

If fmt$ contains three masks, the first mask is used for positive values (> 0), the second mask for negative values (< 0), and the third mask is used if num_expression is zero (0). For example:

FOR y! = -0.5! TO 0.5! STEP 0.5!

x$ = FORMAT$(y!, "+.0;-.0; .0")

NEXT y!

Digit placeholders in a mask do not have to be contiguous. This allows you to format a single number into multiple displayed parts. For example:

A$ = FORMAT$(123456, "00\:00\:00") ' 12:34:56

The following table shows the characters you can use to create the user-defined format strings (masks) and the definition of each formatting character:

Character

Definition

Empty string

[null string] No formatting takes place. The number is converted to Extended-precision and formatted similarly to STR$, but without the leading space that STR$ applies to non-negative numbers.

A$=FORMAT$(0.2) ' .200000002980232

A$=FORMAT$(0.2!, "") ' .200000002980232

A$=FORMAT$(0.2#) ' .2

A$=FORMAT$(0.2#, "") ' .2

[zero] Digit placeholder. ScharfBASIC will insert a digit or 0 in that position.

If there is a digit in num_expression in the position where the 0 appears in the format string, return that digit. Otherwise, return "0". If the number being formatted has fewer digits than there are zeros (on either side of the decimal point) in the format expression, leading or trailing zeros are added. If the number has more digits to the right of the decimal point than there are zeros to the right of the decimal point in the format expression, the number is rounded to as many decimal places as there are zeros in the mask.

If the number has more digits to the left of the decimal point than there are zeros to the left of the decimal point in the format expression, the extra digits are displayed without truncation. If the numeric value is negative, the negation symbol will be treated as a decimal digit. Therefore, care should be exercised when displaying negative values with this placeholder style. In such cases, it is recommended that multiple masks be used.

' Numeric padded with leading zero characters

A$ = FORMAT$(999%, "00000000") ' 00000999

[Number symbol] Digit placeholder. If there is a digit for this position, ScharfBASIC replaces this placeholder with a digit, nothing, or a user-specified character.

Unlike the 0 digit placeholder, if the numeric value has the fewer digits than there are # characters on either side of the decimal placeholder, ScharfBASIC will either:

a) Omit this character position from the final formatted string; or

Substitute a user-specified replacement character if one has been defined (see the asterisk (*) character for more information). To specify leading spaces, prefix the mask with "* " (asterisk and a space character).

For example:

' No leading spaces and trailing spaces

A$ = FORMAT$(0.75!, "####.###") ' 0.75

' Up to 3 Leading spaces before decimal

A$ = FORMAT$(0.75!, "* ##.###") ' 0.75

' Using asterisks for padding characters

A$ = FORMAT$(0.75!, "*=##.###") ' ===0.75=

FORMAT$ may also return a string that is larger than the number of characters in the mask:

A$ = FORMAT$(999999.9, "#.#") ' 999999.9

[period] Decimal placeholder. Determines the position of the decimal point in the resultant formatted string.

If any numeric field is specified to the left of the decimal point, at least one digit will always result, even if only a zero. The zero is not considered to be a "leading" zero if it is the only digit to the left of the decimal. Placing more than one period character in the fmt$ string will produce undefined results.

[percent] Percentage placeholder. ScharfBASIC multiplies num_expression by 100, and adds a trailing percent symbol. For example:

x$ = FORMAT$(1 / 5!, "0.0%") ' 20.0%

[comma] Thousand separator. Used to separate thousands from hundreds within a number that has four or more digits to the left of the decimal point. In order to be recognized as a format character, the comma must be placed immediately after a digit placeholder character (also see Restrictions below).

A$ = FORMAT$(1234567@, "#,") ' 1,234,567

A$ = FORMAT$(12345@, "#,.00") ' 12,345.00

A$ = FORMAT$(12345@, "#.00,") ' 12,345.00

A$ = FORMAT$(1212.46, "$00,000.00") ' $01,212.46

A$ = FORMAT$(1000%, """#""#,") ' #1,000

A$ = FORMAT$(1234567@, "0,") ' 1,234,567

[asterisk] Digit placeholder and fill-character. Instructs ScharfBASIC to insert a digit or character " x " in that position. If there is a digit in num_expression at the position where the * appears in the format string, that digit is used; otherwise, the " x " character is used (where " x " represents your own choice of character). The * x specifier acts as two digit (#) fields.

A$ = FORMAT$(9999.9@,"$**####,.00")' $**9,999.90

A$ = FORMAT$(0@,"$*=###0,.00#") ' $=====0.00=

A$ = FORMAT$(0@,"$* ####0,.00") ' $ 0.00

E- e- E+ e+

[e] Scientific format. ScharfBASIC will use scientific notation in the formatted output. Use E- or e- to place a minus sign in front of negative exponents. Use E+ or e+ to place a minus sign in front of negative exponents and a plus sign in front of non-negative exponents.

In order to be recognized as a format sequence, the E-, e-, E+, or e+ must be placed between two digit placeholder characters. For example:

A$ = FORMAT$( 99.999, "0.0E-##") ' 1.0E2

A$ = FORMAT$(-99.999, "0.0E-##") ' -1.0E2

A$ = FORMAT$( 99.999, "0.0E+##") ' 1.0E+2

A$ = FORMAT$(-99.999, "0.0E+##") ' -1.0E+2

A$ = FORMAT$(0.1!, "0.0e+##") ' 1.0e-1

[double-quote] Quoted string. ScharfBASIC treats all characters up to the next quotation mark as-is, without interpreting them as digit placeholders or format characters. Also see backslash. For example:

A$ = FORMAT$(12, $DQ+"##"+$DQ+"##") ' ##12

A$ = FORMAT$(5.55, """XYZ=""#.##\#") ' XYZ=5.55#

A$ = FORMAT$(25, """x=""#") ' x=25

A$ = FORMAT$(999, """Total ""#") ' Total 999

A$ = FORMAT$(5, $DQ+"x="+$DQ+"#") ' x=5

[backslash] Escaped character prefix. ScharfBASIC treats the character " x " immediately following the backslash (\) as a literal character rather than a digit placeholder or a formatting character. Many characters in a mask have a special meaning and cannot be used as literal characters unless they are preceded by a backslash.

The backslash itself is not copied. To display a backslash, use two backslashes (\\). To display a literal double-quote, use two double-quote characters.

To simplify the mask string for common numeric formats, FORMAT$ permits the dollar symbol, the left and right parenthesis symbols, the plus and minus symbols, and the space character ("$()+- ") to pass through from the mask string into the formatted output string, without requiring an escape (\) prefix character.

A$ = FORMAT$(23, "(* 0\%)") ' ( 23%)

A$ = FORMAT$(99999, "#\#") ' 99999#

A$ = FORMAT$(5, "\"+$DQ+$DQ+"x="+$DQ+ _

"#\"+$DQ) ' "x=5"

A$ = FORMAT$(5, "\""""x=""#\""") ' "x=5"

A$ = FORMAT$(1000%, """#####,""") ' "#####,"

Restrictions

You cannot pass a string expression or string variable in num_expression . Do not place more than one decimal point in the mask.

FORMAT$ can return the maximum possible number of digits (up to 4932 for Extended-precision ); however, the resulting digits will be meaningless beyond the actual precision of num_expression . Consequently, the value of num_expression may produce formatted strings that are wider than the length of fmt$, for example:

A$ = FORMAT$(3e30!, "#,###") ' returns 41 characters

Rounding, if necessary, is implemented by the "banker's rounding" principle: if the fractional digit being rounded off is exactly five, with no trailing digits, the number is rounded to the nearest even number. This provides better results, on average, and follows the IEEE standard. For example:

A$ = FORMAT$(0.5##, "0") ' 0

A$ = FORMAT$(1.5##, "0") ' 2

A$ = FORMAT$(2.5##, "0") ' 2

A$ = FORMAT$(2.51##, "0") ' 3

Semicolon characters, being mask delimiters, should not be used for other purposes in mask strings unless prefixed with an escaped character symbol (\).

FORMAT$, when used with some formatting characters such as the thousands separator (comma), may not produce a "right-justified" formatted string. The simple solution is to apply separate justification with the RSET statement or the RSET$ function. For example:

A$ = SPACE$(12)

RSET A$ = FORMAT$(1,"#,###.00") ' 1.00

RSET A$ = FORMAT$(1000, "#,.00") ' 1,000.00

RSET A$ = FORMAT$(1000000,"#,###.00")' 1,000,000.00

B$ = RSET$(FORMAT$(1e6, "#,"),10) ' " 1,000,000"

One further enhancement would be to combine this into a MACRO function, for example:

MACRO mMoney1(d,l) = "$"+RSET$(FORMAT$(d,"#,"),l-1)

MACRO mMoney2(d,l) = RSET$(FORMAT$(d,"$#,"),l)

' code here

A$ = mMoney1(1000,10) ' "$ 1,000"

B$ = mMoney2(1000,10) ' " $1,000"

See Also

  • BIN$
  • GRAPHIC PRINT
  • GUID$
  • HEX$
  • OCT$
  • REPEAT$
  • SPACE$
  • STR$
  • STRING$
  • USING$
  • VAL
  • XPRINT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202b84
call   0x202b07
mov   edx,0x203a68
call   0x202b84
call   0x202b07
mov   DWORD PTR [ebp-0x6c],esi
fild   DWORD PTR [ebp-0x6c]
mov   edx,0x203a74
call   0x202b84
call   0x2018e8
lea   ebx,[ebp-0xa0]
call   0x202b07
call   0x202a38


INSTR - ScharfBASIC Help

INSTR

Search a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y& = INSTR([ Position& ,] MainStr$ , [ANY] MatchStr$ )

Description

INSTR returns the position of MatchStr$ within MainStr$ . The return value is indexed to one, while zero means "not found".

Position& specifies the character position to begin the search. If Position& is one or greater, MainStr$ is searched left to right. The value one starts at the first character, two the second, etc. If Position& is -1 or less, MainStr$ is searched from right to left. The value -1 starts at the last character, -2 the second to last, etc. If Position& is not given, the default value of +1 is assumed.

x& = INSTR("xyz", "y") ' returns 2

x& = INSTR("xyz", "a") ' returns 0

a$ = "My Dog" : b$ = " "

x& = INSTR(a$, b$) ' returns 3

It is important to note that in all cases, even when Position& is negative, the return value of INSTR() is the absolute position of the match, from left to right, starting with the first character.

If the ANY keyword is included, MatchStr$ specifies a list of single characters. INSTR searches for each of these characters individually. As soon as any one of these characters is found, INSTR returns the position of the match.

x& = INSTR(-2, "efcdef", ANY "ef") returns a result of 5

INSTR is case-sensitive, meaning that upper-case and lower-case letters must match exactly in MatchStr$ and MainStr$ .

Restrictions

Special search terms are evaluated in this sequence:

See Also

  • EXTRACT$
  • LCASE$
  • LEFT$
  • LTRIM$
  • MID$
  • RIGHT$
  • RTRIM$
  • SHRINK$
  • TALLY
  • TRIM$
  • UCASE$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2020b4
call   0x202037
mov   edx,0x203a68
call   0x2020b4
call   0x202037
mov   edx,DWORD PTR [ebp-0x9c]
call   0x202020
mov   eax,0x1
mov   edx,0x203a74
call   0x2020b4
call   0x2018e8
call   0x201f68


IStringBuilderA.Add method - ScharfBASIC Help

IStringBuilderA.Add method

The StringBuilder object offers the ability to concatenate many string

Kind | Keyword
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Description

There are two forms of the StringBuilder object, one for ANSI strings, and one for WIDE (Unicode) strings. While they could have been combined into a single hybrid object, that would have added additional overhead not acceptable for ScharfBASIC. To concatenate ANSI strings, use the StringBuilderA class and the IStringBuilderA interface. To concatenate WIDE (Unicode) strings, use the StringBuilderW class and the IStringBuilderW interface. The methods and mode of operation are identical for both forms.

If you choose the ANSI form, parameter strings must be ANSI, and result strings will be ANSI. With the WIDE (Unicode) form, parameter strings must be wide, and result strings will be wide. Keep those requirements in mind when reviewing the following method definitions. The Dispatch ID ( DispID ) for each member method is displayed within angle brackets.

When you create a StringBuilder object, a dynamic string buffer is created to hold the target string. If you know the size of the result string (or even an approximation), it's usually prudent to use the CAPACITY method first, to establish a size at least as large as the final string. If it's not known, ScharfBASIC will try to make appropriate decisions for you. Once the object is created, the ADD method is used to append string sections as many times as necessary. Finally, the STRING method is used to extract the combined items.

StringBuilder Methods/Properties

ADD ( PowerString$ ) Method<1>

The PowerString$ parameter is appended to the string held in the StringBuilder object. If the internal string buffer overflows, ScharfBASIC will automatically extend it to an appropriate size. If a necessary buffer extension fails, an HResult of E_OUTOFMEMORY (&H8007000E) is returned, and an Object Error (99) is generated.

CAPACITY () AS Long Get Property<2>

The size of the internal string buffer is retrieved and returned to the caller. The size is the number of characters which can be stored without further expansion.

CAPACITY () = Long Set Property<2>

The internal string buffer is expanded to the number of characters specified by the Long Integer. If the new capacity is smaller or equal to the current capacity, no operation is performed.

CHAR ( Index& ) AS Long Get Property<3>

The numeric character code of the character at the position Index& is retrieved and returned to the caller. Index&=1 for the first character, 2 for the second, etc. If Index& is beyond the current length of the string, the value -1 is returned.

CHAR ( Index& ) = Long Set Property<3>

The character at the position Index& is changed to that specified by the Long Integer character code. Index& =1 for the first character, 2 for the second, etc.

CLEAR Method<4>

All data in the object is erased.

DELETE ( Index& , Count& ) Method<5>

Count& characters are removed starting at the position given by Index& . Index& =1 for the first character, 2 for the second, etc.

INSERT ( PowerString$ , Index& ) Method<6>

The PowerString$ parameter is inserted in the string starting at the position given by Index& . Index& =1 for the first character, 2 for the second, etc. If Index& is beyond the current length of the string +1, no operation is performed.

LEN () AS Long Method<7>

The number of characters currently stored in the object is returned as a long integer value.

STRING AS String Method<8>

The string stored in the object is returned to the caller. This string will contain LEN characters.

Details

The StringBuilder object offers the ability to concatenate many string sections at a very high level of performance. The speed of execution is particularly noticeable when the concatenation is performed in many separate operations over a period of time. If all of the string sections are known and available at once, the use of the BUILD$() function could be a better choice. However, both options offer a very large boost as compared to the standard concatenation operators (& or +). In addition to concatenation, the StringBuilder Class also offers a few additional string operations to assist in building the string.

There are two forms of the StringBuilder object, one for ANSI strings, and one for WIDE (Unicode) strings. While they could have been combined into a single hybrid object, that would have added additional overhead not acceptable for ScharfBASIC. To concatenate ANSI strings, use the StringBuilderA class and the IStringBuilderA interface. To concatenate WIDE (Unicode) strings, use the StringBuilderW class and the IStringBuilderW interface. The methods and mode of operation are identical for both forms.

If you choose the ANSI form, parameter strings must be ANSI, and result strings will be ANSI. With the WIDE (Unicode) form, parameter strings must be wide, and result strings will be wide. Keep those requirements in mind when reviewing the following method definitions. The Dispatch ID ( DispID ) for each member method is displayed within angle brackets.

When you create a StringBuilder object, a dynamic string buffer is created to hold the target string. If you know the size of the result string (or even an approximation), it's usually prudent to use the CAPACITY method first, to establish a size at least as large as the final string. If it's not known, ScharfBASIC will try to make appropriate decisions for you. Once the object is created, the ADD method is used to append string sections as many times as necessary. Finally, the STRING method is used to extract the combined items.

StringBuilder Methods/Properties

ADD ( PowerString$ ) Method<1>

The PowerString$ parameter is appended to the string held in the StringBuilder object. If the internal string buffer overflows, ScharfBASIC will automatically extend it to an appropriate size. If a necessary buffer extension fails, an HResult of E_OUTOFMEMORY (&H8007000E) is returned, and an Object Error (99) is generated.

CAPACITY () AS Long Get Property<2>

See Also

  • BUILD$
  • CHR$
  • CSET
  • CSET$
  • JOIN$
  • LSET
  • LSET$
  • REPEAT$
  • RSET
  • RSET$
  • STRING$
  • STRINSERT$
  • WRAP$


JOIN$ - ScharfBASIC Help

JOIN$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

A$ = JOIN$( array() , { delim$ | BINARY})

Description

JOIN$ requires a delimiter string delim$ which may be any length.

If the delimiter expression is a null (zero-length) string, no separators are inserted between the string sections. If the delimiter expression is the 3-byte value of "," (which may be expressed in your source code as the string literal ""","""), a leading and trailing double-quote is added to each string section. This ensures that the returned string contains standard, comma-delimited quoted fields that can be easily parsed.

The array specified by array() may be any data type.

BINARY

If the array consists of fixed size elements (numeric , Nul-Terminated Strings , etc.), the returned string consists of an exact memory image of the array data in internal format. If the array contains variable length data (Dynamic string, Field string ), it is stored in ScharfBASIC and/or Visual Basic packed string format: If a string is shorter than 65535 bytes, it starts with a 2-byte length WORD followed by the string data. Otherwise, it will start with a 2-byte value of 65535, followed by a DWORD indicating the string length, then finally the string data itself.

The JOIN$ function is the natural complement to the PARSE statement.

See Also

  • BUILD$
  • PARSE
  • PARSE$
  • PARSECOUNT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x201093
mov   ecx,0x26
push   0x12e0008
lea   ebx,[ebp-0x11c]
call   0x201908
mov   edx,0x203a54
call   0x202538
call   0x2024bb
mov   edx,0x203a68
call   0x202538
call   0x2024bb
lea   ebx,[ebp-0x11c]
mov   edx,0x203a74
call   0x202538
call   0x201fc4
lea   ebx,[ebp-0xa0]
call   0x2024bb
call   0x2023ec


JESCAPE$ - ScharfBASIC Help

JESCAPE$

Escape a string for use inside a JSON string literal

Kind | Function
Category | JSON String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC extension

Syntax

escaped$ = JESCAPE$(string_expression)
escaped$$ = JESCAPE$(wstring_expression)

Description

JESCAPE$ returns the input text escaped for placement between the quotes of a JSON string literal. It supports STRING and WSTRING input.

The function escapes quotation mark, reverse solidus, backspace, form feed, line feed, carriage return, and tab. Other characters are copied unchanged.

Input character | Output text
" | \"
\ | \\
CHR$(8) | \b
CHR$(9) | \t
CHR$(10) | \n
CHR$(12) | \f
CHR$(13) | \r

Example

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL s AS STRING
    s = "A" + CHR$(34) + "B" + CHR$(10)
    PRINT JESCAPE$(s)
END FUNCTION

The printed text contains A\"B\n.

Validation

The accepted ScharfBASIC feature prototypes cover STRING quote/backslash escaping, STRING control-character escaping, WSTRING quote/backslash escaping, and empty input.

See Also

  • STRING$
  • CHR$


JSLASH$ - ScharfBASIC Help

JSLASH$

Escape a JSON string and also escape solidus characters

Kind | Function
Category | JSON String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC extension

Syntax

escaped$ = JSLASH$(string_expression)
escaped$$ = JSLASH$(wstring_expression)

Description

JSLASH$ returns the input text escaped for placement between the quotes of a JSON string literal. It supports STRING and WSTRING input.

The function performs the same JSON short escaping as JESCAPE$ and additionally converts solidus characters to \/.

Input character | Output text
" | \"
\ | \\
/ | \/
CHR$(8) | \b
CHR$(9) | \t
CHR$(10) | \n
CHR$(12) | \f
CHR$(13) | \r

Example

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL s AS STRING
    s = "A/B" + CHR$(9) + "C"
    PRINT JSLASH$(s)
END FUNCTION

The printed text contains A\/B\tC.

Validation

The accepted ScharfBASIC feature prototypes cover STRING and WSTRING solidus escaping, inherited JSON short escapes, and tab-in-middle output.

See Also

  • JESCAPE$
  • JSTRING$


JSTRING$ - ScharfBASIC Help

JSTRING$

Return a quoted JSON string literal

Category | JSON String Functions
Result | STRING or WSTRING
Status | ScharfBASIC extension

Syntax

json$ = JSTRING$(string_expression)
json$$ = JSTRING$(wstring_expression)

Description

JSTRING$ returns a JSON string literal. The result includes the surrounding quotation marks and escapes quotation mark, reverse solidus, backspace, form feed, line feed, carriage return, and tab using JSON short escapes. Other characters are preserved.

Use JESCAPE$ when only the content between JSON quotes is needed. Use JSTRING$ when the complete quoted JSON string value is needed.

Example

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL s AS STRING
    s = "A" + CHR$(34) + "B" + CHR$(92) + "C"
    PRINT JSTRING$(s)
END FUNCTION

The output is:

"A\"B\\C"

Notes

JSTRING$ supports STRING and WSTRING input in the normal ScharfBASIC build. It can be used in the same program as JESCAPE$; mixed WSTRING helper ownership is handled by the compiler.


JUNESCAPE$ - ScharfBASIC Help

JUNESCAPE$

Decode JSON string escape sequences

Kind | Function
Category | JSON String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC extension

Syntax

text$ = JUNESCAPE$(string_expression)
text$$ = JUNESCAPE$(wstring_expression)

Description

JUNESCAPE$ decodes JSON string escape sequences and returns the unescaped text. It supports STRING and WSTRING input.

STRING and WSTRING input decode quotation mark, reverse solidus, slash, backspace, form feed, line feed, carriage return, and tab.

STRING and WSTRING input also decode accepted ASCII-range Unicode escapes in the form \u00XX, including hex digits A-F. WSTRING input additionally decodes digit-only BMP escapes such as \u2639.

Input text | Output character
\" | "
\\ | \
\/ | /
\b | CHR$(8)
\f | CHR$(12)
\n | CHR$(10)
\r | CHR$(13)
\t | CHR$(9)

Example

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL s AS STRING
    s = "A" + CHR$(92) + CHR$(34) + "B" + CHR$(92) + "n"
    PRINT JUNESCAPE$(s)
END FUNCTION

Current Limits

Surrogate pairs and invalid-escape policy are planned follow-up work.

See Also

  • JESCAPE$
  • JSTRING$


JUNQUOTE$ - ScharfBASIC Help

JUNQUOTE$

Remove JSON string quotes and decode short escape sequences

Kind | Function
Category | JSON String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC extension

Syntax

text$ = JUNQUOTE$(string_expression)
text$$ = JUNQUOTE$(wstring_expression)

Description

JUNQUOTE$ accepts a JSON string value, removes one surrounding quotation-mark pair when present, and decodes JSON short escapes in the remaining content. It supports STRING and WSTRING input.

If the input is not surrounded by quotation marks, JUNQUOTE$ decodes it like JUNESCAPE$.

STRING and WSTRING input also decode accepted ASCII-range Unicode escapes in the form \u00XX, including hex digits A-F. WSTRING input additionally decodes digit-only BMP escapes such as \u2639.

Input text | Output character
\" | "
\\ | \
\/ | /
\b | CHR$(8)
\f | CHR$(12)
\n | CHR$(10)
\r | CHR$(13)
\t | CHR$(9)

Example

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL s AS STRING
    s = CHR$(34) + "A" + CHR$(92) + CHR$(34) + "B" + CHR$(34)
    PRINT JUNQUOTE$(s)
END FUNCTION

The output is:

A"B

Current Limits

Surrogate pairs and invalid-escape policy are planned follow-up work.

See Also

  • JESCAPE$
  • JSTRING$
  • JUNESCAPE$


LCASE$ - ScharfBASIC Help

LCASE$

Return a lowercase version of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = LCASE$( string_expression [,ANSI | OEM])

Description

LCASE$ returns a string equivalent to string_expression , except that uppercase letters in string_expression are converted to lowercase. The optional ANSI or OEM parameter specifies whether the conversion is made using the ANSI charset for the system, or the original IBM OEM charset. If no charset is specified, ScharfBASIC for Windows uses the system ANSI charset, while PB/CC uses the IBM OEM charset. Only "International" characters in the range of CHR$ (128) to CHR$(255) are affected by this parameter.

The OEM charset is based upon the original IBM OEM charset to ensure compatibility with programs written for all previous versions of the ScharfBASIC compiler.

See Also

  • MCASE$
  • UCASE$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2020e4
call   0x202067
mov   edx,0x203a68
call   0x2020e4
call   0x202067
mov   edx,DWORD PTR [ebp-0x9c]
call   0x202050
call   0x201c87
call   0x2018e8
lea   ebx,[ebp-0xa0]
call   0x202067
call   0x201f98


LEFT$ - ScharfBASIC Help

LEFT$

Return the left-most

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = LEFT$( string _ expression , n& )

Description

n& is a Long-integer expression and specifies the number of characters in string_expression to be returned.

LEFT$ returns a string consisting of the left most n& characters of its string argument. If n& is greater than or equal to the length of string_expression , all of string_expression is returned. If n& is zero, LEFT$ returns an empty string. If the length value parameter is negative, it is interpreted as LEN ( string_expression )- ABS ( n& ). For example, LEFT$("1234567890",-2) returns "12345678".

See Also

  • EXTRACT$
  • INSTR
  • LTRIM$
  • MID$
  • RIGHT$
  • RTRIM$
  • SPLIT
  • TALLY
  • TRIM$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201d1c
call   0x201c9f
call   0x201d1c
call   0x201c9f
mov   edx,DWORD PTR [ebp-0x9c]
mov   ecx,0x1
mov   eax,0x3
call   0x201913
lea   ebx,[ebp-0xa0]
call   0x201c9f
call   0x201bd0


LEN - ScharfBASIC Help

LEN

Return the logical length of a

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y& = LEN( target )

Description

If target is a string variable or a string expression , LEN returns a value from 0 to the current string length, representing the number of characters in target. If target is a fixed-length string , the length of the fixed buffer is returned. If target is an nul-terminated string, the length of the data stored in the nul-terminated string is returned, not the maximum size of the nul-terminated string. Use SIZEOF to determine the maximum size of an nul-terminated string.

When used with pointers , LEN returns a value of 4, since a pointer is always stored as a DWORD . You can use LEN with the target of a pointer to return the size of target. If the target is a dynamic string , you will receive the length of the string, not the length of the handle.

target can also be any other variable type, including numeric and User-Defined Types (defined with TYPE/END TYPE ). In that case, ScharfBASIC will return the number of bytes needed to store a variable of that type.

When measuring the size of a padded (aligned) UDT structure with the LEN (or SIZEOF) statement, the measured length includes any padding that was added to the structure. For example, the following UDT structure:

TYPE LengthTestType DWORD

a AS INTEGER

END TYPE

' code here

DIM abc AS LengthTestType

x& = LEN(abc)

Returns a length of 4 bytes in x& , since the UDT was padded with 2 additional bytes to enforce DWORD alignment. Note that the LEN of individual UDT members returns the true size of the member without regard to padding or alignment. In the previous example, LEN(abc.a) returns 2.

See Also

  • CHRBYTES
  • SIZEOF

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201cb0
call   0x201c33
call   0x201cb0
call   0x201c33
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201c1c
call   0x201be8
call   0x201b30


LSET$ - ScharfBASIC Help

LSET$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

result_var = LSET$( string_expression , strlen& [USING ustring_expression ])

Description

LSET$ left-aligns the string string_expression into a string of strlen& characters.

If ustring_expression is null (empty) or is not specified, LSET$ pads string_expression with space characters. Otherwise, LSET$ pads the string with the first character of ustring_expression .

If string_expression is shorter then strlen& , LSET$ left-justifies string_expression within result_var, padding the right side as described above; otherwise, LSET$ returns the left-most strlen& bytes of string_expression .

See Also

  • CSET
  • CSET$
  • GET
  • LET
  • LSET
  • PUT
  • RESET
  • RSET
  • RSET$
  • STRINSERT$
  • TYPE SET


LTRIM$ - ScharfBASIC Help

LTRIM$

Return a copy of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x$ = LTRIM$( MainString [, [ANY] MatchString ])

Description

MainString is the string expression from which to remove characters, and MatchString is the string expression containing the characters to remove.

If MatchString is not specified, LTRIM$ removes leading spaces. LTRIM$ returns a sub-string of MainString , from the first non- MatchString (or non-space) to the end of the string. If MatchString (or a space) is not present at the beginning of MainString , all of MainString is returned.

If the ANY keyword is included, MatchString specifies a list of single characters to be searched for individually. A match on any one of these as a leading character will cause the character to be removed from the result.

LTRIM$ is case sensitive.

See Also

  • CLIP$
  • EXTRACT$
  • INSTR
  • LEFT$
  • MID$
  • REMOVE$
  • REPLACE
  • RIGHT$
  • RTRIM$
  • SHRINK$
  • STRDELETE$
  • STRINSERT$
  • STRREVERSE$
  • TALLY
  • TRIM$
  • UNWRAP$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Ltrim

call   0x201e1c
call   0x201d9f
call   0x201e1c
call   0x201d9f
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201d88
call   0x201b40
lea   ebx,[ebp-0xa0]
call   0x201d9f
call   0x201cd0

Variant 2: Trim

call   0x201e1c
call   0x201d9f
call   0x201e1c
call   0x201d9f
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201d88
call   0x201b40
call   0x201b97
lea   ebx,[ebp-0xa0]
call   0x201d9f
call   0x201cd0


MCASE$ - ScharfBASIC Help

MCASE$

Return a mixed case version of its string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = MCASE$( string_expression [,ANSI | OEM])

Description

MCASE$ returns a string equivalent to string_expression , except that the first letter of each word is capitalized, while the remaining characters are forced to lowercase. A word is considered to be a consecutive series of letters. The optional ANSI or OEM parameter specifies whether the conversion is made using the ANSI charset for the system, or the original IBM OEM charset. If no charset is specified, ScharfBASIC for Windows uses the system ANSI charset, while PB/CC uses the IBM OEM charset. Only "International" characters in the range of CHR$ (128) to CHR$(255) are affected by this parameter.

The OEM charset is based upon the original IBM OEM charset to ensure compatibility with programs written for all previous versions of the ScharfBASIC compiler.

See Also

  • LCASE$
  • UCASE$


MID$ - ScharfBASIC Help

MID$

Replace characters in a string

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MID$( StringVar , Start& [, Count& ]) = replacement
M ID$( StringVar , Start& TO End& = replacement

Description

The MID$ statement replaces characters in a string variable. The first form tells the number of characters to replace, while the second form tells the start and end position instead. Both forms provide the same functionality, so the choice is just a matter of programmer convenience.

Start& and End& are positions in the string, starting with 1 as the first character. Count& tells the number of characters to replace.

If Count& is omitted, or there aren't enough characters in StringVar , all remaining characters are replaced. If there are no characters at the Start& position, no operation is performed.

If Start& or End& are negative, the positions are counted backwards from the end of the string (-1 is the last character). If Count& is negative, it is interpreted as LEN( string_expression )-ABS( Count& ).

The replacement will never extend past the end of StringVar . In other words, MID$ cannot alter the length of a string.

Restrictions

If Start& evaluates to a position outside of the string on either side, or if Start& is zero, no operation is performed.

See Also

  • BUILD$
  • INSTR
  • LTRIM$
  • MID$ function
  • REMOVE$
  • REPLACE
  • RTRIM$
  • TALLY
  • TRIM$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201d1c
call   0x201c9f
call   0x201d1c
call   0x201c9f
mov   edx,DWORD PTR [ebp-0x9c]
mov   ecx,0x2
mov   eax,0x3
call   0x201913
lea   ebx,[ebp-0xa0]
call   0x201c9f
call   0x201bd0


PARSE$ - ScharfBASIC Help

PARSE$

Return a delimited field from a

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = PARSE$( string_expr [, {[ANY] string_delimiter | BINARY }] , index& )

Description

PARSE$ uses the following parameters:

string_expr

The string to parse. If string_expr is empty (a null string) or contains no delimiter character(s), the string is considered to contain exactly one field. In this case, PARSE$ will return string_expr.

string_delimiter

Contains delimiter character(s). A delimiter is a character, list of characters, or string, that is used to mark the end of a field in string_expr . For example, if you consider a sentence to be a list of words, the delimiter between the works is a space (or perhaps punctuation). Text files typically consist of lines that are delimited by CR/LF ( $CRLF or CHR$ (13,10)) characters; a database file may consist of items separated by commas; etc. A delimiter is not considered part of a field, but as the divider between fields, so the delimiter is never returned by PARSE$.

If delim$ is not specified or is null (zero-length), standard comma-delimited (optionally quoted) fields are presumed. In this case only, the following parsing rules apply. If a standard field is enclosed in optional quotes, they are removed. If any characters appear between a quoted field and the next comma delimiter, they are discarded. If no leading quote is found, any leading or trailing blank spaces are trimmed before the field is returned.

Delimiters are case-sensitive, so capitalization may be a consideration.

If the ANY keyword is used, string_delimiter contains a set of characters, any of which may act as a delimiter character. If the ANY keyword is omitted, the entire string_delimiter string acts as a single delimiter.

BINARY

The BINARY option presumes that string_expr was created with the JOIN$/BINARY function, or its equivalent, which creates a string as a binary image or in the ScharfBASIC and/or Visual Basic packed string format: If a string is shorter than 65535 bytes, it starts with a 2-byte length WORD followed by the string data. Otherwise it will start a 2-byte value of 65535, followed by a DWORD indicating the string length, then finally the string data itself.

index&

An integral variable or expression that specifies the delimited field number to return. The first field is 1, and so on up to the maximum number of fields contained in string_expr, which may be determined with the PARSECOUNT function. If index& is negative, string_expr is parsed from right to left. In this case, index& = -1 returns the last field in string_expr, -2 returns the second to last, etc. If index& evaluates to zero, or is outside of the actual field count, an empty string is returned.

See Also

  • JOIN$
  • PARSE
  • PARSECOUNT
  • PATHNAME$
  • PATHSCAN$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x201093
mov   ecx,0x26
push   0x12e0008
lea   ebx,[ebp-0x11c]
call   0x201908
mov   edx,0x203a54
call   0x20268c
call   0x20260f
mov   edx,0x203a68
call   0x20268c
call   0x20260f
mov   edx,DWORD PTR [ebp-0x9c]
call   0x2025f8
lea   ebx,[ebp-0x11c]
mov   edx,0x203a74
call   0x20268c
call   0x202a00
call   0x202540


PARSECOUNT - ScharfBASIC Help

PARSECOUNT

Return the count of delimited strings in a

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x& = PARSECOUNT( string_expr [, {[ANY] string_delimiter | BINARY}])

Description

PARSECOUNT uses the same rules as PARSE$ in the determination of fields within string_expr . Individual fields within string_expr are evaluated, and the tally of the fields forms the result value.

It is important to note that PARSECOUNT may only be used with string data which contains variable length sub-fields, each of which is separated by a delimiter. To determine the count of fixed length data, divide the StringExpr length by the sub-field length. If this function is used with fixed length data, the results are undefined.

string_expr

This is the string to examine and parse. If StringExpr is empty (a null string) or contains no delimiter character(s), the string is considered to contain exactly one sub-field. In this case, PARSECOUNT returns the value 1.

string_delimiter

This defines one or more characters to use as a delimiter. To be valid, the entire delimiter must match exactly, but the delimiter itself is never returned as part of the field.

If string_delimiter is not specified, or contains an empty string, special rules apply. The delimiter is assumed to be a comma. Fields may optionally be enclosed in quotes, and are ignored before the result string is returned. Any characters that appear between a quote mark and the next comma delimiter character are discarded. If no leading quote is found, any leading or trailing quotes are trimmed before the result string is returned.

If the ANY keyword is used, string_delimiter contains a set of characters, any of which may act as a delimiter character. If the ANY keyword is omitted, the entire string_delimiter string acts as a single delimiter.

BINARY

The BINARY option returns the number of sub-fields and presumes that StringExpr was created with the JOIN$/BINARY function, or its equivalent, which creates a string in the ScharfBASIC and/or Visual Basic packed string format: If a string is shorter than 65535 bytes, it starts with a 2-byte length WORD followed by the string data. Otherwise it will start with a 2-byte value of 65535, followed by a DWORD indicating the string length, then the actual string data.

See Also

  • JOIN$
  • PARSE
  • PARSE$
  • PATHNAME$
  • PATHSCAN$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202364
call   0x2022e7
mov   edx,0x203a68
call   0x202364
call   0x2022e7
mov   edx,DWORD PTR [ebp-0x9c]
call   0x2022d0
mov   edx,0x203a74
call   0x202364
call   0x202534
call   0x202218


PART$ - ScharfBASIC Help

PART$

Return a substring using inclusive-last indexing.

Kind | Function
Category | String
ScharfBASIC | EXTENSION
Notes | Native ScharfBASIC string expression function

Syntax

result$ = PART$(source$, first&, last&)
result$ = PART$(source$, first& TO last&)

Description

PART$ extracts a portion of source$ starting at position first& and ending at position last&. Unlike MID$, which uses a count (number of characters), PART$ uses an inclusive-last index.

Parameters

Parameter | Description
source$ | The source string expression.
first& | The starting position (1-based).
last& | The ending position (1-based, inclusive).

Examples

' Comma form (3 arguments)
PRINT PART$("abcdef", 2, 4)   ' Prints "bcd"

' TO form (2 arguments with TO keyword)
PRINT PART$("abcdef", 2 TO 4) ' Prints "bcd"

' Contrast with MID$ count semantics:
PRINT MID$("abcdef", 2, 4)    ' Prints "bcde" (count=4)

Behavior Notes

  • If first& is past the end of source$, an empty string is returned.
  • If first& is zero, the result is empty.
  • If last& exceeds the string length, it is clamped to the string length.
  • Reversed ranges (last& < first&) produce an empty string.

See Also

  • MID$
  • LEFT$
  • RIGHT$


REMOVE$ - ScharfBASIC Help

REMOVE$

Return a copy of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x$ = REMOVE$( MainString , [ANY] MatchString )

Description

The REMOVE$ function has the following parts:

MainString

The string expression from which to remove characters.

MatchString

The string expression to remove all occurrences of. If MatchString is not present in MainString , all of MainString is returned intact.

If the ANY keyword is included, MatchString specifies a list of single characters to be searched for individually, a match on any one of which will cause that character to be removed from the result.

Restrictions

REMOVE is case-sensitive.

See Also

  • CLIP$
  • EXTRACT$
  • INSTR
  • LTRIM$
  • MID$
  • REPLACE
  • RETAIN$
  • RIGHT$
  • RTRIM$
  • SHRINK$
  • TALLY
  • TRIM$
  • UNWRAP$
  • VERIFY


REPEAT$ - ScharfBASIC Help

REPEAT$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = REPEAT$( count& , string_expr )

Description

The REPEAT$ function has the following parts:

count&

Is an integral expression, constant or variable , specifying the number of copies of string_expr to be included in the result. REPEAT$ is very similar to STRING$ (which makes multiple copies of a single character).

string_expr

The string to be duplicated.

See Also

  • BUILD$
  • CHR$
  • GUID$
  • NUL$
  • SPACE$
  • STRING$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201d78
call   0x201cfb
call   0x201d78
call   0x201cfb
mov   ebx,0x3
mov   edx,0x202a74
call   0x201d78
call   0x201913
lea   ebx,[ebp-0xa0]
call   0x201cfb
call   0x201c2c


REPLACE - ScharfBASIC Help

REPLACE

Within a specified string

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

REPLACE [ANY] MatchString WITH NewString IN MainString

Description

The REPLACE statement replaces all occurrences of MatchString in MainString with NewString. The replacement can cause MainString to grow or condense in size. MainString must be a string variable; MatchString and NewString may be string expressions . REPLACE is case-sensitive. When a match is found, the scan for the next match begins at the position immediately following the prior match.

If you use the ANY option, within MainString , each occurrence of each character in MatchString will be replaced with the corresponding character in NewString . In this case, MatchString and NewString must be the same length , because there is a one-to-one correspondence between their characters.

See Also

  • EXTRACT$
  • INSTR
  • LTRIM$
  • MID$
  • REMOVE$
  • RETAIN$
  • RIGHT$
  • RTRIM$
  • SHRINK$
  • TALLY
  • TRIM$
  • UNWRAP$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201e78
call   0x201dfb
call   0x201e78
call   0x201dfb
mov   edx,0x202a74
call   0x201e78
mov   edx,0x202a7c
call   0x201e78
call   0x201de4
call   0x201b50
call   0x201dfb
call   0x201d2c


RETAIN$ - ScharfBASIC Help

RETAIN$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

sResult$ = RETAIN$( mainstr$ , [ANY] matchstr$ )

Description

RETAIN$ returns a string consisting of zero or more copies of the complete expression matchstr$ which are found in mainstr$ . All other characters are removed.

If the ANY option is included, matchstr$ specifies a list of single characters to be retained, if they are found in mainstr$ .

Restrictions

If matchstr$ is an empty string, RETAIN$ returns an empty string.

See Also

  • EXTRACT$
  • REMAIN$
  • REMOVE$
  • REPLACE


RIGHT$ - ScharfBASIC Help

RIGHT$

Return the rightmost

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = RIGHT$( string_expression , n& )

Description

If n& is positive, RIGHT$ returns the indicated number of characters from the string, starting from the right and working left. If n& greater than the length of string_expression, all of string_expression is returned.

If n& is 0, RIGHT$ returns an empty string. If n& is negative, it is interpreted as ( LEN ( string_expression ) - ABS ( n& )). For example, RIGHT$("1234567890", -2) returns "34567890".

See Also

  • EXTRACT$
  • INSTR
  • LEFT$
  • LTRIM$
  • MID$
  • REMOVE$
  • REPLACE
  • RTRIM$
  • SPLIT
  • TALLY
  • TRIM$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201cdc
call   0x201c5f
call   0x201cdc
call   0x201c5f
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201c48
mov   eax,0x3
call   0x2018e8
lea   ebx,[ebp-0xa0]
call   0x201c5f
call   0x201b90


RSET$ - ScharfBASIC Help

RSET$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = RSET$( string_expression , strlen& [USING ustring_expression ])

Description

RSET$ right-aligns the string string_expression into a string of strlen& characters.

If ustring_expression is null (empty) or is not specified, RSET$ pads string_expression with space characters. Otherwise, RSET$ pads the string with the first character of ustring_expression .

If string_expression is shorter then strlen& , RSET$ right-justifies string_expression within the assigned string variable ( a$ ) , padding the left side as described above; otherwise, RSET$ returns the left-most strlen& bytes of string_expression .

See Also

  • CSET
  • CSET$
  • GET
  • LET
  • LSET
  • LSET$
  • PUT
  • RESET
  • RSET
  • STRINSERT$
  • TYPE SET


RTRIM$ - ScharfBASIC Help

RTRIM$

Return a copy of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x$ = RTRIM$( MainString [, [ANY] MatchString ])

Description

MainString is the string expression from which to remove characters, and MatchString is the string expression specifying the characters that should be removed from the right hand side of MainString .

If MatchString is not specified, RTRIM$ removes trailing spaces. RTRIM$ returns a sub-string of MainString , from the beginning of the string to the character preceding the consecutive occurrences of MatchString (or space), which continues to the end of the original string. If MatchString (or a space) is not present at the end of MainString , all of MainString is returned.

RTRIM$ is case-sensitive.

If the ANY keyword is included, MatchString specifies a list of single characters to be searched for individually - a match on any one of which as a trailing character will cause the character to be removed from the result.

See Also

  • CLIP$
  • EXTRACT$
  • INSTR
  • LEFT$
  • LTRIM$
  • MID$
  • REMOVE$
  • REPLACE
  • RIGHT$
  • STRDELETE$
  • STRINSERT$
  • STRREVERSE$
  • TALLY
  • TRIM$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201e1c
call   0x201d9f
call   0x201e1c
call   0x201d9f
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201d88
call   0x201b97
lea   ebx,[ebp-0xa0]
call   0x201d9f
call   0x201cd0


SHRINK$ - ScharfBASIC Help

SHRINK$

Shrink a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

NewString$ = SHRINK$( OldString$ )
NewString$ = SHRINK$( OldString$ , Mask$ )

Description

The purpose of this function is to create a string with consecutive data items (words) separated by a consistent single character. This makes it very straightforward to parse the results as needed.

In the first form, all leading spaces and trailing spaces are removed entirely. All occurrences of two or more spaces are changed to a single space. Therefore, the new string returned consists of zero or more words, each separated by a single space character.

In the second form, Mask$ defines one or more delimiter characters to shrink. All leading and trailing mask characters are removed entirely. All occurrences of one or more mask characters are replaced with the first character of Mask$ . Therefore, the new string returned consists of zero or more words, each separated by the character found in the first position of Mask$ .

WhiteSpace is generally defined as the four common non-printing characters: Space, Tab, Carriage-Return, and Line-Feed. This is pre-defined in ScharfBASIC as string equates for your convenience. The ANSI version is named $WHITESPACE , while the WIDE version is $$WHITESPACE . This equate is particularly well suited to be used as Mask$ in this function.

See Also

  • CLIP$
  • INSTR
  • LTRIM$
  • REMOVE$
  • REPLACE
  • RTRIM$
  • TRIM$
  • UNWRAP$


SPACE$ - ScharfBASIC Help

SPACE$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = SPACE$( numeric_expression )

Description

numeric_expression is a non-negative expression that specifies how many spaces the function is to return. SPACE$ can be useful for formatting or prefilling strings.

See Also

  • BUILD$
  • CHR$
  • CSET
  • CSET$
  • LSET
  • NUL$
  • REPEAT$
  • RSET
  • STRING$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201c7c
call   0x201bff
call   0x201c7c
call   0x201bff
mov   eax,0x5
call   0x201d03
lea   ebx,[ebp-0xa0]
call   0x201bff
call   0x201b30


SPLIT - ScharfBASIC Help

SPLIT

Splits a string

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SPLIT [WORD] MainStr , Part1Len TO Part1Var , Part2Var

Description

MainStr is separated into two parts, which are then assigned to the two string variables specified by Part1Var and Part2Var . Part1Len is a

expression which specifies the number of characters to be assigned to Part1, while the remaining characters are assigned to Part2.

If the WORD option is included, ScharfBASIC guarantees that Part1 will not end on a partial word. This may require that Part1Len is adjusted to a smaller value. In that case, Part2Var would be assigned these characters to compensate. Depending upon the nature of the operation, it may be necessary to remove leading spaces from Part2Var .

See Also

  • GRAPHIC SPLIT
  • LTRIM$
  • XPRINT SPLIT


STR$ - ScharfBASIC Help

STR$

Return the string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = STR$( numeric_expression [, digits ])

Description

STR$ returns the string form of a n umeric variable or expression in printable text form. digits is an optional integral expression specifying the maximum total number of digits to appear in the result. If numeric_expression is greater than or equal to zero, STR$ adds a leading space character; if numeric_expression is less than zero, STR$ adds a leading negation (minus) character.

For example, STR$(14) returns a three-character string, of which the first character is a space, and the second and third are the ASCII characters "1" and "4". LTRIM$ can be used to remove leading space characters.

digits specifies the maximum number of significant digits (1 to 18) desired in the result.

STR$ can also be used to convert numeric values with more than 16 significant digits (i.e., Extended-precision floating-point and Quad-integers ) to a printable form. For example:

a## = 2.0/3.0

x$ = STR$(a##,18)

returns 0.666666666666666667.

The complementary function is VAL , which takes a string argument and returns the numeric equivalent. Thus, number = VAL(STR$( number )).

An integer-class numeric value may also be converted to a string with the FORMAT$ and USING$ functions; however, FORMAT$ can easily return a string that is free from leading space characters. For example, x$ = FORMAT$(a&).

See Also

  • BIN$
  • FORMAT$
  • HEX$
  • LTRIM$
  • OCT$
  • ROUND
  • USING$
  • VAL


STRDELETE$ - ScharfBASIC Help

STRDELETE$

Delete a specified number of characters from a

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = STRDELETE$( string_expression , start& , count& )

Description

Returns a string based on copying string_expression, but with count& characters deleted starting at position start&. The first character in the string is position 1, etc.

See Also

  • CLIP$
  • STRINSERT$
  • STRREVERSE$


String expressions - ScharfBASIC Help

String expressions

A string expression consists of string literals , string variables , and string functions , optionally combined with the concatenation operators (+ or &). String expressions always produce strings as

Kind | Keyword
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

"Cats and dogs" ' string constant

firstname$ ' string variable

firstname$ + lastname$ ' string concatenation

a$ = "Cats " & "and " & "dogs" ' string concatenation

LEFT$(a$ + z$,7) ' string function

a$ + MID$("Cats and dogs",5,3)

RIGHT$(MID$(a$ + z$,1,6),3)

Note that fixed-length strings are always a fixed length (defined in the corresponding DIM statement), string concatenation involving these strings works differently than you might expect. For instance, the following program fragment:

DIM Greeting AS STRING * 40


String Operations Commands - ScharfBASIC Help

String Operations Commands

The following functions manipulate and manage string data:

Kind | Keyword
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Translate a Unicode string into an ANSI string.

Assign a number of values to successive elements of an array .

Delete a single item from a given array.

Insert a single item into a given array.


STRING$ - ScharfBASIC Help

STRING$

Return a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = STRING$( Count& , Character% )
s$ = STRING$( Count& , Character$ )
s$$ = STRING$$( Count& , Character% )
s$$ = STRING$$( Count& , Character$$ )

Description

This function creates a string which consists of multiple copies of a particular character. The STRING$() form creates a string of ANSI (1- byte ) characters, or codes in the range of 0 to 255. The STRING$$() form of the function creates a string of WIDE (2-byte) characters, or codes in the range of 0 to 65535.

Generally speaking, ScharfBASIC handles ANSI/WIDE conversions for you, automatically and transparently. However, there are just a few functions ( CHR$ , PEEK$ , POKE$ , STRING$, etc) which are ambiguous, by definition, and require that the programmer choose the appropriate result type (ANSI or WIDE). Use STRING$ for ANSI results, or use STRING$$ for Unicode results. In the remainder of these remarks, STRING$ is used to represent both STRING$ and STRING$$.

STRING$ with a numeric argument returns a string of Count& copies of the character with the Character Code of Character%. STRING$ with a string argument returns a string of Count& copies of the first character in Character$ or Character$$.

The following functions all return a string of 8 spaces:

A$ = STRING$(8, 32)

A$ = STRING$(8, " ")

A$ = STRING$(8, $SPC)

A$ = SPACE$(8)

A$ = REPEAT$(8, " ")

A$ = REPEAT$(8, $SPC)

Use REPEAT$ to make multiple copies of a multiple-character string, and SPACE$ to return a string of space characters.

See Also

  • ASC
  • BUILD$
  • CHR$
  • NUL$
  • REPEAT$
  • SPACE$


STRINSERT$ - ScharfBASIC Help

STRINSERT$

Insert a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = STRINSERT$( MainStr$ , NewStr$ , position& )

Description

Returns a string consisting of the string expression MainStr$ , with the string expression NewStr$ inserted at position &. If position& is greater than the length of MainStr$ , NewStr$ is appended to MainStr$ . The first character in the string is position 1, etc.

See Also

  • BUILD$
  • CLIP$
  • CSET
  • CSET$
  • LSET
  • RSET
  • STRDELETE$
  • STRREVERSE$
  • WRAP$


STRREVERSE$ - ScharfBASIC Help

STRREVERSE$

Reverse the contents of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = STRREVERSE$( MainStr$ )

Description

Reverses the contents of MainStr$ and returns the result.

See Also

  • STRDELETE$
  • STRINSERT$


TAB DELETE - ScharfBASIC Help

TAB DELETE

A

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TAB DELETE hDlg , ID& , PageNum&
TAB GET COUNT hDlg , ID& TO CountVar&
TAB GET DIALOG hDlg , ID& , PageNum& TO PageDlgVar&
TAB GET IMAGE hDlg , ID& , PageNum& TO ImageVar&
TAB GET PAGE PageDlg TO PageNumVar&
TAB GET SELECT hDlg , ID& TO PageNumVar&
TAB GET TEXT hDlg , ID& , PageNum& TO TextVar$
TAB INSERT PAGE hDlg , ID& , PageNum& , Image& , Text$ [CALL CallBack ] TO PageDlgVar&
TAB RESET hDlg , ID&
TAB SELECT hDlg , ID& , PageNum&
TAB SET IMAGE hDlg , ID& , PageNum& , Image&
TAB SET IMAGELIST hDlg , ID& , hLst
TAB SET TEXT hDlg , ID& , PageNum& , Text$
Function Form:
CountVar& = TAB(COUNT, hDlg , ID& )
PageDlgVar& = TAB(DIALOG, hDlg , ID& , PageNum& )
ImageVar& = TAB(IMAGE, hDlg , ID& , PageNum& )
PageNumVar& = TAB(PAGE, PageDlg& )
PageNumVar& = TAB(SELECT, hDlg , ID& )
TextVar$ = TAB$(TEXT, hDlg , ID& , PageNum& )

Description

In each of the following descriptions, the Tab Control that is the subject of the statement is identified by the handle of the dialog that owns the Tab Control (hDlg), and the unique control ID you gave it upon creation in CONTROL ADD TAB. Whenever a TAB page number or IMAGELIST image number is referenced, it is indexed to one. That is, the first item is 1, the second item is 2, etc. Variations of TAB which return a single value may be written in the optional Function Form, as shown above. These functions may be embedded in an expression of any complexity.

TAB DELETE hDlg , ID& , PageNum&

The page specified by the PageNum& parameter is deleted from the Tab Control.

TAB GET COUNT hDlg , id& TO CountVar&

The number of pages in the TAB Control is retrieved, and assigned to the long integer variable specified by CountVar& .

TAB GET DIALOG hDlg , ID& , PageNum& TO PageDlgVar&

The handle of the child dialog attached to a TAB Control page is retrieved and assigned to the variable designated by PageDlgVar& . The dialog handle to be returned is determined by the value of the parameter PageNum& . If that page/dialog not exist, the value zero is returned.

TAB GET IMAGE hDlg , ID& , PageNum& TO ImageVar&

The index of the image displayed on the specified TAB page is retrieved, and assigned to the variable specified by ImageVar& . If no image is displayed, the value zero (0) is assigned.

TAB GET PAGE PageDlg TO PageNumVar&

Given the handle of a TAB Page Dialog, the PageNum is retrieved, and assigned to the variable specified by PageNumVar& . This may be particularly useful when you process CallBack messages for Tab Page Dialogs. If you also need Parent and ID information, you can use WINDOW GET .

TAB GET SELECT

hDlg , id& TO SelectVar&

The index of the currently selected page in the Tab Control is retrieved, and assigned to the variable specified by SelectVar& . If there is no current selection, the value zero (0) is assigned.

TAB GET TEXT hDlg , ID& , PageNum& TO TextVar$

The text displayed on the specified page tab is retrieved, and assigned to the variable specified by TextVar$ .

TAB INSERT PAGE hDlg , ID& , PageNum& , Image& , Text$ [CALL CallBack ] TO PageDlgVar&

A page is added to this TAB Control. The parameter PageNum& specifies the position of the page to be inserted. An optional image to be displayed on the tab area is selected from the attached IMAGELIST , based upon the parameter Image& . Set Image& to 0 if no image is desired. The Text$ parameter specifies the text to be displayed on the tab area. CallBack is the name of a callback procedure to be used for the page dialog. The handle of the newly created dialog is assigned to the variable designated by PageDlgVar&.

TAB RESET hDlg , id&

All pages in the specified Tab Control are deleted.

TAB SELECT hDlg , ID& , PageNum&

The page specified by the PageNum& parameter is chosen as the selected page for the TAB control, and the associated dialog is displayed.

TAB SET IMAGE hDlg , ID& , PageNum& , Image&

The image specified by the parameter Image& is displayed on the page tab specified by the parameter PageNum& .

TAB SET IMAGELIST hDlg , ID& , hLst

The IMAGELIST specified by hLst is attached to this TAB control. The graphical images contained in the IMAGELIST are displayed on the tabs of this control. The image to be displayed is determined by the specification made in TAB INSERT PAGE or TAB SET IMAGE. When the TAB control is destroyed, any attached IMAGELIST is automatically destroyed.

TAB SET TEXT hDlg , ID& , PageNum& , Text$

The text in the parameter Text$ is displayed on the tab of the page specified by PageNum& .

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD TAB
  • CONTROL SET FONT
  • IMAGELIST


TALLY - ScharfBASIC Help

TALLY

Count the number of occurrences of specified characters or strings within a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x& = TALLY( MainString , [ANY] MatchString )

Description

MainString is the string expression in which to count characters. MatchString is the string expression to count all occurrences of. If MatchString is not present in MainString , zero is returned. When a match is found, the scan for the next match begins at the position immediately following the prior match.

If the ANY keyword is included, MatchString specifies a list of single characters to be searched for individually: a match on any one of which will cause the count to be incremented for each occurrence of that character. Note that repeated characters in MatchString will not increase the tally. For example:

X = TALLY("ABCD", ANY "BDB") ' returns 2, not 3

Restrictions

TALLY is case-sensitive, so be wary of capitalization.

See Also

  • INSTR
  • JOIN$
  • LCASE$
  • LTRIM$
  • MID$
  • PARSE
  • PARSE$
  • PARSECOUNT
  • REMOVE$
  • REPLACE
  • RIGHT$
  • RTRIM$
  • TRIM$
  • UCASE$
  • VERIFY

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201fc8
call   0x201f4b
call   0x201fc8
call   0x201f4b
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201f34
mov   edx,0x202a74
call   0x201fc8
call   0x201b40
call   0x201e7c


TRIM$ - ScharfBASIC Help

TRIM$

Removes leading and trailing characters or substrings.

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

NewString$ = TRIM$( OldString$ [, [ANY] CharsToTrim$ ])
NewString$ = TRIM$( NumrExpr [, Digits& ])

Description

TRIM$ combines the functionality of LTRIM$ and RTRIM$ into a single function . OldString$ is the string expression from which to remove characters, and CharsToTrim$ is the string expression to remove leading and trailing occurrences. If CharsToTrim$ is not specified, TRIM$ removes leading and trailing spaces.

If the ANY keyword is included, CharsToTrim$ specifies a list of single characters to be searched for individually, a match on any one of which as a leading or trailing character will cause the character to be removed from the result.

NumrExpr

If a numeric expression is provided as the parameter, it is converted to a string (just like STR$ ), but with no leading or trailing spaces.

digits&

The maximum number of significant digits, in the range of 1 to 18. If not included, ScharfBASIC supplies a default value of 7 for single precision values, or 16 for more precise values. Use care that digits& is large enough to contain the integral part of a number, or scientific notation must be used to estimate it. For example, TRIM$(123.456, 2) returns "1.2E+2", while FORMAT$ (123.456, 5) returns the string "123.45".

Restrictions

TRIM$ is case sensitive, so capitalization matters.

See Also

  • CLIP$
  • FORMAT$
  • INSTR
  • LCASE$
  • LTRIM$
  • MCASE$
  • MID$
  • REMOVE$
  • REPLACE
  • RIGHT$
  • RTRIM$
  • SHRINK$
  • TALLY
  • UCASE$
  • UNWRAP$
  • VERIFY


UCASE$ - ScharfBASIC Help

UCASE$

Return an all-uppercase (capitalized) version of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = UCASE$( string_expression [,ANSI | OEM])

Description

UCASE$ returns a string equivalent to string_expression , except that lowercase letters in string_expression are converted to uppercase. The optional ANSI or OEM parameter specifies whether the conversion is made using the ANSI charset for the system, or the original IBM OEM charset. If no charset is specified, ScharfBASIC for Windows uses the system ANSI charset, while PB/CC uses the IBM OEM charset. Only "International" characters in the range of CHR$ (128) to CHR$(255) are affected by this parameter.

The OEM charset is based upon the original IBM OEM charset to ensure compatibility with programs written for all previous versions of the ScharfBASIC compiler.

See Also

  • ASC
  • LCASE$
  • MCASE$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x2020e4
call   0x202067
mov   edx,0x203a68
call   0x2020e4
call   0x202067
mov   edx,DWORD PTR [ebp-0x9c]
call   0x202050
call   0x201c87
call   0x20192f
lea   ebx,[ebp-0xa0]
call   0x202067
call   0x201f98


UCODE$ - ScharfBASIC Help

UCODE$

Translates

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

a$ = UCODE$( AnsiStrExpression [, CodePage& ])

Description

This version of ScharfBASIC handles all conversions between ANSI strings and UNICODE strings automatically. For example:

MyWideString$$ = MyAnsiString$

In this case, the ANSI characters are transparently converted to WIDE UNICODE characters when they are stored in MyWideString$ . You should not insert a UCODE$ function here. The simple fact that the variables are of differing types (ANSI/WIDE) causes the compiler to make all conversions for you, whenever they are needed.

Of course, this automatic conversion was not available in previous versions of the compiler. In the past, there were no WIDE UNICODE variables offered, so it was necessary to force wide characters into standard byte strings when UNICODE was needed. The ACODE$ and UCODE$ functions are used for this purpose alone: to support legacy programs which calculated strings in this fashion.

New ScharfBASIC programs and updates to your older ScharfBASIC programs should use the new WIDE UNICODE variables which are now available.

UCODE$ presumes that the AnsiStrExpression contains ANSI byte characters stored in an ANSI byte string. It converts them into WIDE UNICODE characters and returns them as an ANSI byte string. To convert a UNICODE byte string into an ANSI byte string, use the ACODE$ function.

If the optional parameter CodePage& is present, it represents the code page to be used for the conversion process. If not given, the default code page for the locale of the executing computer is used.

Unicode strings require two bytes to represent a Unicode character, whereas ANSI strings (the native ScharfBASIC string format) use one byte to represent a character. Therefore, UCODE$ returns a string that has double the byte count of the ANSI string, yet represents the same number of characters.

See Also

  • ACODE$
  • UCODEPAGE


UCODEPAGE - ScharfBASIC Help

UCODEPAGE

Set the default codepage used for

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UCODEPAGE ANSI|OEM| NumExpr [TO PrevPage& ]

Description

ScharfBASIC will make many conversions between ANSI and UNICODE (wide character) strings . UCODEPAGE specifies the CodePage to be used for these translations. The default is UCODEPAGE ANSI which will use the system ANSI codepage for your computer. UCODEPAGE OEM will use the system OEM codepage for your computer, while a numeric expression can specify a particular CodePage of your choice.

If the optional TO clause is used, the number of the previous default CodePage is assigned to the long integer variable specified by PrevPage& . By saving the previous codepage, you can later restore it, if that's appropriate.

This statement does not change the CodePage in use by your computer. It tells which codepage ScharfBASIC should use for ANSI/UNICODE conversions.

By default, the system ANSI CodePage, is used to map the character translation, and this generally works very well, as it represents the usual codepage for your primary language. However, if you are compiling a CONSOLE application which makes use of the high-order ANSI codes, CHR$ (128) through CHR$(255) for line drawing and a few international characters, you should declare an OEM CodePage by placing UCODEPAGE OEM at the start of your MAIN function.

The CodePage specification is maintained on a thread-by-thread basis. At program start, the default is the system ANSI CodePage. If a new thread is launched, it inherits the CodePage in use by the main thread.

See Also

  • ACODE$
  • UCODE$


UNWRAP$ - ScharfBASIC Help

UNWRAP$

Remove paired characters from the beginning and end of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = UNWRAP$( StringExpression , LeftChar$ , RightChar$ )

Description

The UNWRAP$ function removes the characters in LeftChar$ from the beginning of StringExpression , if there is an exact match. It then removes the characters in RightChar$ from the end, if there is an exact match. The remaining character are then returned. For example:

UNWRAP$("", "<", ">") returns "MyWord"

UNWRAP$ is particularly useful for removing parentheses, quotes, brackets, etc. from a text item.

See Also

  • EXTRACT$
  • LTRIM$
  • MID$
  • REMOVE$
  • REPLACE
  • RTRIM$
  • SHRINK$
  • TRIM$
  • WRAP$


USING$ - ScharfBASIC Help

USING$

Format one or mor

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

sResult$ = USING$( fmtmask$ , expr [, expr [, ...]])

Description

The rules of formatting are based upon the PRINT USING statement supported in many DOS versions of BASIC, including ScharfBASIC for DOS .

However, since it is implemented as a function , it allows far more versatility in that it is not necessary to output a value to gain the benefit of this unique functionality. Also, USING$ offers a wider range of applications than FORMAT$ because it can format both numeric and string expressions, and can take multiple arguments.

fmtmask$

A string expression , string variable or string literal consisting of format characters that will determine how the complete expression should be formatted. This expression is termed the mask . There may be as many format masks in fmtmask$ , arranged in the same order as the expr arguments are specified. See the examples below for more information.

A string or numeric expression, variable, or literal value to be formatted. The mask characters available depend on whether expr is a string or numeric.

Character

Definition

(string expr)

When expr is a string, the following format codes apply within fmtmask$ :

The first character of the string is returned.

The entire string is returned.

The first two characters are returned.

If backslashes enclose n spaces, n + 2 characters of the string expression are returned.

Escape (underscore) character. The following character is interpreted as a literal character instead of a mask format character.

(numeric expr)

When expr is numeric, the following format codes apply within fmtmask$ :

A numeric digit position, which is space-filled to the left, and zero-filled to the right of the decimal point. If the number is negative, a minus sign occupies a digit position.

The decimal point is placed at this position.

A numeric digit position, which signifies that whole number digits should be displayed with a comma each three digits.

Two numeric digit positions which cause a dollar sign to be inserted immediately before the number.

Two numeric digit positions which cause leading blank spaces in the field to be replaced with the character in the second position of the pair " x " (where "x" represents your own choice of character). For example, two asterisks "**" will convert leading spaces to asterisks, and "*=" converts leading spaces to equals characters, etc. The * x mask characters also act as two digit (#) placeholders. Your mask must contain at least three characters to use this.

A plus at the start of the field causes the sign of the value (+ -) to be inserted before the number. A plus at the end of the field causes the sign of the value (+ -) to be added after the number.

A minus at the end of the field causes a minus signed to be added after a negative number, or a space to be added after a positive number. A minus at the start of the field is treated as a literal character, which is always inserted.

Numbers can be formatted in scientific notation by including three to six carets (^) in the format string. Each caret corresponds to a numeric digit position in the exponent, one for E, one for the exponent sign, and one to four for the actual digits of the exponent value.

Escape (underscore) character. The following character is interpreted as a literal character instead of a mask format character. Therefore, to include a literal underscore character in the format mask, use two underscore characters.

All characters in the format mask string that are not identified above are copied into the output string just as they are encountered. You can override or escape any special format code by preceding it with an underscore character ( _ ) and it will be copied as any other literal character. This provides the flexibility to include literal string text within the formatted return string.

Restrictions

The returned string is limited to an absolute length limit of 1024 bytes .

By specifying a single mask in fmtmask$, all expr arguments are subjected to the single mask. See the examples below.

If there are fewer expr arguments than matching format masks in fmtmask$, parsing of the fmtmask$ halts after the last referenced mask position, and subsequent characters in fmtmask$ are ignored. This is consistent with the behavior of PRINT USING$ in PB/DOS.

If a numeric argument overflows its mask (i.e., there are more digits than digit positions), the resulting string will occupy as many spaces as needed to represent the number. In such cases, PB/DOS includes a leading "%" symbol to indicate the mask overflow; however, ScharfBASIC for Windows does not return the additional "%" overflow character.

The semicolon (;) and zero (0) characters are reserved for future use, so it would be prudent to escape such literal characters in USING$ masks to maintain future compatibility.

See Also

  • GRAPHIC PRINT
  • XPRINT
  • FORMAT$
  • STR$


VAL - ScharfBASIC Help

VAL

Convert a text stri

Kind | Statement
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

VAL StrgExpr [, offset ] TO ValueVar [, DigitsVar& , UnusedVar& ]

Description

The VAL statement converts a string argument to a number, but adds additional information about the conversion. Both Leading and trailing white-space characters (spaces, tabs, carriage-returns, and linefeeds) are skipped and ignored. If no number is found, the value zero (0) is returned. Format characters (like commas) are not allowed, and will cause early termination of the evaluation.

VAL interprets the letters "e" and "d" (and "E" and "D") as the symbols for exponentiation and scientific notation:

VAL "10.101e3" TO i& ' 10101 ~ 10.101*(10^3)

VAL "2D4" TO j& ' 20000 ~ 2 * (10 ^ 4)

Hexadecimal, Binary and Octal conversions

VAL can also be used to convert string arguments that are in the form of Hexadecimal, Binary and Octal numbers. Hexadecimal values should be prefixed with "&H" and Binary with "&B". Octal values may be prefixed "&O", "&Q" or just "&". If the StrgExpr contains a leading zero, the result is returned as an unsigned value; otherwise, a signed value is returned. For example:

VAL "&HF5F3" TO i& ' Hex, returns -2573 (signed)

VAL "&H0F5F3" TO j& ' Hex, returns 62963 (unsigned)

VAL "&B0100101101" TO x& ' Binary, returns 301 (unsigned)

VAL "&O4574514" TO y& ' Octal, returns 1243468 (signed)

Valid hex characters include 0 to 9, A to F (and a to f). Valid Octal characters include 0 to 7, and binary 0 to 1.

Use the STR$ , DEC$ , FORMAT$ , and USING$ functions to convert numeric values into decimal strings. Use BIN$ , HEX$ and OCT$ to convert them to Binary, Hexadecimal, and Octal representations.

Offset

If the optional Offset parameter is included, it indicates the position in the string where the conversion should begin. If not given, it defaults to one (1), and begins at the first character.

ValueVar

A numeric variable which receives the result of the conversion.

DigitsVar

An optional long integer variable which receives the count of the number of significant digits found in the evaluation. If this value is zero (0), no valid number was found and zero (0) was also assigned to ValueVar .

UnUsedVar

An optional long integer variable which receives the count of the unused characters. Since the evaluation skips both leading and trailing white-space, a non-zero value indicates that additional characters of some significance may be present. You can use RIGHT$(StrgExpr, UnUsedVar) to separate the unused characters.

Restrictions

VAL stops analyzing string_expression when non-numeric characters are encountered. When dealing with Hexadecimal, Binary, and Octal number systems, the period character is classified as non-numeric. This is because ScharfBASIC only supports floating-point formats for the decimal number system. VAL accepts the period character as a decimal place for all decimal number system values.

VAL does not analyze trailing type-specifiers for decimal strings. For example, VAL("9.1&") is evaluated as 9.1 rather than 9 because the "&" suffix is treated as a non-numeric character, not a type-specifier. However, type suffixes may be used with binary, octal, and hex values.

See Also

  • BIN$
  • DEC$
  • FORMAT$
  • HEX$
  • OCT$
  • STR$
  • USING$
  • VAL function

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202184
call   0x202107
mov   edx,0x203a68
call   0x202184
call   0x202107
mov   edx,DWORD PTR [ebp-0x9c]
call   0x2020f0
mov   eax,0x1
call   0x201b8b
fistp   QWORD PTR [ebp-0x6c]
mov   esi,DWORD PTR [ebp-0x6c]
call   0x202038


VERIFY - ScharfBASIC Help

VERIFY

Determine whether each character of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

x = VERIFY([ start& ,] MainString , MatchString )

Description

VERIFY returns zero if each character in MainString is present in MatchString . If not, it returns the position of the first non-matching character in MainString .

This function is very useful for determining if a string contains only numeric digits, for example.

VERIFY is case-sensitive, so capitalization matters.

Restrictions

If start& evaluates to a position outside of the string on either side, or if start& is zero, VERIFY returns zero.

See Also

  • INSTR
  • LCASE$
  • LTRIM$
  • MID$
  • REMOVE$
  • REPLACE
  • RIGHT$
  • RTRIM$
  • TALLY
  • TRIM$
  • UCASE$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201ce8
call   0x201c6b
call   0x201ce8
call   0x201c6b
mov   edx,DWORD PTR [ebp-0x9c]
call   0x201c54
mov   eax,0x1
mov   edx,0x202a74
call   0x201ce8
call   0x201b40
call   0x201b9c


WRAP$ - ScharfBASIC Help

WRAP$

Add paired characters to the beginning and end of a string

Kind | Function
Category | String Functions
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = WRAP$( StringExpression , LeftChar$ , RightChar$ )

Description

The WRAP$ function prepends LeftChar$ to the StringExpression, then appends RightChar$, and returns the total result. For example:

WRAP$("MyWord", "<", ">") returns ""

It is particularly useful for enclosing text with parenthesess, quotes, brackets, etc.

See Also

  • BUILD$
  • STRINGBUILDER
  • STRINSERT$
  • UNWRAP$


PROCESS GET PRIORITY - ScharfBASIC Help

PROCESS GET PRIORITY

Retrieve the Priority Value for the current

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PROCESS GET PRIORITY TO lResult&

Description

PROCESS GET PRIORITY retrieves the priority value for the current process. The retrieved priority value is assigned to the long or dword variable designated by lResult& .

The process priority value is one of the following:

%IDLE_PRIORITY_CLASS = &H00000040

Indicates a process whose thread run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.

%NORMAL_PRIORITY_CLASS = &H00000020

Indicates a normal process with no special scheduling needs.

%HIGH_PRIORITY_CLASS = &H00000080

Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.

%REALTIME_PRIORITY_CLASS = &H00000100

Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

See Also

  • PROCESS SET PRIORITY
  • THREAD GET PRIORITY
  • THREAD SET PRIORITY


PROCESS SET PRIORITY - ScharfBASIC Help

PROCESS SET PRIORITY

Sets the Priority Value for the current

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PROCESS SET PRIORITY Priority&

Description

PROCESS SET PRIORITY assigns a new priority value to the current process.

The process priority value must be one of the following:

%IDLE_PRIORITY_CLASS = &H00000040

Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.

%NORMAL_PRIORITY_CLASS = &H00000020

Indicates a normal process with no special scheduling needs.

%HIGH_PRIORITY_CLASS = &H00000080

Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is Windows Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.

%REALTIME_PRIORITY_CLASS = &H00000100

Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

See Also

  • PROCESS GET PRIORITY
  • THREAD GET PRIORITY
  • THREAD SET PRIORITY


THREAD CLOSE - ScharfBASIC Help

THREAD CLOSE

Release the handle of a running thread.

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD CLOSE hThread TO lResult&

Description

THREAD CLOSE releases the thread handle of the thread identified by the DWORD value hThread (see THREAD CREATE ).

If successful, lResult& is TRUE (non-zero); otherwise, it is FALSE (zero). If a thread is not closed once it has completed, it will continue to take up memory and CPU resources. Note that THREAD CLOSE does not stop a thread if it is still running; it simply releases the thread's handle (i.e., the resources used to track the thread), and the thread itself will continue to run.

Once a thread handle is released, the value stored in hThread becomes undefined. On this basis, thread handles should not be released until there is no further need to test the thread status or change the suspend count for a thread. If a thread does not need to be monitored, its handle can be released immediately after the THREAD CREATE statement, and the threads resources will be freed automatically when the thread terminates naturally. Best practice suggests that after releasing a thread handle, the thread handle variable should be set to 0, to set it apart from other valid thread handle variables.

Once a thread has exited, it is not possible to restart the same thread (as identified by hThread ). However, a fresh thread can be executed, using the same target thread Function, and resulting in a new thread handle which will identify the new thread.

Restrictions

THREAD CLOSE will always execute successfully provided hThread contains a valid thread handle value. THREAD CLOSE generates no run-time errors ; all exceptions are reported in the return value lResult& .

The WaitForSingleObject API function can be used wait until a nominated thread has finished executing. Similarly, the WaitForMultipleObjects API can be used to wait for one, two, or all secondary threads (to a maximum of 64 or %MAXIMUM_WAIT_OBJECTS) to complete before continuing on. Such functions can be very useful when a program creates a set of "worker" threads to process data, and the primary thread can then sit idle until all the worker threads have completed all their work. At that point, the primary thread may gather the results of the worker threads, etc.

It is also useful to understand that these kind of wait functions are very efficient and use almost no CPU time or resources while they are waiting; however, care must be exercised to avoid a deadlock or circular suspension. For example, a deadlock condition could occur if thread A is halted while it waits for thread B, which in turn has a suspend count that might only be adjustable by Thread A. Similarly, an infinite loop in one thread may also halt any other thread that is waiting for it to terminate.

THREADCOUNT continues to report a thread tally that will include threads whose handle has already been released. A thread ID value may not be used interchangeably with a thread handle value.

See Also

  • FUNCTION/END FUNCTION
  • THREAD Code Group
  • THREAD CREATE
  • THREAD Object
  • THREAD RESUME
  • THREAD STATUS
  • THREAD SUSPEND
  • THREADCOUNT
  • THREADED
  • THREADID

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

lea   ebx,[ebp-0x9c]
call   0x201ad4


THREAD Code Group - ScharfBASIC Help

THREAD Code Group

The Thread

Kind | Keyword
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD DirectorWord [ params ]
THREAD DirectorWord [ params ] TO ReturnVariable(s)

Description

A Windows thread is a smaller "program-within-a-program", that runs concurrently with the main thread and other threads in the same application program. Threads provide powerful ways for an application to perform several tasks at the same time.

With the advent of multi-core CPU's and multi-CPU computers, it's clearly desirable to encapsulate all of the information about a particular thread in a single component. For that reason, ScharfBASIC has introduced the concept of a THREAD OBJECT . While the THREAD Code Group will be supported for some time, we recommend that all new code use THREAD OBJECTS exclusively. They provide much greater control, and much better thread parameter handling for the programmer.

Restrictions

Functions from the Thread Code Group and THREAD OBJECTS may co-exist in the same application. However, it is important that they not be intermixed referencing the same thread.

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD CREATE
  • THREAD GET PRIORITY
  • THREAD Object
  • THREAD RESUME
  • THREAD STATUS
  • THREAD SUSPEND
  • THREADCOUNT
  • THREADED
  • THREADID
  • THREADSAFE option descriptor


THREAD CREATE - ScharfBASIC Help

THREAD CREATE

Create a Windows thread, which is a smaller "program-within-a-program", that runs concurrently with the main thread and other threads in the same application program. Threads provide powerful ways for an application to perform several tasks at the same time.

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD CREATE FuncName ( param ) [ StackSize ,] [SUSPEND] TO hThread

Description

THREAD CREATE creates and begins execution of a new thread Function identified by FuncName . FuncName is specified without quotation marks. This function must take exactly one Long-integer or Double-word (DWORD) parameter by value ( BYVAL ). For example:

THREAD FUNCTION MyThreadFunction(BYVAL x AS LONG) AS LONG

' Thread code goes here

END FUNCTION

' more code here

THREAD CREATE MyThreadFunction(var&) TO hThread???

The 32-bit parameter passed to the thread may be used to pass a value such as a programmer-defined ID or window handle to post "progress" messages back to a GUI window/dialog running in another thread. A more common use for the parameter is to pass the address to a UDT or other data structure. Passing an address this way can enable the thread to use a pointer to access large volumes of data that reside outside of the thread. For example:

THREAD FUNCTION MyThread(BYVAL y AS DWORD) AS DWORD

DIM x AS MyUDT POINTER

x = y ' Set the pointer from the DWORD param

' From here we can access all of the UDT member elements

' using the standard @x pointer syntax

END FUNCTION

' more code here

DIM x AS MyUDT, hThread???

' Initialize the members of x here

THREAD CREATE MyThread( VARPTR(x) ) TO hThread???

' more code here

Note that data passed this way is subject to the notes (below) concerning GLOBAL and STATIC variables , in order to avoid synchronization problems during context-switching.

The return value of the thread Function is retrieved with the THREAD STATUS statement (once the thread has completed execution).

StackSize

A long integer expression to specify the requested size of the stack for this newly created thread. This value should always be specified in increments of 64K (65536). If this parameter is omitted, the size of the stack for the main thread will be used.

SUSPEND

Execution of the thread begins immediately unless the SUSPEND option is included. In that case, the suspend count for the thread will be initially set to 1, and the thread will be initially suspended. The THREAD RESUME statement is used to decrease the suspend count of a thread by 1, and when the suspend count reaches 0, the thread will start (resume) execution. Controlling the suspend state of a thread requires the thread handle value be retained until such time as the thread can be closed or left to run unmonitored.

hThread

If successful, THREAD CREATE returns a Double-word (or Long-integer) handle in hThread , or zero (0) if the thread was not started. This handle is used with the other thread statements to control the suspend count, and to release the thread handle, etc. Also see THREAD CLOSE for more information on monitoring, closing, and waiting for threads to complete.

Func Name

The name of the thread function to execute as a thread. A thread Function must comply exactly with the following syntax:

THREAD FUNCTION ThreadFuncName (BYVAL param AS {LONG | DWORD}) AS {LONG | DWORD}

Restrictions

The THREAD CREATE statement generates no run-time errors ; all exceptions are reported as a zero stored in the return value hThread . However, the target thread Function must be located in the same compiled module as the THREAD CREATE statement. That is, a thread Function may not be an imported Function.

Additionally, a thread Function may not be directly called or executed, except by a THREAD CREATE statement. This restriction is imposed to ensure that ScharfBASIC run-time library can maintain a thread-safe state at all times, correctly allocate and deallocate internal thread-local storage, and the various thread func tions (such as THREADCOUNT) can return accurate values.

One situation that can arise is where a Function may need to be invoked both directly and used as a thread Function. The easiest solution is to create a small wrapper Function for the Function, then use THREAD CREATE with the wrapper Function when a thread is required, or continue to call the original Function directly when a separate thread is not required. For example:

FUNCTION WorkerFunc(BYVAL x AS LONG) AS LONG

' code here

END FUNCTION

THREAD FUNCTION WorkerThread(BYVAL x AS LONG) AS LONG

FUNCTION = WorkerFunc(x)

END FUNCTION

' more code here

' Execute the worker function directly, thus:

lResult& = WorkerFunc(var&)

' Execute the worker thread as a thread, using

' the wrapper function:

THREAD CREATE WorkerThread(var&) TO hThread???

A thread can determine its own ID with the THREADID function. Note: a thread ID is not interchangeable with a thread handle.

Threads are initialized and started asynchronously, so it is wise to give the operating system a small amount of time to perform thread initialization before using the THREADCOUNT function to monitor the thread.

Once a thread has exited, it is not possible to restart the same thread as identified by hThread - however, a new thread can be initiated using the same Function (which naturally provides a new hThread handle value). In addition, the same thread Function can be launched multiple times to create a set of identical threads executing the same code.

As each thread is created, it is assigned its own "private" stack frame. Therefore, LOCAL and REGISTER variables are private to each thread, and are automatically " thread-safe ".

Exercise care when using GLOBAL and STATIC variables that may be accessed by more than one thread at the same time. If one thread is part way through storing data at the point where another thread begins to read the same memory block, it can result in the second thread reading only partially updated (i.e., invalid) data. The point where one thread is suspended so that another can run is called a " context-switch ". In these situations, the use of Windows' synchronization functions (such as Critical Sections and Mutexes ) may be employed to create thread-safe code.

Thread-safe code is deemed to be unaffected by context-switching, regardless of when context-switching occurs. Local variables, being stored in a "private" stack frame, are not affected by context-switching.

Local variable storage created by each thread is automatically freed when the thread Function terminates, in the same manner as a normal Sub , Function, Method , or Property . However, the thread handle must be explicitly freed with a THREAD CLOSE statement. The THREAD CLOSE can occur at any time, since it only frees the thread handle and has no other impact on the running thread. If the thread result value is not required (or the thread state does not need to be altered), THREAD CLOSE can be used immediately after the THREAD CREATE statement, leaving the thread to run its course.

For more information on threading and synchronization techniques, please refer to MSDN http://msdn.microsoft.com .

The ScharfBASIC run-time library is thread-safe and reentrant.

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD Code Group
  • THREAD GET PRIORITY
  • THREAD Object
  • THREAD RESUME
  • THREAD STATUS
  • THREAD SUSPEND
  • THREADCOUNT
  • THREADED
  • THREADID

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   ecx,0x2010ed
push   0x100000
lea   ebx,[ebp-0xa0]
call   0x201b6a


THREAD GET PRIORITY - ScharfBASIC Help

THREAD GET PRIORITY

Retrieve the Priority Value for a thread

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD GET PRIORITY hThread TO lResult&

Description

THREAD GET PRIORITY retrieves the priority value for the thread specified by the thread handle ( hThread ). The thread handle is returned by the THREAD CREATE statement at the time the thread is created. If hThread is zero (0), the thread which is currently executing is presumed. The retrieved priority value is assigned to the long or dword variable designated by lResult& . A thread ID cannot be used in place of a thread handle.

The thread priority value is one of the following:

%THREAD_PRIORITY_IDLE = -15

%THREAD_PRIORITY_LOWEST = -2

%THREAD_PRIORITY_BELOW_NORMAL = -1

%THREAD_PRIORITY_NORMAL = 0

%THREAD_PRIORITY_ABOVE_NORMAL = +1

%THREAD_PRIORITY_HIGHEST = +2

%THREAD_PRIORITY_TIME_CRITICAL= +15

See Also

  • PROCESS GET PRIORITY
  • PROCESS SET PRIORITY
  • THREAD Code Group
  • THREAD CREATE
  • THREAD Object
  • THREAD SET PRIORITY


THREAD RESUME - ScharfBASIC Help

THREAD RESUME

Resume execution of a Windows thread.

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD RESUME hThread TO lResult&

Description

THREAD RESUME decreases the suspend count of the thread identified by the 32-bit DWORD value stored in hThread (see THREAD CREATE ). If it succeeds, the lResult& value is the thread's previous suspend count; otherwise, it is -1.

Execution of a suspended thread resumes when the suspend count of a thread is decremented to zero. If the SUSPEND option is included in the associated THREAD CREATE statement, the thread will have an initial suspend count of 1. In that case, execution of the thread will only begin when a THREAD RESUME statement is executed, using the thread handle stored in hThread to identify the thread.

Restrictions

The THREAD RESUME statement generates no run-time errors ; all exceptions are reported in the return value lResult& . A thread ID cannot be used interchangeably with a thread handle. A thread can suspend itself by incrementing its own suspend count, but logically, cannot decrement its own suspend count.

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD Code Group
  • THREAD CREATE
  • THREAD Object
  • THREAD STATUS
  • THREAD SUSPEND
  • THREADCOUNT
  • THREADED
  • THREADID


THREAD SET PRIORITY - ScharfBASIC Help

THREAD SET PRIORITY

Sets the Priority Value for a thread

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD SET PRIORITY hThread , Priority&

Description

THREAD SET PRIORITY assigns a new priority value to the thread specified by the thread handle ( hThread ). The thread handle is returned by the THREAD CREATE statement at the time the thread is created. If hThread is zero (0), the thread which is currently executing is presumed. A thread ID cannot be used in place of a thread handle.

The thread priority value must be one of the following:

%THREAD_PRIORITY_IDLE = -15

%THREAD_PRIORITY_LOWEST = -2

%THREAD_PRIORITY_BELOW_NORMAL = -1

%THREAD_PRIORITY_NORMAL = 0

%THREAD_PRIORITY_ABOVE_NORMAL = +1

%THREAD_PRIORITY_HIGHEST = +2

%THREAD_PRIORITY_TIME_CRITICAL= +15

See Also

  • PROCESS GET PRIORITY
  • PROCESS SET PRIORITY
  • THREAD Code Group
  • THREAD CREATE
  • THREAD GET PRIORITY
  • THREAD Object


THREAD STATUS - ScharfBASIC Help

THREAD STATUS

Retrieve the Status of a Windows thread.

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD STATUS hThread TO lResult&

Description

THREAD STATUS assigns the status of the thread identified by the DWORD value in hThread (see THREAD CREATE ) to lResult& .

If the function fails, lResult& is set to zero. If the thread is still running, the system value &H103 is assigned. If the thread has terminated and the thread handle has not yet been closed, the return value from the thread Function is assigned to lResult& . To wait for one or more threads to complete execution, use the WaitForSingleObject or WaitForMultipleObjects API functions - see THREAD CLOSE for more information.

The number of currently running threads in a module can be determined with the THREADCOUNT function.

Restrictions

The THREAD STATUS statement generates no run-time errors ; all exceptions are reported in the return value lResult& . A thread ID cannot be used in place of a thread handle.

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD Code Group
  • THREAD CREATE
  • THREAD Object
  • THREAD RESUME
  • THREAD SUSPEND
  • THREADCOUNT
  • THREADED
  • THREADID


THREAD SUSPEND - ScharfBASIC Help

THREAD SUSPEND

Suspend execution of a Windows thread.

Kind | Statement
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREAD SUSPEND hThread TO lResult&

Description

THREAD SUSPEND adds 1 to the suspend count of the thread specified by hThread (see THREAD CREATE ). If it succeeds, the lResult& value is the thread's previous suspend count; otherwise, it is -1. A thread is always suspended if it has a suspend count of 1 or higher.

To decrement the suspend count of a thread, use the THREAD RESUME statement. A suspended thread will only resume execution when its suspend count is decremented to 0.

Restrictions

The THREAD SUSPEND statement generates no run-time errors ; all exceptions are reported in the return value lResult& . A thread ID cannot be used interchangeably with a thread handle. A thread can suspend itself by incrementing its own suspend count.

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD Code Group
  • THREAD CREATE
  • THREAD Object
  • THREAD RESUME
  • THREAD STATUS
  • THREADCOUNT
  • THREADED
  • THREADID


THREADCOUNT - ScharfBASIC Help

THREADCOUNT

Return the number of ScharfBASIC-created active threads that exist in a module.

Kind | Function
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

lCount& = THREADCOUNT

Description

Applications will return a THREADCOUNT of at least 1, which is attributed to the "primary" application thread. Additional threads created by the application or module with the THREAD CREATE function will also be included in the tally returned by THREADCOUNT .

THREADCOUNT can be useful for when a "controlling thread" needs to poll the state of a collection of "worker threads" as they complete a set of tasks. However, care should be exercised if other (unrelated) threads may also be running in the same module - in such cases, using THREAD STATUS is the preferred solution. If polling is not desired, the WaitForMultipleObjects API function can also be useful - see THREAD CLOSE for more information.

Restrictions

THREADCOUNT includes threads that have had their thread handle released with THREAD CLOSE, yet are still running.

Threads are initialized and started asynchronously, so it is wise to give the operating system a small amount of time to perform thread initialization before using the THREADCOUNT function to monitor the thread.

A thread Function may not be directly called or executed, except by a THREAD CREATE statement. This restriction is imposed to ensure that ScharfBASIC run-time library can maintain a thread-safe state at all times, correctly allocate and deallocate internal thread-local storage), and functions such as THREADCOUNT can return accurate values. See THREAD CREATE for more information and solutions.

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD Code Group
  • THREAD CREATE
  • THREAD Object
  • THREAD RESUME
  • THREAD STATUS
  • THREAD SUSPEND
  • THREADED
  • THREADID

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201bee


THREADID - ScharfBASIC Help

THREADID

Return a

Kind | Function
Category | Threading
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

thrdID& = THREADID

Description

The thread ID value is returned for the thread that is currently executing. The Thread ID is intended for use with the various (advanced) thread-related API functions provided by Windows.

Restrictions

The thread ID value cannot be used interchangeably with the thread handle returned by THREAD CREATE .

See Also

  • FUNCTION/END FUNCTION
  • THREAD CLOSE
  • THREAD CREATE
  • THREAD RESUME
  • THREAD STATUS
  • THREAD SUSPEND
  • THREADED


Accessing the fields of a User-Defined Type - ScharfBASIC Help

Accessing the fields of a User-Defined Type

To work with the individual fields within a record variable, separate the field name from the variable name with a period. Here are some examples using the Student variable in the above DIM statement:

Kind | Structure
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Last$ = Student.LastName

Message$ = "Id number is: " + STR$(Student.IdNum)

Student.FirstName = "Bob"

Student.LastName = "Smith"

Fullname$ = Student.LastName + " " + Student.FirstName

Fullname$ = RTRIM$(Student.LastName) + ", " + RTRIM$(Student.FirstName)

Note that the last two statements above produce slightly differing results. The former produces a string that contains the text plus any $SPC (space) characters that pad the text in each of the Student.LastName and Student.FirstName members. Comparatively, the latter statement returns a string with these padding characters removed. In many cases, it can be easier to use a nul-terminated string members to alleviate the need to frequently trim such fixed-length strings , but allowance must be made for the additional $NUL terminator byte required by nul-terminated strings.

User-Defined Types (UDTs)


Arrays within User-Defined Types - ScharfBASIC Help

Arrays within User-Defined Types

In prior versions of this compiler, arrays could not be part of a UDT structure. However, we now support both one and two-dimensional arrays of variables that have a fixed-length (for each element) -

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Two-dimensional arrays within Types work exactly as do any other array in ScharfBASIC, except that their dimensions are specified by positive numeric constant values, and are therefore not dynamically alterable. That is, the dimension sizes must be specified with numeric equates or numeric literal values, and these cannot be altered at run-time.

Like conventional arrays, the default lower array boundary is zero, but positive non-zero values may be used to specify a specific range of subscript index values for the array, separated from the upper array boundary subscript with the TO keyword. Additionally, both the lower and upper subscript index values must be zero or greater (ie, negative subscript values are not permitted). Examples of valid syntax follow:

id AS INTEGER ' Scalar UDT member

Styles(6) AS DWORD ' 7 elements (0 TO 6)

Yrs(1980 TO 2010) AS LONG ' 31 elements

Team(100 TO 101) AS BYTE ' 2 elements

Rating(1 TO 10) AS DWORD ' 10 elements

X(1 TO 5, 0 TO 5) AS EXT ' 30 elements (5x6)


Defining User-Defined Types - ScharfBASIC Help

Defining User-Defined Types

The definition of a User-Defined Type begins with the reserved word TYPE and ends with the keywords END TYPE. In between, you define the names and data types of the member elements (fields) that are t

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

LastName AS STRING * 20 ' A 20-character string

FirstName AS STRING * 15 ' A 15-character string

IDnum AS LONG ' Student ID, a Long-integer

Contact AS STRING * 30 ' Emergency contact person

ContactPhone AS STRING * 14 ' Their phone number

ContactRel AS STRING * 8 ' Relationship to student.

AverageGrade AS SINGLE ' Single-precision % grade


ENUM/END ENUM statements - ScharfBASIC Help

ENUM/END ENUM statements

Creates a group of logically related

Kind | Statement
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ENUM Name [SINGULAR] [BITS] [AS COM]
EquateName [= value ]
...
END ENUM

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edi,0x2a


MACRO/END MACRO - ScharfBASIC Help

MACRO/END MACRO

Define a single or multi-line text substitution block.

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MACRO macroname [( prm1 , prm2 , ...)] = replacementtext
MACRO macroname [( prm1 , prm2 , ...)]
[MACROTEMP ident1 [, ident2 , ...]]
DIM ident1 AS type [, ident2 AS type , ...]]
{ replacementtext }
[EXIT MACRO]
END MACRO
MACRO FUNCTION macroname [( prm1 , prm2 , ...)]
[MACROTEMP ident1 [, ident2 , ...]
{replacementtext}
END MACRO = returnexpression

Description

Macro is a powerful text substitution construct that may take a single-line or multi-line format. It generates absolutely no executable code unless it is referenced, and effectively allows the programmer to design a part of the ScharfBASIC language to his/her own needs and requirements. For example, a simple single-line macro can allow ScharfBASIC to emulate the CONST syntax used in Visual Basic - see the box-out below for more information.

A macro must always be defined before it is referenced, and the parameter count must always match the definition. When a macro is referenced, the occurrence of the name is replaced by the defined replacement text, expanded with parameter substitution. The first line of a MACRO definition is termed the macro prototype, and this line may not be split into multiple logical lines with the underscore (_) line continuation character. Likewise, the END MACRO = returnexpression may not be split with underscores either. A Macro also cannot end with a line continuation character.

Macros may be nested, and may forward-reference other macros. However, care should be exercised to avoid circular references.

A single-line macro or a macro function may be referenced at any source code position which, when expanded, will be syntactically correct (also see the Restrictions section below). Consider the following simplistic example:

MACRO concatenate(prm1,prm2) = prm1 & $SPC & prm2

' more code here

A$ = concatenate("Hello","World")

During compilation, ScharfBASIC would internally expand this code to become:

A$ = "Hello" & $SPC & "World"

A multi-line macro, while more powerful in terms of coding, may be referenced only in the "statement" position, which is the first position on a line. That single reference is internally expanded into multiple lines of inline code to perform a complex task. For example:

MACRO Display6times(prm1)

CALL Display(prm1) : CALL Display(prm1)

CALL Display(prm1) : CALL Display(prm1)

CALL Display(prm1) : CALL Display(prm1)

END MACRO

' more code here

Display6times("This is very cool...")

The single-line MACRO offers a cunning way to retain the CONST syntax used in MSBASIC and Visual Basic in your ScharfBASIC code, while maintaining the low overhead advantage of ScharfBASIC. For example:

MACRO CONST = MACRO

' more code here

CONST Version = 1&

CONST AppTitle = "My Application"

' more code here

a$ = AppTitle & " v" & FORMAT$(Version)

During compilation, the CONST keyword is replaced by the MACRO keyword, dynamically creating a new macro that, in turn, defines a numeric or string literal . When the real macro name is referenced in the code, the literal is substituted directly.

MACROTEMP

The MACROTEMP statement may be used to specify a list of one or more identifiers, each of which is automatically made unique to each expansion of a multi-line macro. This is done by internally appending the digits 0001, 0002, etc, to the identifier upon each expansion of the macro.

A text identifier may represent a variable , label , or any other word, which expands appropriately to avoid a duplicate name conflict in your code.

MACROTEMP just creates a symbol name. If this symbol is a variable name, the variable must still be formally declared with an appropriate DIM (or LOCAL ) statement. For example:

MACRO CopyUntilNul(ptr1,ptr2)

MACROTEMP LoopPoint, ByteVar

DIM ByteVar AS BYTE

LoopPoint:

ByteVar = @ptr1

@ptr2 = ByteVar

INCR ptr1

INCR ptr2

IF ByteVar <> 0 THEN LoopPoint

END MACRO

Using that MACRO definition, the code "CopyUntilNul(Source, Dest)" would expand to something like this:

DIM ByteVar0001 AS BYTE

LoopPoint0001:

ByteVar0001 = @Source

@Dest = ByteVar0001

INCR Source

INCR Dest

IF ByteVar0001 <> 0 THEN LoopPoint0001

If the MACROTEMP statement were not used, serious naming conflicts would occur most any time that a macro was expanded more than once in a program. MACROTEMP statements may appear 0, 1, or more times in a macro definition, but they must always precede any other text in the macro.

MACROTEMP statements should be used with any label in a macro that may be expanded more than once in a program, and with any variable that should not be shared with any other expansion of the macro.

EXIT MACRO

EXIT MACRO may be used to terminate execution of code in the current macro expansion. It is functionally identical to the imaginary concept of GOTO END-MACRO.

END MACRO

A macro function block can return a value with the END MACRO = returnexpression statement.

Restrictions

A macro definition may contain replacement text up to approximately 4000 characters. Macros may specify up to 240 parameters, which may occupy up to approximately 2000 bytes total expanded space per macro.

Macro Function substitutions are limited to an expanded total of approximately 16000 characters per line of original source code.

Macro parameters are substituted directly, so whitespace characters in the passed macro parameters may cause unexpected problems if the expanded code is syntactically incorrect with the additional whitespace. For example, this can be important when specifying UDT variables as macro parameters. Consider the following code:

TYPE MyType

lCount AS LONG

szText AS ASCIIZ * 256

END TYPE

MACRO PresetUDT(u)

u.lCount = 1

u.szText = SPACE$(256)

END MACRO

FUNCTION PBMAIN

DIM x AS MyType

PresetUDT(x)

PresetUDT(x ) ' This line causes an Error 526

END FUNCTION

In the code above, the second macro expansion fails to compile because the trailing space in the passed macro parameter becomes part of the expanded code. In this situation, this additional space character breaks the syntax of the UDT variable reference within the expanded macro, triggering a compile-time Error 526 ("Period not allowed"). If we examine how the two expanded macro statements would appear, the problem becomes immediately obvious:

x .lCount = 1

x .szText = SPACE$(256)

(Please note that the caret symbols (^) above have been added purely to illustrate the exact position of the problem)

When using single-line macros that contain numeric expressions, use parentheses around the macro body to guard against unexpected order of precedence problems when the macro is used within an expression. For example, consider the following macro and expansion:

MACRO Calculate(p1, p2, p3) = (p1 * p2) \ p3

' more code here

x = Calculate(a,b,c) ^ 3

When this macro is expanded, the expression would be calculated as follows:

x = (a * b) \ c ^ 3

However, if the macro body was enclosed in parentheses:

MACRO Calculate(p1, p2, p3) = ((p1 * p2) \ p3)

then the expanded expression would be calculated thus:

x = ((a * b) \ c) ^ 3

MACRO prototypes (those beginning with the MACRO keyword) and END MACRO = returnexpression lines must be constructed on a single line of source code. That is, they may not be split across multiple lines of source code with line continuation characters, since these interfere with the text substitution process. For example, the following prototype is invalid:

MACRO FUNCTION MyMacro1(sParam1, sParam2, sParam3, sParam4)

If a macro expands directly to a Function call, the macro can be called using the SUB -style syntax, automatically discarding the function return value. For example:

MACRO sm(Msg) = SendMessage(a, Msg, b, c)

can be called like this (if the return value is not required):

A macro cannot expand directly to a REMark, because REM and ' are processed before the macro is assigned. So, MACRO hello = REM winds up as an invalid, blank macro.

Finally, it should be noted that the Integrated Debugger appears to step over macro references as if they were conventional BASIC statements. This occurs because macro expansion takes place during the compilation process and the original source code is not affected or altered by the compile-time expansion.

See Also

  • EXIT
  • FUNCTION/END FUNCTION
  • METHOD
  • PROPERTY
  • SUB/END SUB

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

inc    esi
inc    esi


Nesting User-Defined Types - ScharfBASIC Help

Nesting User-Defined Types

The fields within a User-Defined Type can be made up of other User-Defined Types. Just like a set of Chinese boxes, with each box containing a smaller box, you can nest one User-Defined Type within an

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Instead of storing the student names as two separate fields, we could instead define a Type called NameRec as follows:

Initial AS STRING * 1

Then, when we define our Student Record Type, we can define the field containing the individual student's name as NameRec :


TYPE SET - ScharfBASIC Help

TYPE SET

Assign the value of a

Kind | Statement
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TYPE SET typevar = { typevar | ByteStringExpr$ } [USING ustring_expression ]

Description

TYPE SET is primarily designed to assign the value of a User-Defined Type (UDT) to a different class of User-Defined Type. Additionally, TYPE SET can be used to assign a string expression ( ByteStringExpr$ ) to a UDT, though it is generally not appropriate to assign a wide Unicode string.

Any Byte positions remaining after the assignment are filled (padded) in the target typevar with the first character of the USING string expression, or binary zeros if not specified.

See Also

  • CSET
  • CSET$
  • LET (with Types)
  • LSET
  • LSET$
  • RSET
  • RSET$
  • TYPE/END TYPE


TYPE/END TYPE - ScharfBASIC Help

TYPE/END TYPE

Define a

Kind | Structure
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TYPE MyType [BYTE | WORD | DWORD | QWORD] [FILL]
[ MemberName [( subscripts )] AS] TypeName
[ MemberName [(subscripts)] AS TypeName ]
[...]
END TYPE

Description

The TYPE statement has the following parts:

The beginning of a User-Defined Type definition.

MyType

The name of the User-Defined Type, which must conform to standard variable naming conventions.

Member alignment

TYPE definitions may optionally specify an alignment of BYTE (the default), WORD , DWORD , or QWORD , as well as FILL characteristics. With standard alignment, each member of a Type Structure will be located on the specified boundary. For example, with DWORD, up to 3 bytes may be skipped between members to accomplish alignment.

However, when a user-defined type is defined as a member of a larger user-defined type, this "sub-type" retains its original size and alignment, just as first declared.

Each member will be aligned on a BYTE boundary - no padding or alignment is applied to the structure. This is the default alignment method.

Each member will be aligned on a WORD boundary. Any odd byte between members of TYPE will be automatically skipped and ignored. The UDT structure may also be padded with one trailing byte to ensure the total structure size is a multiple of 2 bytes.

Each member will be aligned on a DWORD boundary. Up to three bytes will be skipped to accomplish this alignment. The UDT structure is also padded with up to three trailing bytes to ensure the total structure size is a multiple of 4 bytes.

QWORD alignment is included for compatibility with Windows, it cannot be fully implemented in a 32-bit operating system. With QWORD, individual members are 64-bit aligned for the appropriate structure size, but variables of that type may only be aligned on 32-bit boundaries, as stack pointer alignment is not guaranteed.

If the FILL option is specified, such as TYPE xxx DWORD FILL, the following rules apply:

1. No bytes are skipped if the next member of the Type will fit entirely into that space to be skipped.

2. Fixed-length strings are considered to be an array of bytes, so no bytes are skipped preceding them.

3. The total size of an array is considered to determine if FILL should affect its placement within the structure. For example, with DWORD FILL, an array of two integers would be started on a 4-byte boundary, even if two or three bytes must be skipped.

Type members

MemberName

The name of a member of the User-Defined Type. This too must follow the standard variable naming conventions.

subscripts

The dimensions of a member array . Arrays of one and two dimensions are supported, but must be defined with constant or numeric literal values. That is, the total size of a UDT must be known at compile-time, so items like dynamic strings , which vary in size, cannot be part of a TYPE structure. A STRING PTR can, however, since a pointer is implemented as a DWORD.

Like conventional arrays, the default lower array boundary is zero, but positive non-zero values may be used to specify a specific range of subscript index values for the array, separated from the upper array boundary subscript with the TO keyword. Additionally, both the lower and upper subscript index values must be zero or greater (ie, negative subscript values are not permitted). Examples of valid syntax follow:

TYPE MYTYPE

id AS INTEGER ' Scalar UDT member

Styles(6) AS DWORD ' 7 elements (0 TO 6)

Yrs(1980 TO 2010) AS LONG ' 31 elements

Team(100 TO 101) AS BYTE ' 2 elements

Rating(1 TO 10) AS DWORD ' 10 elements

X(1 TO 5, 0 TO 5) AS EXT ' 30 elements (5x6)

Y(4,3) AS QUAD ' 20 elements (5x4)

END TYPE

Individual UDT structures can be up to 16 MB each. A single member element of a UDT may also occupy the entire 16 MB. For example, arrays within a UDT, nul-terminated strings , and fixed-length strings . UDT member arrays are not resizable at runtime. Additionally, the cannot be used directly on a UDT member array. Instead, use DIM..AT to declare a conventional array at the same memory address as the UDT member array, and the ARRAY statement can then be used on that array.

TypeName

One of the supported data types, including User-Defined Types and Unions , with the exception of arrays.

END TYPE

Marks the end of the User-Defined Type definition.

It is often very convenient to be able to refer to several different types of things as a single unit or data structure. For example, in an accounting program, an account number and amount are part of what makes up a single journal entry. The TYPE/END TYPE block statements make it easy to create a single UDT that holds such information.

TYPE JournalType DWORD ' type name and alignment

AccountNumber AS LONG ' member name and data type

Amount AS CUR ' this is another one

END TYPE ' end of type declaration

DIM JournalEntry AS JournalType ' declare a record

TYPE/END TYPE blocks must be defined outside of a Sub , Function , or Class and may be defined only once in any program. It is usually easiest to put your TYPE/END TYPE block definitions in an Include file and use the #INCLUDE metastatement in any module that may need to use them.

TYPE/END TYPE blocks do not declare any variables; instead, they simply define a new type. You can declare variables of that type using the DIM or REDIM statements, or any statement that lets you use an AS clause:

DIM TypeVariable as TypeVariableType

Once you have a User-Defined Type variable declared, you can access its member elements using the following format:

TypeVariable.Element

For example, to change the account number in the JournalEntryType type, you might use a statement like:

JournalEntry.AccountNumber = 1000

A User-Defined Type can be used like any built-in ScharfBASIC type. For example, you can define an array of record variables:

DIM JournalEntries(1 TO 100) AS JournalEntryType

or even create a procedure that accepts a record variable:

SUB PrintJournalEntry(aJournalEntry AS JournalEntryType)

' Print journal

END SUB

You can also use pointers in a TYPE definition. Note that the first member in the next example is auto-aligned to start on a DWORD boundary, and three bytes are skipped so that the second member is also aligned on a DWORD boundary:

TYPE MyType DWORD

Count AS BYTE ' Aligned to a DWORD boundary

y AS INTEGER PTR ' Aligned to next DWORD boundary

z AS STRING PTR

END TYPE

Since pointers are stored as a DWORD, their length is 4 bytes when used in a TYPE/END TYPE, regardless of the length of their target. To access the target of a pointer, you must place the at-sign in front of the TYPE/END TYPE member, not the name of the TYPE itself:

iResult% = @MyType.y ' Invalid

iResult% = MyType.@y ' Valid

You can also declare a variable that is a pointer to a TYPE:

TYPE MyData

Val1 AS INTEGER

Val2 AS INTEGER

Val3 AS INTEGER

Val4 AS INTEGER

END TYPE

DIM Info AS MyData PTR

Info = VARPTR(YourData)

Message$ = HEX$(@Info.Val1) + $CRLF + _

HEX$(@Info.Val2) + $CRLF + _

HEX$(@Info.Val3) + $CRLF + _

HEX$(@Info.Val4)

Note that the target specifier is in front of the TYPE name since it is the pointer. Val1, Val2, Val3, and Val4 represent offsets from that pointer. ScharfBASIC does support a pointer within a structure pointer, but you should be very careful in their use. Changing the structure pointer itself could make all member pointers invalid. See the topic on pointers for more information.

Bit Variables

TYPE structures may contain bit variables, which are named BIT (unsigned values) or SBIT (signed values). Each bit variable may occupy from 1 to 31 bits, and they may be packed one after another up to a total of 32 bits per bit field. The size of a bit variable is defined as follows:

var AS BIT * nlit [IN BYTE|WORD|DWORD]

where the term "* nlit" defines the number of bits (1 to 31), and the optional term "IN BYTE|WORD|DWORD", if present, defines the start of a new bit field of 1, 2, or 4 bytes. For example:

TYPE ABCD

Valu2 AS BIT * 31 IN DWORD

Sign1 AS SBIT * 1

nybl2 AS BIT * 4 IN BYTE

nybl1 AS BIT * 4

END TYPE

The example TYPE structure above is 5 bytes in size, containing a 4-byte bit field and a 1-byte bit field. In this case, each contains two bit-variables of varying size. The range of values which may be stored depends upon the number of bits available. For example, "BIT * 4" has a range of 0 to 15, "SBIT * 1" has a range of -1 to 0, and "SBIT * 5" has a range of -16 to +15.

Structures within structures

Structures (TYPE/UNION) may be embedded within another structure, for simplification in referencing deeply nested items, by simply stating the structure name alone at the appropriate position. The internal alignment of the member structure is precisely maintained regardless of other alignment specifications, to foster inheritance issues. For example:

TYPE ABCD3

A AS LONG

C AS LONG

END TYPE

TYPE ABCD2

D AS DWORD

E AS DOUBLE

END TYPE

UNION ABCD1

F AS DWORD

G AS LONG

H AS SINGLE

END UNION

In this case, you could access the lone Single-precision float member of this structure very simply. Assuming DIM X AS ABCD3, you could reference the Single-precision Union member with the statement X.H, instead of the extended syntax X.ABCD2.ABCD1.H

For related information, please refer to the UNION/END UNION and User-Defined Types and Unions sections.

Restrictions

When measuring the size of a padded (aligned) UDT structure with the LEN or SIZEOF statements, the measured length includes any padding that was added to the structure. For example, the following UDT structure:

TYPE LengthTestType DWORD

a AS INTEGER

END TYPE

' more code here

DIM abc AS LengthTestType

x& = LEN(abc)

Returns a length of 4 bytes in x& , since the UDT was padded with 2 additional bytes to enforce DWORD alignment. Note that the LEN and SIZEOF of individual UDT members will return the true size of the member without regard to padding or alignment. In the previous example, LEN(abc.a) returns 2.

Individual UDT structures can be up to 16 MB each. Arrays within a UDT, nul-terminated strings and fixed-length strings may occupy the full 16 MB structure size limit.

Field strings and dynamic strings cannot be used in UDT or UNION structures. Attempting to do so results in a compile-time Error 485 ("Dynamic/Field strings not allowed").

See Also

  • DIM
  • LEN
  • REDIM
  • LET (with Types)
  • SIZEOF
  • TYPE SET
  • UNION/END UNION
  • User-Defined Types
  • Unions


UNION/END UNION - ScharfBASIC Help

UNION/END UNION

Create a new

Kind | Structure
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

UNION UnionName
MemberName [( subscripts )] AS TypeName
[ MemberName [( subscripts )] AS TypeName ]
[...]
END UNION

Description

A union is a type - very similar to a User-Defined Type - except that its elements overlap in memory. While this may seem strange at first, it has enormous potential.

For example, say you are designing an accounting program. You want to make it general purpose so it has widespread appeal. But everyone does their accounting differently; for example, some people use account numbers that are plain integral values, while others may use alphanumeric account names. Using a Union makes this easy. Another common use of a Union is variable type conversion. The is best described by way of an example:

UNION VarConvert

iLong AS LONG

iDword AS DWORD

sStr AS STRING * 4

END UNION

DIM x AS VarConvert, y AS DWORD, z AS STRING

x.iLong = 123456&

y = x.iDword

z = x.sStr

Like a User-Defined Type, a Union may also contain arrays , and these follow the same rules as User-Defined Type member arrays (see Type Members for syntax rules and additional examples). The following example demonstrates the use of a Union member array:

UNION Arrs

a1(1 TO 1024) AS BYTE

st AS ASCIIZ * 10

END UNION

FUNCTION PBMAIN

DIM a AS Arrs

a.a1(1) = 72

a.a1(2) = 101

a.a1(3) = 108

a.a1(4) = 108

a.a1(5) = 111

a.a1(6) = 33

' At this point, a.st contains "Hello!"

END FUNCTION

Bit Variables

UNION structures may contain bit variables, which are named BIT (unsigned values) or SBIT (signed values). Each bit variable may occupy from 1 to 31 bits, and they may be packed one after another up to a total of 32 bits per bit field. The size of a bit variable is defined as follows:

var AS BIT * nlit [IN BYTE|WORD|DWORD]

where the term "* nlit" defines the number of bits (1 to 31), and the optional term "IN BYTE|WORD|DWORD", if present, defines the start of a new bit field of 1, 2, or 4 bytes. For example:

UNION ABCDE

Odd1 AS BIT * 1 IN DWORD

Value1 AS LONG

END UNION

The example UNION structure above is 4 bytes in size, containing a 1-byte bit field and a 4-byte LONG.

UNION abcde

Part1 AS BIT * 8 IN DWORD

Part2 AS BIT * 16

END UNION

The example union above is 4 bytes in size, containing an 8-bit field and an overlapping 16-bit field.

Structures within structures

Structures (TYPE/UNION) may be embedded within another structure, for simplification in referencing deeply nested items, by simply stating the structure name alone at the appropriate position. The internal alignment of the member structure is precisely maintained regardless of other alignment specifications, to foster inheritance issues. For example:

TYPE ABCD3

A AS LONG

C AS LONG

END TYPE

TYPE ABCD2

D AS DWORD

E AS DOUBLE

END TYPE

UNION ABCD1

F AS DWORD

G AS LONG

H AS SINGLE

END UNION

In this case, you could access the lone Single-precision float member of this structure very simply. Assuming DIM X AS ABCD3, you could reference the Single-precision Union member with the variable name X.H, instead of the extended syntax X.ABCD2.ABCD1.H

Restrictions

A Union can contain elements of dissimilar sizes. The size of a Union structure is always determined by the longest member element. This is usually an important consideration when using a Union within another Union or UDT structure, in order to determine the size of the final structure.

For related information, please refer to the TYPE/END TYPE , User-Defined Types and Unions sections.

Field strings cannot be used in UDT or UNION structures. Attempting to do so results in a compile-time Error 485 ("Dynamic/Field strings not allowed").

See Also

  • DIM
  • LEN
  • LET (with Types)
  • SIZEOF
  • TYPE/END TYPE
  • User-Defined Types
  • Unions


User-Defined Types (UDTs) - ScharfBASIC Help

User-Defined Types (UDTs)

Arrays are useful when you need to treat a set of similar variables as a unit. For instance, ten test scores or ten student names. But what if you need to store several unrelated data types and be abl

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Once created, you can define as many variables of your new Type as you please. Moreover, since User-Defined Types can be associated with a random file's buffer, this provides you with a whole new way to access your random files.

ScharfBASIC's User-Defined Type is similar to a C struct or Pascal record. The elements of a User-Defined Type may include any of ScharfBASIC's data types, with the exception of dynamic (variable-length) strings , field strings , and arrays of dynamic strings.

To get an idea of the power of the User-Defined Type, imagine you are a teacher who needs a program to keep track of student grades. Since your school is on a very tight budget (and what schools aren't these days?), you decide to write the program yourself in ScharfBASIC. For each student in the class you need to track the following information:

Currently these records are being kept in a small file box. The information about each student is contained on a single file card. How do you transfer this information to the computer? Simple. Define a Student Record Type that will contain all the information about a single student.

The variables you create as User-Defined Types are often called records or record variables , since each variable of that Type contains one record, or one set of related information . The individual elements are referred to as fields or members . In the example above, each set of student information is a record, and each piece of information within that record (the last name for example) is a field.

Accessing the fields of a User-Defined Type

Nesting User-Defined Types

Arrays within User-Defined Types


Using arrays of User-Defined Types - ScharfBASIC Help

Using arrays of User-Defined Types

You can create arrays of User-Defined Types just as you can create arra ys of integers or strings or any of ScharfBASIC's other data types. For example:

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

DIM Class(1 TO 30) AS StudentRecord

To access the individual elements of the Class array, you use subscript index values just as you do with any other array. The third student record is Class(3) , for instance. The period separator and the field name follows the array subscript:

Class(3).FullName.First

This would access the first name of the third student in the class array. Think of it this way: the array is made up of elements of the Type Student Record , so the subscript belongs with the name of the variable as a whole.

You can create multidimensional arrays of User-Defined Types just as you can with any other ScharfBASIC data type. The limit on the number of elements and dimensions in such arrays is governed by the same rules as well: The limits are defined by the amount of data storage required for each element. Additionally, arrays within structures must contain a static subscript list, defined at compile-time. Therefore, arrays within structures cannot be redimensioned at run-time.

User-Defined Types (UDTs)

Defining User-Defined Types

Accessing the fields of a User-Defined Type


Using User-Defined Types with procedures - ScharfBASIC Help

Using User-Defined Types with procedures

Subroutines , functions , Methods , and Properties can process User-Defined Types as well as any other data type. This topic covers the following topics:

Kind | Keyword
Category | Types
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Passing fields as arguments

Members in User-Defined Types that are one of the built-in ScharfBASIC types ( INTEGER , WORD , STRING , and so on) can be passed to procedures and functions as if they were simple variables. For example, given the User-Defined Type PatientRecord , as follows:

FullName AS STRING * 32

DIM Patient AS PatientRecord

you could use a procedure PrintStatement :


Adding Controls to the Dialog - ScharfBASIC Help

Adding Controls to the Dialog

Once the dialog has been created, we can add controls to it. For our example, we will add a text box to let the user type in their name, and also add two BUTTON controls ("OK" and "Cancel"):

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

CONTROL ADD TEXTBOX, hDlg, IdText&

, "", 14, 21, 134, 12, Style&, exStyle&

CONTROL ADD BUTTON, hDlg, 1, "&OK", 44, 38, 40, 14, %BS_DEFAULT or %WS_TABSTOP CALL Ok

CONTROL ADD BUTTON, hDlg, 2, "&Cancel", 90, 38, 40, 14 CALL Cancel

hDlg refers to the handle of the dialog you're adding the control to, as returned by the DIALOG NEW statement.

The next parameter IdText& , 1 , and 2 in the example lines above) is the unique numeric identifier (ID) for the control. Whereas dialog handles are determined by Windows at run-time, controls use ID values that are specified by the programmer. By knowing the dialog handle and a control ID , we can identify and interact programmatically with any control on a DDT dialog using any of the control-related DDT statements.

In general, ID values should be kept within in the range 100 to 65535. It should also be noted that some values below 100 are reserved by Windows for special purposes. For example, the special ID value 1 (%IDOK) is usually assigned to a Button control that is to be activated when the ENTER key is pressed (this would typically be the "OK" button on a dialog). Similarly, the special ID value of 2 (%IDCANCEL) is usually assigned to a Button control that is to be activated when the ESCAPE key is pressed (typically this would be the "Cancel" button).

In general, two controls on a given dialog should not use the same ID value, as it prevents them from being identified uniquely. However, it is common to assign the special value -1& to plain Label (static) controls that will not have their content, style, or color changed at run-time.

It is always a good idea to plan the values of control identifiers carefully. For example, a set of related Option (radio) controls should use ID values that are ordered sequentially, as this makes it very easy to manipulate them as a group with the CONTROL SET OPTION statement, etc. Another common scheme is keep all the ID numbers for the controls in a specific range. For example, the first dialog in a program might use controls whose ID values are in the range 100 to 199, the second dialog might use the range 200 to 299, etc.


Built In RGB Color Equates - ScharfBASIC Help

Built In RGB Color Equates

The following is a list of RGB color equates built into the compiler, which can be used with routines that accept RGB color values.

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Back to command index


COMBOBOX ADD - ScharfBASIC Help

COMBOBOX ADD

Manipulate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMBOBOX ADD hDlg , id& , StrExpr [TO datav& ]
COMBOBOX DELETE hDlg , id& , item&
COMBOBOX FIND hDlg , id& , item& , StrExpr TO datav&
COMBOBOX FIND EXACT hDlg , id& , item& , StrExpr TO datav&
COMBOBOX GET COUNT hDlg , id& TO datav&
COMBOBOX GET SELCOUNT hDlg , id& TO datav&
COMBOBOX GET SELECT hDlg , id& TO datav&
COMBOBOX GET STATE hDlg , id& , item& TO datav&
COMBOBOX GET TEXT hDlg , id& [, item& ] TO txtv$
COMBOBOX GET USER hDlg , id& , item& TO datav&
COMBOBOX INSERT hDlg , id& , item& , StrExpr [TO datav& ]
COMBOBOX RESET hDlg , id&
COMBOBOX SELECT hDlg , id& , item&
COMBOBOX SET TEXT hDlg , id& , item& , StrExpr
COMBOBOX SET USER hDlg , id& , item& , NumExpr
COMBOBOX UNSELECT hDlg , id&

Description

In each of the following samples and descriptions, the COMBOBOX control which is the subject of the statement is identified by the handle of the dialog that owns the COMBOBOX ( hDlg ), and the unique control identifier you gave it upon creation in CONTROL ADD COMBOBOX.

COMBOBOX ADD hDlg , id& , StrExpr [TO datav& ]

The string value specified by StrExpr is added to the COMBOBOX control. If the COMBOBOX has the %CBS_SORT style, the new string is inserted in alphanumeric order; otherwise it is added to the end of the existing list. If the optional TO clause is included, the index position of the added string is assigned to the variable represented by datav& . The index is one for the first string, two for the second, etc. If the index is less than one, an error occurred and no string was added.

COMBOBOX DELETE hDlg , id& , item&

The string at the position specified by item& is deleted from the COMBOBOX. The item number ( item& ) is indexed to one (1=first, 2=second, and so on).

COMBOBOX FIND hDlg , id& , item& , StrExpr TO datav&

Strings in the COMBOBOX are searched to find the first string which begins with the data in StrExpr , regardless of any characters which follow. Comparisons are not case-sensitive. Strings are searched beginning with the string specified by item& , and ending with the last string in the COMBOBOX. Searching does not wrap to the beginning of the list. The item number (item& ) is indexed to 1 (1=first, 2=second, etc.). To search the entire COMBOBOX starting with the first string, item& should be set to one (1). If a matching string is found, the index value of the match is assigned to the variable specified by datav& . If no match is found, the value zero (0) is assigned to it.

COMBOBOX FIND EXACT hDlg , id& , item& , StrExpr TO datav&

Strings in the COMBOBOX are searched to find the first string which exactly matches the data in StrExpr . Comparisons are not case-sensitive. Strings are searched beginning with the string specified by item&, and ending with the last string in the COMBOBOX. Searching does not wrap to the beginning of the list. The item number ( item& ) is indexed to 1 (1=first, 2=second, etc.). To search the entire COMBOBOX starting with the first string, item& should be set to one (1). If a matching string is found, the index value of the match is assigned to the variable specified by datav& . If no match is found, the value zero (0) is assigned to it.

COMBOBOX GET COUNT hDlg , id& TO datav&

The number of items in the list box of the COMBOBOX is retrieved, and assigned to the long integer variable specified by datav& .

COMBOBOX GET SELCOUNT hDlg , id& TO datav&

The number of selected items in the list box of the COMBOBOX is retrieved, and assigned to the long integer variable specified by datav& . Since this is a single-selection list box, the retrieved value will always be either zero or one.

COMBOBOX GET SELECT hDlg , id& TO datav&

The index of the currently selected item in the list box of the COMBOBOX is retrieved, and assigned to the variable specified by datav& . The index is 1 for the first item, 2 for the second item, etc. If there is no current selection, the value zero (0) is assigned.

COMBOBOX GET STATE hDlg , id& , item& TO datav&

A data item is checked to see if it is currently selected. The numeric value item& specifies which user value is to be checked, 1 for the first item, 2 for the second item, etc. If the item is selected, -1 (true) is assigned to the variable specified by datav& . Otherwise, 0 (false) is assigned to it.

COMBOBOX GET TEXT hDlg , id& [, item& ] TO txtv$

Text is retrieved from the COMBOBOX and assigned to the string variable specified by txtv$ . If the numeric expression item& is included, it determines which text string is returned, 1 for the first item, 2 for the second item, etc. If item& is missing, or contains the value zero, the selected text is returned (or an empty string if none is selected). If you wish to retrieve the text found in the edit box portion of the COMBOBOX (regardless of whether it was typed or selected), you should use the CONTROL GET TEXT statement instead.

COMBOBOX GET USER hDlg , id& , item& TO datav&

Each item in a COMBOBOX may have a long integer user value associated with it at the discretion of the programmer. This user value is retrieved with COMBOBOX GET USER. The numeric value item& specifies which user value is requested, 1 for the first item, 2 for the second item, etc. The returned user value is assigned to the long integer variable specified by datav& . COMBOBOX user values are assigned with the COMBOBOX SET USER statement. In addition to these COMBOBOX user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER .

COMBOBOX INSERT hDlg , id& , item& , StrExpr [TO datav& ]

The text for a new data item, specified by StrExpr , is inserted at the location given by item& . The value of item& = 1 for the first item, 2 for the second item, etc. The list of data items is not re-sorted, even if the COMBOBOX was created with the style %CBS_SORT. If you wish to sort all of the items, use COMBOBOX ADD instead. If the optional TO clause is included, the index position of the inserted string is assigned to the variable represented by datav& . The index is one for the first string, two for the second, etc. If the index is less than one, an error occurred and no string was inserted.

COMBOBOX RESET hDlg , id&

Delete all contents of the specified COMBOBOX.

COMBOBOX SELECT hDlg , id& , item&

The string value specified by item& is chosen as selected text for the COMBOBOX control, and the selected text is scrolled into a visible position. The value of item& = 1 for the first item, 2 for the second item, etc.

COMBOBOX SET TEXT hDlg, id&, item&, StrExpr

The text for the data item specified by item& is replaced with the new text in StrExpr . The value of item& = 1 for the first item, 2 for the second item, etc. The list of data items is not re-sorted, even if the COMBOBOX was created with the style %CBS_SORT. If you wish to sort all of the items, use COMBOBOX DELETE followed by COMBOBOX ADD instead.

COMBOBOX SET USER hDlg , id& , item& , NumExpr

Each item in a COMBOBOX may have a long integer user value associated with it at the discretion of the programmer. This user value is assigned with COMBOBOX SET USER, and retrieved with COMBOBOX GET USER. The numeric value item& specifies which user value is to be accessed, 1 for the first item, 2 for the second item, etc. The value specified by NumExpr is saved for later retrieval. In addition to these COMBOBOX user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER.

COMBOBOX UNSELECT hDlg , id&

All items in a COMBOBOX control are set to an unselected state.

Restrictions

Under Windows 95/98/ME, a list box is limited to 32,767 items. In all versions of Windows, the actual string data contained by the list box is limited only by available memory.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD COMBOBOX
  • CONTROL GET TEXT


COMM PRINT - ScharfBASIC Help

COMM PRINT

Send a string of text through a serial port with optional CR/LF.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

COMM PRINT [#] hComm , string_expression [;] [TO CharCountVar ]

Description

T he text data contained in string_ expression is sent to the serial port associated with the file number hComm . The number symbol (#) is optional.

T he data is sent in the character form specified in the COMM OPEN statement. If CHR=WIDE was given, the data is sent in wide Unicode characters. Otherwise, it is sent in ANSI bytes. The data will be converted to the appropriate form automatically.

This statement is a variation of COMM SEND , but is usually used with text only. Each string_ expression sent is automatically followed by a Carriage-Return and Line-Feed pair to delimit the line. However, if a trailing semi-colon (;) is added, the CR/LF is suppressed.

I f the optional "TO CharCountVar " clause is included, a count of the number of characters written is assigned to it. This count includes the CR/LF, if utilized. This will allow you to gauge the success of the operation. If a TimeOut occurred, this value will be less than expected, and a run-time error 24 (Device Timeout) will be generated.

C OMM PRINT is ideal for sending "AT" commands to a modem. Omit the trailing semicolon for this purpose, since you would want the CR/LF to be sent along with the data.

See Also

  • Serial Communications
  • COMM CLOSE
  • COMM function
  • COMM LINE
  • COMM OPEN
  • COMM RECV
  • COMM RESET
  • COMM SEND
  • COMM SET
  • COMM TIMEOUT


Communication Control - ScharfBASIC Help

Communication Control

The following functions can be used for external communications:

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Retrieve the value or status of a communications parameter

Close an open serial port

Receive a CR/LF terminated "line" of data from a serial port


CONTROL ADD BUTTON - ScharfBASIC Help

CONTROL ADD BUTTON

Add a command button to a dialog. A command button is a button that causes an action to occur when the button is clicked. A common example of a command button is the "OK" button on a message box dialog.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD BUTTON, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD BUTTON, hDlg, id&, txt$, 100, 100, 150, 200, , , _
CALL ButtonCallback() ' Use default styles

Description

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will be displayed underscored. This adds a control accelerator (hot-key) to enable the user to directly "click" a control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "E&xit" makes ALT+x the hot-key.

On Windows XP and Windows 2000 you may need to press the ALT key before Control Accelerators are made visible. You can set if Command Accelerators are visible when using the ALT key or all the time in the Windows Display Settings.

Unless the %BS_FLAT style is used, the button is drawn on the dialog using a 3-dimensional look. When the user clicks a button, a message is sent to the Callback Function designated for the button. If there is no Callback Function designated, the message is sent to the callback for the dialog.

In general, if the control Callback Function processes a message, it should return TRUE (non-zero) to prevent the message being passed unnecessarily to the dialog callback (if one exists). The dialog callback should also return TRUE, if the notification message is processed by that Callback Function. Otherwise, the DDT engine processes unhandled messages.

Notification messages are sent to the Callback Function, with CB.MSG = %WM_COMMAND, CB.CTL holding the ID (id&) of the control, and CB.CTLMSG holding the following values:

%BN_CLICKED

Sent when the user clicks a mouse button, or activates the button with the hot-key (unless the button has been disabled).

%BN_DISABLE

Sent when a button is disabled.

%BN_KILLFOCUS

Sent when a button loses the keyboard focus. The button must include the %BS_NOTIFY style.

%BN_SETFOCUS

Sent when a button receives the keyboard focus. The button must include the %BS_NOTIFY style.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET TEXT
  • CONTROL SET FONT
  • CONTROL SET TEXT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x205bc8
mov   edx,0x20ca54
call   0x205bb0
fild   DWORD PTR ds:0x20ca60
call   0x205a78
fild   DWORD PTR ds:0x20ca60
call   0x205a78
fild   DWORD PTR ds:0x20ca64
call   0x205a78
fild   DWORD PTR ds:0x20ca68
call   0x205a78
mov   eax,0x1
call   0x204d52
call   0x204d44
call   0x202d16
call   0x205af8


CONTROL ADD CHECK3STATE - ScharfBASIC Help

CONTROL ADD CHECK3STATE

Add an auto 3-state checkbox to a dialog. This is commonly used to indicate a selection that may be True (set or checked), False (unset or cleared) or Indeterminate (grayed), and is often found in dialogs that provide "multiple choice" options.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD CHECK3STATE, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD CHECK3STATE, hDlg, id&, txt$, 100, 100, 40, 14, , , _
CALL Check3Callback() ' Use default styles

Description

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will be displayed underscored. This adds a control accelerator (hot-key) to enable the user to directly "click" a control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "Set s&tate" makes ALT+t the hot-key.

When the user clicks a 3-state checkbox, a message is sent to the Callback Function designated for the control. If there is no Callback Function designated, the message is sent to the callback for the dialog.

If the control callback processes the notification message, it should return TRUE (non-zero) to prevent the message being passed needlessly to the dialog callback, and eventually to the DDT engine itself.

Notification messages are sent to the Callback Function, with CB.MSG = %WM_COMMAND, CB.CTL holding the ID (id&) of the control, and CB.CTLMSG holding the following values:

%BN_CLICKED

Sent when the user clicks a mouse button, or activates the control with the hot-key (unless the control has been disabled).

%BN_DISABLE

Sent when a control is disabled.

%BN_KILLFOCUS

Sent when a control loses the keyboard focus. The control must include the %BS_NOTIFY style.

%BN_SETFOCUS

Sent when a control receives the keyboard focus. The control must include the %BS_NOTIFY style.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD CHECKBOX
  • CONTROL ADD OPTION
  • CONTROL GET CHECK
  • CONTROL SET CHECK
  • CONTROL SET COLOR
  • CONTROL SET FONT


CONTROL ADD CHECKBOX - ScharfBASIC Help

CONTROL ADD CHECKBOX

Add an auto-checkbox to a dialog. This is typically used to indicate a True/False or on/off selection, and is common in dialogs that offer choices of options to a user.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD CHECKBOX, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD CHECKBOX, hDlg, id&, txt$, 100, 100, 40, 14, , , _
CALL CheckboxCallback() ' Use default styles

Description

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will be displayed underscored. This adds a control accelerator (hot-key) to enable the user to directly "click" a control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "O&ption " makes ALT+p the hot-key.

When the user clicks a control, a message is sent to the Callback Function designated for the control. If there is no Callback Function designated, the message is sent to the callback for the dialog.

If the control callback processes the notification message, it should return TRUE (non-zero) to prevent the message being passed needlessly to the dialog callback, and eventually to the DDT engine itself.

Notification messages are sent to the Callback Function, with CB.MSG = %WM_COMMAND, CB.CTL holding the ID (id&) of the control, and CB.CTLMSG holding the following values:

%BN_CLICKED

Sent when the user clicks a mouse button or activates the control with the hot-key (unless the control has been disabled).

%BN_DISABLE

Sent when a control is disabled.

%BN_KILLFOCUS

Sent when a control loses the keyboard focus. The control must include the %BS_NOTIFY style.

%BN_SETFOCUS

Sent when a control receives the keyboard focus. The control must include the %BS_NOTIFY style.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD CHECK3STATE
  • CONTROL ADD OPTION
  • CONTROL GET CHECK
  • CONTROL SET CHECK
  • CONTROL SET COLOR
  • CONTROL SET FONT


CONTROL ADD COMBOBOX - ScharfBASIC Help

CONTROL ADD COMBOBOX

Add a combo box to a dialog. A combo box is often used to allow a user to select an item from a predefined list, or enter a fresh (unlisted) item. A combo box may contain only text strings. To put numbers in a combo box, convert them to strings

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD COMBOBOX, hDlg , id& , [ items$() ], x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD COMBOBOX, hDlg, id&, txt$(), 100, 100, 100, 40, , , CALL ComboCallback() ' Use default styles

Description

When the user selects an item or edits the text of a combo box, a message is sent to the Callback Function designated for the combo box. If there is no Callback Function designated then the message is sent to the callback for the dialog.

If the control callback processes the notification message, it should return TRUE (non-zero) to prevent the message being passed needlessly to the dialog callback, and eventually to the DDT engine itself.

Notification messages are sent to the Callback Function, with CB.MSG = %WM_COMMAND, CB.CTL holding the ID (id&) of the control, and CB.CTLMSG holding the following values:

%CBN_CLOSEUP

Sent when the list box of a combo box has been closed.

%CBN_DBLCLK

Sent when the user double-clicks a string in the list box of a combo box.

%CBN_DROPDOWN

Sent when the list box of a combo box is about to be made visible.

%CBN_EDITCHANGE

Sent after the user has taken an action that may have altered the text in the text box portion of a combo box. Unlike the %CBN_EDITUPDATE notification message, this notification message is sent after Windows updates the screen.

%CBN_EDITUPDATE

Sent when the text box portion of a combo box is about to display altered text. This notification message is sent after the control has formatted the text, but before it displays the text.

%CBN_ERRSPACE

Sent when a combo box cannot allocate enough memory to meet a specific request.

%CBN_KILLFOCUS

Sent when a combo box loses the keyboard focus.

%CBN_SELCHANGE

Sent when the selection in the list box of a combo box is about to be changed, as a result of the user either clicking in the list box or changing the selection by using the arrow keys.

%CBN_SELCANCEL

Sent when the user selects an item, but then selects another control or closes the dialog box. It indicates the user's initial selection is to be ignored.

%CBN_SELENDOK

Sent when the user selects a list item, or selects an item and then closes the list. It indicates that the user's selection is to be processed.

%CBN_SETFOCUS

Sent when a combo box receives the keyboard focus.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • COMBOBOX
  • CONTROL SET COLOR
  • CONTROL SET FONT


CONTROL ADD FRAME - ScharfBASIC Help

CONTROL ADD FRAME

Add a frame to a dialog. This is also known as a "group" control, and is typically drawn around controls to indicate a visual association between such controls. A frame control is often used around related Option controls.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD FRAME, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]]
CONTROL ADD FRAME, hDlg, id&, txt$, 100, 100, 40, 14, , ' Use default styles

Description

A frame control does not send messages to its parent dialog and does not require or support a Callback .

See Also

  • Dynamic Dialog Tools
  • CONTROL GET TEXT
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • CONTROL SET TEXT


CONTROL ADD GRAPHIC - ScharfBASIC Help

CONTROL ADD GRAPHIC

Add a static graphic control to a dialog for drawing, pictures, text, etc.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD GRAPHIC, hDlg , ID , Txt$ , x , y , nWide , nHigh [, style ] [, exstyle ] [,CALL CallBack ]

Description

A graphic control is typically used with graphic statements to draw graphs, pictures, text, etc. After you create a graphic control, you would normally use GRAPHIC ATTACH to select it as the target of subsequent GRAPHIC statements. However, if there is no selected graphic target at the time of creation, the new Graphic Control is automatically attached and selected.

A graphic control will only send notification messages to a callback if the %SS_NOTIFY style is used. Notification messages are sent to the callback function with CB.MSG = %WM_COMMAND, CB.CTL holding the ID ( id& ) of the control, and CB.CTLMSG holding one of the following values:

%STN_CLICKED

Sent when the user clicks a mouse button on the graphic control (unless the image control has been disabled).

%STN_DBLCLK

Sent when the user double-clicks on a graphic control (unless the control has been disabled).

%STN_DISABLE

Sent when a graphic control has been disabled.

%STN_ENABLE

Sent when a graphic control has been enabled.

When a callback function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

All ScharfBASIC graphical displays are persistent -- they will be automatically redrawn when altered or temporarily covered by another window.

See Also

  • Dynamic Dialog Tools
  • GRAPHIC ATTACH
  • GRAPHIC COLOR
  • GRAPHIC SCALE
  • GRAPHIC SET FONT
  • GRAPHIC STYLE
  • GRAPHIC WIDTH
  • GRAPHIC WINDOW


CONTROL ADD HEADER - ScharfBASIC Help

CONTROL ADD HEADER

Add a header control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD HEADER, hDlg , ID , Txt$ , x , y , wide , high [, style ] [, exstyle ] [,CALL CallBack ]

Description

Handle of the dialog on which the header control will be placed. The dialog will become the parent of the control.

A unique numeric identifier for this control which is specified by the programmer. It must be an integral value in the range of 1 to 65535. This ID is usually specified with a numeric equate for clarity of the code. For example, the equate %IDC_HEADER1 is more informative than a literal value such as 497. ScharfBASIC recommends that identifier values should start at 100 to avoid conflict with any of the standard predefined identifiers.

Text to associate with the Header control. A Header control does not display this text, so it is common to set this value to a null, empty string literal ("" or $NUL).

Integral expressions which specify the location of the control within the dialog client area. X is the horizontal position, and Y is the vertical position. 0,0 refers to the upper left corner of the Dialog. Coordinates are specified in the same terms ( pixels or dialog units ) as the parent dialog.

wide, high

Integral expressions which specify the overall width and height of the header area.

Optional primary style of the header control. This value can be a combination of the values below, combined together with the OR operator to form a bitmask. If style is omitted, the default combination is %WS_CHILD OR %WS_VISIBLE.

%WS_CHILD

The control is a child window.

%WS_VISIBLE

The control is visible.

%WS_BORDER

Add a thin line border around the header control.

exstyle

Optional extended style of the header control.

callback

Optional name of a Callback Function that receives all %WM_COMMAND and %WM_NOTIFY messages for the control. See the #MESSAGES metastatement to choose which messages will be received. If a callback for the control is not designated, you must create a dialog Callback Function to process messages from your control.

If the Callback Function processes a message, it should return TRUE (non-zero) to prevent the message being passed unnecessarily to the dialog callback (if one exists). The dialog callback should also return TRUE if the notification message is processed by that Callback Function. Otherwise, the DDT engine processes unhandled messages.

See Also

  • HEADER


CONTROL ADD IMAGE - ScharfBASIC Help

CONTROL ADD IMAGE

Add a (non-resizing) image control to a dialog. This is typically used to display a bitmap or icon stored in a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD IMAGE, hDlg , id& , image$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]

Description

The bitmap or icon used in the image is not resized to fit the control. If your control is 64 dialog units wide and your icon or bitmap is only 32, half of the image will be blank. For best results, icons should be 32x32 pixels.

Once an image control has been created, the images it displays can be changed with the CONTROL SET IMAGE statement, but only if the images are of the same format as the original. For example, if an image control was initially created showing a bitmap file, all subsequent image changes must also be bitmap images. However, if the image format must be changed at run-time, for example, because icons are to be displayed instead of bitmaps, there are a couple of options. For example, the application could use separate controls for each image format, or the existing control could be destroyed, and a new control created with an image of the opposite format.

An image control will only send notification messages to a callback if the %SS_NOTIFY style is used. Notification messages are sent to the Callback Function with CB.MSG = %WM_COMMAND, CB.CTL holding the ID ( id& ) of the control, and CB.CTLMSG holding the following values:

%STN_CLICKED

Sent when the user clicks a mouse button on the image control (unless the image control has been disabled).

%STN_DBLCLK

Sent when the user double-clicks on an image control (unless the control has been disabled).

%STN_DISABLE

Sent when an image control has been disabled.

%STN_ENABLE

Sent when an image control has been enabled.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX


CONTROL ADD IMAGEX - ScharfBASIC Help

CONTROL ADD IMAGEX

Add a stretched image control to a dialog. This is typically used to display bitmaps and icons, which are automatically stretched or condensed to fill the controls client area.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD IMAGEX, hDlg , id& , image$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]

Description

The bitmap or icon used in the image is resized to fit the control. If your control is 64 dialog units wide and your icon or bitmap is only 32, it will be stretched to cover the entire control. For best results, icons should be 32x32 pixels.

An image control will only send notification messages to a callback if the %SS_NOTIFY style is used. Notification messages are sent to the Callback Function with CB.MSG = %WM_COMMAND, CB.CTL holding the ID ( id& ) of the control, and CB.CTLMSG holding the following values:

%STN_CLICKED

Sent when the user clicks a mouse button on the image control (unless the image control has been disabled).

%STN_DBLCLK

Sent when the user double-clicks on an image control (unless the control has been disabled).

%STN_DISABLE

Sent when an image control has been disabled.

%STN_ENABLE

Sent when an image control has been enabled.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

Restrictions

Under Windows 95/98/ME, an attempt to stretch an icon significantly above 64x64 may fail due to internal limits that vary between those particular versions of Windows. Bitmaps are not affected in this manner. Windows NT/2000/XP systems do not impose any comparable limitations on either icons or bitmaps.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX


CONTROL ADD IMGBUTTON - ScharfBASIC Help

CONTROL ADD IMGBUTTON

Add an image button to a dialog. Image buttons are often used to enhance the appearance of a dialog.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD IMGBUTTON, hDlg , id& , image$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD IMGBUTTON, hDlg, id&, txt$, 100, 100, 150, 200, , , _
CALL ImgButtonCallback() ' Use default styles

Description

The bitmap or icon used in the button is not resized to fit the button. If your button is 64 dialog units wide and your icon or bitmap is only 32, half of the button will be blank. For best results, icons should be 32x32 pixels.

An image button is drawn on the dialog using a 3-dimensional look, unless the %BS_FLAT style is specified. When the user clicks on the image button, a message is sent to the button's Callback Function. If there is no Callback Function designated, the message is sent to the callback for the dialog.

Notification messages are sent to the Callback Function with CB.MSG = %WM_COMMAND, CB.CTL holding the ID ( id& ) of the control, and CB.CTLMSG holding the following values:

%BN_CLICKED

Sent when the user clicks a mouse button, or activates the button with the hot-key (unless the button has been disabled).

%BN_DISABLE

Sent when a button is disabled.

%BN_KILLFOCUS

Sent when a button loses the keyboard focus. The button must include the %BS_NOTIFY style.

%BN_SETFOCUS

Sent when a button receives the keyboard focus. The button must include the %BS_NOTIFY style.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX


CONTROL ADD IMGBUTTONX - ScharfBASIC Help

CONTROL ADD IMGBUTTONX

Add a stretched image button to a dialog. Stretched image buttons are often used to enhance the appearance of a dialog, with the image being automatically stretched or condensed to fill the control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD IMGBUTTONX, hDlg , id& , image$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD IMGBUTTONX, hDlg, id&, txt$, 100, 100, 150, 200, , , _
CALL ImgButtonxCallback() ' Use default styles

Description

The bitmap or icon used in the button is resized to fit the button. If your button is 64 dialog units wide and your icon or bitmap is only 32, it will be stretched to cover the entire button. For best results, icons should be 32x32 pixels.

The image button is drawn on the dialog using a 3-dimensional look, unless the %BS_FLAT style is specified. When the user clicks a button, a message is sent to the Callback Function designated for the button. If there is no Callback Function designated, the message is sent to the callback for the dialog.

Notification messages are sent to the Callback Function with CB.MSG = %WM_COMMAND, CB.CTL holding the ID ( id& ) of the control, and CB.CTLMSG holding the following values:

%BN_CLICKED

Sent when the user clicks a mouse button, or activates the button with the hot-key (unless the button has been disabled).

%BN_DISABLE

Sent when a button is disabled.

%BN_KILLFOCUS

Sent when a button loses the keyboard focus. The button must include the %BS_NOTIFY style.

%BN_SETFOCUS

Sent when a button receives the keyboard focus. The button must include the %BS_NOTIFY style.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL SET IMAGE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX


CONTROL ADD LABEL - ScharfBASIC Help

CONTROL ADD LABEL

Add a text label to a dialog. A text label is similar to a conventional static control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD LABEL, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD LABEL, hDlg, id&, txt$, 100, 100, 150, 200, , , _
CALL LabelCallback() ' Use default styles

Description

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will be displayed underscored. This adds a control accelerator (hot-key) to enable the user to directly "click" the control that immediately follows in the Tab-Order after the Label control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "Choose &Security Level" makes ALT+S the hot-key.

A label control will only send messages to a callback if the %SS_NOTIFY style is used. The following notifications are sent to the Callback Function:

%STN_CLICKED

Sent when the user clicks a mouse button, or activates the button with the hot-key (unless the button has been disabled).

%STN_DBLCLK

Sent when the user double-clicks on a label control (unless the control has been disabled).

%STN_DISABLE

Sent when a button is disabled.

%STN_ENABLE

Sent when a label control has been enabled.

Use the CONTROL SET TEXT statement to change the text in a label control and CONTROL SET FONT to change the font used in a label control. This is only possible if the label has a unique ID value (i.e., id& should not be -1).

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET TEXT
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • CONTROL SET TEXT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x205bc8
mov   edx,0x20ca54
call   0x205bb0
fild   DWORD PTR ds:0x20ca64
call   0x205a78
fild   DWORD PTR ds:0x20ca68
call   0x205a78
fild   DWORD PTR ds:0x20ca6c
call   0x205a78
fild   DWORD PTR ds:0x20ca70
call   0x205a78
mov   eax,0x5
call   0x204d52
call   0x204d44
call   0x202d16
call   0x205af8


CONTROL ADD LINE - ScharfBASIC Help

CONTROL ADD LINE

Add a line control to a dialog. A line control may also be a rectangle (empty or filled).

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD LINE, hDlg, id&, txt$, x, y, xx, yy [, [style&] [, [exstyle&]]] [[,] CALL callback]
CONTROL ADD LINE, hDlg, id&, "", 100, 100, 150, 1, , , CALL LineCallback() ' Use default styles

Description

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will be displayed underscored. This adds a control accelerator (hot-key) to enable the user to directly "click" the control that immediately follows in the Tab-Order after the Line control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "&Test Suite " makes ALT+T the hot-key.

A line control will only send messages to a callback if the %SS_NOTIFY style is used. The following notifications are sent to the Callback Function:

%STN_CLICKED

Sent when the user clicks a line control (unless the control has been disabled).

%STN_DBLCLK

Sent when the user double-clicks a line control (unless the control has been disabled).

%STN_DISABLE

Sent when a line control has been disabled.

%STN_ENABLE

Sent when a line control has been enabled.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL HANDLE
  • CONTROL SEND


CONTROL ADD LISTBOX - ScharfBASIC Help

CONTROL ADD LISTBOX

Add a list box control to a dialog. A list box contains a set of predefined entries that permit a user to select one or more items. A list box may contain strings

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD LISTBOX, hDlg , id& , [ items$() ], x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD LISTBOX, hDlg, id&, items$(), 100, 100, 150, 200, , , _
CALL ListboxCallback() ' Use default styles

Description

The following notifications are sent to the Callback Function:

%LBN_DBLCLK

Sent when the user double-clicks a string in the list portion of a list box.

%LBN_ERRSPACE

Sent when a list box cannot allocate enough memory to meet a specific request.

%LBN_KILLFOCUS

Sent when a list box loses the keyboard focus.

%LBN_SELCANCEL

Sent when the user selects an item, but then selects another control or closes the dialog box. It indicates the user's initial selection is to be ignored.

%LBN_SELCHANGE

Sent when the selection in the list box is about to be changed as a result of the user either clicking in the list box or changing the selection by using the arrow keys.

%LBN_SETFOCUS

Sent when a list box receives the keyboard focus.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

Restrictions

Under Windows 95/98/ME, a list box is limited to 32,736 items. In all versions of Windows, the actual string data contained by the list box is limited only by available memory.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • LISTBOX


CONTROL ADD LISTVIEW - ScharfBASIC Help

CONTROL ADD LISTVIEW

Add a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD LISTVIEW, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD LISTVIEW, hDlg, id&, "", 100, 100, 150, 200, , , CALL LVCallback()

Description

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • HEADER
  • LISTVIEW


CONTROL ADD OPTION - ScharfBASIC Help

CONTROL ADD OPTION

Add an option button to a dialog. An option button is just like a conventional "radio button" control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD OPTION, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD OPTION, hDlg, id&, txt$, 100, 100, 150, 200, , , _
CALL OptionButtonCallback() ' Use default styles

Description

Option buttons are used for presenting a list of choices, only one of which may be selected. So, there is no point in having just a single option button. If what you want is to allow turning a single item on or off, use a Checkbox instead.

When a group of option buttons are created, you should explicitly set the "selected" and "unselected" state of all option buttons, using the CONTROL SET OPTION statement to set the Check State of all the buttons in the group.

In addition, the first OPTION control in a group should have the style %WS_GROUP (to mark the beginning of a group of buttons) and %WS_TABSTOP. The remainder of the OPTION controls in the group should not have %WS_GROUP or %WS_TABSTOP styles. However, the very next non-OPTION control to appear in the tab order after the group should be given the %WS_GROUP and %WS_TABSTOP styles (the latter may depend on the type of control it is). If there are no other controls after the group, add %WS_GROUP to the first control in the dialog. This ensures that keyboard navigation with the arrow keys will operate within the group of OPTION controls, and that the TAB and SHIFT+TAB keys will switch focus between whole groups of controls (instead of individual controls as is common when each group member has the %WS_TABSTOP style).

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will be displayed underscored. This adds a control accelerator (hot-key) to enable the user to directly select the Option control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "Level &3" makes ALT+3 the hot-key.

When the user clicks an option button, a message is sent to the Callback Function designated for the control. If there is no Callback Function designated then the message is sent to the callback for the dialog.

The following notifications are sent to the Callback Function:

%BN_CLICKED

Sent when the user clicks a mouse button, or activates the button with the hot-key (unless the button has been disabled).

%BN_KILLFOCUS

Sent then the option button loses keyboard focus, provided the button has the %BS_NOTIFY style.

%BN_SETFOCUS

Sent when the option button receives keyboard focus, provided the option button has the %BS_NOTIFY style.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD CHECK3STATE
  • CONTROL ADD CHECKBOX
  • CONTROL GET CHECK
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • CONTROL SET OPTION


CONTROL ADD PROGRESSBAR - ScharfBASIC Help

CONTROL ADD PROGRESSBAR

Add a ProgressBar control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD PROGRESSBAR, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD PROGRESSBAR, hDlg, id&, "",90,90,90,20, , , CALL PBCallback()

Description

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET COLOR
  • PROGRESSBAR


CONTROL ADD SCROLLBAR - ScharfBASIC Help

CONTROL ADD SCROLLBAR

Add a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD SCROLLBAR, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD SCROLLBAR, hDlg, id&, txt$, 100, 100, 150, 14, , , _
CALL Scrollbar1Callback() ' Use default styles

Description

If the ampersand (&) character appears in the txt$ parameter, the letter that follows will become a control accelerator (hot-key) to enable the user to directly select the scroll bar control, simply by pressing and holding the ALT key while pressing the specified hot-key. For example, "&9" makes ALT+9 the hot-key. The actual text in txt$ is not displayed in a scroll bar control.

When the user clicks on a scroll bar, drags the thumb (also called the scroll box), or initiates a scroll event with the keyboard, a message is sent to the Callback Function designated for the control. If there is no Callback Function designated, the message is sent to the callback for the dialog.

The following notifications are sent to the Callback Function:

%WM_HSCROLL

Sent when the user adjusts a horizontal scroll bar.

%WM_VSCROLL

Sent when the user adjusts a vertical scroll bar.

When a Callback Function receives a %WM_HSCROLL or %WM_VSCROLL message, it should retrieve and set the scroll bar control settings through the GetScrollInfo API and SCROLLBAR SET POS function calls. Be sure to use the %SB_CTL flag with these API functions, rather than the %SB_HORZ or %SB_VERT flags.

See Also

  • Dynamic Dialog Tools
  • CONTROL HANDLE
  • CONTROL SEND
  • CONTROL SET COLOR
  • SCROLLBAR


CONTROL ADD - ScharfBASIC Help

CONTROL ADD

Add a custom control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD classname$, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]

Description

When the user interacts with the control, a message is sent to the designated Callback Function. If there is no Callback Function designated, the message is sent to the callback for the dialog.

The style& and exstyle& values are dependent on the type of custom control or common control being used. The notification messages sent to your callback are also dependent on the type of custom control or common control being used.

When the Callback Function receives a %WM_COMMAND message, the identity of the control sending the message can be found with the CB.CTL function. Use the CB.CTLMSG function to retrieve the notification message value in your callback. However, many Windows common controls send %WM_NOTIFY messages (to the parent dialog's callback, not the control callback) rather than the more conventional %WM_COMMAND messages. In such cases, the meaning of the message parameters CB.WPARAM and CB.LPARAM will vary according to the type of notification message being processed.

Restrictions

Custom controls may require special handling other than the DDT generic functions ( CONTROL SET COLOR , CONTROL SET FONT , etc.). Consult the controls documentation for information.

See Also

  • #MESSAGES
  • Dynamic Dialog Tools
  • CONTROL HANDLE
  • CONTROL SEND


CONTROL ADD STATUSBAR - ScharfBASIC Help

CONTROL ADD STATUSBAR

Add a StatusBar control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD STATUSBAR, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD STATUSBAR, hDlg, id&, "", 5, 5, 5, 5, , , CALL SBCallback()

Description

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET FONT
  • STATUSBAR


CONTROL ADD TAB - ScharfBASIC Help

CONTROL ADD TAB

Add a Tab Control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD TAB, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD TAB, hDlg, id&, "",90,90,200,90, , , CALL PBCallback()

Description

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET FONT
  • TAB


CONTROL ADD TEXTBOX - ScharfBASIC Help

CONTROL ADD TEXTBOX

Add a text box control to a dialog. A text box is very similar to a conventional edit control, and it is used to enter text into an application. Text boxes support single-line and multiple-line input.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD TEXTBOX, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD TEXTBOX, hDlg, id&, txt$, 100, 100, 150, 200, , , _
CALL EditControlCallback() ' Use default styles

Description

If you specify the %ES_AUTOHSCROLL style, the control automatically scrolls horizontally when the caret goes past the right edge of the control. To start a new line, the user must press the ENTER key.

If you do not specify %ES_AUTOHSCROLL, the control automatically wraps words to the beginning of the next line when necessary. A new line is also started if the user presses the ENTER key. The control size determines the position of the word wrap.

The following notifications are sent to the Callback Function:

%EN_CHANGE

Sent when the user has taken an action that may have altered text in the text box. Unlike the %EN_UPDATE notification, this message is sent after Windows updates the screen. Programmatically changing the text in a control also triggers this message.

%EN_ERRSPACE

Sent when the text box cannot allocate enough memory to meet a specific request.

%EN_HSCROLL

Sent when the user clicks a multi-line text box's horizontal scroll bar. The callback is notified before the screen is updated.

%EN_KILLFOCUS

Sent when an edit control loses the keyboard focus.

%EN_MAXTEXT

Sent when the current text insertion has exceeded the specified number of characters for the text box. The text insertion is truncated.

%EN_SETFOCUS

Sent when an edit control receives the keyboard focus.

%EN_UPDATE

Sent when a text box is about to display altered text. This notification message is sent after the control has formatted the text, but before it displays the text. Also see %EN_CHANGE.

%EN_VSCROLL

Sent when the user clicks a text box's vertical scroll bar. The callback is notified before the screen is updated.

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification message.

Use CONTROL GET TEXT to retrieve the text from a text box control, and use CONTROL SET TEXT to change the text in a text box control. Changing the text in a text box control (in response to a %EN_CHANGE or %EN_UPDATE message) will trigger a second set of %EN_CHANGE and %EN_UPDATE messages. Unless this is compensated for, these notifications can unwittingly cause an endless loop.

For example, the following is potentially fatal:

CALLBACK FUNCTION EditControlCallback()

IF CB.CTL = %ID_EDITBOX1 AND CB.CTLMSG = %EN_CHANGE THEN

CONTROL SET TEXT CB.HNDL, CB.CTL, "New Text"

EXIT FUNCTION

END IF

[ statements ]

As CONTROL SET TEXT is a "blocking" statement (that is, the statement does not complete until the text has been changed), it is a simple matter to block the endless loop effect:

CALLBACK FUNCTION EditControlCallback()

STATIC EditBusy&

IF CB.CTL = %ID_EDITBOX1 AND CB.CTLMSG = %EN_CHANGE THEN

IF EditBusy& THEN EXIT FUNCTION

EditBusy& = -1

CONTROL SET TEXT CB.HNDL, CB.CTL, "New Text"

RESET EditBusy&

EXIT FUNCTION

END IF

[ statements ]

See Also

  • Dynamic Dialog Tools
  • CONTROL GET TEXT
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • CONTROL SET TEXT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x205bc8
mov   edx,0x20ca54
call   0x205bb0
fild   DWORD PTR ds:0x20ca60
call   0x205a78
fild   DWORD PTR ds:0x20ca64
call   0x205a78
fild   DWORD PTR ds:0x20ca68
call   0x205a78
fild   DWORD PTR ds:0x20ca6c
call   0x205a78
mov   eax,0x9
call   0x204d52
call   0x204d44
call   0x202d16
call   0x205af8


CONTROL ADD TOOLBAR - ScharfBASIC Help

CONTROL ADD TOOLBAR

Add a ToolBar control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD TOOLBAR, hDlg , ID , Txt$ , x , y , nWide , nHigh [, style ] [, exstyle& ] [,CALL callback ]
CONTROL ADD TOOLBAR, hDlg, id&, "", 1, 1, 1, 1, , , CALL TBCallback()

Description

When a Callback Function receives a message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the notification messages.

See Also

  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • Dynamic Dialog Tools
  • CONTROL SET FONT
  • TOOLBAR


CONTROL ADD TREEVIEW - ScharfBASIC Help

CONTROL ADD TREEVIEW

Add a TreeView control to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ADD TREEVIEW, hDlg , id& , txt$ , x , y , xx , yy [, [ style& ] [, [ exstyle& ]]] [[,] CALL callback ]
CONTROL ADD TREEVIEW, hDlg, id&, "", 100, 100, 150, 200, , , CALL TVCallback()

Description

When a Callback Function receives a %WM_COMMAND message, it should explicitly test the value of CB.CTL and CB.CTLMSG to guarantee it is responding appropriately to the messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • TREEVIEW


CONTROL DISABLE - ScharfBASIC Help

CONTROL DISABLE

Disable a control so that it no longer receives any

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL DISABLE hDlg , id&

Description

hDlg refers to the dialog that owns the control. id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

A disabled control will not receive any messages when clicked with the mouse or selected with the keyboard. Most, but not all, controls will redraw themselves as "gray" when disabled.

See Also

  • Dynamic Dialog Tools
  • CONTROL ENABLE
  • CONTROL KILL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x65
call   0x202cae
call   0x205a9c


CONTROL ENABLE - ScharfBASIC Help

CONTROL ENABLE

Enable a control so that it can receive messages when the user interacts with it via the mouse or keyboard.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL ENABLE hDlg , id&

Description

hDlg refers to the dialog that owns the control. id& is the unique control identifier as assigned to the control with a CONT ROL ADD statement.

An enabled control will receive messages when clicked with the mouse or selected with the keyboard.

See Also

  • Dynamic Dialog Tools
  • CONTROL DISABLE
  • CONTROL KILL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   ebx,0x1
mov   eax,0x65
call   0x202cae
call   0x205a9c


CONTROL GET CHECK - ScharfBASIC Help

CONTROL GET CHECK

Get the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL GET CHECK hDlg , id& TO lResult&

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTRO L ADD statement.

lResult& receives the Check State of the control as follows:

lResult&

Check State of control

0 (Zero)

Button is unchecked (unset, or cleared)

1 (One)

Button is checked (set)

2 (Two)

Button is indeterminate (grayed) (CHECK3STATE only)

Note that a grayed (indeterminate) CHECK3STATE control does not mean the control is disabled. Rather, the Check State of the control is both checked and unchecked.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD CHECK3STATE
  • CONTROL ADD CHECKBOX
  • CONTROL ADD OPTION
  • CONTROL SET CHECK
  • CONTROL SET OPTION
  • TREEVIEW GET CHECK
  • TREEVIEW SET CHECK

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Control Get Check

mov   eax,0x65
call   0x203bac
call   0x205a9c

Variant 2: Get

mov   edx,0x203a54
call   0x2024b0
call   0x202433
mov   WORD PTR [ebp-0x46],0x1
mov   ecx,0x4
call   0x2018c8
call   0x202364


CONTROL GET CLIENT - ScharfBASIC Help

CONTROL GET CLIENT

Return the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL GET CLIENT hDlg , id& TO w& , h&

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONT ROL ADD statement.

The size of the control client area is placed in the w& (width) and h& (height) variables . The size is specified in the same terms (pixels or dialog units ) as the parent dialog.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET LOC
  • CONTROL GET SIZE
  • CONTROL SET CLIENT
  • CONTROL SET CLIENT
  • CONTROL SET LOC
  • CONTROL SET SIZE
  • DIALOG UNITS
  • DIALOG PIXELS
  • GRAPHIC GET CLIENT


CONTROL GET LOC - ScharfBASIC Help

CONTROL GET LOC

Get the location of the specified control in a dialog.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL GET LOC hDlg , id& TO x& , y&

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

The location of the top left corner of the control is placed in the x& (horizontal location) and y& (vertical location) variables . The location is relative to the upper-left corner of the client area in the parent dialog. The coordinates are specified in the same terms (pixels or dialog units) as the parent dialog.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • CONTROL GET SIZE
  • CONTROL SET LOC
  • CONTROL SET SIZE


CONTROL GET SIZE - ScharfBASIC Help

CONTROL GET SIZE

Get the size of a control in the specified

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL GET SIZE hDlg , id& TO nWide& , nHigh&

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

The width is placed in the nWide& and the height is placed in nHigh& variables . The coordinates are specified in the same terms ( pixels or dialog units ) as the parent dialog.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • CONTROL GET LOC
  • CONTROL SET LOC
  • CONTROL SET SIZE


CONTROL GET TEXT - ScharfBASIC Help

CONTROL GET TEXT

Get the text from a control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL GET TEXT hDlg , id& TO txt$

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement. Any text in the control is placed into the txt$ variable.

With combo boxes , CONTROL GET TEXT returns the text entered in the edit portion of the control. To retrieve the selected text from the list portion of a combo box or a list box control, use the COMBOBOX GET TEXT statement or LISTBOX GET TEXT statement respectively.

See Also

  • Dynamic Dialog Tools
  • COMBOBOX GET TEXT
  • CONTROL SET TEXT
  • LISTBOX GET TEXT
  • LISTVIEW GET TEXT
  • TREEVIEW GET TEXT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x65
call   0x203904
call   0x20395a
lea   ebx,[ebp-0xa0]
call   0x204ccc
call   0x205b7b
call   0x205aac


CONTROL GET USER - ScharfBASIC Help

CONTROL GET USER

Retrieve a value from the user data area of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL GET USER hDlg , id& , index& TO retvar&

Description

Each DDT control has a user data area consisting of eight Long-integer values which may be used at the programmer's discretion to save relevant data. CONTROL GET USER allows one of the values to be retrieved, based upon the index parameter value (1 through 8).

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

index& is the index number of the user data value to retrieve, in the range 1 to 8 inclusive.

retvar& receives the Long-integer data value store in the nominated user data index.

Restrictions

Data in the user data area is lost when the control is destroyed. The data area is completely separate from the %GWL_USERDATA area maintained by Windows.

See Also

  • Dynamic Dialog Tools
  • COMBOBOX GET USER
  • COMBOBOX SET USER
  • CONTROL SET USER
  • DIALOG GET USER
  • DIALOG SET USER
  • LISTBOX GET USER
  • LISTBOX SET USER
  • LISTVIEW GET USER
  • LISTVIEW SET USER
  • TREEVIEW GET USER
  • TREEVIEW SET USER


CONTROL HANDLE - ScharfBASIC Help

CONTROL HANDLE

Return a window

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL HANDLE hDlg , id& TO hCtl&

Description

hDlg refers to the dialog that owns the control. id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

The returned value is a window handle for the control, assigned by Windows when the control was initially created, uniquely identifying the control from all other controls. Some API functions require a window handle value rather than a control ID value.

See Also

  • Dynamic Dialog Tools
  • CONTROL SEND
  • WINDOW GET ID
  • WINDOW GET PARENT


CONTROL HIDE - ScharfBASIC Help

CONTROL HIDE

Make a control

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL HIDE HDlg , ID&

Description

The Control identified by the HDlg / ID& combination is made invisible.

HDlg is the handle of the dialog which owns the control. ID& is the unique control identifier assigned to the control with CONTROL ADD.

See Also

  • CONTROL NORMALIZE
  • CONTROL SET SIZE
  • DIALOG HIDE
  • DIALOG NORMALIZE


CONTROL KILL - ScharfBASIC Help

CONTROL KILL

Remove a control from a dialog.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL KILL hDlg , id&

Description

hDlg refers to the dialog that owns the control. id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

The control is destroyed and removed from the dialog. The Callback Function for the control or dialog will no longer receive messages for the control.

Restrictions

A control should not be destroyed while processing a notification message from the same control, but it is permissible to kill a different control in the notification handler. If is absolutely necessary to kill a control while processing one of its notification messages, use the PostMessage API function (or the DIALOG POST or CONTROL POST statements) to post a user-defined message to the dialog callback, and kill the control when processing the user-defined message.

See Also

  • Dynamic Dialog Tools
  • CONTROL DISABLE
  • CONTROL ENABLE


CONTROL NORMALIZE - ScharfBASIC Help

CONTROL NORMALIZE

Make a control

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL NORMALIZE HDlg , ID&

Description

The Control identified by the HDlg/ID& combination is made visible.

HDlg is the handle of the dialog which owns the control. ID& is the unique control identifier assigned to the control with CONTROL ADD.

See Also

  • CONTROL HIDE
  • CONTROL SET SIZE
  • DIALOG HIDE
  • DIALOG NORMALIZE


CONTROL POST - ScharfBASIC Help

CONTROL POST

Place a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL POST hDlg , id& , Msg& , wParam& , lParam&

Description

CONTROL POST places the message in the message queue and returns immediately. The message is processed by the control at a later time, when it reads the message from the queue.

This behavior is quite different to the CONTROL SEND statement, which forces the control to process the message immediately before returning. Since CONTROL POST is an asynchronous operation, it is not possible to retrieve a return code from the message.

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

Msg& is the message you want to post to the control.

wParam& is the first message parameter. lParam& is the second message parameter. The values of wParam& and lParam& are message-dependent. By Default, ScharfBASIC passes these parameters BYVAL. If the target control is expected to alter the values held by variables passed in the wParam& and lParam& parameters, pass them using VARPTR() or the changes will likely be discarded.

Note that the address of the data must remain valid until after the control has processed the message and accessed the data. In this case, using STATIC or GLOBAL variables can be very important or a General Protection Fault (GPF) may occur (that is, if the variables have gone out of scope by the time the message is processed).

An example of posting the addresses of variables to a control:

' Retrieve an Edit controls Current Selection

' Sel1& and Sel2& must be STATIC or GLOBAL

CONTROL POST CB.HNDL, %ID_EDIT6, %EM_GETSEL, VARPTR(Sel1&), VARPTR(Sel2&)

CONTROL POST returns immediately after the placing the message in the queue.

Restrictions

To post a custom message to a control, use a message value in the range of (%WM_USER + 500) to (%WM_USER + &H07FFF), or use the RegisterWindowMessage API to obtain a unique message value from the operating system. Using messages with a numeric value of less then %WM_USER + 500 may conflict with Windows Common Control messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL HANDLE
  • CONTROL SEND
  • DIALOG POST
  • DIALOG SEND


CONTROL REDRAW - ScharfBASIC Help

CONTROL REDRAW

Schedule a designated control to be redrawn.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL REDRAW hDlg , id&

Description

CONTROL REDRAW invalidates the target control and schedules a redraw event to occur.

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

Restrictions

Redrawing of individual controls is considered a low priority event, and a control redraw may not happen instantly if there are pending messages in the message queue. That is, pending messages in the message queue may need to be processed before the scheduled redraw event occurs.

It is not advisable to use CONTROL REDRAW or DIALOG REDRAW within the %WM_PAINT and associated message handling code, or an infinite redraw loop could occur.

See Also

  • Dynamic Dialog Tools
  • CONTROL SET COLOR
  • DIALOG SET COLOR
  • DIALOG REDRAW


CONTROL SEND - ScharfBASIC Help

CONTROL SEND

Send a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SEND hDlg , id& , Msg& , wParam& , lParam& [TO lResult& ]

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

Msg& is the message you want to send the control.

wParam& is the first message parameter. lParam& is the second message parameter. The values of wParam& and lParam& are message-dependent. By default, ScharfBASIC passes these parameters BYVAL. If the target control is expected to return or alter the values passed in the wParam& and lParam& parameters, pass them using VARPTR or the return values will be discarded. For example:

' Retrieve an Edit control's Current Selection

CONTROL SEND CB.HNDL, %ID_EDIT1, %EM_GETSEL, VARPTR(Sel1&), VARPTR(Sel2&)

CONTROL SEND does not return from execution until the control's callback has processed the message. This synchronous behavior is quite different to the behavior of CONTROL POST , which simply places the message in the control's message queue (for processing at a later time) and immediately returns. On this basis, CONTROL SEND can receive a return value from the message, but CONTROL POST cannot.

The return value from the message can optionally be assigned to lResult &.

If CONTROL SEND sends a message that arrives back in the same callback as the message originated, care should be exercised to ensure that critical STATIC and GLOBAL variables are not unexpectedly altered by the second message processing code in the callback. This is known as re-entrant code design.

Restrictions

To send a custom message to a dialog, use a message value in the range of (%WM_USER + 500) to (%WM_USER + &H07FFF), or use the RegisterWindowMessage API to obtain a unique message value from the operating system. Using messages with a numeric value of less then %WM_USER + 500 may conflict with Windows Common Control messages.

See Also

  • Dynamic Dialog Tools
  • CONTROL HANDLE
  • CONTROL POST
  • DIALOG POST
  • DIALOG SEND


CONTROL SET CHECK - ScharfBASIC Help

CONTROL SET CHECK

Set the Check State for a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET CHECK hDlg , id& , checkstate&

Description

With a checkbox control, the Check State is set (checked) when an 'X' symbol is shown in the check box. The Check State is deemed unset (unchecked or cleared) when the check box is empty.

A CHECK3STATE control supports a third state, known as indeterminate. In this state, the check box is grayed.

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the button control with a CONTROL ADD statement.

For CHECKBOX controls, set checkstate& to zero (0) to uncheck (unset or clear) the Check State of the control, or one (1) to check (set) the Check State of the control.

For CHECK3STATE controls, set checkstate& to zero (0) to uncheck (unset or clear) the Check State of the control, one (1) to check (set) the Check State (display an 'X' symbol in the box), or two (2) to set the indeterminate state (display a grayed check box).

To set the Check State of OPTION controls, use the CONTROL SET OPTION statement.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD CHECK3STATE
  • CONTROL ADD CHECKBOX
  • CONTROL ADD OPTION
  • CONTROL GET CHECK
  • CONTROL SET OPTION
  • TREEVIEW GET CHECK
  • TREEVIEW SET CHECK

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   ecx,0x65
mov   eax,0x1
call   0x203bc1
call   0x205a9c


CONTROL SET CLIENT - ScharfBASIC Help

CONTROL SET CLIENT

Change the size of a control to a specific

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET CLIENT hDlg , id& , nWide& , nHigh&

Description

Client size may be smaller than total size, depending on the type of borders used. The client area is the part inside the borders of a control, which varies depending upon the style and exstyle at creation. In a control without borders, the client size and total size is the same. As an alternate example, a control with the %WS_BORDER style will typically have a client area a few pixels smaller than the total size.

Handle of the dialog that owns the control.

The unique control identifier , assigned to the control with the CONTROL ADD statement.

nWide& , nHigh&

Integral expressions, variables , or numeric literal values, specifying the desired size of the client area. Width and height are specified in pixels or dialog units , depending upon the system used when the parent dialog was created.

Graphic Controls

Beginning with this version of ScharfBASIC, GRAPHIC CONTROLS may be resized with CONTROL SET CLIENT, GRAPHIC SET CLIENT, CONTROL SET SIZE , and GRAPHIC SET SIZE.

When you change the size of a graphic control, the original bitmap is copied, pixel for pixel, to the newly resized control. Any expanded area is filled with the current background color. Your program draws to it in the normal fashion for a bitmap of the new size.

If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP, based upon the new size of the drawing area.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • CONTROL GET LOC
  • CONTROL GET SIZE
  • CONTROL SET LOC
  • CONTROL SET SIZE
  • GRAPHIC SET CLIENT
  • GRAPHIC SET SIZE


CONTROL SET COLOR - ScharfBASIC Help

CONTROL SET COLOR

Set the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET COLOR hDlg , id& , foreclr& , backclr&

Description

hDlg identifies the control?s parent dialog, and id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

Color values of foreclr& and backclr& must be in the range of &H0 to &H00FFFFFF. RGB can be a useful function to derive a 32-bit color value from discrete Red, Green and Blue values:

foreclr&

The foreground color parameter foreclr& is used to set the color of the text displayed in the control. If foreclr& = -1&, the default foreground text color is used.

backclr&

The backclr& parameter specifies the color of the background behind the text in the control. If backclr& = -1&, the default background text color is used. If backclr& = -2&, the text background is not painted, allowing the background to show "through" the text. The non-visible background style may produce undesirable side effects with some controls. For example, on a FRAME control, the caption text will appear superimposed over an unbroken frame.

In 16-bit or greater color-depth mode, the specified RGB color is used when the background of the control is drawn. However, in 8-bit (256-color) mode, the color system works quite differently. Behind the scenes in Windows, the base system palette usually contains 20 solid colors that are not dithered when drawn on the controls background. These solid-colors are ideal for control background colors with DDT dialogs in 256-color mode.

Conversely, when using a non-solid RGB color value, Windows will dither (approximate) the color to draw the control, using combinations of two or more colors. This usually produces an undesirable pattern effect.

To avoid these problems when in 256-color mode, controls should be colored with one of the 20 standard (solid) system colors, or the default color should be used instead. ScharfBASIC includes the following 10 built-in equates for help with the selection of a standard solid color:

%RGB_BLACK %RGB_BLUE %RGB_GREEN %RGB_CYAN %RGB_RED

%RGB_MAGENTA %RGB_YELLOW %RGB_WHITE %RGB_GRAY %RGB_LIGHTGRAY

Many non standard colors are also built into the compiler, see the Built In RGB Color Equates topic for a complete list.

If you prefer to disable color in 256-color mode, the number of colors can be easily tested with the following code:

' Determine number of colors

LOCAL hDC AS DWORD, iColors AS LONG

hDC = GetWindowDC(GetDeskTopWindow())

iColors = 2& ^ (GetDeviceCaps(hDC, %BITSPIXEL) * GetDeviceCaps(hDC, %PLANES))

ReleaseDC GetDeskTopWindow(), hDC

IF iColors > 256 THEN _

CONTROL SET COLOR hDlg, idctl&, -1, RGB(0,255,100)

In 256-color mode on most computers, the values of the standard 20 system colors can be found by requesting the first and last 10 (0 to 9, and 246 to 255 inclusive) entries from the GetSystemPaletteEntries API function, as follows:

' Fill array with solid colors

DIM hDC AS DWORD, Cols AS LONG, x AS LONG

hDC = GetWindowDC(GetDesktopWindow)

Cols = GetDeviceCaps(hDC, %NUMRESERVED)

REDIM lp(1 TO Cols) AS LONG

x& = GetSystemPaletteEntries(hDC, 0, Cols \ 2, BYVAL VARPTR(lp(1)))

x& = GetSystemPaletteEntries(hDC, 256 - x&, Cols - x&, BYVAL VARPTR(lp(x& + 1)))

ReleaseDC GetDesktopWindow, hDC

' Array lp() now contains the solid color table

For more information on working with palettes in 256-color mode, please consult WIN32.HLP or visit http://msdn.microsoft.com .

Restrictions

Windows does not permit the color of standard push button controls, line controls, image controls, image buttons, and most common controls to be altered by the standard CONTROL SET COLOR techniques.

To create a colored push button or colored region on a dialog, the preferred solution is to use an IMGBUTTON / IMAGEBUTTONX or IMAGE / IMAGEX control, with a suitably colored bitmap. Some common controls offer specific ways to set their color. For example, the background color of a List View control can be set with the %LVM_SETBKCOLOR message.

When dynamically changing colors of a control from within a callback (i.e., after the DIALOG SHOW statement), a CONTROL SET COLOR statement should be immediately followed by an explicit CONTROL REDRAW statement.

Without this forced control redraw, the control background color change may not become evident to the user until the control is eventually repainted in the normal course of user interaction. For example, a normal repaint may only occur if the control becomes obscured and then uncovered by another window. Ensuring a timely repaint of the control will guarantee the control maintains an up-to-date appearance at all times.

When updating the colors of multiple controls at the same time, a DIALOG REDRAW is usually more efficient than multiple CONTROL REDRAW statements.

See Also

  • Built In RGB Color Equates
  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • CONTROL GET SIZE
  • CONTROL REDRAW
  • CONTROL SET FONT
  • DIALOG REDRAW
  • DIALOG SET COLOR


CONTROL SET FOCUS - ScharfBASIC Help

CONTROL SET FOCUS

Set the keyboard focus to the specified control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET FOCUS hDlg , id&

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

The control that owns the focus will receive all keyboard messages. Many controls change their appearance when they receive (and lose) keyboard focus, usually by the display of a "focus rectangle" around or on the control that has keyboard focus. Only one control can have keyboard focus at any moment, and situations can arise where no controls have focus.

Controls that include a "notify" style (i.e., %BS_NOTIFY) will receive a notification message when focus is gained or lost. That is, when one such control loses focus, it receives a message to that effect and the control gaining focus may also receive an appropriate focus notification message.

When a control gains focus the parent dialog will also be set as the foreground window.

Windows does not guarantee the order in which focus notification messages are dispatched to the control losing focus and the control gaining focus. Applications should not rely on the order in which these types of messages are received.

Restrictions

CONTROL SET FOCUS cannot be used to set the focus of a control in a separate thread.

See Also

  • Dynamic Dialog Tools


CONTROL SET FONT - ScharfBASIC Help

CONTROL SET FONT

Select a font to be used for a particular Windows Control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET FONT hDlg , id& , FontHndl&

Description

The font specified by FontHndl& is selected to be used by this particular control, until or unless it is changed with another CONTROL SET FONT statement. If you specify a FontHndl& of zero, the font is changed back to the original default font chosen by ScharfBASIC.

You can predefine virtually any number of fonts and attributes by executing FONT NEW statements for each of them. That makes them ready for immediate use when selected by CONTROL SET FONT, GRAPHIC SET FONT , and XPRINT SET FONT .

See Also

  • DIALOG DEFAULT FONT
  • FONT END
  • FONT NEW
  • GRAPHIC SET FONT
  • XPRINT SET FONT


CONTROL SET IMAGE - ScharfBASIC Help

CONTROL SET IMAGE

Change the icon or bitmap displayed in an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET IMAGE hDlg , id& , newimage$

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with the CONTROL ADD IMAGE statement.

newimage$ specifies the name of the bitmap or icon in the resource file . If the image resource uses an integral identifier, newimage$ should begin with a Number symbol (#), followed by the integer identifier in ASCII format. For example, "#998". Otherwise, the text identifier name should be used.

Restrictions

Images can only be exchanged with images of the same type. That is, if the control is displaying a bitmap then the replacement image must also be a bitmap. If the control is displaying an icon, the replacement image must also be an icon. For best results, icons should be 32x32 pixels.

When an image is changed, CONTROL SET IMAGE automatically releases the old image from memory. Previous versions of ScharfBASIC placed the onus on the programmer to release the old image handle.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL GET CLIENT
  • CONTROL GET SIZE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX


CONTROL SET IMAGEX - ScharfBASIC Help

CONTROL SET IMAGEX

Change the icon or bitmap displayed in an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET IMAGEX hDlg , id& , newimage$

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with the CONTROL ADD IMAGEX statement.

newimage$ specifies the name of the bitmap or icon in the resource file . If the image resource uses an integral identifier, newimage$ should begin with a Number symbol (#), followed by the integer identifier in ASCII format. For example, "#998". Otherwise, the text identifier name should be used.

Restrictions

Images can only be exchanged with images of the same type. That is, if the control is displaying a bitmap then the replacement image must also be a bitmap. If the control is displaying an icon, the replacement image must also be an icon. For best results, icons should be 32x32 pixels.

When an image is changed, CONTROL SET IMAGEX automatically releases the old image from memory. Previous versions of ScharfBASIC placed the onus on the programmer to release the old image handle.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGE
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX


CONTROL SET IMGBUTTON - ScharfBASIC Help

CONTROL SET IMGBUTTON

Change the icon or bitmap displayed in an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET IMGBUTTON hDlg , id& , newimage$

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with the CONTROL ADD IMGBUTTON statement.

newimage$ specifies the name of the bitmap or icon in the resource file . If the image resource uses an integral identifier, newimage$ should begin with a Number symbol (#), followed by the integer identifier in ASCII format. For example, "#998". Otherwise, the text identifier name should be used.

Restrictions

Images can only be exchanged with images of the same type. That is, if the control is displaying a bitmap then the replacement image must also be a bitmap. If the control is displaying an icon, the replacement image must also be an icon. For best results, icons should be 32x32 pixels.

When an image is changed, CONTROL SET IMGBUTTON automatically releases the old image from memory. Previous versions of ScharfBASIC placed the onus on the programmer to release the old image handle.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTONX


CONTROL SET IMGBUTTONX - ScharfBASIC Help

CONTROL SET IMGBUTTONX

Change the icon or bitmap displayed in an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET IMGBUTTONX hDlg , id& , newimage$

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with the CONTROL ADD IMGBUTTONX statements.

newimage$ specifies the name of the bitmap or icon in the resource file . If the image resource uses an integeral identifier, newimage$ should begin with a Number symbol (#), followed by the integer identifier in ASCII format. For example, "#998". Otherwise, the text identifier name should be used.

Restrictions

Images can only be exchanged with images of the same type. That is, if the control is displaying a bitmap then the replacement image must also be a bitmap. If the control is displaying an icon, the replacement image must also be an icon. For best results, icons should be 32x32 pixels.

When an image is changed, CONTROL SET IMGBUTTONX automatically releases the old image from memory. Previous versions of ScharfBASIC placed the onus on the programmer to release the old image handle.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD GRAPHIC
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGE
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON


CONTROL SET LOC - ScharfBASIC Help

CONTROL SET LOC

Move the control to a new location in the dialog.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET LOC hDlg , id& , x& , y&

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

x& and y& specify the new location for the upper left corner of the control. These coordinates are relative to the upper left corner of the client area of the parent dialog (0,0), and are specified in the same terms (pixels or dialog units) as the parent dialog.

The location coordinates may be negative or larger than the width of the parent dialog's client area, causing the control to be clipped (partially displayed) or completely hidden.

This technique is often employed to capture the ENTER key, by creating a default button (%BS_DEFAULT) and positioning the control outside of the client area of the dialog - even though the control is not visible, it is still active and can respond to control accelerator keystrokes, etc.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • CONTROL GET LOC
  • CONTROL GET SIZE
  • CONTROL SET SIZE


CONTROL SET OPTION - ScharfBASIC Help

CONTROL SET OPTION

Set the Check State for an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET OPTION hDlg , id& , minid& , maxid&

Description

The Check State is deemed set (checked) when the check box is selected, and unset (unchecked or clear) if the check box is empty. Only one OPTION control in a group of OPTION controls should ever have its Check State set at any given time. OPTION controls in a group should be assigned unique sequential identifier numbers.

hDlg refers to the dialog that owns the OPTION controls.

id& is the unique control identifier as assigned to the button control with a CONTROL ADD OPTION statement. CONTROL SET OPTION sets the Check State for this control, and unsets the Check State for all of the remaining OPTION controls whose identifiers are included in the range minid& through maxid& , inclusive.

The first OPTION control in a group should have the style %WS_GROUP to mark the beginning of a group of buttons, and the first non-OPTION control after the group should also have this style set. If there are no other controls after the group, add %WS_GROUP to the first control in the dialog. This ensures keyboard navigation with the arrow buttons will operate within the group of OPTION controls.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD OPTION
  • CONTROL GET CHECK

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Control Get Option

mov   eax,0x65
call   0x203904
call   0x20395a
lea   ebx,[ebp-0xa0]
call   0x204ccc
call   0x205b7b
call   0x205aac

Variant 2: Control Set Option

mov   eax,0x65
call   0x203904
mov   edx,0x20ca54
call   0x205b64
call   0x204d04
call   0x20398e
call   0x205aac


CONTROL SET SIZE - ScharfBASIC Help

CONTROL SET SIZE

Change the size of a control

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET SIZE hDlg , id& , nWide& , nHigh&

Description

O verall size may be larger than client size, depending on the type of borders used. The client area is the part inside the borders of a control, which varies depending upon the style and exstyle at creation. Overall size includes the borders. In a control without borders, the client size and total size is the same. However, a control with the %WS_BORDER style will typically have a client area a few pixels smaller than the total size.

Handle of the dialog that owns the control.

nWide&, nHigh&

Integral numeric expressions which specify the desired size of the overall area. Width and height are specified in pixels or dialog units , depending upon the system used when the parent dialog was created.

Graphic Controls

Beginning with this version of ScharfBASIC, GRAPHIC CONTROLS may be resized with CONTROL SET CLIENT , GRAPHIC SET CLIENT , CONTROL SET SIZE, and GRAPHIC SET SIZE .

When you change the size of a graphic control, the original bitmap is copied, pixel for pixel, to the newly resized control. Any expanded area is filled with the current background color. Your program draws to it in the normal fashion for a bitmap of the new size.

If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP , based upon the new size of the drawing area.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • CONTROL GET LOC
  • CONTROL GET SIZE
  • CONTROL SET LOC
  • GRAPHIC SET CLIENT
  • GRAPHIC SET SIZE


CONTROL SET TEXT - ScharfBASIC Help

CONTROL SET TEXT

Change the text in a control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET TEXT hDlg , id& , txt$

Description

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

txt$ is the new text for the control. Any existing text in the control is replaced with the new text.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET TEXT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x65
call   0x203904
mov   edx,0x20ca54
call   0x205b64
call   0x204d04
call   0x20398e
call   0x205aac


CONTROL SET USER - ScharfBASIC Help

CONTROL SET USER

Set a value in the user data area of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SET USER hDlg , id& , index& , usrval&

Description

Each DDT control has a user data area consisting of eight Long-integer values which may be used at the programmer's discretion to save relevant data. CONTROL SET USER allows one of the values to be set, based upon the index parameter value (1 through 8).

hDlg refers to the dialog that owns the control.

id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

index& is the index number of the user data value to set, in the range 1 to 8 inclusive.

usrval& is the Long-integer data value to store in the user data area.

Restrictions

Data in the user data area is lost when the control is destroyed. The data area is completely separate from the %GWL_USERDATA area maintained by Windows.

See Also

  • Dynamic Dialog Tools
  • COMBOBOX GET USER
  • COMBOBOX SET USER
  • CONTROL GET USER
  • DIALOG GET USER
  • DIALOG SET USER
  • LISTBOX GET USER
  • LISTBOX SET USER
  • LISTVIEW GET USER
  • LISTVIEW SET USER
  • TREEVIEW GET USER
  • TREEVIEW SET USER


CONTROL SHOW STATE - ScharfBASIC Help

CONTROL SHOW STATE

Change the visible state of a control.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

CONTROL SHOW STATE hDlg , id& , showstate& [TO lResult& ]

Description

CONTROL SHOW STATE is used to alter the state and/or appearance of the specified control, identified by the parent dialog handle hDlg , and control id& unique identifier combination.

showstate& can be one of the following (with a value in the range from 0 to 10) as defined in the WIN32API.INC file):

%SW_HIDE

Hide the control.

%SW_MAXIMIZE

Maximize the specified control.

%SW_MINIMIZE

Minimize the specified control.

%SW_RESTORE

Activate and display the control. If the control is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized control.

%SW_SHOW

Activate the control and display it in its current size and position.

%SW_SHOWMAXIMIZED

Synonym of %SW_MAXIMIZE.

%SW_SHOWMINIMIZED

Activate the control and minimize it.

%SW_SHOWNA

Display the control in its current state without activating it. The currently active window/control remains active.

%SW_SHOWNOACTIVATE

Display the control in its most recent size and position without activating it. The currently active window/control remains active.

%SW_SHOWNORMAL

Activate and display the control. If the control is minimized or maximized, it is restored it to its original size and position.

If the optional TO clause is included, the lResult& variable is assigned the value zero if the control was previously not visible, or non-zero if it was previously visible.

See Also

  • Dynamic Dialog Tools
  • CONTROL DISABLE
  • CONTROL ENABLE
  • DIALOG SHOW STATE


Control Styles - ScharfBASIC Help

Control Styles

When creating child controls for your dialogs, you are free to use almost any control style permitted by Windows. These styles mostly start with the %WS_ prefix (Window Style), and are included in the

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

If the style parameter in your CONTROL ADD statements is set to 0, DDT will set default styles automatically for you. The default styles will depend on the type of control you are adding to your dialog. For example, a button will be given the %WS_TABSTOP style.

Note that DDT always gives your controls certain styles, such as %WS_CHILD and %WS_VISIBLE, regardless of the styles you specify. When setting your style parameter, you can safely ignore these two styles and concentrate on the more important styles that are required. This has the advantage of reducing the clutter of your code. The exception is custom controls - in this case you must explicitly specify all required styles.

The "tab-order" of controls (also known as the "z-order") is determined by the order that DDT controls are created at run-time. That is, the first control added to a dialog is the first control in the z-order, the second control added is second, and so forth. When a dialog is initially displayed, keyboard focus is automatically given to the first control in the z-order that has the %WS_TABSTOP style. Each time the TAB key is subsequently pressed, the keyboard focus moves to the next control in the tab-order. To ensure all controls in a dialog can be selected using the TAB key, each control in the dialog should include the %WS_TABSTOP style. The z-order also determines the order that controls are drawn on a dialog, to help ensure that control that overlap one another can be drawn in a predictable manner.

Controls that are disabled (because either they have the %WS_DISABLED style or they have been dynamically disabled with CONTROL DISABLE ) are skipped over.

Most DDT controls are created with the %WS_TABSTOP style by default. However, you should explicitly include the %WS_TABSTOP style in the control style parameter, if your DDT code creates controls with custom (non-default) styles. If you do not include this style, these control(s) may not be able to receive keyboard focus.

The following table lists the default DDT styles for many of the standard controls:


Controls - ScharfBASIC Help

Controls

A Control is a special Window that provides a method for interacting with the user. Buttons , Combo boxes , List boxes , and Text boxes are all examples of controls. Whenever the user interacts with a

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

When you add a control to a dialog , it is important that each control has a unique numeric identifier. This identifier helps your application to know which control is sending an event. For example, if your program has two buttons in it, the control ID allows you distinguish between them.

As each control is created, Windows assigns a unique window handle to identify the control. Because your program does not assign these handle values, your code cannot directly use them to identify individual controls. Further, each time a control is destroyed and recreated, a new unique handle value is assigned, further complicating the task. The control ID overcomes these problems, as the programmer determines the ID for each control.

Controls are added to your dialog with the CONTROL ADD statement. Make sure that each control you create has a unique numeric identifier, so that you (and Windows) can tell it apart from other controls on the dialog.

Given the ID of a control, DDT provides the CONTROL HANDLE statement to retrieve the window handle value of the control. If a given ID is duplicated in a dialog, CONTROL HANDLE is only able to identify the first control that matches the ID, and the remaining controls will essentially be ignored. Control ID's can often be duplicated for Label (static) text controls, provided these controls (and their contents, color , or styles ) are not going to be modified at run-time. If such a Label control is to be modified, its control ID must be unique.

ScharfBASIC provides a comprehensive set of statements and functions for dealing with controls. The following is a small sample of these statements and functions with a brief description of the purpose of each:

Specify which messages should be sent to a Control Callback Function


Creating a Dialog - ScharfBASIC Help

Creating a Dialog

In this example, we will create a simple dialog that asks the user to enter his/her name, providing a text box for input, plus both "OK" and "Cancel" buttons. To create the dialog, first we use the DI

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

LOCAL hParent AS DWORD

DIALOG NEW hParent, Caption$,,, 160, 50, Style&, exStyle& TO hDlg

hParent refers to the parent window handle . If this value is 0 (or %HWND_DESKTOP), the dialog has no parent window, and may be referred to as a "top-level" window. However, if the dialog has a parent window and the dialog is a MODAL dialog, Windows will automatically disable the parent window while the DDT dialog is displayed.

Caption$ is the text displayed in the caption of the dialog. This may be the name of your program, or it can be used to convey other information to the user.

The next two parameters for the location on the screen are omitted (this causes the dialog to be centered on the screen), and the size is set to 160 dialog units wide by 50 dialog units tall. Style& specifies how the dialog is drawn on the screen (with a caption, without a caption, etc). exStyle& specifies an extended style attributes for drawing the dialog. For information on the range of possible dialog styles, please see the DIALOG NEW statement.

Once the dialog has been created, the handle for it is placed in the hDlg variable. hDlg may be a Long-integer or Double-word variable (i.e., hDlg& or hDlg??? ), but a Double-word variable is recommended . This handle is used by Windows (and your program) code to identify the dialog. Windows gives each dialog a unique handle value at run-time; no two windows, dialogs, or controls can have the same handle value. This means that the actual handle value will be different every time the dialog is created.

Note that the height and width values determine the client size of the dialog, if the dialog style explicitly includes the %WS_CAPTION style. Otherwise, they are interpreted as the outer dimensions of the complete dialog.


DESKTOP GET CLIENT - ScharfBASIC Help

DESKTOP GET CLIENT

Retrieve the size of the client area of the desktop, in

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DESKTOP GET CLIENT TO ncWidth& , ncHeight&

Description

The desktop client size is the part of the screen that is not obscured by the system tray.

This can be used in combination with DESKTOP GET LOC or DESKTOP GET SIZE for exact positioning of windows on the desktop.

See Also

  • Dynamic Dialog Tools
  • DESKTOP GET LOC
  • DESKTOP GET SIZE


DESKTOP GET LOC - ScharfBASIC Help

DESKTOP GET LOC

Retrieve the location of the top, left corner of the client area of the desktop, in

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DESKTOP GET LOC TO x& , y&

Description

The desktop client area is the part of the screen that is not obscured by the system tray. The system tray's position on the screen determines the upper, left position of the client area. If the tray is located at the bottom of the screen (default), left and top coordinates are 0,0. If the tray is located on the right side of the screen, left and top coordinates are 0,0. If the tray is located on the left side of the screen, left and top coordinates are TrayWidth,0. If the tray is located at the top of the screen, left and top coordinates are 0,TrayHeight.

This can be used in combination with DESKTOP GET CLIENT or DESKTOP GET SIZE for exact positioning of windows on the desktop.

See Also

  • DESKTOP GET CLIENT
  • DESKTOP GET SIZE


DESKTOP GET SIZE - ScharfBASIC Help

DESKTOP GET SIZE

Retrieve the size of the entire desktop, in

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DESKTOP GET SIZE TO ncWidth& , ncHeight&

Description

The desktop size includes the space taken up by the system tray and is same as the screen size. This can be used in combination with DESKTOP GET CLIENT or DESKTOP GET LOC for exact positioning of windows on the desktop.

See Also

  • DESKTOP GET CLIENT
  • DESKTOP GET LOC


DIALOG DEFAULT FONT - ScharfBASIC Help

DIALOG DEFAULT FONT

Specify the default

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG DEFAULT FONT fontname$ [, points& , style& , charset& ]
DIALOG FONT [DEFAULT] fontname$ [, points& , style& , charset& ]

Description

The DIALOG DEFAULT FONT statement specifies the font which will be used for all subsequent dialogs created with DIALOG NEW , until another DIALOG DEFAULT FONT statement is executed. When a DIALOG NEW statement is executed, the selected default font is associated with it, and its vhild controls , for the lifetime of the dialog.

The default font is particularly important when creating new dialogs which use dialog units (rather than pixels) as the unit of measurement. When sizing in dialog units, Windows calculates the physical size of the window based upon the font size, among other factors. Changing the font size later will not update the window size.

You may use the value zero (0) for any of the numeric parameters to designate that the compiler should use the default for that item. If parameter(s) are missing, the compiler substitutes the default value for all remaining parameters. If no DIALOG DEFAULT FONT statement is executed, ScharfBASIC will select MS Sans Serif, 8 point, with no style attributes.

When specifying a font, care should be exercised to use a standard font that is available in all versions of Windows, such as "Times New Roman", "Arial", "Courier", "MS Sans Serif", etc. Specifying a font name that is not available forces Windows to substitute a font that may not be visually appealing, and may also alter the relative size of the dialog.

DIALOG DEFAULT FONT is module-specific. That is, it only affects subsequent dialogs created by code in the same EXE or DLL . For example, a DIALOG DEFAULT FONT statement in a DLL, will not affect dialogs created in the calling EXE or other DLLs loaded by the EXE.

See Also

  • CONTROL SET FONT
  • Dynamic Dialog Tools
  • DIALOG NEW
  • DIALOG SET COLOR
  • FONT END
  • FONT NEW
  • GRAPHIC SET FONT
  • XPRINT SET FONT


DIALOG DISABLE - ScharfBASIC Help

DIALOG DISABLE

Disable a dialog so that it no longer receives any mouse or keyboard

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG DISABLE hDlg

Description

hDlg refers to the dialog you want to disable. A disabled dialog will not receive any messages when it is clicked with the mouse or selected with the keyboard. Disabling a dialog that is already disabled has no effect.

If the dialog has a Callback Function, a %WM_ENABLE message is sent to the Callback Function before DIALOG DISABLE finishes.

See Also

  • Dynamic Dialog Tools
  • DIALOG ENABLE
  • DIALOG HIDE
  • DIALOG NORMALIZE
  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • DIALOG SHOW STATE


DIALOG DOEVENTS - ScharfBASIC Help

DIALOG DOEVENTS

Process pending window or dialog

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG DOEVENTS [ sleep& ] [TO count& ]

Description

DIALOG DOEVENTS is usually used to create a " message pump " for modeless dialog boxes.

If a window message is pending, it is processed appropriately. If no messages are pending, execution of the current thread is paused for the time specified by the sleep& parameter. If sleep& is zero (0), the remainder of the current time slice is relinquished to other threads or processes. If sleep& is greater than zero, the current thread is paused for that number of milliseconds to allow other threads or processes to continue. If sleep& is not specified, it defaults to a value of one (1). During the sleep period, all time-slices for the current thread are given to other threads and processes. If there are no other threads of equal priority, execution continues immediately. The time-slice duration (also known as the Quantum) can vary from version to version of Windows, ranging from 20 mSec to 120 mSec. If the optional TO clause is included, the number of active dialogs is returned in the count& variable, once all of the pending messages have been processed.

Restrictions

The DIALOG DOEVENTS loop must run for the duration of the modeless dialog(s), or they will not respond or be redrawn correctly.

See Also

  • Dynamic Dialog Tools
  • DIALOG NEW
  • DIALOG SHOW MODELESS
  • SLEEP

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Dialog Doevents

mov   eax,0x1
call   0x201ee1
call   0x202880

Variant 2: Doevents

mov   eax,0x1
call   0x201ee1
call   0x202880


DIALOG ENABLE - ScharfBASIC Help

DIALOG ENABLE

Enable a dialog so that it can receive

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG ENABLE hDlg

Description

hDlg refers to the dialog you want to enable. An enabled dialog will receive messages when it is clicked with the mouse or selected with the keyboard. Enabling a dialog has no effect if the dialog is already enabled.

If the dialog has a Callback Function, a %WM_ENABLE message is sent to the Callback Function before DIALOG ENABLE finishes.

See Also

  • Dynamic Dialog Tools
  • DIALOG DISABLE
  • DIALOG HIDE
  • DIALOG NORMALIZE
  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • DIALOG SHOW STATE


DIALOG END - ScharfBASIC Help

DIALOG END

Close and destroy the specified dialog.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG END hDlg [, lResult& ]

Description

The dialog specified by the hDlg variable is destroyed.

lResult& optionally specifies a value to return to the DIALOG SHOW MODAL or DIALOG SHOW MODELESS statement that activated the dialog initially.

Restrictions

DIALOG END cannot close or destroy a dialog in a separate thread. In this case, send or post a message to the dialog to signal it to close, and respond to the message in the callback for the specified dialog. For example:

' Trigger a DIALOG END in a separate thread

DIALOG SEND hDlg, %WM_SYSCOMMAND, %SC_CLOSE, 0

DIALOG END cannot be used during processing of the %WM_INITDIALOG message. If this effect is necessary, the solution is to post a user-defined message to the dialog and use DIALOG END at that point. For example:

CALLBACK FUNCTION MyDialogCallback

SELECT CASE CB.MSG

CASE %WM_INITDIALOG

IF gMustEnd& THEN _ ' We have to stop!

DIALOG POST CB.HNDL, %WM_USER+999&, 0, 0

CASE %WM_USER + 999&

DIALOG END CB.HNDL

FUNCTION = 1

END SELECT

END FUNCTION

See Also

  • Dynamic Dialog Tools
  • DIALOG NEW
  • DIALOG SHOW MODELESS
  • THREAD CREATE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,DWORD PTR [ebp-0xa8]
call   0x202a08
call   0x205a9c


DIALOG GET CLIENT - ScharfBASIC Help

DIALOG GET CLIENT

Return the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG GET CLIENT hDlg TO nWide& , nHigh&

Description

hDlg refers to the dialog to examine. The size of the dialog client area is placed in the nWide& (width) and nHigh& (height) variables . The size is specified in the same terms ( pixels or dialog units) as the parent dialog.

See Also

  • Dynamic
  • Dialog Tools
  • CONTROL GET CLIENT
  • DIALOG GET LOC
  • DIALOG GET SIZE
  • DIALOG PIXELS
  • DIALOG SET CLIENT
  • DIALOG SET LOC
  • DIALOG SET SIZE
  • DIALOG UNITS


DIALOG GET LOC - ScharfBASIC Help

DIALOG GET LOC

Return the location of the specified

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG GET LOC hDlg TO x& , y&

Description

hDlg refers to the dialog to examine. The location of the dialog is placed in the x& (horizontal position) and y& (vertical position) variables as a relative location. If the dialog was created with the PIXELS option in the DIALOG NEW statement, the values are returned in pixel units. If the UNITS option was used (or no scaling option was specified), the values are returned in dialog units.

[OBJECT]If the [OBJECT]parent[OBJECT] of the dialog is zero (or %HWND_DESKTOP), the location is relative to the upper-left corner of the display. Otherwise, it is relative to the upper-left corner of client area of the parent window.

See Also

  • Dynamic Dialog Tools
  • DIALOG GET CLIENT
  • DIALOG GET SIZE
  • DIALOG PIXELS
  • DIALOG SET LOC
  • DIALOG SET SIZE
  • DIALOG UNITS


DIALOG GET SIZE - ScharfBASIC Help

DIALOG GET SIZE

Return the size of the specified

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG GET SIZE hDlg TO x& , y&

Description

hDlg refers to the dialog to examine. The total size of the dialog is placed in the x& (width) and y& (height) variables . If the dialog was created with the PIXELS option in the DIALOG NEW statement, the values are returned in pixel units. If the UNITS option was used (or no scaling option was specified), the values are returned in dialog units .

See Also

  • Dynamic Dialog Tools
  • DIALOG GET CLIENT
  • DIALOG GET LOC
  • DIALOG PIXELS
  • DIALOG SET LOC
  • DIALOG SET SIZE
  • DIALOG UNITS

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,DWORD PTR [ebp-0xa8]
mov   eax,0x80000000
call   0x203e7c
fistp   QWORD PTR [ebp-0x6c]
mov   esi,DWORD PTR [ebp-0x6c]
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
call   0x205aac


DIALOG GET TEXT - ScharfBASIC Help

DIALOG GET TEXT

Retrieve the text in a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG GET TEXT hDlg TO titletext$

Description

The text of the dialog or window caption specified by hDlg . For DDT dialogs, hDlg is the dialog handle returned by the DIALOG NEW statement. In a dialog Callback Function, the CB.HNDL function will return the parent dialog handle and this can also be used with DIALOG GET TEXT.

titletext$

The text is returned and placed into the string variable titletext$. If the window or dialog is invalid, titletext$ will be set to an empty string.

Restrictions

hDlg is a dialog or window handle, so DIALOG GET TEXT works with both DDT dialogs and conventional windows and dialogs.

See Also

  • CB Callback functions
  • CONTROL GET TEXT
  • CONTROL SET TEXT
  • DIALOG NEW
  • DIALOG SET TEXT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,DWORD PTR [ebp-0xa8]
call   0x20395a
lea   ebx,[ebp-0xa4]
call   0x204ccc
call   0x205b7b
call   0x205aac


DIALOG GET USER - ScharfBASIC Help

DIALOG GET USER

Retrieve a value from the user data area of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG GET USER hDlg , index& TO retvar&

Description

Each DDT dialog has a user data area consisting of eight Long-integer values which may be used at the programmer's discretion to save relevant data. DIALOG GET USER allows one of the values to be retrieved, based upon the index parameter value (1 through 8).

hDlg refers to the dialog that contains the user data.

index& is the index number of the user data value to retrieve, in the range 1 to 8 inclusive.

retvar& receives the Long-integer data value stored in the nominated user data index.

Restrictions

Data in the user data area is lost when the dialog is destroyed. The data area is completely separate from the %GWL_USERDATA area maintained by Windows.

See Also

  • Dynamic Dialog Tools
  • COMBOBOX SET USER
  • CONTROL GET USER
  • CONTROL SET USER
  • DIALOG SET USER
  • LISTBOX GET USER
  • LISTBOX SET USER
  • LISTVIEW GET USER
  • LISTVIEW SET USER
  • TREEVIEW GET USER
  • TREEVIEW SET USER


DIALOG HIDE - ScharfBASIC Help

DIALOG HIDE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG HIDE hDlg

Description

The Dialog identified by the handle hDlg is made invisible.

See Also

  • CONTROL HIDE
  • CONTROL NORMALIZE
  • DIALOG MAXIMIZE
  • DIALOG MINIMIZE
  • DIALOG NORMALIZE


DIALOG MAXIMIZE - ScharfBASIC Help

DIALOG MAXIMIZE

Maximize a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG MAXIMIZE hDlg

Description

The Dialog identified by the handle hDlg is maximized. You can restore the Dialog to its normal state with DIALOG NORMALIZE .

See Also

  • CONTROL HIDE
  • CONTROL NORMALIZE
  • CONTROL SET SIZE
  • DIALOG MINIMIZE
  • DIALOG NORMALIZE
  • DIALOG SET SIZE


DIALOG MINIMIZE - ScharfBASIC Help

DIALOG MINIMIZE

Minimize a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG MINIMIZE hDlg

Description

The Dialog identified by the handle hDlg is minimized. You can restore the Dialog to its normal state with DIALOG NORMALIZE .

See Also

  • CONTROL HIDE
  • CONTROL NORMALIZE
  • CONTROL SET SIZE
  • DIALOG MAXIMIZE
  • DIALOG NORMALIZE
  • DIALOG SET SIZE


DIALOG NEW - ScharfBASIC Help

DIALOG NEW

Create a new dialog in memory, ready for display.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG NEW [PIXELS, | UNITS,] hParent , title$ , [ x& ], [ y& ], xx& , yy& [, [ style& ] [, [ exstyle& ]]] [,] TO hDlg

Description

A new empty dialog is created, but not yet displayed. Once the dialog has been created and all of the desired controls have been added with CONTROL ADD statements, the dialog can be displayed with the DIALOG SHOW MODELESS , or DIALOG SHOW MODAL statements.

If a modeless dialog is created, the application must create a DIALOG DOEVENTS message pump for the duration of the dialog. Failure to provide a message pump can result in disruptions to the display of the dialog, or the inability of the dialog to respond to messages such as button clicks, etc. Modal dialogs do not require a message pump. To change the displayed state of a dialog (i.e., hidden, minimized, etc) after the dialog has been created, use the DIALOG SHOW STATE statement.

If a dialog does not have either %WS_CHILD or %WS_POPUP styles , Windows may enforce a minimum dialog width of some 60-70 dialog units .

PIXELS

If the PIXELS keyword is specified, all size and position parameters are specified in pixels. In this case, related statements such as DIALOG GET LOC will also return values in Pixels.

If UNITS is specified (or no scaling option is specified), all size and position parameters are specified in Dialog Units. (default)

DIALOG NEW takes the following parameters.

hParent

Handle of the parent window or dialog. If there is no parent, use zero (0) or %HWND_DESKTOP. If the dialog is MODAL, the parent window/dialog will be disabled while this "child" dialog is running.

title$

The text displayed in the title or caption bar of the dialog.

x&, y&

Optional location of the top-left corner for the dialog. The location is specified in the same terms (pixels or dialog units) as specified in the DIALOG NEW statement. If neither x& and y& are specified, the dialog is centered on the screen.

If %CW_USEDEFAULT (&H080000000) is specified, the default Windows position is used (cascading from the upper-left corner).

xx&, yy&

The width and height of the dialog. The size is specified in the same terms (pixels or dialog units) as specified in the DIALOG NEW statement.

If the default dialog style (or any other dialog style that includes the %WS_CAPTION style) is used, the width and height parameters specify the client size only, and this does not include any caption and border dimensions.

If the style does not include %WS_CAPTION, the width and height specify the overall dialog size, including the caption and border, if any.

Note that %WS_CAPTION is a combination of the %WS_BORDER and %WS_DLGFRAME styles. The default dialog style includes %WS_BORDER and %WS_DLGFRAME styles, so it implicitly includes the %WS_CAPTION style.

style&

An optional bitmask describing how the dialog should be displayed. default style of &H084C000D4& is made up %DS_3DLOOK, %DS_SETFONT, %DS_MODALFRAME, %DS_NOFAILCREATE, %WS_BORDER, %WS_CLIPSIBLINGS, %WS_DLGFRAME and %WS_POPUP. used if parameter omitted from statement completely. For example:

DIALOG NEW 0, "Dialog Title",,, 100, 200,, TO hDlg

Custom style values replace the default values. That is, they are not additional to the default style values - your code must specify all necessary style parameters (with the exception of %DS_NOFAILCREATE, %DS_SETFONT and %DS_3DLOOK, which are automatically added into the style& parameter by ScharfBASIC).

This also applies to the extended styles parameter - if your code specifies a custom primary style, the default extended style will no longer be in effect either. In this case, an explicit extended style may also need to be added to the DIALOG NEW statement if an explicit primary style is specified.

The primary style& value can be a combination of any values below, combined together with the OR operator to form a bitmask:

%DS_3DLOOK Give the dialog box a non-bold font, and draw three-dimensional borders around controls in the dialog box. The %DS_3DLOOK style is not required by applications marked with #OPTION VERSION4 or #OPTION VERSION5 ; as Windows automatically applies the 3D appearance. DDT dialogs are always created with this style. (default)

%DS_3DLOOK

Give the dialog box a non-bold font , and draw three-dimensional borders around controls in the dialog box. The %DS_3DLOOK style is not required by applications marked with #OPTION VERSION4 or #OPTION VERSION5 ; as Windows automatically applies the 3D appearance. DDT dialogs are always created with this style. (default)

%DS_ABSALIGN

Indicate that the coordinates of the dialog box are screen coordinates; otherwise, Windows assumes they are client coordinates.

%DS_CENTER

Center the dialog box in the working area (the area not obscured by the task bar and system tray). This is the default if x& and y& are not specified.

%DS_CENTERMOUSE

Center the mouse cursor in the dialog box when the dialog is initially created.

%DS_CONTEXTHELP

Include a question mark in the title bar of the dialog box. When the user clicks the question mark, the cursor changes to a question mark with a pointer. If the user then clicks a control in the dialog box, the dialog callback receives a %WM_HELP message. This style cannot be used with the %WS_MAXIMIZEBOX and %WS_MINIMIZEBOX styles. Also see %WS_EX_CONTEXTHELP.

%DS_CONTROL

Create a dialog that works as a child control of another dialog, smoothing the keyboard focus interface across the two dialogs when the TAB key or control accelerators are used. Typically used for dialogs that form the "pages" for tab controls and property-sheets.

%DS_MODALFRAME

Create a dialog box with a modal dialog-box frame that can be combined with a title bar and System menu by specifying the %WS_CAPTION and %WS_SYSMENU styles. (default)

%DS_NOFAILCREATE

The dialog is created regardless of any errors that may occur during the creation phase. DDT dialogs are always created with this style. (default)

%DS_SETFONT

The font to be used by a DDT dialog and its controls can be predetermined with the DIALOG DEFAULT FONT statement. If the DIALOG DEFAULT FONT statement is not used, the default font (MS Sans Serif, 8 point) is used. The size of the dialog font proportionately affects the conversion of dialog units values into pixels, so an increase in default font size will automatically create a larger dialog, even through the dialog dimensions have remained constant. As child controls are added to a %DS_SETFONT dialog, they will be sent a %WM_SETFONT message to ensure they also make use of the specified dialog font. DDT dialogs are always created with this style. (default)

%DS_SETFOREGROUND

Bring the dialog box to the foreground. Internally, Windows calls the SetForegroundWindow API function for the dialog box.

%DS_SYSMODAL

Create a system-modal dialog box. This style causes the dialog box to have the %WS_EX_TOPMOST style, but otherwise has no effect on the dialog box or the behavior of other applications and windows when the dialog box is displayed.

%WS_BORDER

Create a dialog that has a thin-line border.

%WS_CAPTION

Create a dialog that has a title bar. Includes the %WS_BORDER and %WS_DLGFRAME styles. When this style is used, the xx& and yy& parameters specify the size of the client area of the dialog; otherwise, they specify the outer dimensions of the dialog. (default)

%WS_CHILD

Create a child dialog. Cannot be used with the %WS_POPUP style. Typically used with %DS_CONTROL for tab control and property sheet "pages".

%WS_CLIPCHILDREN

Exclude the area occupied by child controls when drawing occurs on the dialog background. FRAME and LINE controls on a dialog with this style usually use the extended style %WS_EX_TRANSPARENT so the background of those controls is drawn by the dialog before the controls are drawn. %WS_CLIPCHILDREN is commonly used to reduce redraw flicker when a %WS_THICKFRAME style dialog is being resized.

%WS_CLIPSIBLINGS

Child controls are clipped (not overdrawn) by one another when the dialog window is repainted. (default)

%WS_DISABLED

Create a dialog that is initially disabled. A disabled dialog cannot receive input from the user.

%WS_DLGFRAME

Create a window that has a border of the style typically used with dialog boxes. (default)

%WS_HSCROLL

Dialog contains a horizontal scroll bar.

%WS_ICONIC

Create a dialog that is initially minimized, the same as the %WS_MINIMIZE style.

%WS_MAXIMIZE

Create a dialog that is initially maximized.

%WS_MAXIMIZEBOX

Create a dialog that has a Maximize button. Use with the %WS_SYSMENU style.

%WS_MINIMIZE

Create a dialog that is initially minimized, the same as the %WS_ICONIC style.

%WS_MINIMIZEBOX

Create a dialog that has a Minimize button. Use with the %WS_SYSMENU style.

%WS_OVERLAPPED

Create an overlapped window. An overlapped window has a title bar (caption) and a border. Synonym of the obsolete style %WS_TILED.

%WS_OVERLAPPEDWINDOW

Combination style producing an overlapping dialog. Comprises %WS_CAPTION, %WS_SYSMENU, %WS_THICKFRAME, %WS_MINIMIZEBOX, %WS_MAXIMIZEBOX, and %WS_OVERLAPPED styles.

%WS_POPUP

Create a popup dialog. When used by itself, a flat dialog is created with no caption or borders. Combine with %DS_MODALFRAME to create a 3D border. A popup dialog can overlap another window or dialog. (default)

%WS_POPUPWINDOW

Create a popup dialog but with a border and system menu. Comprises %WS_BORDER, %WS_POPUP and %WS_SYSMENU. Combine %WS_POPUPWINDOW with %WS_CAPTION to make the Window menu visible.

%WS_SYSMENU

Create a dialog that has a System-menu box in its title bar. Must be used with the %WS_CAPTION style.

%WS_THICKFRAME

Create a dialog that has a sizing border. That is, the dialog will be resizable.

%WS_VSCROLL

Dialog contains a vertical scroll bar. Also see %WS_EX_LEFTSCROLLBAR.

exstyle&

An optional extended style bitmask describing how the dialog should be displayed. The default extended dialog style comprises %WS_EX_LEFT with %WS_EX_LTRREADING and %WS_EX_RIGHTSCROLLBAR. The default extended style is used only if there are no explicit primary or extended styles parameters in the DIALOG NEW statement.

An explicit extended style value can be a combination of any values below, combined together with the OR operator to form a bitmask:

%WS_EX_ACCEPTFILES

The dialog accepts drag+drop files. The dialog Callback Function receives a %WM_DROPFILES message when files have been dropped onto the dialog.

%WS_EX_APPWINDOW

Force a top-level dialog onto the application taskbar when the window is minimized.

%WS_EX_CLIENTEDGE

Dialog has a border with a sunken edge.

%WS_EX_CONTEXTHELP

Include a question mark in the title bar of the dialog. When the user clicks the question mark, the cursor changes to a question mark with a pointer. If the user then clicks a child window, the child receives a %WM_HELP message. Also see %DS_CONTEXTHELP.

%WS_EX_CONTROLPARENT

The user may navigate among the child dialogs of the window by using the TAB key. See %DS_CONTROL.

%WS_EX_LEFT

Dialog has generic "left-aligned" properties. (default)

%WS_EX_LEFTSCROLLBAR

If present, the vertical scroll bar is positioned to the left of the client area. Also see %WS_VSCROLL.

%WS_EX_LTRREADING

Display the dialog text using Left to Right reading-order properties. (default)

%WS_EX_NOPARENTNOTIFY

Suppress %WM_PARENTNOTIFY messages when dialog is created or destroyed.

%WS_EX_OVERLAPPEDWINDOW

Comprised of the %WS_EX_CLIENTEDGE and %WS_EX_WINDOWEDGE styles.

%WS_EX_PALETTEWINDOW

Comprised of the %WS_EX_WINDOWEDGE, %WS_EX_TOOLWINDOW and %WS_EX_TOPMOST styles.

%WS_EX_RIGHT

Dialog has generic "right-aligned" properties that depend on the window class. This style has an effect only if the shell language is Hebrew, Arabic, or another language that supports reading order alignment. Otherwise, the style is ignored.

%WS_EX_RIGHTSCROLLBAR

If present, the vertical scroll bar is positioned to the right of the client area. See %WS_VSCROLL. (default)

%WS_EX_RTLREADING

If the shell language is Hebrew, Arabic, or another language that supports reading order alignment, the dialog text is displayed using Right to Left reading-order properties. For other languages, the style is ignored.

%WS_EX_STATICEDGE

Dialog has a 3D border. Primarily used for dialogs that do not require user-input.

%WS_EX_TOOLWINDOW

Create a tool window (a window intended to be used as a floating toolbar). A tool window has a shorter than normal caption area and the dialog caption is drawn using a smaller font. A tool window does not appear in the task bar, or in the window that appears when the user presses ALT+TAB. The hybrid versions of Windows (95/98/ME) may require this extended style to be added after creation, using the SetWindowLong API function.

%WS_EX_TOPMOST

Place dialog above all non-topmost windows and keep it above them, even while the dialog is deactivated.

%WS_EX_TRANSPARENT

Controls/windows beneath the dialog are drawn before the dialog is drawn. The dialog is deemed transparent because elements behind the dialog have already been painted - the dialog itself is not drawn differently. True transparency is achieved by using Regions - see MSDN for more information.

%WS_EX_WINDOWEDGE

Dialog has a border with a raised edge.

Long-integer Variable where the Windows window handle of the dialog is stored after it has been created and assigned by Windows. This handle should be used with subsequent DIALOG and CONTROL statements, and may be directly used with Windows API calls.

If the dialog could not be created (i.e., due to low Windows resources), zero is returned.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD
  • DIALOG DOEVENTS
  • DIALOG END
  • DIALOG HIDE
  • DIALOG MAXIMIZE
  • DIALOG MINIMIZE
  • DIALOG NONSTABLE
  • DIALOG NORMALIZE
  • DIALOG SET COLOR
  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • DIALOG STABILIZE
  • DIALOG SHOW STATE
  • TXT pseudo-object

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x20ca54
call   0x205b90
fild   DWORD PTR ds:0x20ca60
call   0x205a58
fild   DWORD PTR ds:0x20ca64
call   0x205a58
push   0x2100000
call   0x204d24
call   0x2018d8
mov   DWORD PTR [ebp-0xa8],eax
call   0x205ad8


DIALOG NONSTABLE - ScharfBASIC Help

DIALOG NONSTABLE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG NONSTABLE hDlg

Description

The Dialog identified by the handle hDlg is made non-stable, meaning that it can be closed by the user. If there is a system menu, the close option and the close box are enabled. The ALT-F4 close key is also enabled. This is the default mode of operation.

See Also

  • DIALOG STABILIZE


DIALOG NORMALIZE - ScharfBASIC Help

DIALOG NORMALIZE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG NORMALIZE hDlg

Description

The Dialog identified by the handle hDlg is made visible at its normal size and position.

See Also

  • DIALOG HIDE
  • DIALOG MAXIMIZE
  • DIALOG MINIMIZE
  • DIALOG SHOW STATE


DIALOG PIXELS - ScharfBASIC Help

DIALOG PIXELS

Convert pixels (device units) into

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG PIXELS hDlg , x& , y& TO UNITS xx& , yy&

Description

The pixel values specified in the x& and y& variables are converted into dialog units, based on the default font of the dialog specified by hDlg . The resulting value in dialog units is stored in the xx& and yy& variables.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • DIALOG GET CLIENT
  • DIALOG GET LOC
  • DIALOG GET SIZE
  • DIALOG SET LOC
  • DIALOG SET SIZE
  • DIALOG UNITS


DIALOG POST - ScharfBASIC Help

DIALOG POST

Place a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG POST hDlg , Msg& , wParam& , lParam&

Description

DIALOG POST places the message in the message queue and returns immediately. The message is processed by the dialog at a later time, when it reads the message from the queue.

This behavior is quite different to the DIALOG SEND statement, which forces the control to process the message immediately before returning. Since DIALOG POST is an asynchronous operation, it is not possible to retrieve a return code from the message.

hDlg refers to the target dialog.

Msg& is the message you want to post to the dialog.

wParam& is the first message parameter. lParam& is the second message parameter. The values of wParam& and lParam& are message-dependent. By Default, ScharfBASIC passes these parameters BYVAL. If the target dialog is expected to alter the values held by variables passed in the wParam& and lParam& parameters, pass them using VARPTR() or the changes will likely be discarded.

Note that the address of the data must remain valid until after the dialog has processed the message and accessed the data. In this case, using STATIC or GLOBAL variables can be very important or a General Protection Fault (GPF) may occur (that is, if the variables have gone out of scope by the time the message is processed).

An example of posting the addresses of variables to a dialog:

' Sel1& and Sel2& must be STATIC or GLOBAL

DIALOG POST CB.HNDL, %WM_USER + 999&, VARPTR(Sel1&), VARPTR(Sel2&)

DIALOG POST returns immediately after the placing the message in the queue.

To post a custom message to a dialog, use a message value in the range of (%WM_USER + 500) to (%WM_USER + &H07FFF), or use the RegisterWindowMessage API to obtain a unique message value from the operating system. Using messages with a numeric value of less then %WM_USER + 500 may conflict with Windows Common Control messages.

See Also

  • Dynamic Dialog Tools
  • CB Callback functions
  • CONTROL POST
  • CONTROL SEND
  • DIALOG SEND


DIALOG REDRAW - ScharfBASIC Help

DIALOG REDRAW

Signal a designated

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG REDRAW hDlg

Description

DIALOG REDRAW invalidates the target dialog area, and signals a redraw/repaint to occur immediately, even if there are pending messages in the message queue.

hDlg refers to the dialog that is to be redrawn.

Restrictions

It is not advisable to use DIALOG REDRAW or CONTROL REDRAW statements within the %WM_PAINT and associated message handling code, or an infinite redraw loop could occur.

See Also

  • Dynamic Dialog Tools
  • CONTROL REDRAW
  • CONTROL SET COLOR
  • DIALOG SET COLOR


DIALOG SEND - ScharfBASIC Help

DIALOG SEND

Send a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SEND hDlg , msg& , wParam& , lParam& [TO lResult& ]

Description

hDlg identifies the dialog which should receive the message specified by msg& . wParam& is the first message parameter, and lParam& is the second message parameter.

By default, ScharfBASIC passes these parameters BYVAL. If the target dialog is expected to return or alter the values passed in the wParam& and lParam& parameters, pass them using VARPTR() or the return values will be discarded. For example:

DIALOG SEND CB.HNDL, %WM_USER, VARPTR(Param1&), VARPTR(Param2&)

The return value may be returned and stored in the variable lResult& after the message was processed by the dialog.

Restrictions

If the target dialog was not created by the same thread, the DIALOG SEND statement becomes blocked until the thread processes the message. The InSendMessage API function will return TRUE (non-zero) if the callback code is currently processing a message from a separate thread.

To send a custom message to a dialog, use a message value in the range of (%WM_USER + 500) to (%WM_USER + &H07FFF), or use the RegisterWindowMessage API to obtain a unique message value from the operating system.

A dialog callback can send a message to its own dialog, but care should be taken not to create an infinite loop. Also, if DIALOG SEND sends a message that arrives back in the same callback as the message originated, care should be exercised to ensure that critical STATIC and GLOBAL variables are not unexpectedly altered by the second message processing code in the callback. This is known as re-entrant code design.

See Also

  • Dynamic Dialog Tools
  • CONTROL SEND


DIALOG SET CLIENT - ScharfBASIC Help

DIALOG SET CLIENT

Change the size of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET CLIENT hDlg , x& , y&

Description

hDlg refers to the handle of the dialog to change. x& and y& specify the new width and height of the dialog client area. x& and y& are specified in dialog units or pixels , depending upon the system used when the dialog was created.

The dialog client size may be smaller than total size, depending on the type of borders used. The client area is the part below the dialog caption, and an eventual menu, where controls can be placed.

See Also

  • Dynamic Dialog Tools
  • DIALOG NEW
  • DIALOG PIXELS
  • DIALOG UNITS
  • DIALOG GET CLIENT
  • DIALOG GET LOC
  • DIALOG GET SIZE
  • DIALOG SET LOC
  • DIALOG SET SIZE


DIALOG SET COLOR - ScharfBASIC Help

DIALOG SET COLOR

Set the background

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET COLOR hDlg , foreclr& , backclr&

Description

hDlg identifies the dialog to colorize.

Color values foreclr& and backclr& must be in the range of &H0 to &H00FFFFFF, while the value -1& is used to specify the system default color. RGB can be a useful function to derive a 32-bit color value from discrete Red, Green and Blue values.

foreclr&

In the current implementation of ScharfBASIC, the dialog foreground color parameter foreclr& is not used, but the syntax is retained for future implementation. It is recommended that the foreground color parameter be set to -1&.

backclr&

In 16-bit or greater color-depth mode, the RGB color specified is used when the background of the dialog is drawn. If backclr& = -1&, the default dialog background color is used. If backclr& = -2&, the dialog background is not painted, allowing the content behind the dialog to become visible through the dialog.

In 16-bit or greater color-depth mode, the specified RGB color is used when the background of the dialog is drawn. However, in 8-bit (256-color) mode, the color system works quite differently. Behind the scenes in Windows, the base system palette usually contains 20 solid colors that are not dithered when drawn on a dialog background. These solid-colors are ideal for background colors with DDT dialogs in 256-color mode.

Conversely, when using a non-solid RGB color value, Windows will dither (approximate) the color to draw the dialog, using combinations of two or more colors. This usually produces an undesirable pattern effect.

To avoid these problems when in 256-color mode, dialogs should either be colored with one of the 20 standard (solid) system colors, or the default color should be used instead. ScharfBASIC includes the following 10 built-in equates for help with the selection of a standard solid color:

%RGB_BLACK %RGB_BLUE %RGB_GREEN %RGB_CYAN %RGB_RED

% RGB_ MAGENTA %RGB_YELLOW %RGB_WHITE %RGB_GRAY %RGB_LIGHTGRAY

Many non standard colors are also built into the compiler, see the Built In RGB Color Equates topic for a complete list.

If you prefer to disable color in 256-color mode, the number of colors can be easily tested with the following code:

' Determine number of colors

LOCAL hDC AS DWORD, iColors AS LONG

hDC = GetWindowDC(GetDeskTopWindow())

iColors = 2& ^ (GetDeviceCaps(hDC, %BITSPIXEL) * GetDeviceCaps(hDC, %PLANES))

ReleaseDC GetDeskTopWindow(), hDC

IF iColors > 256 THEN _

DIALOG SET COLOR hDlg, -1, RGB(0,100,192)

In 256-color mode on most computers, the values of the standard 20 system colors can be found by requesting the first and last 10 (0 to 9, and 246 to 255 inclusive) entries from the GetSystemPaletteEntries API function, as follows:

' Fill array with solid colors

DIM hDC AS DWORD, Cols AS LONG, x AS LONG

hDC = GetWindowDC(GetDesktopWindow)

Cols = GetDeviceCaps(hDC, %NUMRESERVED)

REDIM lp(1 TO Cols) AS LONG

x& = GetSystemPaletteEntries(hDC, 0, Cols \ 2, BYVAL VARPTR(lp(1)))

x& = GetSystemPaletteEntries(hDC, 256 - x&, Cols - x&, BYVAL VARPTR(lp(x& + 1)))

ReleaseDc GetDesktopWindow, hDC

' Array lp() now contains the solid color table

For more information on working with palettes in 256-color mode, please consult WIN32.HLP or visit http://msdn.microsoft.com.

When dynamically changing colors of a dialog from within a callback (i.e., after the DIALOG SHOW statement), a DIALOG SET COLOR statement should be immediately followed by an explicit DIALOG REDRAW statement.

Without a forced dialog redraw, the dialog background color change may not become evident to the user until the dialog is eventually repainted in the normal course of user interaction. For example, a normal repaint may only occur if the dialog becomes obscured and then uncovered by another window. Ensuring a timely repaint of the dialog will guarantee the dialog maintains an up-to-date appearance at all times.

See Also

  • Built In RGB Color Equates
  • Dynamic Dialog Tools
  • CONTROL REDRAW
  • DIALOG REDRAW
  • CONTROL SET COLOR
  • DIALOG SET ICON


DIALOG SET ICON - ScharfBASIC Help

DIALOG SET ICON

Change both the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET ICON hDlg , newicon$

Description

DIALOG SET ICON changes both the small icon (as used in the dialog caption bar), and the large icon (visible in the icon task list presented during ALT+TAB task switching).

Handle of the dialog that is to have its icon changed.

newicon$

A string expression which specifies the name of the icon in the resource file . If the icon resource uses an integral identifier, newicon$ should begin with a Number symbol (#), followed by the integral identifier in ASCII format. For example, "#998". Otherwise, the text identifier name should be used.

Restrictions

DIALOG SET ICON cannot use bitmap files. 32x32 pixel icons produce the most visually pleasing results.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD IMAGE
  • CONTROL ADD IMAGEX
  • CONTROL ADD IMGBUTTON
  • CONTROL ADD IMGBUTTONX
  • CONTROL SET IMAGEX
  • CONTROL SET IMGBUTTON
  • CONTROL SET IMGBUTTONX
  • DIALOG SET TEXT


DIALOG SET LOC - ScharfBASIC Help

DIALOG SET LOC

Change the position of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET LOC hDlg , x& , y&

Description

hDlg identifies the dialog to reposition. x& and y& specify the new coordinates of the upper-left corner of the target dialog. x& and y& are the horizontal and vertical coordinates respectively. If the dialog was created with the PIXELS option in the DIALOG NEW statement, the values are returned in pixel units . If the UNITS option was used (or no scaling option was specified), the values are returned in dialog units .

If the dialog has a parent , the coordinates are relative to the upper-left corner of the parent dialog client area . Otherwise, the coordinates are relative to the upper-left corner of the desktop workspace.

See Also

  • Dynamic Dialog Tools
  • DIALOG GET CLIENT
  • DIALOG GET LOC
  • DIALOG GET SIZE
  • DIALOG PIXELS
  • DIALOG SET SIZE
  • DIALOG UNITS


DIALOG SET SIZE - ScharfBASIC Help

DIALOG SET SIZE

Change the size of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET SIZE hDlg , nWide& , nHigh&

Description

hDlg identifies the dialog to resize. nwide& and nhigh& specify the new width and height, in dialog units , for the dialog. If the dialog was created with the PIXELS option in the DIALOG NEW statement, the values are set in pixel units . If the UNITS option was used (or no scaling option was specified), the values are set in dialog units.

See Also

  • Dynamic Dialog Tools
  • DIALOG GET CLIENT
  • DIALOG GET LOC
  • DIALOG GET SIZE
  • DIALOG PIXELS
  • DIALOG SET CLIENT
  • DIALOG SET LOC
  • DIALOG UNITS

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,DWORD PTR [ebp-0xa8]
mov   eax,0x80000000
fild   DWORD PTR ds:0x20ca54
fild   DWORD PTR ds:0x20ca58
call   0x203ec5
call   0x205aac


DIALOG SET TEXT - ScharfBASIC Help

DIALOG SET TEXT

Set the text in a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET TEXT hDlg , titletext$

Description

The caption of the dialog or window specified by hDlg is set with the DIALOG SET TEXT statement. For DDT dialogs, hDlg is the dialog handle returned by the DIALOG NEW statement. In a dialog Callback Function, the CB.HNDL function will return the parent dialog handle and this can also be used with DIALOG SET TEXT.

titletext$

The caption text is specified in titletext$ . If the window or dialog is invalid, the operation is ignored.

Restrictions

hDlg is a dialog or window handle, so DIALOG SET TEXT works with both DDT dialogs and conventional windows and dialogs.

See Also

  • Dynamic Dialog Tools
  • CB Callback functions
  • CONTROL GET TEXT
  • CONTROL SET TEXT
  • DIALOG GET TEXT
  • DIALOG NEW
  • DIALOG SET ICON

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,DWORD PTR [ebp-0xa8]
mov   edx,0x20ca54
call   0x205b64
call   0x204d04
call   0x20398e
call   0x205aac


DIALOG SET USER - ScharfBASIC Help

DIALOG SET USER

Set a value in the user data area of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SET USER hDlg , index& , usrval&

Description

Each DDT dialog has a user data area consisting of eight Long-integer values which may be used at the programmer's discretion to save relevant data. DIALOG SET USER allows one of the values to be set, based upon the index parameter value (1 through 8).

hDlg refers to the dialog that owns the user data area.

index& is the index number of the user data value to set, in the range 1 to 8 inclusive.

usrval& is the Long-integer data value to store in the user data area.

Restrictions

Data in the user data area is lost when the dialog is destroyed. The data area is completely separate from the %GWL_USERDATA area maintained by Windows.

See Also

  • Dynamic Dialog Tools
  • COMBOBOX SET USER
  • CONTROL GET USER
  • CONTROL SET USER
  • DIALOG GET USER
  • LISTBOX GET USER
  • LISTBOX SET USER
  • LISTVIEW GET USER
  • LISTVIEW SET USER
  • TREEVIEW GET USER
  • TREEVIEW SET USER


DIALOG SHOW MODAL - ScharfBASIC Help

DIALOG SHOW MODAL

Display and activate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SHOW MODAL hDlg [[,] CALL callback ] [TO lResult& ]

Description

hDlg identifies a dialog created using DIALOG NEW . You can specify a Callback Function for all dialog messages using the CALL keyword, followed by the name of the Callback Function.

When a modal dialog is displayed, the DIALOG SHOW MODAL statement is blocked until the dialog is destroyed with DIALOG END. During the duration of the dialog, the Callback Function code is executed in response to messages for the dialog.

If a parent was specified in the DIALOG NEW statement, the parent window is disabled until the modal dialog is destroyed.

callback

If specified, dialog messages are routed to the nominated Callback Function.

Just before a dialog is initially displayed, the dialog Callback Function is sent a %WM_INITDIALOG message. By processing this message within the dialog callback, an application can take the opportunity to load controls with data before the controls become visible to the user. For example, a list box control could be loaded with a list of items so that the control appears populated with data when initially displayed.

The nominated callback function name must be a CALLBACK FUNCTION or a compile-time Error 547 ("Callback function required") will occur.

lResult&

When the modal dialog is destroyed using the DIALOG END statement, the resulting value is assigned to the lResult& variable, if specified. lResult& is excluded from becoming a Register variable by the compiler, since this value can be assigned from outside of the function containing the DIALOG SHOW MODAL statement, and this may only be performed with a memory variable. However, if the target variable is explicitly declared as a register variable, ScharfBASIC raises a compile-time Error 491 ("Invalid register variable").

See Also

  • Dynamic Dialog Tools
  • DIALOG END
  • DIALOG NEW
  • DIALOG SHOW MODELESS

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x201083
ret   0x10


DIALOG SHOW MODELESS - ScharfBASIC Help

DIALOG SHOW MODELESS

Display and activate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SHOW MODELESS hDlg [[,] CALL callback ] [TO lResult& ]

Description

hDlg identifies a dialog created using DIALOG NEW . You can specify a Callback Function for all dialog messages, using the CALL keyword followed by the name of the Callback Function.

Once a modeless dialog is displayed, the DIALOG SHOW MODELESS statement completes, and execution of the code continues. At the same time, the dialog can receive messages and process them via the Callback Function. A DIALOG SHOW MODELESS statement is usually followed by a message pump loop. For more information, please refer to the examples under DIALOG DOEVENTS .

callback

If specified, dialog messages are routed to the nominated Callback Function.

The nominated callback function name must be a CALLBACK FUNCTION or a compile-time Error 547 ("Callback function required") will occur.

lResult&

When the modeless dialog is destroyed using the DIALOG END statement, the resulting value is assigned to the lResult& variable , if specified. lResult& is excluded from becoming a Register variable by the compiler, since this value can be assigned from outside of the function containing the DIALOG SHOW MODELESS statement, and this may only be performed with a memory variable. However, if the target variable is explicitly declared as a register variable, ScharfBASIC raises a compile-time Error 491 ("Invalid register variable").

See Also

  • Dynamic Dialog Tools
  • DIALOG DOEVENTS
  • DIALOG END
  • DIALOG NEW
  • DIALOG SHOW MODAL


DIALOG SHOW STATE - ScharfBASIC Help

DIALOG SHOW STATE

Change the visible state of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG SHOW STATE hDlg , showstate& [TO lResult& ]

Description

DIALOG SHOW STATE changes the visible state of the dialog identified by hDlg .

showstate& can be one of the following values:

%SW_HIDE

Hide the dialog.

%SW_MAXIMIZE

Maximize the specified dialog.

%SW_MINIMIZE

Minimize the specified dialog.

%SW_RESTORE

Activate and display the dialog. If the dialog is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized dialog.

%SW_SHOW

Activate the dialog and displays it in its current size and position.

%SW_SHOWMAXIMIZED

Synonym of %SW_MAXIMIZE.

%SW_SHOWMINIMIZED

Activate the dialog and minimize it.

%SW_SHOWNA

Display the dialog in its current state without activating it. The currently active window remains active.

%SW_SHOWNOACTIVATE

Display the dialog in its most recent size and position without activating it. The currently active window remains active.

%SW_SHOWNORMAL

Activate and display the dialog. If the dialog is minimized or maximized, Windows restores it to its original size and position.

If the optional lResult& parameter is used, it will contain the previous visibility state. If lResult& is set to TRUE (non-zero), the dialog was visible. If the dialog was previously hidden, lResult& is set to FALSE (zero).

Restrictions

In previous versions of ScharfBASIC, the DIALOG SHOW STATE was not permitted to be executed before a DIALOG SHOW MODAL or DIALOG SHOW MODELESS statement had been executed for that specific dialog. Starting with this version of ScharfBASIC, DIALOG SHOW STATE may be executed before or after the dialog is activated with DIALOG SHOW MODAL or DIALOG SHOW MODELESS statement.

When utilized prior to dialog activation, the attributes %SW_HIDE, %SW_MAXIMIZE, and %SW_MINIMIZE are remembered for use when activated. All other possible attributes are translated to the standard %SW_SHOW. Generally speaking, it is unwise to use %SW_HIDE with a modal dialog.

DIALOG SHOW STATE can be used to show a dialog before the message pump for a modeless dialog begins operating (i.e., after the DIALOG SHOW MODELESS statement, etc). However, until the message pump begins its operation, the dialog may not be drawn or displayed completely.

For more information on message pumps, see DIALOG DOEVENTS and DIALOG SHOW MODELESS .

See Also

  • Dynamic Dialog Tools
  • CONTROL SHOW STATE
  • DIALOG DOEVENTS
  • DIALOG HIDE
  • DIALOG MAXIMIZE
  • DIALOG MINIMIZE
  • DIALOG NONSTABLE
  • DIALOG NORMALIZE
  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • DIALOG STABILIZE


DIALOG STABILIZE - ScharfBASIC Help

DIALOG STABILIZE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG STABILIZE hDlg

Description

The Dialog identified by the handle hDlg is stabilized, meaning that it cannot be closed by the user. If there is a system menu, the close option and the close box are grayed. The ALT-F4 close key is disabled. This allows you to be certain that your operations on the dialog can be completed. When a dialog is stabilized, only DIALOG END or program termination will close it.

See Also

  • DIALOG END
  • DIALOG NONSTABLE


Dialog Styles - ScharfBASIC Help

Dialog Styles

Like control styles , DDT provides a default style for a dialog window, if the DIALOG NEW statement does not specify a specific style parameters.

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

The default style comprises the combination of %WS_POPUP, %WS_CAPTION, %DS_SETFONT, %DS_NOFAILCREATE, %DS_MODALFRAME, and %DS_3DLOOK. These equates are equivalent to a style of &H080C00D4. The extended style default is zero.

If you explicitly specify %WS_CAPTION in your DIALOG NEW statement, DDT will interpret the width and height values as client dimensions, rather then as overall dialog dimensions. This can be very useful for the times when you need to build a dialog with particular client dimensions.

You can create dialogs using combinations of the following styles:

Dialog has a thin-line border.

Dialog has a title bar (includes the %WS_BORDER style).


DIALOG UNITS - ScharfBASIC Help

DIALOG UNITS

Convert

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIALOG UNITS hDlg , x& , y& TO PIXELS xx& , yy&

Description

The dialog units specified in the x& and y& variables are converted into pixels, based on the default font of the dialog specified by hDlg . The resultant pixel values are stored in the xx& and yy& variables.

See Also

  • Dynamic Dialog Tools
  • CONTROL GET CLIENT
  • DIALOG GET CLIENT
  • DIALOG GET LOC
  • DIALOG GET SIZE
  • DIALOG PIXELS
  • DIALOG SET LOC
  • DIALOG SET SIZE


DISPLAY BROWSE - ScharfBASIC Help

DISPLAY BROWSE

Display a folder selection dialog to return the user's choice.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DISPLAY BROWSE [ hParent ], [ xpos& ], [ ypos& ], title$ , start$ , flags& TO folder$

See Also

  • DISPLAY COLOR
  • DISPLAY FONT
  • DISPLAY OPENFILE
  • DISPLAY SAVEFILE


DISPLAY COLOR - ScharfBASIC Help

DISPLAY COLOR

Display a color selection dialog to return the user's choice.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DISPLAY COLOR [hParent], [xpos&], [ypos&] , firstcolor& , custcolors , flags& TO colorval&

Description

If you offer the user the ability to create custom colors, it is suggested you retain the custcolors& UDT variable without change. It may then be used again on a later invocation of DISPLAY COLOR with the user's custom colors intact.

See Also

  • Built In RGB Color Equates
  • DISPLAY BROWSE
  • DISPLAY FONT
  • DISPLAY OPENFILE
  • DISPLAY SAVEFILE
  • RGB


DISPLAY FONT - ScharfBASIC Help

DISPLAY FONT

Display a font

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DISPLAY FONT [hParent], [xpos&], [ypos&], defname$ , defpoints& , defstyle& , flags & _
TO fontname$ , points& , style& [, colorval& , charset& ]

See Also

  • CONTROL SET FONT
  • DIALOG DEFAULT FONT
  • DISPLAY BROWSE
  • DISPLAY COLOR
  • DISPLAY OPENFILE
  • DISPLAY SAVEFILE
  • FONT END
  • FONT NEW
  • GRAPHIC SET FONT
  • XPRINT SET FONT


DISPLAY OPENFILE - ScharfBASIC Help

DISPLAY OPENFILE

Display an OpenFile selection dialog to return user choices.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DISPLAY OPENFILE [hParent], [xpos & ], [ypos & ] , title$ , folder$ , filter$ , _
start$ , defextn$ , flags & TO filevar$ [, countvar& ]
"BASIC" + CHR$(0) + "*.BAS" + CHR$(0)
CHR$("BASIC", 0, "*.BAS", 0)
CHR$("BASIC", 0, "*.BAS;*.INC;*.BAK", 0)

Description

The current default directory is never altered by this statement, even if the user changes the directory while searching for files.

See Also

  • DISPLAY BROWSE
  • DISPLAY COLOR
  • DISPLAY FONT
  • DISPLAY SAVEFILE


DISPLAY SAVEFILE - ScharfBASIC Help

DISPLAY SAVEFILE

Display a SaveFile selection dialog to return user choices.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DISPLAY SAVEFILE [hParent], [xpos & ], [ypos & ] , title$ , folder$ , filter$ , _
start$ , defext$ , flags & TO filevar$ [, countvar& ]
"BASIC" + CHR$(0) + "*.BAS" + CHR$(0)
CHR$("BASIC", 0, "*.BAS", 0)
CHR$("BASIC", 0, "*.BAS;*.INC;*.BAK", 0)

Description

The current default directory is never altered by this statement, even if the user changes the directory while searching for files.

See Also

  • DISPLAY BROWSE
  • DISPLAY COLOR
  • DISPLAY FONT
  • DISPLAY OPENFILE


Dynamic Dialog Tools - ScharfBASIC Help

Dynamic Dialog Tools

The following functions can be used to create GUI application interfaces:

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Attach a table of keyboard accelerators to a DDT dialog.

Define a Dialog /Control Callback Function block.

Return the numeric ID of the control sending a callback message .

Return the numeric notification message parameter.


Dynamic Dialog Tools (DDT) - ScharfBASIC Help

Dynamic Dialog Tools (DDT)

Welcome to ScharfBASIC's powerful and improved Dynamic Dialog Tools?. DDT allows a BASIC programmer to easily create a Graphical User Interface (GUI) for an application using simple BASIC statements. W

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

For programmers who are familiar with DDT, you will find that ScharfBASIC has expanded the DDT implementation even further in this version of ScharfBASIC, with advanced features such as User Data storage and accelerator tables.

This chapter describes ScharfBASIC's Dynamic Dialog Tools and how to easily create full-featured Graphical User Interfaces in your code.

Adding Controls to the Dialog


FONT END - ScharfBASIC Help

FONT END

Destroy a font when it is no longer needed.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FONT END fonthndl&

Description

When you have no further need for a font originally created with FONT NEW , you can destroy it and reclaim the memory space which was originally allocated for it.

If the specified font is still in use by a CONTROL , a Graphic Control , a Graphic Window , or an XPrint page, an error 5 (Illegal Function Call) will be generated. To avoid this error, you may restore the original default font with CONTROL/GRAPHIC/XPRINT SET FONT using a handle number of zero (0).

When your program ends, any existing fonts are automatically destroyed by ScharfBASIC.

See Also

  • CONTROL SET FONT
  • FONT NEW
  • GRAPHIC PRINT
  • GRAPHIC SET FONT
  • XPRINT
  • XPRINT SET FONT


FONT NEW - ScharfBASIC Help

FONT NEW

Create a new font for use with CONTROL

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

FONT NEW fontname$ [, points! , style& , charset& , pitch& , escapement& ] TO fhndl
Modern font (Pica, Courier...)

Description

This is the preferred method of creating and specifying fonts in ScharfBASIC. Using FONT NEW, you can create a group of fonts, in advance, and switch between them easily using CONTROL SET FONT , GRAPHIC SET FONT , and XPRINT SET FONT .

If the requested font is not available on the computer, Windows will search for a substitute font, which is similar to the attributes specified (CharSet, Font Family, etc.).

You may use the value zero (0) for any of the numeric parameters to designate that the compiler should use the default for that item. If parameters are missing, the compiler substitutes the default value for all remaining parameters.

See Also

  • CONTROL SET FONT
  • FONT END
  • GRAPHIC PRINT
  • GRAPHIC SET FONT
  • XPRINT
  • XPRINT SET FONT

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x202bc8
call   0x202b4b
mov   edx,0x203a60
call   0x202bc8
fild   DWORD PTR ds:0x203a6c
call   0x202a70
push   0x2000
call   0x201f5c
call   0x202c36
call   0x202a7c


GRAPHIC ARC - ScharfBASIC Help

GRAPHIC ARC

Draw an arc in the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC ARC ( x1! , y1! ) - ( x2! , y2! ), arcStart! , arcEnd! [, rgbColor& ]

Description

An arc is a section of a circle or an ellipse. To specify a particular arc, you would first define the full circle or ellipse of which it is a part, and then specify the points on the ellipse where the arc starts and stops.

The full circle or ellipse is defined by its bounding rectangle, which is defined as the smallest rectangle which can be drawn around the circle or ellipse. For example, if the circle is centered at position (400,400), with a radius of 100 pixels, the upper left corner ( x1! , y1! ) of the bounding rectangle is (300,300), and the lower right corner ( x2! , y2! ) is (500,500). The start point and end point of the arc are specified by their angle, which must be given in radians. A complete circle or ellipse is 2*pi radians. On a 12-hour clock-face, the values 0 and 2*pi both refer to the position of 3 o'clock, while the value 1*pi refers to the position of 9 o'clock. Other positions are specified by a radian value relative to these. In ScharfBASIC, arcs are always drawn counter-clockwise from the starting point to the ending point.

Prior to any graphical operations, the graphic target must first be selected with GRAPHIC ATTACH . The Coordinates are specified in the same terms (pixels or dialog units) as the parent dialog (or world coordinates, if those were chosen with GRAPHIC SCALE ). Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE . Because of the nature of an arc, GRAPHIC ARC neither uses, nor updates, GRAPHIC POS (last point referenced).

x1! , y1!

The upper left corner of the bounding rectangle of the full circle or ellipse.

x2! , y2!

The lower right corner of the bounding rectangle of the full circle or ellipse.

ArcStart!

The starting angle of the arc, in radians, from 0 to 2*pi.

ArcEnd!

The ending angle of the arc, in radians, from 0 to 2*pi radians. Note that arcs are always drawn counter-clockwise from arcStart! to arcEnd! . Compared with a 12-hour clock-face, 0 or 2*pi radians is at 3 o'clock, and 1*pi radians is at 9 o'clock.

rgbColor&

Optional RGB color for the arc. If omitted (or -1), the current foreground color for the graphic window is used.

See Also

  • Built In RGB Color Equates
  • GRAPHIC ATTACH
  • GRAPHIC COLOR
  • GRAPHIC ELLIPSE
  • GRAPHIC PIE
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH


GRAPHIC ATTACH - ScharfBASIC Help

GRAPHIC ATTACH

Select the graphic target (

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC ATTACH hWin , id [, REDRAW]

Description

This statement chooses a graphic target. All further graphic operations will be directed to this target until another GRAPHIC ATTACH or GRAPHIC DETACH statement is executed, or the graphic target is deleted. All ScharfBASIC graphical displays are persistent -- they will be automatically redrawn even if minimized or temporarily covered by another window.

By default, all graphic operations are displayed immediately upon execution of a graphic statement. In many cases, this is a good choice, because the display is always up-to-date. However, as the complexity of graphic operations increases, this continuous update process does not afford the best performance. It is usually better to use the REDRAW option described below, as it will generally provide a dramatic improvement in overall performance.

Only one thread may be attached to a particular Graphic Target at a time. An attempt to attach more than one will generate an Illegal Function Call Error 5 .

Handle of the GRAPHIC WINDOW , DIALOG , or BITMAP to be used with GRAPHIC statements.

The control id, if the target is a GRAPHIC CONTROL , or zero if the target is a GRAPHIC WINDOW or GRAPHIC BITMAP.

REDRAW

This option can provide a dramatic improvement in the execution speed of graphic statements, as it eliminates repetitive updates to the display. If this option is included, all drawing statements are buffered until a GRAPHIC REDRAW statement is executed, or the operating system chooses to update the target window. Without REDRAW, all graphical statements (Line, Box, Print, etc.) are performed immediately. However, in most cases, it's better to defer the display until a number of statements have been performed.

While the REDRAW option defers update of the display, it does not guarantee that no interim updates will be performed. There are times when the operating system, or other factors, may intervene. If update must be suppressed until complete, you should create your graphic invisibly using a GRAPHIC BITMAP, then display it by using GRAPHIC COPY .

Usage Examples

  1. ' Draw a blue gradient fill.
  2. ' Each line is displayed as it's drawn.
  3. GRAPHIC ATTACH hDlg, %IDC_GRAPHIC1
  4. FOR y& = 0 TO 255
  5. GRAPHIC LINE (0, y&) - (255, y&), RGB(0, 0, y&)
  6. NEXT
  7. ' Draw a buffered, blue gradient fill.
  8. ' Nothing is displayed before GRAPHIC REDRAW,
  9. ' this enhancing performance dramatically.
  10. GRAPHIC ATTACH hDlg, %IDC_GRAPHIC2, REDRAW
  11. GRAPHIC REDRAW

See Also

  • CONTROL ADD GRAPHIC
  • GRAPHIC BITMAP LOAD
  • GRAPHIC BITMAP NEW
  • GRAPHIC DETACH
  • GRAPHIC WINDOW


GRAPHIC BITMAP END - ScharfBASIC Help

GRAPHIC BITMAP END

Close the selected graphic bitmap.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC BITMAP END

Description

You must close every memory bitmap (that was created with GRAPHIC BITMAP LOAD or GRAPHIC BITMAP NEW ) when you are finished using them for graphical operations. To close a bitmap, select it with the GRAPHIC ATTACH statement, then execute GRAPHIC BITMAP END.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC BITMAP LOAD
  • GRAPHIC BITMAP NEW


GRAPHIC BITMAP LOAD - ScharfBASIC Help

GRAPHIC BITMAP LOAD

Create a memory bitmap and load an image into it.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC BITMAP LOAD BmpName$ , nWidth& , nHeight& [, stretch& ] TO hBmp???

Description

GRAPHIC BITMAP LOAD creates a new memory bitmap, loading a bitmap image from a resource or a disk file. This bitmap works just like a GRAPHIC WINDOW , except that it is not visible. The parameter BmpName$ specifies the name of the image to be loaded. If BmpName$ contains a period, it is presumed to be the name of a disk file. Otherwise, an attempt is made to load it from a resource -- if not found, it is then presumed to be a disk file.

The parameters nWidth& and nHeight& specify the width and height of the bitmap, in pixels . If either of the size parameters are zero (0), the bitmap is loaded at its natural size. If either of the size parameters is different from the natural size, the bitmap is stretched or condensed to the requested size.

If the bitmap creation is successful, the bitmap handle is assigned to the variable hbmp??? . If not successful, hbmp??? is set to zero. When you are finished using this memory bitmap, you must delete it with GRAPHIC BITMAP END .

If the stretch& parameter is included, it is one of the values in the following table. If not included, or it is the value zero (0), the stretch mode is unchanged. An appropriate choice of stretch mode can substantially enhance the quality of bitmaps which are changed in size. The stretch mode equates are predefined in ScharfBASIC.

The 4 stretch modes are:

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

The following code will retrieve the natural size of an image in a bitmap file, in pixels:

nFile& = FREEFILE

OPEN "myimage.bmp" FOR BINARY AS nFile&

GET #nFile&, 19, nWidth&

GET #nFile&, 23, nHeight&

CLOSE nFile&

See Also

  • GRAPHIC BITMAP END
  • GRAPHIC BITMAP NEW
  • GRAPHIC GET STRETCHMODE
  • GRAPHIC IMAGELIST
  • GRAPHIC RENDER
  • GRAPHIC SET STRETCHMODE
  • GRAPHIC STRETCH


GRAPHIC BITMAP NEW - ScharfBASIC Help

GRAPHIC BITMAP NEW

Create a new memory bitmap.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC BITMAP NEW nWidth& , nHeight& TO hBmp???

Description

GRAPHIC BITMAP NEW creates a new memory bitmap, which may be manipulated and drawn just as if it were a GRAPHIC WINDOW , except that it is not visible. The parameters nWidth& and nHeight& specify the width and height of the bitmap, in pixels. If the bitmap creation is successful, the bitmap handle is assigned to the variable hBmp??? . If not successful, hBmp??? is set to zero. When you are finished using this memory bitmap, you must delete it with GRAPHIC BITMAP END .

See Also

  • GRAPHIC ATTACH
  • GRAPHIC BITMAP END
  • GRAPHIC BITMAP LOAD
  • GRAPHIC IMAGELIST


GRAPHIC BOX - ScharfBASIC Help

GRAPHIC BOX

Draw a box with square or rounded corners in the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC BOX ( x1! , y1! ) - ( x2! , y2! ) [, [ corner& ] [ , [ rgbColor& ] [ ,
[ fillcolor& ] [ , [ fillstyle& ]]]]]

Description

The coordinates are specified in Page Units . Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE . Because of the nature of a box, GRAPHIC BOX neither uses, nor updates, the last point referenced (POS). Windows graphic conventions consider the bottom and right coordinates of a BOX to be exclusive. The pixels at the bottom and right edges are not drawn unless Overlap Mode is enabled. See GRAPHIC SET OVERLAP for details.

x1! , y1!

The upper left corner of the box.

x2! , y2!

The lower right corner of the box.

corner&

The percentage of roundness of the corners, in the range of 0 to 100. A value of zero creates square corners, while 100 creates a circle/oval. A value of 20 being most common for a pleasant, rounded appearance. If corner& is omitted, the default is 0, which creates a rectangle with square corners.

rgbColor&

Optional RGB color of the box edge. If omitted (or -1), the edge color defaults to the current foreground color for the selected graphic target.

fillcolor&

Optional RGB color of the box interior. If fillcolor& is omitted (or -2), the interior of the box is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • GRAPHIC ATTACH
  • GRAPHIC COLOR
  • GRAPHIC LINE
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH


GRAPHIC CLEAR - ScharfBASIC Help

GRAPHIC CLEAR

Clear the entire selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC CLEAR [ rgbColor& [, fillstyle& ]]

Description

The graphic target must first be selected with GRAPHIC ATTACH . The last point referenced (POS) is set to the upper left corner of the graphic window (0,0).

rgbColor&

Optional RGB value representing the fill color. If rgbColor& is omitted (or -1), the graphic target is cleared to the default background color for the selected graphic target.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the rgbC olor& , while the background is specified by the default background color for the selected graphic window. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • GRAPHIC ATTACH
  • GRAPHIC COLOR


GRAPHIC Code Group - ScharfBASIC Help

GRAPHIC Code Group

The Graphic

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC DirectorWord [ params ]
GRAPHIC DirectorWord [ params ] TO ReturnVariable(s)
ReturnVariable = GRAPHIC ( DirectorWord [,params])
ReturnVariable$ = GRAPHIC$ ( DirectorWord [,params])

Description

Some of the functionality of the GRAPHIC group was available in prior versions of ScharfBASIC, but it has now been expanded. Some Graphic Procedures (namely those which return a single value) may be used in two forms, a statement with a TO clause, or a function which may be used as a term in an expression:

GRAPHIC GET LINES TO LineCountVar&

LineCountVar& = GRAPHIC(LINES)

The two examples above are functionally identical. The choice is simply a matter of your personal preference. If you use the second form (as a function which returns a value), it can be a term in any expression of any complexity. When a function form is available, it is labeled with the prefix "Function Form".

Some Graphic procedures return two or more values. As it is not possible to simultaneously inject multiple terms into a valid expression, the function option is not available for them.

GRAPHIC TARGET

The term GRAPHIC TARGET refers to a Graphic Bitmap, a Graphic Control, or a Graphic Window. You may want to think of a graphic target as your painter's canvas, where you display any amount of text and graphics. Many graphic targets may exist simultaneously, but only one is attached to the graphic stream at a time. The attached graphic target is the one acted upon by graphic code.

Graphic Bitmap

This is a non-visible target typically used as a work area to construct an image prior to displaying it. You can create a new, blank bitmap with GRAPHIC BITMAP NEW , or load one from a resource or disk file with GRAPHIC BITMAP LOAD . At that point, other graphic code can be used to act on it.

Graphic Control

This is a static control/window which is placed on a DDT Dialog with CONTROL ADD GRAPHIC . Once you attach this control, you can display all forms of text and graphics on it.

Graphic Window

This is a standalone window which can be placed at any location on the desktop. It's created with GRAPHIC WINDOW and can even be used as a graphical console window. Once you attach this window, you can display all forms of text and graphics on it.

GRAPHIC STREAM

The Graphic Stream is the connection between graphic code and a graphic target. The Graphic Stream is created when you attach a particular target with GRAPHIC ATTACH . From that moment forward, all graphic code acts on that selected target. This continues until such time as you select a new graphic target. When this occurs, the graphic stream to the first target is disabled, and a new graphic stream to the new target is created.

You can redirect the graphic stream to different graphic targets as often as necessary for the logic of your program.

PAGE UNITS

PAGE UNITS are used to measure the size of a graphical item, or to define a particular position on a graphic target. You can define page units to be pixels , dialog units, or scaled units of your choice.

Initially, each graphic target inherits the page unit size from its parent : pixels or dialog units. You can change this to scaled world coordinates of your choice with GRAPHIC SCALE . You can revert from dialog units or scaled units back to pixels (the most accurate form) by executing GRAPHIC SCALE PIXELS .

By default, the upper left corner of a graphic target is considered to be the X,Y position 0,0 and grows larger to the right or downward. The X axis is horizontal, while the Y axis is vertical. Whenever an X,Y position is given, the X value is stated first. Both the limits and the axis direction can be altered with GRAPHIC SCALE.

GRAPHIC POSITION (POS)

Each time you draw text or graphics, it is displayed at the current graphic position (POS) for that target. Upon completion, the POS is updated to the last point referenced. You can draw a relative distance from the POS (using a STEP option), or set an entirely new position with GRAPHIC SET POS .

Most ScharfBASIC functions specify graphic and pixel positions in Page Units as X,Y (horizontal term first, then the vertical term). This is true for both graphics and text. When you draw text with GRAPHIC PRINT , POS defines the position of the upper-left corner of the first character.

TEXT CELL (ROW/COLUMN POSITION)

For ease of programming, a few procedures specify text position by row and column. In this case, the position is measured in text cells, which is the space occupied by one character. This works well with fixed width fonts , which is recommended. If a variable width font is chosen, ScharfBASIC must use the average character size for these calculations, which can give imprecise results.

For compatibility with most current and prior versions of BASIC (ScharfBASIC included), code which references text rows and columns names the vertical term first (ROWS, COLUMNS). Rows and columns are always numbered from one upward.

See Also

  • Graphic Commands
  • Graphics


GRAPHIC COLOR - ScharfBASIC Help

GRAPHIC COLOR

Sets the foreground and background color.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC COLOR foreground& [, background& ]

Description

If either parameter is -1, the default foreground/background color is used. If the background parameter is -2, the background is not painted, allowing the content behind to become visible. If either parameter is -3, the existing color is not changed. Otherwise, the specified RGB color is used.

See Also

  • Built In RGB Color Equates
  • GRAPHIC ATTACH
  • GRAPHIC PRINT
  • GRAPHIC SET FONT


Graphic Commands - ScharfBASIC Help

Graphic Commands

The followings can be used to display graphics:

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Add a (non-resizing) image control to a dialog .

Add a stretched image control to a dialog.

CONTROL ADD IMGBUTTON

Add an image button to a dialog.

CONTROL ADD IMGBUTTONX

Add a stretched image button to a dialog.


GRAPHIC COPY - ScharfBASIC Help

GRAPHIC COPY

Copy a bitmap

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC COPY hbmpSource??? , id& [, style& ]
GRAPHIC COPY hbmpSource??? , id& TO ( x! , y! ) [, style& ]
GRAPHIC COPY hbmpSource??? , id& , ( x1! , y1! )-( x2! , y2! ) TO ( x! , y! ) [, style% ]

Description

You can copy a complete bitmap, or a portion of it, to the selected graphic target. The expression hbmpSource??? specifies the handle of the source GRAPHIC BITMAP , GRAPHIC WINDOW , or dialog containing a GRAPHIC CONTROL . The expression id& is the unique control identifier in the range 1 to 65535, as assigned with the CONTROL ADD GRAPHIC statement. id& must be 0 for a GRAPHIC WINDOW or a GRAPHIC BITMAP. The destination of the copy operation is the window selected by GRAPHIC ATTACH . You must take care that your parameters are valid for the specified bitmap, or the results of the operation are undefined.

The first form of the GRAPHIC COPY statement copies the complete bitmap, positioning it at (0,0), which is the upper left corner of the destination.

The second form of GRAPHIC COPY also copies the complete bitmap, but positions it at the point specified by the parameter ( x! , y! ).

The third form copies a portion of the bitmap, specified by x1,y1 as the upper left corner and x2,y2 as the lower right corner. It is positioned at the point specified by the parameter (x,y). You must use care that your parameters are valid for the specified bitmaps, or results of the operation are undefined.

If the style parameter is included, it is one of the values in the following table. If not included, a default of %mix_CopySrc is presumed. There are 8 mix modes available to use for mixing drawing colors with the colors which already exist at the at the drawing location The mix mode equates are predefined in ScharfBASIC.

%mix_Blackness

Pixel is always 0 (black).

%mix_NotMergeSrc

Pixel is the inverse of the MergeSrc color.

%mix_MaskNotSrc

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%mix_NotCopySrc

Pixel is the inverse of the pen color.

%mix_MaskSrcNot

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%mix_Not

Pixel is the inverse of the pixel color.

%mix_XorSrc

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%mix_NotMaskSrc

Pixel is the inverse of the MaskSrc color.

%mix_MaskSrc

Pixel is a combination of the colors common to both the source and the pixel.

%mix_NotXorSrc

Pixel is the inverse of the XorSrc color.

%mix_Nop

Pixel remains unchanged.

%mix_MergeNotSrc

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_CopySrc

Pixel is the source color (default).

%mix_MergeSrcNot

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_MergeSrc

Pixel is a combination of the source color and the pixel color.

%mix_Whiteness

Pixel is always 1 (white).

See Also

  • GRAPHIC GET STRETCHMODE
  • GRAPHIC RENDER
  • GRAPHIC SET STRETCHMODE
  • GRAPHIC STRETCH


GRAPHIC DETACH - ScharfBASIC Help

GRAPHIC DETACH

Detaches a graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC DETACH

Description

Though detached from the graphic stream, the graphic target is not deleted, nor is it altered in any way. Until another graphic target is attached, any GRAPHIC statements executed are ignored. If no graphic is attached, this statement performs no operation.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC BITMAP LOAD
  • GRAPHIC BITMAP NEW
  • GRAPHIC WINDOW


GRAPHIC ELLIPSE - ScharfBASIC Help

GRAPHIC ELLIPSE

Draw an ellipse or a circle in the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC ELLIPSE ( x1! , y1! ) - ( x2! , y2! ) [ , [ rgbColor& ] [ ,[ fillcolor& ] [ , [ fillstyle& ]]]]

Description

Coordinates are specified in Page Units . Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE . Because of the nature of an ellipse, which has no obvious beginning or end, GRAPHIC ELLIPSE neither uses, nor updates, the last point referenced (POS).

The coordinate pair define an invisible bounding rectangle which would enclose the ellipse to be drawn. It tells both the size and the proportions of the ellipse. Windows graphic conventions consider the bottom and right coordinates of it to be exclusive. The pixels at the bottom and right edges are ignored, unless Overlap Mode is enabled. See GRAPHIC SET OVERLAP for details.

x1! , y1!

The upper left corner of the bounding rectangle.

x2! , y2!

The lower right corner of the bounding rectangle.

rgbColor&

Optional RGB color of the ellipse edge. If omitted (or -1), the edge color defaults to the current foreground color for the selected graphic window.

fillcolor&

Optional RGB color of the ellipse interior. If fillcolor& is omitted (or -2), the interior of the ellipse is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color for the selected graphic window. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC COLOR
  • GRAPHIC LINE
  • GRAPHIC PIE
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH


GRAPHIC GET BITS - ScharfBASIC Help

GRAPHIC GET BITS

Retrieve a copy of a bitmap , storing it as a device-independent bitmap in a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET BITS TO bitvar$

Description

This statement retrieves a copy of the entire bitmap for the selected graphic target , assigning it to the dynamic string variable specified by bitvar$ . This allows you to make many modifications to the bitmap very quickly, particularly operations which may not be directly supported by GRAPHIC code. For example, you might change all red pixels in a bitmap to blue. Once your operations are complete, the bitmap is replaced using GRAPHIC SET BITS .

The bitvar$ string will contain a series of four-byte values, each of which represents a long integer . You can convert the four-byte string sections to numeric values with the CVL function, and convert a numeric value to a four-byte string with MKL$ . The first four-byte value specifies the width of the bitmap, in pixels, and the second specifies the height. Following that will be one four-byte value for each pixel in the bitmap, which represents the color of that pixel. So, a 20 by 20 bitmap would have 400 pixels and require 1600 bytes (400 * 4), plus 4 bytes for the width and 4 bytes for the height, or a total of 1608 bytes.

The first four-byte pixel value in the string represents the top-left corner of the image, the second represents the second pixel of the first row, and so on. After the last pixel of the first row will be the first pixel of the second row, etc.

If execution speed is most important, it's likely that the string can be manipulated most efficiently with pointer variables.

Some Windows API functions, namely those which reference Device-Independent Bitmaps (DIB), require that colors be specified in the reverse of normal RGB sequence (Blue-Green-Red instead of Red-Green-Blue). To maximize performance, GRAPHIC GET BITS uses BGR format as well. You can use the BGR() function to translate an RGB value to its BGR equivalent.

See Also

  • Built In RGB Color Equates
  • BGR
  • CVL
  • GRAPHIC SET BITS
  • MKL$
  • RGB


GRAPHIC GET SCALE - ScharfBASIC Help

GRAPHIC GET SCALE

Retrieve the current

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET SCALE TO x1! , y1! , x2! , y2!

Description

GRAPHIC SCALE allows you to define your own world coordinate system for subsequent GRAPHIC statements. World coordinates may be floating point values, with the only requirement that x1! not equal x2!, and y1! not equal y2!.

GRAPHIC GET SCALE retrieves the coordinate limits, which may be either custom world coordinates (if a GRAPHIC SCALE has been executed), or else default pixel coordinates. This allows you to save and restore a previous set of coordinates. This statement will automatically adjust to allow Dialog Unit scale factors to be retrieved.

See Also

  • GRAPHIC SCALE
  • GRAPHIC SCALE PIXELS


GRAPHIC IMAGELIST - ScharfBASIC Help

GRAPHIC IMAGELIST

Displays an image from an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC IMAGELIST ( x! , y! ), hLst , index& , overlay& , style&

Description

One of the images stored in an IMAGELIST is displayed on the selected graphic control , bitmap , or window . The parameters x!,y! define the upper left corner of the position of the image. hLst is the handle of the IMAGELIST and index& is the selector of the image to be displayed (1=first, 2=second, etc.). If overlay& is non-zero, it specifies an overlay image to be added to the displayed image from the image list. The parameter style& may be one of the following style bits:

%ILD_NORMAL

Draws the image using the background color of the image list. If the background color is the default value %CLR_NONE (defined in the Commctrl.inc file), the image is drawn transparently.

%ILD_TRANSPARENT

Draws the image transparently if there is a mask.

%ILD_MASK

Draws the mask.

%ILD_BLEND25

If there is a mask, the image is drawn blending 25% with the system highlight color.

%ILD_BLEND50

If there is a mask, the image is drawn blending 50% with the system highlight color.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC COPY
  • GRAPHIC RENDER
  • GRAPHIC STRETCH
  • IMAGELIST


GRAPHIC INPUT FLUSH - ScharfBASIC Help

GRAPHIC INPUT FLUSH

Remove all buffered keyboard data.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC INPUT FLUSH

See Also

  • GRAPHIC INKEY$
  • GRAPHIC INPUT
  • GRAPHIC INSTAT
  • GRAPHIC LINE INPUT
  • GRAPHIC WAITKEY$


GRAPHIC LINE - ScharfBASIC Help

GRAPHIC LINE

Draw a line on the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC LINE [STEP] [( x1! , y1! )] - [STEP] ( x2! , y2! )[, rgbColor& ]

Description

The line is drawn from the first point, up to, but not including the second point. Coordinate points are specified in Page Units . Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE .

Windows graphic conventions consider the final x2 and y2 coordinates to be exclusive. Therefore, by default, the final pixel is not drawn unless Overlap Mode is enabled. See GRAPHIC SET OVERLAP for details.

x1! , y1!

Optional values which define the starting point of the line. If this optional first point is omitted, the line begins at the last point referenced (POS) in a preceding GRAPHIC statement. If the first STEP option is included, the x1! and y1! starting coordinates are relative to the last point referenced (POS).

x2! , y2!

The ending point of the line. If the second STEP option is included, the x2! and y2! ending coordinates are relative to the starting coordinates.

rgbColor&

Optional RGB color value for the line. If rgbColor& is omitted (or -1), the line color defaults to the current foreground color.

See Also

  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC BOX
  • GRAPHIC COLOR
  • GRAPHIC ELLIPSE
  • GRAPHIC PIE
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

fild   DWORD PTR ds:0x209a54
fild   DWORD PTR ds:0x209a54
call   0x205735
fild   DWORD PTR ds:0x209a58
fild   DWORD PTR ds:0x209a58
call   0x203b19


GRAPHIC PAINT - ScharfBASIC Help

GRAPHIC PAINT

Fill an area with a solid

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC PAINT [BORDER | REPLACE] [STEP] ( x! , y! ) [, [ rgbFill& ] [, [ rgbBorder& ] [, [ fillstyle& ]]]]

Description

The coordinate points are specified in Page Units .

x! , y!

The point where filling begins. If the STEP option is included, the x and y coordinates are relative to the last point referenced (POS) in the selected graphic target.

rgbFill&

Optional RGB color value for the fill area. If rgbFill& is omitted (or -1), the default foreground color is used.

rgbBorder&

Optional RGB base color of the fill area. If the REPLACE option is chosen, filling continues outward in all directions until a color other than rgbBorder& is found. If the BORDER option (or no option) is included, filling continues outward until the rgbBorder& color is found. If rgbBorder& is not specified, it is assumed to be the same as the rgbFill& parameter.

fillstyle&

Optional fill style (pattern) to use. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the rgbFill& , while the background is specified by the default background color for the selected graphic target. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC BOX
  • GRAPHIC COLOR
  • GRAPHIC ELLIPSE
  • GRAPHIC LINE
  • GRAPHIC PIE


GRAPHIC PIE - ScharfBASIC Help

GRAPHIC PIE

Draw a pie section on the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC PIE ( x1! , y1! ) - ( x2! , y2! ), arcStart! , arcEnd! [, [ rgbColor& ] [ , [fillcolor& ] [ , [ fillstyle& ]]]]

Description

A pie section is an arc, with a line drawn from each end point to the center of the circle or ellipse. To specify a pie section, you would first define the full circle or ellipse of which it is a part, and then specify the points on the ellipse where the arc starts and stops.

The full circle or ellipse is defined by its bounding rectangle, which is the smallest rectangle which can be drawn around the circle or ellipse. For example, if the circle is centered at position (400,400), with a radius of 100 pixels, the upper left corner (x1,y1) of the bounding rectangle is (300,300), and the lower right corner (x2,y2) is (500,500).

The start point and end point of the arc are specified by their angle, which must be given in radians. A complete circle or ellipse is 2*pi radians. On a 12-hour clock-face, the values 0 and 2*pi both refer to the position of 3 o'clock, while the value 1*pi refers to the position of 9 o'clock. Other positions are specified by a radian value relative to these. In ScharfBASIC, arcs are always drawn counter-clockwise from the starting point to the ending point.

Prior to any graphical operations, the graphic target must first be selected with GRAPHIC ATTACH . The Coordinates are specified in the same terms (pixels or dialog units) as the parent dialog (or world coordinates, if those were chosen with GRAPHIC SCALE ). Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE . Because of the nature of a pie section, GRAPHIC PIE neither uses, nor updates, graphic POS (last point referenced).

x1! , y1!

The upper left corner of the bounding rectangle of the full circle or ellipse.

x2! , y2!

The lower right corner of the bounding rectangle of the full circle or ellipse.

ArcStart!

The starting angle of the arc, in radians, from 0 to 2*pi.

ArcEnd!

The ending angle of the arc, in radians, from 0 to 2*pi radians. Note that arcs are always drawn counter-clockwise from arcStart! to arcEnd! . Compared with a 12-hour clock-face, 0 or 2*pi radians is at 3 o'clock, and 1*pi radians is at 9 o'clock.

rgbColor&

Optional RGB color of the pie section edge. If omitted (or -1), the edge color defaults to the current foreground color.

fillcolor&

Optional RGB color of the pie section interior. If fillcolor& is omitted (or -2), the interior of the pie section is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC BOX
  • GRAPHIC COLOR
  • GRAPHIC ELLIPSE
  • GRAPHIC LINE
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH


GRAPHIC POLYGON - ScharfBASIC Help

GRAPHIC POLYGON

Draw a polygon in the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC POLYGON points [,[ rgbColor& ] [, [ fillcolor& ] [,[ fillstyle& ] [, fillmode& ]]]]

Description

The Coordinates are specified in Page Units . Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE . GRAPHIC POLYGON neither uses, nor updates, the last point referenced ( POS ).

points

User-defined type that defines the number of vertices and the location of each. There must be at least two, and no more than 1024 vertices. The first member is a long integer point count, followed directly by the appropriate number of single precision floats to specify the actual coordinates. Floating point coordinates are required, because of the possibility of their use as world coordinates with SCALE. You can use a type with a scalar list, like this:

TYPE PolyPoints

count as long

x1 as single

y1 as single

x2 as single

y2 as single

x3 as single

y3 as single

END TYPE

Or, you can create an array using point types, like this:

TYPE PolyPoint

x as single

y as single

END TYPE

TYPE PolyArray

count as long

xy(1 TO 3) as PolyPoint

END TYPE

rgbColor&

Optional RGB color of the polygon edge. If omitted (or -1), the edge color defaults to the current foreground color.

fillcolor&

Optional RGB color of the polygon interior. If fillcolor& is omitted (or -2), the interior of the ellipse is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

fillmode&

If fillmode& is missing (or zero), the winding mode is selected. This fills any region with a non-zero winding value. If fillmode& is non-zero, the alternate mode is selected. This fills the area between odd-numbered and even-numbered polygon sides on each scan line. That is, it fills the area between the first side and the second side, between the third side and fourth side, etc.

See Also

  • Built In RGB Color Equates
  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC BOX
  • GRAPHIC COLOR
  • GRAPHIC ELLIPSE
  • GRAPHIC LINE
  • GRAPHIC POLYLINE
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH


GRAPHIC POLYLINE - ScharfBASIC Help

GRAPHIC POLYLINE

Draw a series of connected line segments.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC POLYLINE points [, rgbColor& ]

Description

The Coordinates are specified in Page Units . Line width can be set using GRAPHIC WIDTH . If line width is set to 1 (the default), the line style can be set with GRAPHIC STYLE . GRAPHIC POLYLINE neither uses, nor updates, the last point referenced ( POS ).

Windows graphic conventions consider the final x and y coordinates to be exclusive. Therefore, by default, the final pixel is not drawn unless Overlap Mode is enabled. See GRAPHIC SET OVERLAP for details.

points

User-defined type that defines the number of vertices and the location of each. There must be at least two, and no more than 1024 vertices. The first member is a long integer point count, followed directly by the appropriate number of single precision floats to specify the actual coordinates. Floating point coordinates are required, because of the possibility of their use as world coordinates with SCALE. You can use a type with a scalar list, like this:

TYPE PolyPoints

count as long

x1 as single

y1 as single

x2 as single

y2 as single

x3 as single

y3 as single

END TYPE

Or, you can create an array using point types, like this:

TYPE PolyPoint

x as single

y as single

END TYPE

TYPE PolyArray

count as long

xy(1 TO 3) as PolyPoint

END TYPE

rgbColor&

Optional RGB color of the polyline. If omitted (or -1), the color defaults to the current foreground color.

See Also

  • Built In RGB Color Equates
  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC BOX
  • GRAPHIC COLOR
  • GRAPHIC ELLIPSE
  • GRAPHIC LINE
  • GRAPHIC POLYGON
  • GRAPHIC SET OVERLAP
  • GRAPHIC STYLE
  • GRAPHIC WIDTH


GRAPHIC PRINT - ScharfBASIC Help

GRAPHIC PRINT

Output text to the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC PRINT [EXPRLIST] [POS( n )] [SPC( n )] [TAB( n )] [,] [;]...

Description

Prior to any graphical operations are executed, you should be certain that a graphic target has been selected, either by default, or with GRAPHIC ATTACH . The text color and the text background color are set with GRAPHIC COLOR . Text which extends beyond the bounds of the graphic target is clipped. The size of the text to be printed can be determined in advance with GRAPHIC TEXT SIZE , and formatted to fit a particular field with GRAPHIC SPLIT . Drawing begins at the last point referenced by another GRAPHIC procedure, or the point specified by GRAPHIC SET POS . The upper left corner of the text is positioned at the POS .

GRAPHIC PRINT has the following parts, which may occur in any order and quantity, within a single statement:

EXPRLIST

Numeric and/or string expression(s) to be written to the graphic target. A semicolon can be used as separator between multiple expressions in the same statement. Upon completion, the POS is moved to the left margin of the next line.

POS( n )

An optional function used to set the POS to the horizontal page unit ( pixel, dialog unit , scaled unit , etc.) specified by the numeric argument, Multiple uses of the POS function is permitted in a single statement. The vertical position of the POS is never changed.

SPC( n )

An optional function used to insert n spaces into the printed output. Multiple use of SPC is permitted in a single statement. Values of n less than 1 are ignored.

TAB( n )

An optional function used to tab to the nth column before printing the next expression. Multiple use of TAB is permitted in a single statement. Since TAB references columns , rather than pixels, it can give unpredictable results when used with a variable width font . It is best used with a fixed width font.

Special characters that determine the position of the next text item printed. A semicolon (;) means the next text item is printed immediately; a comma (,) means the next text item is printed at the start of the next print zone. Print zones begin every 14 columns.

If the final argument is a semicolon or comma, the POS is maintained at the current location, rather than the default action of moving to the start of the next line. For example:

GRAPHIC PRINT "Hello";

GRAPHIC PRINT " world!";

...produces the contiguous result "Hello world!"

If you omit all arguments, GRAPHIC PRINT just moves the POS to the left margin of the next line. Any control codes, such as Carriage Return, Line-Feed, and Backspace are not interpreted. They will display as symbols in the currently selected font.

USING$ is a separate function, which may be included in the ExprList. See the USING$() function for more information.

It is not possible to print a User-Defined Type (UDT), a Variant , an object variable, or an entire array . Individual member values must be extracted with the appropriate function before they can be displayed.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC CHR SIZE
  • GRAPHIC SET FONT
  • GRAPHIC GET POS
  • GRAPHIC SET POS
  • GRAPHIC SET SCROLLTEXT
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC SPLIT
  • GRAPHIC TEXT SIZE
  • USING$

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x209a54
call   0x202c78
call   0x201fbc
call   0x2053f7
call   0x20541e


GRAPHIC REDRAW - ScharfBASIC Help

GRAPHIC REDRAW

Update buffered graphical statements, drawing them to the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC REDRAW

Description

This statement is only needed when GRAPHIC ATTACH with the REDRAW option have been chosen for faster, buffered draw operations. Otherwise, it performs no operation.

All ScharfBASIC graphical displays are persistent -- they are automatically redrawn for you after resuming from being minimized or temporarily covered by other windows.

In intensive drawing operations, it is preferable to delay the display until a number of statements have been performed by using the REDRAW option with the GRAPHIC ATTACH statement and the GRAPHIC REDRAW statement. This can improve the overall performance dramatically.

See Also

  • GRAPHIC ATTACH


GRAPHIC RENDER - ScharfBASIC Help

GRAPHIC RENDER

Render an image on the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC RENDER [BITMAP | ICON] ImgName , ( x1! , y1! )-( x2! , y2! )

Description

Renders an image (bitmap or icon), loaded from a resource or a disk file, on the selected graphic target. The optional director word identifies whether the source is a b itmap or an icon. If not specified, Bitmap is the default.

The parameter ImgName tells the name of the image. If ImgName is a numeric resource ID, it can be given as a numeric expression or the string equivalent with a leading pound sign (e.g. "#10023"). Otherwise, the string resource ID or the file name is given as a string expression. If the string name contains a period, it's presumed to be the name of a disk file. Otherwise, an attempt is made to load it as a resource; if not found, it's presumed to be a disk file.

The parameters x1! , y1! define the upper left corner of the target rectangle, while x2! , y2! define the lower right corner of that rectangle. If the target rectangle is larger or smaller than the original, the image is stretched or condensed to the requested size.

The following code will retrieve the natural size of an image in a bitmap file, in pixels :

nFile& = FREEFILE

OPEN "myimage.bmp" FOR BINARY AS nFile&

GET #nFile&, 19, nWidth&

GET #nFile&, 23, nHeight&

CLOSE nFile&

See Also

  • GRAPHIC COPY
  • GRAPHIC GET STRETCHMODE
  • GRAPHIC IMAGELIST
  • GRAPHIC SET STRETCHMODE
  • GRAPHIC STRETCH


GRAPHIC SAVE - ScharfBASIC Help

GRAPHIC SAVE

Save an image to a bitmap (.BMP) file.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SAVE BmpName$

Description

The selected graphic target (a graphic bitmap , control , or window , etc.) is saved to a disk file using the filename specified by BmpName$. The bitmap is always saved in a single plane, 24-bit format, to allow for the maximum (true color) resolution.

See Also

  • CONTROL ADD GRAPHIC
  • GRAPHIC ATTACH
  • GRAPHIC BITMAP LOAD
  • GRAPHIC BITMAP NEW


GRAPHIC SCALE - ScharfBASIC Help

GRAPHIC SCALE

Define a custom coordinate system for the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SCALE ( x1! , y1! ) - ( x2! , y2! )
GRAPHIC SCALE PIXELS

Description

The graphic tar get must first be chosen with GRAPHIC ATTACH . GRAPHIC SCALE lets you define your own world coordinate system for subsequent GRAPHIC statements. The custom coordinates remain with the graphic target until GRAPHIC SCALE is repeated, or the target is deleted. World coordinates may be floating point values, with the only requirement that x1! not equal x2!, and y1! not equal y2!. If either is equal, the statement is ignored.

If x2! is greater than x1! , coordinates grow larger as they move to the right. Otherwise, they grow larger as they move to the left.

If y2! is greater than y1! , coordinates grow larger as they move downward. Otherwise, they grow larger as they move upward.

By default, the position x2!/y2! translates to the first pixel which is outside of the client area, and therefore not drawn. However, if OVERLAP MODE is enabled by GRAPHIC SET OVERLAP , x2!/y2! translates to the final pixel in the client area and is drawn.

GRAPHIC SCALE PIXELS sets or resets the coordinate system to pixel coordinates. This can be particularly valuable when the original coordinates are in Dialog Units , since this provides increased resolution for other graphic functions.

Note: GRAPHIC SCALE will not work with negative numeric values - all numeric arguments must be positive.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC CELL SIZE
  • GRAPHIC GET SCALE
  • GRAPHIC SET OVERLAP


GRAPHIC SET AUTOSIZE - ScharfBASIC Help

GRAPHIC SET AUTOSIZE

Expands a graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET AUTOSIZE nWidth , nHeight [,USERSIZE]

Description

AUTOSIZE mode allows the attached graphic target ( control or window )to display the contents of a virtual window , which may be larger or smaller. The entire contents of the virtual window are always displayed on the screen, so the image is stretched or condensed to fit properly. The physical size of the display area is not changed. If the graphic target is a bitmap , no operation is performed, as there is no display area.

This statement may be used to change a target to AUTOSIZE mode, or to change the sizes and UserSize option of an existing AUTOSIZE target.

When executed, a new virtual bitmap of the specified height and width is created. nWidth and nHeight are always specified in Pixels or Dialog Units , depending upon the original window creation. The new virtual bitmap is immediately filled with the original bitmap, but stretched or condensed to fit. This is done to avoid flashing effects which sometimes occur with a brief color change. Your program may now draw to the new bitmap in the normal fashion for a bitmap of the new size.

If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP , based upon the new size of the drawing area. You can retrieve the size of the virtual drawing area, at any time, with GRAPHIC GET CANVAS .

AUTOSIZE mode is quite similar to VIRTUAL mode. Both create a virtual window which is the target of your drawing and text printing operations. The difference is the way in which they are displayed. VIRTUAL displays a viewport, smaller than the virtual window, which can be moved to various positions. This allows the user to view one selected section at a time. AUTOSIZE displays the entire virtual window, all of the time, by stretching or condensing it as needed.

If you add the USERSIZE option, an attached graphic window is displayed with a thick frame, which allows the user to "drag" the edges to a new size at any time. This option is not appropriate for a graphic control, and is ignored in that case.

See Also

  • GRAPHIC GET CANVAS
  • GRAPHIC SCALE
  • GRAPHIC SET CLIP
  • GRAPHIC SET FIXED
  • GRAPHIC SET VIRTUAL


GRAPHIC SET BITS - ScharfBASIC Help

GRAPHIC SET BITS

Replace a copy of a bitmap that was retrieved as a device-independent bitmap.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET BITS bitexpr$

Description

This statement replaces a bitmap that was originally retrieved with the GRAPHIC GET BITS statement. The bitmap is assigned to the selected graphic target from the string expression specified by bitexpr$ . This allows you to make many modifications to the bitmap very quickly, particularly operations which may not be directly supported by ScharfBASIC. For example, a typical use might be to change all red pixels in a bitmap to blue.

The bitexpr$ string contains a series of four- byte values, each of which represents a long integer . You can convert the four-byte string sections to numeric values with the CVL function, and convert a numeric value to a four-byte string with MKL$ . The first four-byte value specifies the width of the bitmap, in pixels, and the second specifies the height. Following that will be one four-byte value for each pixel in the bitmap, which represents the color of that pixel. So, a 20 by 20 bitmap would have 400 pixels and require 1600 bytes (400 * 4), plus 4 bytes for the width and 4 bytes for the height, or a total of 1608 bytes.

The first four-byte pixel value in the string represents the top-left corner of the image, the second represents the second pixel of the first row, and so on. After the last pixel of the first row will be the first pixel of the second row, etc.

If execution speed is most important, it's likely that the string can be manipulated most efficiently with pointer variables.

Some Windows API functions, namely those which reference Device-Independent Bitmaps (DIB), require that colors be specified in the reverse of normal RGB sequence (Blue-Green-Red instead of Red-Green-Blue). To maximize performance, GRAPHIC SET BITS uses BGR format as well. You can use the BGR function to translate an RGB value to its BGR equivalent.

See Also

  • Built In RGB Color Equates
  • BGR
  • CVL
  • GRAPHIC GET BITS
  • MKL$
  • RGB


GRAPHIC SET CAPTION - ScharfBASIC Help

GRAPHIC SET CAPTION

Change the caption on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET CAPTION CaptionExpr$

Description

If the selected Graphic Target has a title bar, the caption is changed to the contents of the string expression .

See Also

  • GRAPHIC WINDOW


GRAPHIC SET CLIENT - ScharfBASIC Help

GRAPHIC SET CLIENT

Change the size of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET CLIENT nWide& , nHigh&

Description

Client size may be smaller than overall size, depending on the type of borders used. The client area is the part inside the borders, which varies depending upon the style and exstyle at creation. Overall size includes the borders. A graphic target with a border will typically have a larger overall size than one without a border.

Beginning with this version of ScharfBASIC, GRAPHIC CONTROLS may be resized with CONTROL SET CLIENT , GRAPHIC SET CLIENT, CONTROL SET SIZE , and GRAPHIC SET SIZE .

The original bitmap is copied, pixel for pixel, to the newly resized graphic control or window. Any expanded area is filled with the current background color. Your program draws to it in the normal fashion for a bitmap of the new size.

If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP , based upon the new size of the drawing area.

See Also

  • CONTROL GET CLIENT
  • CONTROL GET SIZE
  • CONTROL SET CLIENT
  • CONTROL SET SIZE
  • GRAPHIC GET CANVAS
  • GRAPHIC GET CLIENT
  • GRAPHIC GET SIZE
  • GRAPHIC SET CLIP
  • GRAPHIC SET SIZE


GRAPHIC SET CLIP - ScharfBASIC Help

GRAPHIC SET CLIP

Establishes margins around the outer edges of the graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET CLIP LeftMargin! , TopMargin! , RightMargin! , BottomMargin!

Description

This statement establishes margins on any or all sides of the graphic target. All subsequent GRAPHIC operations are "clipped" on these boundaries, so that no additional text or graphics are displayed in these protected areas. However, the margins are not erased, so anything already written in these areas will remain unchanged.

Each of the 4 parameters is specified in the PAGE UNITS currently in effect. However, as this statement changes the target space available to you, the page units are immediately set to pixels . The upper left corner of the clip area is now addressed as point (0,0), while the right and bottom limits are reduced by the size of the margins. If you would prefer to use Scaled Page Units for this revised clip area, you must execute a new GRAPHIC SCALE .

GRAPHIC SET CLIP is particularly useful for displaying text , where enclosing "white space" improves the appearance a good deal.

You can disable a clip area by executing GRAPHIC SET CLIP 0,0,0,0.

See Also

  • GRAPHIC GET CLIP
  • GRAPHIC SCALE


GRAPHIC SET FIXED - ScharfBASIC Help

GRAPHIC SET FIXED

Restores a graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET FIXED

Description

The attached graphic target ( control or window ) is restored to the standard FIXED mode. The drawing area is set equal to the physical size of the display area, which is not changed.

When executed, it is assumed that the graphic subsystem is set to AUTOSIZE or VIRTUAL mode. If not, no operation is performed. A new bitmap of the client area size is created. The original bitmap is copied, pixel for pixel, at the existing size. Any expanded area is filled with the current background color . Your program draws to it in the normal fashion for a bitmap of the new size.

If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP , based upon the new size of the drawing area. You can retrieve the size of the drawing area with GRAPHIC GET CANVAS or GRAPHIC GET CLIENT .

See Also

  • GRAPHIC GET CANVAS
  • GRAPHIC GET CLIENT
  • GRAPHIC SCALE
  • GRAPHIC SET AUTOSIZE
  • GRAPHIC SET VIRTUAL


GRAPHIC SET FOCUS - ScharfBASIC Help

GRAPHIC SET FOCUS

Bring the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET FOCUS

Description

A graphic window must first be chosen with GRAPHIC ATTACH . The GRAPHIC SET FOCUS statement brings the graphic window to the foreground, directing focus to it. This is particularly useful when another window may overlap the graphic window.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC WINDOW


GRAPHIC SET FONT - ScharfBASIC Help

GRAPHIC SET FONT

Select a font for use on the graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET FONT fonthndl&

Description

The font specified by fonthndl& is selected to be used by all of the following GRAPHIC PRINT , GRAPHIC INPUT , and GRAPHIC LINE INPUT statements. This is the most efficient way to change fonts and their general appearance (size, style, etc.). If you specify a fonthndl& of zero, the font is changed back to the original default font chosen by ScharfBASIC.

You can predefine virtually any number of fonts and attributes by executing FONT NEW statements for each of them. That makes them ready for immediate use when selected by GRAPHIC SET FONT.

If no specific font is selected, the default font is MS Sans Serif, 8 point, with no style attributes.

Restrictions

GRAPHIC SET FONT replaces GRAPHIC FONT. Note that the GRAPHIC FONT statement is no longer supported, so update your code to use the new syntax.

See Also

  • FONT NEW
  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC CELL SIZE
  • GRAPHIC CHR SIZE
  • GRAPHIC INPUT
  • GRAPHIC LINE INPUT
  • GRAPHIC PRINT
  • GRAPHIC TEXT SIZE


GRAPHIC SET LOC - ScharfBASIC Help

GRAPHIC SET LOC

Change the location of the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET LOC x& , y&

Description

This statement changes the location of the selected Graphic Window. If no graphic target is selected, or it is not a Graphic Window, no action is taken. The location is always given in pixels, relative to the upper left corner of the screen.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC GET LOC
  • GRAPHIC GET PPI


GRAPHIC SET MIX - ScharfBASIC Help

GRAPHIC SET MIX

Set the color mix mode for the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET MIX mode&

Description

There are 16 mix modes available to use for mixing the drawing color with the color that already exists at the drawing location. The mix mode equates are predefined in ScharfBASIC.

%mix_Blackness

Pixel is always 0 (black).

%mix_NotMergeSrc

Pixel is the inverse of the MergeSrc color.

%mix_MaskNotSrc

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%mix_NotCopySrc

Pixel is the inverse of the pen color.

%mix_MaskSrcNot

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%mix_Not

Pixel is the inverse of the pixel color.

%mix_XorSrc

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%mix_NotMaskSrc

Pixel is the inverse of the MaskSrc color.

%mix_MaskSrc

Pixel is a combination of the colors common to both the source and the pixel.

%mix_NotXorSrc

Pixel is the inverse of the XorSrc color.

%mix_Nop

Pixel remains unchanged.

%mix_MergeNotSrc

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_CopySrc

Pixel is the source color (default).

%mix_MergeSrcNot

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_MergeSrc

Pixel is a combination of the source color and the pixel color.

%mix_Whiteness

Pixel is always 1 (white).

See Also

  • GRAPHIC ATTACH
  • GRAPHIC GET MIX


GRAPHIC SET OVERLAP - ScharfBASIC Help

GRAPHIC SET OVERLAP

Enables or disables Graphic Overlap Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET OVERLAP [ NumrExpr& ]

Description

GRAPHIC SET OVERLAP enables or disables overlap mode for the graphic target which is currently attached to the graphic stream . It has no effect on any other graphic target. If NumrExpr& is true (non-zero), overlap mode is enabled. If false (zero), wrap mode is disabled. If NumrExpr& is missing, the default is to enable Overlap Mode.

With Overlap Mode, you control how ScharfBASIC treats graphic operations which involve a RECT structure in their definition. Windows graphic conventions consider the bottom and right coordinates of a RECT to be exclusive. In other words, the pixels at the bottom and right edges lie immediately outside the rectangle. They are not drawn, but are ignored. For example:

GRAPHIC BOX (0,0) - (50,50)

In this case, a box is drawn from 0,0 to 49,49. The final pixels at the bottom and right edge are simply not drawn. However, if Overlap Mode is enabled with GRAPHIC SET OVERLAP, the box is drawn from 0,0 to 50,50.

The Overlap Mode affects drawing operations involving GRAPHIC SCALE , GRAPHIC BOX , GRAPHIC ELLIPSE , GRAPHIC LINE , GRAPHIC POLYLINE , etc.

See Also

  • GRAPHIC GET OVERLAP


GRAPHIC SET PIXEL - ScharfBASIC Help

GRAPHIC SET PIXEL

Draw a single

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET PIXEL [STEP] ( x! , y! ) [, rgbColor& ]

Description

The coordinate point is specified in Page Units . If the STEP option is included, the x! and y! coordinates are relative to the last point referenced ( POS ).

See Also

  • Built In RGB Color Equates
  • GRAPHIC COLOR
  • GRAPHIC GET PIXEL
  • GRAPHIC SET BITS


GRAPHIC SET POS - ScharfBASIC Help

GRAPHIC SET POS

Set the last point referenced (POS) for the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET POS [STEP] ( x! , y! )

Description

The coordinate point is specified in Page Units . If the STEP option is included, the x! and y! coordinates are relative to the last point referenced (POS).

See Also

  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC GET POS
  • GRAPHIC SCALE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

fild   DWORD PTR ds:0x209a54
fild   DWORD PTR ds:0x209a54
call   0x205715


GRAPHIC SET SCROLLTEXT - ScharfBASIC Help

GRAPHIC SET SCROLLTEXT

Enables or disables Graphic ScrollText Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET SCROLLTEXT [ NumrExpr& ]

Description

GRAPHIC SET SCROLLTEXT enables or disables scroll mode for the graphic target which is currently attached to the graphic stream . It has no effect on any other graphic target. If NumrExpr& is true (non-zero), ScrollText mode is enabled. If false (zero), the mode is disabled. If NumrExpr& is missing, the default is to enable ScrollText Mode.

With ScrollText Mode, you can control how ScharfBASIC prints text on a graphic target when it reaches the end of a page. Since a graphic target operates on a full page basis, the default is to ignore text which is printed past the end of the page.

When ScrollText Mode is enabled, scrolling of a page is triggered only by GRAPHIC PRINT . If the POS (last point referenced) is located on the bottom row of the graphic target, and a GRAPHIC PRINT statement moves the POS off of the page, the entire contents of the graphic target is scrolled one row, and a new blank row is opened at the bottom.

See Also

  • GRAPHIC GET SCROLLTEXT
  • GRAPHIC SET AUTOSIZE
  • GRAPHIC SET VIRTUAL
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP


GRAPHIC SET SIZE - ScharfBASIC Help

GRAPHIC SET SIZE

Change the overall size of a graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET SIZE nWide& , nHigh&

Description

Overall size may be larger than client size, depending on the type of borders used. The client area is the part inside the borders, while overall size includes the borders. A graphic target with a border will typically have a larger overall size than one without a border.

Beginning with this version of ScharfBASIC, GRAPHIC CONTROLS may be resized with CONTROL SET CLIENT , GRAPHIC SET CLIENT , CONTROL SET SIZE , and GRAPHIC SET SIZE.

The original bitmap is copied, pixel for pixel, to the newly resized control. Any expanded area is filled with the current background color . Your program draws to it in the normal fashion for a bitmap of the new size.

If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP , based upon the new size of the drawing area.

nWide& , nHigh&

Integral numeric expressions which specify the desired size of the overall area. Width and height are specified in pixels or dialog units , depending upon the system used at creation.

See Also

  • CONTROL SET CLIENT
  • CONTROL SET SIZE
  • GRAPHIC GET SIZE
  • GRAPHIC SET CLIENT


GRAPHIC SET STRETCHMODE - ScharfBASIC Help

GRAPHIC SET STRETCHMODE

Sets the default bitmap stretching mode for the current

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET STRETCHMODE ModeExpr

Description

There are several operations in ScharfBASIC which involve stretching or condensing images on bitmaps, most notably GRAPHIC STRETCH . As individual pixels must be added or removed, there is a good chance that the quality of the image will be degraded. However, if you describe the nature of the image by defining a StretchMode, you can substantially enhance the appearance.

The default StretchMode is maintained individually for each DC. You can set the default mode with this statement, or retrieve it with GRAPHIC GET STRETCHMODE . Of course, you can also override the default StretchMode when you execute one of the affected statements.

The 4 stretch mode equates are predefined in ScharfBASIC.

Equate

Description

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

See Also

  • GRAPHIC BITMAP LOAD
  • GRAPHIC COPY
  • GRAPHIC GET STRETCHMODE
  • GRAPHIC RENDER
  • GRAPHIC STRETCH


GRAPHIC SET VIEW - ScharfBASIC Help

GRAPHIC SET VIEW

Changes the position of the viewport on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET VIEW XPos , YPos

Description

Moves the position of the viewport to the new position on a virtual graphic target. The position is specified in Page Units . If no graphic target has been attached, or no virtual window has been created, then no operation is performed.

See Also

  • GRAPHIC GET VIEW
  • GRAPHIC SET AUTOSIZE
  • GRAPHIC SET VIRTUAL


GRAPHIC SET VIRTUAL - ScharfBASIC Help

GRAPHIC SET VIRTUAL

Expands a graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET VIRTUAL nWidth& , nHeight& [,USERSIZE]

Description

VIRTUAL mode allows the attached graphic target ( control or window ) to display the contents of a larger virtual window. The physical size of the display area is not changed. Instead, the display area acts as a smaller viewport , which can be moved around the larger virtual window to view one section at a time. The physical size of the display area is not changed. If the graphic target is a bitmap , no operation is performed, as there would be no display area.

This statement may be used to change a target to VIRTUAL mode, or to change the sizes and UserSize option of an existing VIRTUAL target.

When executed, a new virtual bitmap of the specified height and width is created. nWidth& and nHeight& are always specified in Pixels or Dialog Units , depending upon the original window creation. The original bitmap is copied, pixel for pixel, at the existing size. Any expanded area is filled with the current background color . Your program draws to it in the normal fashion for a bitmap of the new size. Scroll bars are added so the user can move the viewport to the desired section. The size of the viewport is not changed.

The graphic viewport is initially placed at the upper-left corner of the virtual window. If a clip area had been established to create margins, it is reset. If scaled coordinates had been established, they are also reset, as neither would be appropriate for the altered size. You can enable these attributes again with GRAPHIC SCALE or GRAPHIC SET CLIP , based upon the new size of the drawing area. You can retrieve the size of the virtual drawing area, at any time, with GRAPHIC GET CANVAS .

The graphic viewport can be moved by clicking the scrollbars, or by moving the mouse wheel to alter the vertical position. Depressing the control key, along with the mouse wheel, alters the horizontal position. In addition, the cursor movement keys (Left, Right, Up, Down, PageUp, PageDown, Home, End) may also be used for this purpose. VIRTUAL mode is quite similar to AUTOSIZE mode. Both create a virtual window which is the target of your drawing and text printing operations. The difference is the way in which they are displayed.

VIRTUAL displays a viewport, smaller than the virtual window, which can be moved to various positions. This allows the user to view one selected section at a time. AUTOSIZE displays the entire virtual window, all of the time, by stretching or condensing it as needed.

If you add the USERSIZE option, an attached graphic window is displayed with a thick frame, which allows the user to "drag" the edges to a new size at any time. This option is not appropriate for a graphic control, and is ignored in that case.

Generally speaking, it is not advisable to enable ScrollText mode on a virtual graphic window, as the display may be confusing to the user.

See Also

  • GRAPHIC GET CANVAS
  • GRAPHIC GET VIEW
  • GRAPHIC SET AUTOSIZE
  • GRAPHIC SET FIXED
  • GRAPHIC SET VIEW


GRAPHIC SET WORDWRAP - ScharfBASIC Help

GRAPHIC SET WORDWRAP

Enables or disables Graphic WordWrap Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET WORDWRAP [ NumrExpr& ]

Description

GRAPHIC SET WORDWRAP enables or disables WordWrap mode for the graphic target which is currently attached to the graphic stream . It has no effect on any other graphic target. If NumrExpr& is true (non-zero), WordWrap mode is enabled. If false (zero), wrap mode is disabled. If NumrExpr& is missing, the default is to enable WordWrap Mode.

With WordWrap Mode, you can control how ScharfBASIC prints text on a graphic target when it reaches the end of a line. Since a graphic target operates on a full page basis, the default is to ignore text which is printed past the end of the line.

When WordWrap mode is enabled, it affects only GRAPHIC PRINT operations. If GRAPHIC PRINT attempts to display a word beyond the end of a row, the entire word is automatically wrapped to the first column of the next row.

See Also

  • GRAPHIC CELL
  • GRAPHIC GET WORDWRAP
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC SPLIT


GRAPHIC SET WRAP - ScharfBASIC Help

GRAPHIC SET WRAP

Enables or disables Graphic Wrap Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SET WRAP [ NumrExpr& ]

Description

GRAPHIC SET WRAP enables or disables wrap mode for the graphic target which is currently attached to the graphic stream . It has no effect on any other graphic target. If NumrExpr& is true (non-zero), wrap mode is enabled. If false (zero), wrap mode is disabled. If NumrExpr& is missing, the default is to enable Wrap Mode.

With Wrap Mode, you can control how ScharfBASIC prints text on a graphic target when it reaches the end of a line. Since a graphic target operates on a full page basis, the default is to ignore text which is printed past the end of the line.

When Wrap Mode is enabled, it affects only GRAPHIC PRINT operations. If GRAPHIC PRINT attempts to display a character beyond the end of a row, it is automatically wrapped to the first column of the next row.

See Also

  • GRAPHIC CELL
  • GRAPHIC GET WRAP
  • GRAPHIC PRINT
  • GRAPHIC SET SCROLLTEXT
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SPLIT


GRAPHIC SPLIT - ScharfBASIC Help

GRAPHIC SPLIT

Splits a string into two parts for display on a graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC SPLIT [WORD] MainStr , Part1Len To Part1Var , Part2Var

Description

Generally speaking, GRAPHIC SPLIT allows you to determine how much text will fit on a line (or a line section), so you don't overrun the end. This is critical with variable-width fonts. Since these text characters have different widths, you cannot rely on a simple character count.

GRAPHIC SPLIT separates the MainStr string expression into two parts, which are then assigned to the two string variables specified by Part1Var and Part2Var. The numeric expression Part1Len specifies the maximum width of the print field, using page units (pixels, dialog units, scaled units ). After completion of GRAPHIC SPLIT, the Part1Var will contain those characters which can be safely displayed in the print field. The Part2Var will contain the remaining characters, which might be displayed on following lines.

Since this operation creates a " line break" not contemplated in the original text, you may have to modify the results in order to obtain the best appearance. For example, it's usually best to remove any leading spaces from Part2Var before printing it.

If the WORD option is included, ScharfBASIC guarantees that Part1Var will not end on a partial word. This may require that Part1Len is adjusted to a smaller value. In that case, Part2Var would be assigned these characters to compensate.

See Also

  • GRAPHIC CELL
  • GRAPHIC PRINT
  • GRAPHIC SET SCROLLTEXT
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • SPLIT


GRAPHIC STRETCH - ScharfBASIC Help

GRAPHIC STRETCH

Copy and resize a bitmap to the selected

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC STRETCH hBmp , ID , ( x1 , y1 )-( x2 , y2 ) TO ( x3 , y3 )-( x4 , y4 ) [, Mix , Stretch ]
GRAPHIC STRETCH PAGE hBmp , ID [, Mix , Stretch ]

Description

You can copy a complete bitmap, or a portion of it, to the selected graphic target , while resizing it to a larger or smaller size. The handle variable hBmp specifies the handle of the source bitmap, control, or window. The parameter ID is the control identifier (1 to 65535) assigned with the CONTROL ADD GRAPHIC . ID must be zero (0) for a GRAPHIC WIN DOW or a bitmap . The destination of the stretch operation is always the attached graphic target. The bitmap is automatically resized to fit the destination parameters. You must use care that your parameters are valid for the specified bitmap, or the result of the operation is undefined.

The second form, GRAPHIC STRETCH PAGE, is a shortcut for copying a complete bitmap to the clip or client area of the selected graphic target. The image is automatically stretched or condensed to fit the target appropriately.

If the Mix parameter is included, it is one of the values in the following table. If not included, or the value zero (0), a default of %mix_CopySrc is presumed. There are 16 mix modes available to use for mixing drawing colors with the colors which already exist at the drawing location. The mix mode equates are predefined in ScharfBASIC.

%mix_Blackness

Pixel is always 0 (black).

%mix_NotMergeSrc

Pixel is the inverse of the MergeSrc color.

%mix_MaskNotSrc

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%mix_NotCopySrc

Pixel is the inverse of the pen color.

%mix_MaskSrcNot

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%mix_Not

Pixel is the inverse of the pixel color.

%mix_XorSrc

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%mix_NotMaskSrc

Pixel is the inverse of the MaskSrc color.

%mix_MaskSrc

Pixel is a combination of the colors common to both the source and the pixel.

%mix_NotXorSrc

Pixel is the inverse of the XorSrc color.

%mix_Nop

Pixel remains unchanged.

%mix_MergeNotSrc

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_CopySrc

Pixel is the source color (default).

%mix_MergeSrcNot

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_MergeSrc

Pixel is a combination of the source color and the pixel color.

%mix_Whiteness

Pixel is always 1 (white).

Stretch

If the stretch& parameter is included, it is one of the values in the following table. If not included, or it is the value zero (0), the stretch mode is unchanged. An appropriate choice of stretch mode can substantially enhance the quality of bitmaps which are changed in size. The stretch mode equates are predefined in ScharfBASIC.

Equate

Description

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

See Also

  • GRAPHIC COPY
  • GRAPHIC IMAGELIST
  • GRAPHIC RENDER
  • GRAPHIC SET STRETCHMODE


GRAPHIC STYLE - ScharfBASIC Help

GRAPHIC STYLE

Set the line style to be used by various graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC STYLE linestyle&

Description

The graphic target must first be selected with GRAPHIC ATTACH . Due to limitations in the Windows graphics device interface (GDI), styles are only applied if the line width is set to 1, the default. If the line width is greater than 1, the style is interpreted as 0, solid.

Available line styles are:

Solid (default)

DashDot

DashDotDot

See Also

  • GRAPHIC ARC
  • GRAPHIC ATTACH
  • GRAPHIC BOX
  • GRAPHIC ELLIPSE
  • GRAPHIC LINE
  • GRAPHIC PIE
  • GRAPHIC WIDTH


GRAPHIC WIDTH - ScharfBASIC Help

GRAPHIC WIDTH

Set the line width to be used by various graphic

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WIDTH linewidth&

Description

If line width is set to a value greater than 1 (default), the line style is always interpreted to be 0 (solid).

See Also

  • GRAPHIC ARC
  • GRAPHIC BOX
  • GRAPHIC ELLIPSE
  • GRAPHIC LINE
  • GRAPHIC PIE
  • GRAPHIC STYLE


GRAPHIC WINDOW CLICK - ScharfBASIC Help

GRAPHIC WINDOW CLICK

Check whether a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW CLICK [ hwin& ] TO click& , x! , y!

Description

GRAPHIC WINDOW CLICK checks whether the specified GRAPHIC WINDOW has been clicked since the last time this statement was executed on this window. If so, the value one (1) is assigned to the click& variable for a single click, or two (2) for a double click. Also, the mouse position is assigned to x! and y! . If the has been no click, the value zero (0) is assigned to all three result variables.

In case of a double click, a click& value of one (1) is returned immediately after the first click, and a click& value of two (2) is also returned after the second click.

If the optional handle ( hwin& ) is omitted, the graphic window which is currently selected with GRAPHIC ATTACH is used.

See Also

  • GRAPHIC WINDOW


GRAPHIC WINDOW END - ScharfBASIC Help

GRAPHIC WINDOW END

Close and destroy a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW END [ hWin ]

Description

The GRAPHIC WINDOW identified by the handle hWin is closed and destroyed. If hWin is omitted, or is equal to zero (0), the currently attached graphic window is destroyed.

GRAPHIC WINDOW END can be used to close and destroy a graphic window at any time. Otherwise, the window is automatically destroyed when the program ends.

See Also

  • GRAPHIC DETACH
  • GRAPHIC WINDOW
  • GRAPHIC WINDOW HIDE


GRAPHIC WINDOW HIDE - ScharfBASIC Help

GRAPHIC WINDOW HIDE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW HIDE [ hWin ]

Description

The GRAPHIC WINDOW identified by the handle hWin is made invisible. If hWin is omitted, or is equal to zero (0), the currently attached graphic window is made invisible.

See Also

  • GRAPHIC WINDOW END
  • GRAPHIC WINDOW MINIMIZE
  • GRAPHIC WINDOW NONSTABLE
  • GRAPHIC WINDOW NORMALIZE
  • GRAPHIC WINDOW STABILIZE


GRAPHIC WINDOW MINIMIZE - ScharfBASIC Help

GRAPHIC WINDOW MINIMIZE

Minimize a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW MINIMIZE [ hWin ]

Description

The GRAPHIC WINDOW identified by the handle hWin is minimized. If hWin is omitted, or is equal to zero (0), the currently attached graphic window is minimized. You can restore the graphic window to its normal state with GRAPHIC WINDOW NORMALIZE .

See Also

  • GRAPHIC WINDOW HIDE
  • GRAPHIC WINDOW NONSTABLE
  • GRAPHIC WINDOW NORMALIZE
  • GRAPHIC WINDOW STABILIZE


GRAPHIC WINDOW NONSTABLE - ScharfBASIC Help

GRAPHIC WINDOW NONSTABLE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW NONSTABLE [ hWin ]

Description

The GRAPHIC WINDOW identified by the handle hWin is made non-stable, meaning that it can be closed by the user. If there is a system menu, the close option and the close box are enabled. The ALT-F4 close key is also enabled. This is the default mode of operation.

If hWin is omitted, or is equal to zero (0), the currently attached graphic window is made non-stable.

See Also

  • GRAPHIC WINDOW HIDE
  • GRAPHIC WINDOW MINIMIZE
  • GRAPHIC WINDOW NORMALIZE
  • GRAPHIC WINDOW STABILIZE


GRAPHIC WINDOW NORMALIZE - ScharfBASIC Help

GRAPHIC WINDOW NORMALIZE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW NORMALIZE [ hWin ]

Description

The GRAPHIC WINDOW identified by the handle hWin is made visible. If hWin is omitted, or is equal to zero (0), the currently attached graphic window is made visible.

See Also

  • GRAPHIC WINDOW HIDE
  • GRAPHIC WINDOW MINIMIZE
  • GRAPHIC WINDOW NONSTABLE
  • GRAPHIC WINDOW STABILIZE


GRAPHIC WINDOW STABILIZE - ScharfBASIC Help

GRAPHIC WINDOW STABILIZE

Make a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW STABILIZE [ hWin ]

Description

The GRAPHIC WINDOW identified by the handle hWin is stabilized, meaning that it cannot be closed by the user. If there is a system menu, the close option and the close box are grayed. The ALT-F4 close key is disabled. This allows you to be certain that your operations on the graphic window can be completed. When a graphic window is stabilized, only GRAPHIC WINDOW END or program termination will close it.

See Also

  • GRAPHIC WINDOW END
  • GRAPHIC WINDOW HIDE
  • GRAPHIC WINDOW MINIMIZE
  • GRAPHIC WINDOW NONSTABLE
  • GRAPHIC WINDOW NORMALIZE


GRAPHIC WINDOW - ScharfBASIC Help

GRAPHIC WINDOW

Creates a new standalone graphic window.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WINDOW NEW Caption$ , x& , y& , n Width& , n Height& [, hFont ] TO hWinVar [,HIDE|NORMALIZE]
GRAPHIC WINDOW TEXT Caption$ , x& , y& , n Rows& , n Columns& [, hFont ] TO hWinVar [,HIDE|NORMALIZE]

Description

A Graphic Window is a standalone window which is used to display most any form of text and graphics. After a graphic window has been created with this statement, GRAPHIC ATTACH would normally be used to choose it as the selected graphic target. However, if there is no selected graphic target at the time of creation, the new Graphic Window is automatically attached and selected. You can then draw text, lines , circles , and other forms with various statements.

GRAPHIC WINDOW END can be used to close and destroy the selected Graphic window at any time. Otherwise, the window is automatically destroyed when the program ends.

All ScharfBASIC graphical displays are persistent -- they are automatically redrawn for you after resuming from being minimized or temporarily covered by other windows.

The TEXT option is used to create a window oriented more towards the display of text. The size of the window is specified in rows and columns (rather than pixels ), based upon the size of initial font -- the default font (MS Sans Serif, 8 point) or the optional initial font specified by the Font parameter. This does not limit the ability to display graphics, as e very graphic function is still available. It simply makes it easier to create a window of the desired size. This option is best used with fonts which have a fixed width for each character (Courier, Lucida, etc.).

The parameter Caption$ contains the text to be displayed in the title or caption bar of the graphic window. If caption$ is empty (zero-length), the window is displayed without a title bar, so the appearance is different and the window cannot be dragged by the user.

The parameters x& and y& specify the location of the window, in pixels, relative to the upper left corner of the desktop.

The parameter nWidth& gives the width of the client area of the window, not including the frame. The width is specified in pixels.

The Parameter nHeight& gives the height of the client area of the window, not including the frame. The height is specified in pixels.

The parameter hFont specifies the handle of the initial font to be used in the GRAPHIC WINDOW. If this optional parameter is included, it is the handle of a font created with FONT NEW . This parameter is particularly important when you use the TEXT option, as the size of the window is based upon the size of the initial font. If not included, the default font (MS Sans Serif, 8 point) is selected for you.

The Long / DWord variable hWinVar receives the handle of the newly created window. If the window could not be created, hWinVar is assigned the value zero (0).

The option words HIDE or NORMALIZE determine whether the window will be made visible immediately. You may wish to initially hide the window so you can first make additional changes to it, such as with the GRAPHIC WINDOW STABILIZE statement. If neither HIDE nor NORMALIZE is chosen, the default is to show it immediately.

A newly-created GRAPHIC WINDOW automatically receives the focus. That is, keyboard input is directed to the graphic window until it is closed, or you choose another focus target.

See Also

  • CONTROL ADD GRAPHIC
  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC COLOR
  • GRAPHIC DETACH
  • GRAPHIC SET AUTOSIZE
  • GRAPHIC SET CAPTION
  • GRAPHIC SET CLIENT
  • GRAPHIC SET CLIP
  • GRAPHIC SET FIXED
  • GRAPHIC SET FONT
  • GRAPHIC SET LOC
  • GRAPHIC SET OVERLAP
  • GRAPHIC SET SCROLLTEXT
  • GRAPHIC SET SIZE
  • GRAPHIC SET STRETCHMODE
  • GRAPHIC SET VIRTUAL
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC WINDOW CLICK
  • GRAPHIC WINDOW END
  • GRAPHIC WINDOW HIDE
  • GRAPHIC WINDOW MINIMIZE
  • GRAPHIC WINDOW NONSTABLE
  • GRAPHIC WINDOW NORMALIZE
  • GRAPHIC WINDOW STABILIZE
  • TXT pseudo-object

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x209a54
call   0x202c98
push   0xc8
push   0xc8
call   0x201fdc
call   0x2042a2


GRAPHIC$(CAPTION) - ScharfBASIC Help

GRAPHIC$(CAPTION)

Retrieves the caption from a

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET CAPTION To CaptionVar$
CaptionVar$ = GRAPHIC$(CAPTION)

Description

GRAPHIC GET CAPTION retrieves the text (if any) which is currently displayed as the caption of the selected Graphic Target . This area is also called the "title bar". A Graphic Window is the only form of Graphic Target which may have a caption, so other forms will return a null (zero-length) string.

See Also

  • GRAPHIC SET CAPTION
  • GRAPHIC WINDOW


GRAPHIC$(INKEY$) - ScharfBASIC Help

GRAPHIC$(INKEY$)

Reads a keyboard character if one is ready.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC INKEY$ TO InkeyVar$
InkeyVar$ = GRAPHIC$(INKEY$)

Description

GRAPHIC INKEY$ returns a string of 0, 1, or 2 characters that reflects the status of the keyboard buffer for the selected graphic target. A null string (LEN=0) means that the buffer is empty - no key pressed.

A string length of one means that an ASCII key was pressed and the string contains the ASCII character. An ASCII value between 1 and 31 indicate a control code.

A string length of two means that an extended key was pressed. In this case, the first character in the string has an ASCII value of zero, and the second is the extended keyboard code.

See Also

  • GRAPHIC INPUT
  • GRAPHIC INPUT FLUSH
  • GRAPHIC INSTAT
  • GRAPHIC LINE INPUT
  • GRAPHIC WAITKEY$


GRAPHIC$(WAITKEY$) - ScharfBASIC Help

GRAPHIC$(WAITKEY$)

Reads a keyboard character or extended key, waiting until one is ready.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC WAITKEY$ [To WaitVar$ ]
GRAPHIC WAITKEY$ ([ KeyMask$ ] [, TimeOut& ]) [TO WaitVar$ ]
Function Form:
WaitVar$ = GRAPHIC$(WAITKEY$)
WaitVar$ = GRAPHIC$(WAITKEY$, [ KeyMask$ ] [, TimeOutVal& ])

Description

Reads a character or extended key from the keyboard without echoing anything to the screen. If no data is available, GRAPHIC WAITKEY$ will wait for an event to occur. It is very similar to GRAPHIC INKEY$, except that it waits for input to be available. While waiting, time slices are released to the operating system to reduce CPU load.

It returns a string of one or two characters if a key was pressed. If the TO clause is omitted, the keyboard character is discarded.

If the optional KeyMask$ expression is included, only a limited set of keys are recognized. KeyMask$ may include any number of Sub-Masks, one for each key to observe. For example, GRAPHIC WAITKEY$("YyNn") will recognize upper-case or lower-case Y or N (for yes/no answers), while any other key will be ignored. If KeyMask$ is omitted, or evaluates to a zero-length string, any key event will be recognized.

If the optional TimeOutVal& expression is included, it tells the maximum number of milliseconds to wait for a key. GRAPHIC WAITKEY$(5000) will wait a maximum of 5 seconds. The specified TimeOut period will only be approximate, so you should not rely upon precision accuracy. If the TimeOut period is exceeded, a zero-length string is returned. If the TimeOutVal& parameter is omitted, or evaluates to zero (0), it will wait an infinite length of time. The maximum TimeOut& permitted is one hour.

A string length of one ( LEN (i$) = 1) means that a standard character key was pressed. The result string contains the character. An ASC ()value between 1 and 31 indicates a control code.

A string length of two (LEN(i$) = 2) means that an extended key was pressed. In this case, the first character in the result string has an ASC() value of zero (0), and the second is the extended keyboard scan code. For example, pressing the F1 key will return CHR$ (0, 59).

See Also

  • GRAPHIC INKEY$
  • GRAPHIC INPUT
  • GRAPHIC INPUT FLUSH
  • GRAPHIC INSTAT
  • GRAPHIC LINE INPUT


GRAPHIC(CANVAS.X) - ScharfBASIC Help

GRAPHIC(CANVAS.X)

Retrieves the writable size of the attached graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET CANVAS TO WidthVar! , HeightVar!
WidthVar! = GRAPHIC(CANVAS.X)
HeightVar! = GRAPHIC(CANVAS.Y)

Description

GRAPHIC GET CANVAS retrieves the size of the drawing buffer for the attached graphic window, control, or bitmap. The size is specified in Page Units , so it could return scaled values if they were applied with GRAPHIC SCALE . If the graphic window or control is FIXED (the default), the size returned is equivalent to the CLIENT size (other than the scaling factor). The CANVAS size does not include a caption , frame, scrollbars, etc. If no graphic target has been attached with GRAPHIC ATTACH , the values 0,0 are returned.

See Also

  • GRAPHIC GET CLIENT
  • GRAPHIC GET CLIP
  • GRAPHIC GET SIZE
  • GRAPHIC GET SCALE
  • GRAPHIC SCALE


GRAPHIC(Cell.Size.X) - ScharfBASIC Help

GRAPHIC(Cell.Size.X)

Retrieve the character

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC CELL SIZE TO WidthVar! , HeightVar!
WidthVar! = GRAPHIC ( Cell.Size.X)
HeightVar! = GRAPHIC(Cell.Size.Y)

Description

GRAPHIC CELL SIZE retrieves the size of one character cell, for the current font , on the attached graphic target . The returned character size is specified in PAGE UNITS , and allows you to calculate the number of text lines which will fit in a particular space. The height value is the size of the displayed character, including external leading (if any) for this particular font.

If the font is a fixed-width font, like Courier New or Lucida Console,the sizes returned are as exact as possible, given the fractional rounding approximations necessary for some scaled units. If the font is proportional, like Arial or Times New Roman, the width will be the average size for the entire font.

External leading is the vertical distance from the bottom of one character to the top of the character below it. This value is specified by the font in use. It may vary from zero to a larger value, depending upon the font and point size. To retrieve the exact height of characters without external leading, use GRAPHIC CHR SIZE .

See Also

  • GRAPHIC CELL
  • GRAPHIC CHR SIZE
  • GRAPHIC SET FONT
  • GRAPHIC TEXT SIZE


GRAPHIC(Chr.Size.X) - ScharfBASIC Help

GRAPHIC(Chr.Size.X)

Retrieve the character size on the Graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC CHR SIZE To WidthVar!, HeightVar!
WidthVar! = GRAPHIC(Chr.Size.X)
HeightVar! = GRAPHIC(Chr.Size.Y)

Description

GRAPHIC CHR SIZE retrieves the size of one character, for the current font , on the attached graphic target. The returned character size is specified in Page Units . The height value is the actual size of the displayed character, without including external leading (if any) for this particular font.

If the font is a fixed-width font, like Courier New or Lucida Console,the sizes returned are as exact as possible, given the fractional rounding approximations necessary for some scaled units. If the font is proportional, like Arial or Times New Roman, the width will be the average size for the entire font.

External leading is the vertical distance from the bottom of one character to the top of the character below it. This value is specified by the font in use. It may vary from zero to a larger value, depending upon the font and point size. To retrieve the total row height including external leading, use GRAPHIC CELL SIZE instead.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC CELL SIZE
  • GRAPHIC SET FONT
  • GRAPHIC PRINT
  • GRAPHIC TEXT SIZE


GRAPHIC(Client.X) - ScharfBASIC Help

GRAPHIC(Client.X)

Retrieve the client size of the selected

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET CLIENT To WidthVar! , HeightVar!
WidthVar! = GRAPHIC(Client.X)
HeightVar ! = GRAPHIC(Client.Y)

Description

GRAPHIC GET CLIENT retrieves the physical size of the client area (visible part) of the attached graphic window or control . The size is specified in Pixels or Dialog Units , depending upon how it was created. The sizes returned are not altered or affected by GRAPHIC SCALE , VIRTUAL , or AUTOSIZE operations, as it returns the physical size of the viewable area in the terms used to create it. The client area does not include a caption , frame, scrollbars, etc. When GRAPHIC GET CLIENT is used with a bitmap , it returns 0,0. You would normally use GRAPHIC GET CANVAS with a Bitmap, or to obtain the size of the area which can be drawn. If no graphic target has been attached with GRAPHIC ATTACH , the values 0,0 are returned.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC GET CANVAS
  • GRAPHIC GET CLIP
  • GRAPHIC GET SIZE
  • GRAPHIC SET CLIENT


GRAPHIC(Clip.X) - ScharfBASIC Help

GRAPHIC(Clip.X)

Retrieves the size of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET CLIP TO WidthVar! , HeightVar!
WidthVar! = GRAPHIC(Clip.X)
HeightVar! = GRAPHIC(Clip.Y)

Description

The clip area of a graphic target is that space where GRAPHIC operations can be displayed. That is, the clip area is that portion of the client area which is not protected (clipped) by GRAPHIC SET CLIP .

GRAPHIC GET CLIP retrieves the size of the clip area, and assigns these values to the variables specified by WidthVar! and HeightVar! . The size is specified in PAGE UNITS . If no graphic target is selected, the values 0,0 are returned.

See Also

  • GRAPHIC GET CANVAS
  • GRAPHIC GET CLIENT
  • GRAPHIC SET CLIP


GRAPHIC(COL) - ScharfBASIC Help

GRAPHIC(COL)

Sets or retrieves the next

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC CELL = RowValue& , ColValue&
GRAPHIC CELL TO RowVar& , ColVar&
GRAPHIC COL TO ColVar&
GRAPHIC ROW TO RowVar&
ColVar& = GRAPHIC(COL)
RowVar& = GRAPHIC(ROW)

Description

GRAPHIC CELL is used to set or retrieve the print position, based upon the row and column position of a Text Cell. That is the row column position where the next printed text will be displayed. These operations are very similar to GRAPHIC GET POS and GRAPHIC SET POS , except that the position is reported in text rows and columns, rather than Page Units . The current graphic position is translated to a row and column number, based upon the standard character size in a fixed width font , or the average character size for a variable width font.

RowValue& specifies the horizontal screen row (starting at 1) at which to position the cursor. ColValue& specifies the vertical screen column (starting at 1) at which to position the cursor. Since row and column numbers start at one (1), the upper left corner of the window is considered to be cell 1,1.

The first form of GRAPHIC CELL moves the print position to the desired row and column. If a value given is zero (0), that parameter is ignored and that position is not changed.

The second form of GRAPHIC CELL retrieves the current print position, and assigns the values to the variables specified by RowVar& and ColVar& . Every point which falls within a text character cell is reported as that Row/Column position. If the graphic position is not at the upper left corner of the text character, you may get imprecise or unexpected results. This can occur if you perform a graphic operation other than GRAPHIC PRINT which leaves the "Last Point Referenced" at a mid-cell position.

The remaining forms allow you to retrieve just a single value, either row or column, and are supported in both statement and function form.

See Also

  • GRAPHIC CELL SIZE
  • GRAPHIC GET POS
  • GRAPHIC SET FONT
  • GRAPHIC SET POS
  • GRAPHIC SET SCROLLTEXT
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC SPLIT


GRAPHIC(DC) - ScharfBASIC Help

GRAPHIC(DC)

Retrieve the handle of the DC (device context) for the selected

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET DC TO hDC???
Function Form:
DCVar??? = GRAPHIC(DC)

Description

The DC handle may be used with various Windows API functions to perform specialized graphic operations in the graphic target. If no graphic window is currently selected, zero is returned.

See Also

  • GRAPHIC ATTACH


GRAPHIC(INSTAT) - ScharfBASIC Help

GRAPHIC(INSTAT)

Determines whether a keyboard character is ready.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC INSTAT TO NumericVar
InstatVar& = GRAPHIC(INSTAT)

Description

The integral variable receives the keyboard buffer status for the selected graphic target . The value assigned is TRUE (non-zero) if a keyboard character is ready to be retrieved, or FALSE (zero) if not.

GRAPHIC INSTAT does not remove the character from the buffer, so repeated execution will continue to return TRUE until the character is read with GRAPHIC INKEY$ , GRAPHIC INPUT , etc.

See Also

  • GRAPHIC INKEY$
  • GRAPHIC INPUT
  • GRAPHIC INPUT FLUSH
  • GRAPHIC LINE INPUT
  • GRAPHIC WAITKEY$


GRAPHIC(LINES) - ScharfBASIC Help

GRAPHIC(LINES)

Retrieves the number of

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET LINES TO linecount&
linecount& = GRAPHIC(LINES)

Description

GRAPHIC GET LINES retrieves the number of lines of text which will fit on the graphic target, given the current selected font . This value is assigned to linecount& .

See Also

  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC CHR SIZE
  • GRAPHIC PRINT
  • GRAPHIC SET FONT
  • GRAPHIC TEXT SIZE


GRAPHIC(LOC.X) - ScharfBASIC Help

GRAPHIC(LOC.X)

Retrieves the location of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET LOC TO x& , y&
F unction Form:
x& = GRAPHIC(LOC.X)
y& = GRAPHIC(LOC.Y)

Description

This statement retrieves the location of the selected Graphic Window. If no graphic object is selected, or it is not a Graphic Window, 0,0 is returned. The location is specified in pixels, relative to the upper left corner of the screen.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC GET PPI
  • GRAPHIC SET LOC


GRAPHIC(MIX) - ScharfBASIC Help

GRAPHIC(MIX)

Retrieve the color mix mode for the selected

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET MIX TO mixmode&
mixmode& = GRAPHIC(MIX)

Description

There are 16 mix modes available to use for mixing the drawing color with the color that already exists at the drawing location.

%mix_Blackness

Pixel is always 0 (black).

%mix_NotMergeSrc

Pixel is the inverse of the MergeSrc color.

%mix_MaskNotSrc

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%mix_NotCopySrc

Pixel is the inverse of the pen color.

%mix_MaskSrcNot

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%mix_Not

Pixel is the inverse of the pixel color.

%mix_XorSrc

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%mix_NotMaskSrc

Pixel is the inverse of the MaskSrc color.

%mix_MaskSrc

Pixel is a combination of the colors common to both the source and the pixel.

%mix_NotXorSrc

Pixel is the inverse of the XorSrc color.

%mix_Nop

Pixel remains unchanged.

%mix_MergeNotSrc

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_CopySrc

Pixel is the source color (default).

%mix_MergeSrcNot

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_MergeSrc

Pixel is a combination of the source color and the pixel color.

%mix_Whiteness

Pixel is always 1 (white).

See Also

  • GRAPHIC SET MIX


GRAPHIC(OVERLAP) - ScharfBASIC Help

GRAPHIC(OVERLAP)

Retrieves the status of Graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET OVERLAP To OverlapVar&
OverlapVar& = GRAPHIC(OVERLAP)

Description

GRAPHIC GET OVERLAP retrieves the status of overlap mode and assigns it to the variable specified by OverlapVar& . If Overlap Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the graphic target which is currently attached to the graphic stream .

With Overlap Mode, you control how ScharfBASIC treats graphic operations which involve a RECT structure in their definition. Windows graphic conventions consider the bottom and right coordinates of a RECT to be exclusive. In other words, the pixels at the bottom and right edges lie immediately outside the rectangle. They are not drawn, but are ignored. For example:

GRAPHIC BOX (0,0) - (50,50)

In this case, a box is drawn from 0,0 to 49,49. The final pixels at the bottom and right edge are simply not drawn. However, if Overlap Mode is enabled with GRAPHIC SET OVERLAP , the box is drawn from 0,0 to 50,50.

The Overlap Mode affects drawing operations involving GRAPHIC SCALE , GRAPHIC BOX , GRAPHIC ELLIPSE , GRAPHIC LINE , GRAPHIC POLYLINE , etc.

See Also

  • GRAPHIC SET OVERLAP


GRAPHIC(PIXEL...) - ScharfBASIC Help

GRAPHIC(PIXEL...)

Retrieve the color of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET PIXEL [STEP] ( x! , y! ) To PixelVar&
PixelVar& = GRAPHIC(PIXEL [STEP], x! , y! )

Description

The coordinate points x! , y! are specified in Page Units .

See Also

  • GRAPHIC ATTACH
  • GRAPHIC COLOR
  • GRAPHIC SCALE
  • GRAPHIC SET PIXEL


GRAPHIC(POS.X) - ScharfBASIC Help

GRAPHIC(POS.X)

Retrieve the POS (last point referenced) by a graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET POS To XVar! , YVar!
XVar! = GRAPHIC(POS.X)
YVar! = GRAPHIC(POS.Y)

Description

The coordinate points XVar! , YVar! are specified in the same terms ( pixels or dialog units) as the parent dialog (or world coordinates, if those were chosen with GRAPHIC SCALE ).

See Also

  • GRAPHIC ATTACH
  • GRAPHIC CELL
  • GRAPHIC SCALE
  • GRAPHIC SET POS


GRAPHIC(PPI.X) - ScharfBASIC Help

GRAPHIC(PPI.X)

Retrieve the resolution of the display device, in points per inch.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET PPI TO XVar& , YVar&
XVar& = GRAPHIC(PPI.X)
YVar& = GRAPHIC(PPI.Y)

Description

The resolution is always specified in pixels . This statement is particularly useful in drawing items such as rulers and graphs to a representative physical size". There are 25.4 millimeters per inch, so just divide by 25.4 to convert from pixels per inch to pixels per millimeter.

"Representative physical size" means that the actual image may be close to a particular physical size, but is subject to factors including Windows default PPI setting, the driver's DPI to PPI ratio and even how the monitor has been adjusted. By using the GRAPHIC GET PPI, results, you can construct a representative graphic image that can be saved and later output at the intended scale by more precise means, for example a higher resolution Windows printer.

See Also

  • GRAPHIC ATTACH
  • GRAPHIC SCALE


GRAPHIC(SCROLLTEXT) - ScharfBASIC Help

GRAPHIC(SCROLLTEXT)

Retrieves the status of Graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET SCROLLTEXT To ScrollVar&
ScrollVar& = GRAPHIC(SCROLLTEXT)

Description

GRAPHIC GET SCROLLTEXT retrieves the status of ScrollText mode and assigns it to the variable specified by ScrollVar& . If ScrollText Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the graphic target which is currently attached to the graphic stream .

With ScrollText Mode, you can control how ScharfBASIC prints text on a graphic target when it reaches the end of a page. Since a graphic target operates on a full page basis, the default is to ignore text which is printed past the end of the page. This can be modified under program control by using GRAPHIC SET SCROLLTEXT .

When ScrollText Mode is enabled, scrolling of a page is triggered only by GRAPHIC PRINT . If the POS (last point referenced) is located on the bottom row of the graphic target, and a GRAPHIC PRINT statement moves the POS off of the page, the entire contents of the graphic target is scrolled one row, and a new blank row is opened at the bottom.

See Also

  • GRAPHIC CELL
  • GRAPHIC SET SCROLLTEXT


GRAPHIC(SIZE.X) - ScharfBASIC Help

GRAPHIC(SIZE.X)

Retrieves the overall size of the selected graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET SIZE To WidthVar& , HeightVar&
WidthVar& = GRAPHIC(SIZE.X)
HeightVar& = GRAPHIC(SIZE.Y)

Description

GRAPHIC GET SIZE retrieves overall physical size of the selected graphic window or control . The size is specified in Pixels or Dialog Units , depending upon how it was created. The size always includes any caption , frame, scrollbars, etc. If no graphic target is attached, the values 0,0 are returned.

See Also

  • GRAPHIC GET CANVAS
  • GRAPHIC GET CLIENT
  • GRAPHIC GET CLIP
  • GRAPHIC GET LINES
  • GRAPHIC SET SIZE


GRAPHIC(STRETCHMODE) - ScharfBASIC Help

GRAPHIC(STRETCHMODE)

Retrieves the default bitmap stretching mode for the attached

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET STRETCHMODE TO ModeVar&
ModeVar& = GRAPHIC(STRETCHMODE)

Description

There are several operations in ScharfBASIC which involve stretching or condensing images on bitmaps, most notably GRAPHIC STRETCH . As individual pixels must be added or removed, there is a good chance that the quality of the image will be degraded. However, if you describe the nature of the image by defining a StretchMode, you can substantially enhance the appearance.

The default StretchMode is maintained individually for each DC. You can retrieve the default mode with this statement, or set it with GRAPHIC GET STRETCHMODE. Of course, you can also override the default StretchMode when you execute one of the affected statements.

The 4 stretch mode equates are predefined in ScharfBASIC.

Equate

Description

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

See Also

  • GRAPHIC BITMAP LOAD
  • GRAPHIC COPY
  • GRAPHIC RENDER
  • GRAPHIC SET STRETCHMODE
  • GRAPHIC STRETCH


GRAPHIC(TEXT.SIZE.X...) - ScharfBASIC Help

GRAPHIC(TEXT.SIZE.X...)

Calculate the size of text to be

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC TEXT SIZE txt$ TO WidthVar! , HeightVar!
Function Form:
WidthVar! = GRAPHIC(TEXT.SIZE.X, txt$ )
HeightVar! = GRAPHIC(TEXT.SIZE.Y, txt$ )

Description

This statement calculates the total size of the printed text, based upon the current font for the graphic target . The sizes returned are specified in Page Units .

This allows you to easily calculate the appropriate print position, particularly when using a proportional font.

See Also

  • FONT NEW
  • GRAPHIC CELL
  • GRAPHIC CELL SIZE
  • GRAPHIC CHR SIZE
  • GRAPHIC PRINT
  • GRAPHIC SET FONT
  • GRAPHIC SCALE
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC SPLIT


GRAPHIC(View.X) - ScharfBASIC Help

GRAPHIC(View.X)

Retrieves the position of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET VIEW To WidthVar! , HeightVar!
WidthVar! = GRAPHIC(View.X)
HeightVar! = GRAPHIC(View.Y)

Description

Retrieves the position of the viewport on a virtual graphic target . The size is specified in Page Units . If no graphic target has been selected, or no virtual window has been created, the values 0,0 are returned.

See Also

  • GRAPHIC SET VIEW
  • GRAPHIC SET VIRTUAL


GRAPHIC(WORDWRAP) - ScharfBASIC Help

GRAPHIC(WORDWRAP)

Retrieves the status of Graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET WORDWRAP TO WrapVar&
WrapVar& = GRAPHIC(WORDWRAP)

Description

GRAPHIC GET WORDWRAP retrieves the status of wordwrap mode and assigns it to the variable specified by WrapVar& . If WordWrap Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the graphic target which is currently attached to the graphic stream .

With WordWrap Mode, you can control how ScharfBASIC prints text on a graphic target when it reaches the end of a line. Since a graphic target operates on a full page basis, the default is to ignore text which is printed past the end of the line. This can be modified under program control by using GRAPHIC SET WORDWRAP .

When WordWrap mode is enabled, it affects only GRAPHIC PRINT operations. If GRAPHIC PRINT attempts to display a word beyond the end of a row, the entire word is automatically wrapped to the first column of the next row.

See Also

  • GRAPHIC CELL
  • GRAPHIC GET WRAP
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC SPLIT


GRAPHIC(WRAP) - ScharfBASIC Help

GRAPHIC(WRAP)

Retrieves the status of Graphic

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GRAPHIC GET WRAP TO WrapVar&
WrapVar& = GRAPHIC(WRAP)

Description

GRAPHIC GET WRAP retrieves the status of wrap mode and assigns it to the variable specified by WrapVar& . If Wrap Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the graphic target which is currently attached to the graphic stream .

With Wrap Mode, you can control how ScharfBASIC prints text on a graphic target when it reaches the end of a line. Since a graphic target operates on a full page basis, the default is to ignore text which is printed past the end of the line. This can be modified under program control by using GRAPHIC SET WRAP .

When Wrap Mode is enabled, it affects only GRAPHIC PRINT operations. If GRAPHIC PRINT attempts to display a character beyond the end of a row, it is automatically wrapped to the first column of the next row.

See Also

  • GRAPHIC CELL
  • GRAPHIC GET WORDWRAP
  • GRAPHIC SET WORDWRAP
  • GRAPHIC SET WRAP
  • GRAPHIC SPLIT


Graphics - ScharfBASIC Help

Graphics

This version of ScharfBASIC offers an excellent graphics package for most any programming need. It's fast. It's complete. And it handles all those messy Windows details for you... automatically!

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

First, it's good to know that graphics in ScharfBASIC are persistent. Create it once... and forget it. You'll never worry about redrawing when your window is minimized or temporarily covered. ScharfBASIC handles everything. Automatically!

So, how about a quick overview? Just what can you do? First, how about some fancy text? Any font. Any size. Any color. Bold. Italic. Underline and Strikeout. Mix any combination of fonts on a single Window. Print just about anything, just about anywhere. Then add bitmaps. Stretch them or condense them. Copy them or change them. Circles, ovals, lines and boxes. Fat lines, skinny lines, ellipses, rounded rectangles. Filled forms or empty. Colors or not. You'll create a custom scaling system -- even with fractional floating point coordinates!

So, let's get started. You should know that almost every graphical function name starts with the word GRAPHIC . You'll find all of them together in the help file or the book.

Step one -- you'll need a canvas. A place to create these works of art. So, create a GRAPHIC WINDOW . Or two. Or ten. They'll be visible right away and give you quick feedback.

GRAPHIC WINDOW "PowerGraphics", 600, 200, 400, 300 TO hWin???

You'll get a new window, with the title "PowerGraphics". It's positioned on the upper right side of the screen at x=600, y=200. It's 400 pixels wide, and 300 pixels high.

A second option is a memory bitmap. These aren't visible at all. You create your image "behind-the-scenes", then copy or stretch it to a visible window whenever you're ready. Use GRAPHIC BITMAP NEW for a blank bitmap, or GRAPHIC BITMAP LOAD to get one from a resource or a disk file. You can have one window or five. One bitmap or twenty. As each is created, it returns a handle that you need to save. That's how you'll identify each of your canvases.

Use GRAPHIC ATTACH to choose a "graphic target". This tells ScharfBASIC which window or memory bitmap to use, for the actions which follow. Until you execute another GRAPHIC ATTACH to change it again. Move back and forth, as often as necessary. There is no limitation here.


HEADER GET COUNT - ScharfBASIC Help

HEADER GET COUNT

Manipulate a HEADER control in order to set/retrieve data.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

HEADER SEND hWin , ID& , Msg& , wParam& , lParam& [TO ResultVar& ]

Description

The HEADER statement is used to communicate with a HEADER control to set or retrieve various types of data. While you may create a custom header control for your own purposes, the most common usage is to communicate with the HEADER control which is embedded in every LISTVIEW control.

To communicate with a LISTVIEW HEADER, use the LISTVIEW GET HEADERID to get the values for the hWin and ID& parameters. Otherwise, those parameters would be assigned as with any other control.

HEADER GET COUNT hWin , ID& TO CountVar&

Retrieves the count of the items in a header control. If the operation was successful, the count value is assigned to the variable specified by CountVar& . If the operation failed, the value -1 is assigned to CountVar& instead.

HEADER GET ITEM hWin , ID& , Index& , ItemPtr [TO ResultVar& ]

Retrieves an HD_Item structure which describes an item in a Header Control. Index& defines the item to be retrieved (1=first, 2=second, etc.). ItemPtr is the address of an HD_Item structure to be filled. If the operation succeeds, true is assigned to the variable specified by ResultVar& . If it fails, false is assigned instead.

HEADER SEND hWin , ID& , Msg& , wParam& , lParam& [TO ResultVar& ]

A window message specified by Msg& is sent to the HEADER control, along with message dependent parameters (if any). If a result is returned, it is assigned to the variable specified by ResultVar& .

HEADER SET ITEM hWin , ID& , Index& , ItemPtr [TO ResultVar& ]

Sets the attributes of the specified item in a Header Control. Index& defines the item to be set (1=first, 2=second, etc.). ItemPtr is the address of an HD_Item structure which defines the attributes. If the operation succeeds, true is assigned to the variable specified by ResultVar& . If it fails, false is assigned instead.

See Also

  • LISTVIEW


IMAGELIST ADD BITMAP - ScharfBASIC Help

IMAGELIST ADD BITMAP

Create and manage an IMAGELIST object to use with other functions.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

IMAGELIST ADD BITMAP hLst , hBmp [, hMsk ] [TO dataValue& ]
IMAGELIST ADD BITMAP hLst , Bmp$ [, Msk$ ] [TO dataValue& ]
IMAGELIST ADD ICON hLst , hIcn [TO dataValue& ]
IMAGELIST ADD ICON hLst , Icn$ [TO dataValue& ]
IMAGELIST ADD MASKED hLst , hBmp , rgbColor& [TO dataValue& ]
IMAGELIST ADD MASKED hLst , Bmp$ , rgbColor& [TO dataValue& ]
IMAGELIST GET COUNT hLst TO dataValue&
IMAGELIST KILL hLst
IMAGELIST NEW BITMAP|ICON nWidth& , nHeight& , depth& , initial& TO hLst
IMAGELIST SET OVERLAY hLst , image& , overlay&

Description

An IMAGELIST is a structure which contains any number of graphical images, either bitmaps or icons, but not a mixture. All of the images are automatically converted to the type, size, and color depth specified when the IMAGELIST is created. A bitmap (file type *.BMP) is a single color image, while an icon (file type *.ICO) supports transparency by including both a color bitmap and a mask bitmap. The mask bitmap is a monochrome image (one bit per pixel ), where each "set" bit describes a pixel which remains transparent. The IMAGELIST structure can best be described as a set, or array , of images. You can retrieve the images individually by index number, or pass the entire IMAGELIST to a control which requires it ( LISTVIEW , etc.).

An empty ImageList is first created with IMAGELIST NEW. Images are then added with IMAGELIST ADD, until the structure is complete. If you add an image which is wider than the size specified by nWidth& , the image is separated into multiple bitmaps, each of which is added in sequence. When an IMAGELIST is attached to a control like LISTVIEW, it is usually destroyed automatically when the control is destroyed. Consult the control documentation for that information. If not, you must explicitly destroy it with IMAGELIST KILL.

IMAGELIST ADD BITMAP hLst , hBmp [, hMsk ] [TO dataValue& ]

An image is added to the ImageList specified by hLst . With this syntax, the image is specified by a handle ( hBmp ), so it must have been loaded into memory (e.g. with string ). If the ImageList is an ICON type, a second mask bitmap is also specified by a handle (hMsk). If the TO clause is included, the index position of the first added bitmap (starting with 1) is assigned to the variable designated by dataValue&. If the operation fails, the value 0 is assigned.

IMAGELIST ADD BITMAP hLst , Bmp$ [, Msk$ ] [TO dataValue& ]

An image is added to the ImageList specified by hLst . With this syntax, the image is specified by a name string (Bmp$), which is the name of an embedded resource or a disk file. If the name string contains a period, it is presumed to be a disk file. Otherwise, an attempt is made to load it from a resource - if not found, it is then presumed to be a disk file. If the image name is a numeric resource, it should be described with a leading pound sign ("#12345"). If the ImageList is an ICON type, a second mask bitmap is also specified by a handle (hMsk). If the TO clause is included, the index position of the first added bitmap (starting with 1) is assigned to the variable designated by dataValue&. If the operation fails, the value 0 is assigned.

IMAGELIST ADD ICON hLst , hIcn [TO dataValue& ]

An icon is added to the ImageList specified by hLst . With this syntax, the icon is specified by a handle ( hIcn ), so it must have been loaded into memory (e.g. with the WinApi LoadIcon. If the TO clause is included, the index position of the first added icon (starting with 1) is assigned to the variable designated by dataValue& . If the operation fails, the value 0 is assigned.

IMAGELIST ADD ICON hLst , Icn$ [TO dataValue& ]

An icon is added to the ImageList specified by hLst . With this syntax, the icon is specified by a name string ( Icn$ ), which is the name of an embedded resource or a disk file. If the name string contains a period, it is presumed to be a disk file. Otherwise, an attempt is made to load it from a resource - if not found, it is then presumed to be a disk file. If the icon name is a numeric resource, it should be described with a leading pound sign ("#12345"). If the TO clause is included, the index position of the first added bitmap (starting with 1) is assigned to the variable designated by dataValue& . If the operation fails, the value 0 is assigned.

IMAGELIST ADD MASKED hLst , hBmp , rgbColor& [TO dataValue& ]

A bitmap is added to the icon ImageList specified by hLst . With this syntax, the bitmap is specified by a handle ( hBmp ), so it must have been loaded into memory (e.g. with GRAPHIC BITMAP). The parameter rgbColor& specifies the RGB color used in the bitmap to specify transparent pixels. Each pixel of that color is changed to the color black, and a mask bitmap is created to describe the transparent pixels. If the TO clause is included, the index position of the first added icon (starting with 1) is assigned to the variable designated by dataValue& . If the operation fails, the value 0 is assigned.

IMAGELIST ADD MASKED hLst , Bmp$ , rgbColor& [TO dataValue& ]

A bitmap is added to the icon ImageList specified by hLst . With this syntax, the bitmap is specified by a name string ( Bmp$ ), which is the name of an embedded resource or a disk file. If the name string contains a period, it is presumed to be a disk file. Otherwise, an attempt is made to load it from a resource - if not found, it is then presumed to be a disk file. If the image name is a numeric resource, it should be described with a leading pound sign ("#12345"). The parameter rgbColor& specifies the RGB color used in the bitmap to specify transparent pixels. Each pixel of that color is changed to the color black, and a mask bitmap is created to describe the transparent pixels. If the TO clause is included, the index position of the first added bitmap (starting with 1) is assigned to the variable designated by dataValue& . If the operation fails, the value 0 is assigned.

IMAGELIST GET COUNT hLst TO dataValue&

The number of images in the IMAGELIST is retrieved, and assigned to the long integer variable specified by dataValue& .

IMAGELIST KILL hLst

The IMAGELIST specified by hLst is destroyed. All allocated memory and resources are released.

IMAGELIST NEW BITMAP|ICON nWidth& , nHeight& , depth& , initial& TO hLst

A new ImageList structure is created. If you specify BITMAP, each image you add will be stored as a single bitmap. If you specify ICON, each image you add will be stored as two bitmaps in order to support transparent areas. The parameters nWidth& and nHeight& specify the size of each image in pixels. The depth& parameter specifies the color depth in bits per pixel (4,8,16,24,32). A depth of 4 offers 16 colors, 8 offers 256 colors, etc. The initial& parameter specifies the initial size of the ImageList. While it can grow beyond this number, it is most efficient to allocate space accurately at the time of creation. The variable hLst receives the handle of the newly created ImageList, or zero if the operation failed.

IMAGELIST SET OVERLAY hLst , image& , overlay&

The image specified by the index number image & is declared to be an overlay image. The overlay& parameter must be in the range of 1 to 15, and it is used later to retrieve and/or specify this particular overlay image.

See Also

  • GRAPHIC BITMAP LOAD
  • GRAPHIC BITMAP NEW
  • GRAPHIC IMAGELIST
  • LISTVIEW
  • TAB SET IMAGELIST
  • TREEVIEW
  • XPRINT IMAGELIST


LISTBOX ADD - ScharfBASIC Help

LISTBOX ADD

Manipulate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LISTBOX ADD hDlg , id& , StrExpr [TO datav& ]
LISTBOX DELETE hDlg , id& , item&
LISTBOX FIND hDlg , id& , item& , StrExpr TO datav&
LISTBOX FIND EXACT hDlg , id& , item& , StrExpr TO datav&
LISTBOX GET COUNT hDlg , id& TO datav&
LISTBOX GET SELCOUNT hDlg , id& TO datav&
LISTBOX GET SELECT hDlg , id& [, item& ] TO datav&
LISTBOX GET STATE hDlg , id& , item& TO datav&
LISTBOX GET TEXT hDlg , id& [, item& ] TO txtv$
LISTBOX GET USER hDlg , id& , item& TO datav&
LISTBOX INSERT hDlg , id& , item& , StrExpr [TO datav& ]
LISTBOX RESET hDlg , id&
LISTBOX SELECT hDlg , id& , item&
LISTBOX SET TEXT hDlg , id& , item& , StrExpr
LISTBOX SET USER hDlg , id& , item& , NumExpr
LISTBOX UNSELECT hDlg , id& [, item& ]

Description

In each of the following samples and descriptions, the LISTBOX control which is the subject of the statement is identified by the handle of the dialog that owns the LISTBOX ( hDlg ), and the unique control identifier you gave it upon creation in CONTROL ADD LISTBOX.

The value item& refers to the position of the string data item in the LISTBOX, and is always indexed to one. The first string is position 1, the second is position 2, and so forth.

LISTBOX ADD hDlg , id& , StrExpr [TO datav& ]

The string value specified by StrExpr is added to the LISTBOX control. If the LISTBOX has the %LBS_SORT style, the new string is inserted in alphanumeric order; otherwise it is added to the end of the existing list. If the optional TO clause is included, the index position of the added string is assigned to the variable represented by datav& . The index is one for the first string, two for the second, etc. If the index is less than one, an error occurred and no string was added.

LISTBOX DELETE hDlg , id& , item&

The string at the position specified by item& is deleted from the LISTBOX. The parameter item& is indexed to one (1 for the first string, 2 for the second, and so on).

LISTBOX FIND hDlg , id& , item& , StrExpr TO datav&

Strings in the LISTBOX are searched to find the first string which begins with the data in StrExpr , regardless of any characters which follow. Comparisons are not case-sensitive. Strings are searched beginning with the string specified by item& , and ending with the last string in the LISTBOX. Searching does not wrap to the beginning of the list. The item number ( item& ) is indexed to 1 (1=first, 2=second, etc.). To search the entire LISTBOX starting with the first string, item& should be set to one (1). If a matching string is found, the index value of the match is assigned to the variable specified by datav& . If no match is found, the value zero (0) is assigned to it.

LISTBOX FIND EXACT hDlg , id& , item& , StrExpr TO datav&

Strings in the LISTBOX are searched to find the first string which exactly matches the data in StrExpr . Comparisons are not case-sensitive. Strings are searched beginning with the string specified by item& , and ending with the last string in the LISTBOX. Searching does not wrap to the beginning of the list. The item number ( item& ) is indexed to 1 (1=first, 2=second, etc.). To search the entire LISTBOX starting with the first string, item& should be set to one (1). If a matching string is found, the index value of the match is assigned to the variable specified by datav& . If no match is found, the value zero (0) is assigned to it.

LISTBOX GET COUNT hDlg , id& TO datav&

The number of items in the LISTBOX is retrieved, and assigned to the long integer variable specified by datav& .

LISTBOX GET SELCOUNT hDlg , id& TO datav&

The number of selected items in the LISTBOX is retrieved, and assigned to the long integer variable specified by datav& .

LISTBOX GET SELECT hDlg , id& [, item& ] TO datav&

The LISTBOX is searched to find the first selected item. If the item& parameter is included, searching starts at that position to facilitate retrieving multiple selected items. If item& is omitted, the search starts at the first data item. The index number of the selected item is assigned to the variable designated by datav& . If no item is selected, the value zero (0) is assigned to it.

LISTBOX GET STATE hDlg , id& , item& TO datav&

A data item is checked to see if it is currently selected. The numeric value item& specifies which user value is to be checked, 1 for the first item, 2 for the second item, etc. If the item is selected, -1 ( true ) is assigned to the variable specified by datav& . Otherwise, 0 ( false ) is assigned to it.

LISTBOX GET TEXT hDlg , id& [, item& ] TO txtv$

Text is retrieved from the LISTBOX and assigned to the string variable specified by txtv$ . If the numeric expression item& is included, it determines which text string is returned, 1 for the first item, 2 for the second item, etc.

The parameter item& may be omitted, or contain the value zero (0). In the case of a single-selection listbox, the current selected text (if any) is retrieved and assigned to txtv$ . With a multiple-selection listbox ( %LBS_MULTIPLESEL or %LBS_EXTENDEDSEL style), the text of the first (base) selected item is assigned to txtv$ . To retrieve additional selected text items from a multiple-selection listbox, use LISTBOX GET SELECT to retrieve selected item numbers. Then apply the item numbers with LISTBOX GET TEXT to retrieve the string data.

LISTBOX GET USER hDlg , id& , item& TO datav&

Each item in a LISTBOX may have a long integer user value associated with it at the discretion of the programmer. This user value is retrieved with LISTBOX GET USER. The numeric value item& specifies which user value is requested, 1 for the first item, 2 for the second item, etc. The returned user value is assigned to the long integer variable specified by datav& . LISTBOX user values are assigned with the LISTBOX SET USER statement. In addition to these LISTBOX user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER .

LISTBOX INSERT hDlg , id& , item& , StrExpr [TO datav& ]

The text for a new data item, specified by StrExpr , is inserted at the location given by item& . The value of item& = 1 for the first item, 2 for the second item, etc. The list of data items is not re-sorted, even if the LISTBOX was created with the style %LBS_SORT . If you wish to sort all of the items, use LISTBOX ADD instead. If the optional TO clause is included, the index position of the inserted string is assigned to the variable represented by datav& . The index is one for the first string, two for the second, etc. If the index is less than one, an error occurred and no string was inserted.

LISTBOX RESET hDlg , id&

Delete all contents of the specified LISTBOX.

LISTBOX SELECT hDlg , id& , item&

The string data item specified by item& is chosen as selected text for the LISTBOX control, and the selected text is scrolled into a visible position. The value of item& = 1 for the first item, 2 for the second item, etc. If the value of item& = 0 with a multiple selection listbox, then all string data items are selected. LISTBOX SELECT may be used with both single and multiple selection listboxes.

LISTBOX SET TEXT hDlg , id& , item& , StrExpr

The text for the data item specified by item& is replaced with the new text in StrExpr . The value of item& = 1 for the first item, 2 for the second item, etc. The list of data items is not re-sorted, even if the LISTBOX was created with the style %LBS_SORT. If you wish to sort the items, use LISTBOX DELETE followed by LISTBOX ADD instead.

LISTBOX SET USER hDlg , id& , item& , NumExpr

Each item in a LISTBOX may have a long integer user value associated with it at the discretion of the programmer. This user value is assigned with LISTBOX SET USER, and retrieved with LISTBOX GET USER. The numeric value item& specifies which user value is to be accessed, 1 for the first item, 2 for the second item, etc. The value specified by NumExpr is saved for later retrieval. In addition to these LISTBOX user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER.

LISTBOX UNSELECT hDlg , id& [, item& ]

The string value specified by item& is set to an unselected state for the LISTBOX control. The value of item& = 1 for the first item, 2 for the second item, etc. If item& is missing, or has the value zero, all items are set to an unselected state. LISTBOX UNSELECT may be used with both single and multiple selection listboxes.

Restrictions

Under Windows 95/98/ME, a list box is limited to 32,767 items. In all versions of Windows, the actual string data contained by the list box is limited only by available memory.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD LISTBOX
  • CONTROL SET COLOR
  • CONTROL SET FONT


LISTVIEW DELETE COLUMN - ScharfBASIC Help

LISTVIEW DELETE COLUMN

Manipulate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LISTVIEW DELETE COLUMN hDlg , id& , col&
LISTVIEW DELETE ITEM hDlg , id& , item&
LISTVIEW FIND hDlg , id& , item& , StrExpr TO datav&
LISTVIEW FIND EXACT hDlg , id& , item& , StrExpr TO datav&
LISTVIEW FIT CONTENT hDlg , id& , col&
LISTVIEW FIT HEADER hDlg , id& , col&
LISTVIEW GET COLUMN hDlg , id& , col& TO datav&
LISTVIEW GET COUNT hDlg , id& TO datav&
LISTVIEW GET HEADER hDlg , id& , col& TO txtv$
L ISTVIEW GET HEADERID hDlg , id& TO hLV , idv&
LISTVIEW GET MODE hDlg , id& TO datav&
LISTVIEW GET SELCOUNT hDlg , id& TO datav&
L ISTVIEW GET SELECT hDlg , id& [, item& ] TO datav&
LISTVIEW GET STATE hDlg , id& , item& , col& TO datav&
LISTVIEW GET STYLEXX hDlg , id& TO datav&
LISTVIEW GET TEXT hDlg , id& , item& , col& TO txtv$
LISTVIEW GET USER hDlg , id& , item& TO datav&
LISTVIEW INSERT COLUMN hDlg , id& , col& , StrExpr , ColWidth& , format&
LISTVIEW INSERT ITEM hDlg , id& , item& , image& , StrExpr
LISTVIEW RESET hDlg , id&
LISTVIEW SELECT hDlg , id& , item& [, col& ]
LISTVIEW SET COLUMN hDlg , id& , col& , NumExpr
LISTVIEW SET HEADER hDlg , id& , col& , StrExpr
LISTVIEW SET IMAGE hDlg , id& , item& , NumExpr
LISTVIEW SET IMAGE2 hDlg , id& , item& , NumExpr
LISTVIEW SET IMAGELIST hDlg , id& , hLst , NumExpr
LISTVIEW SET MODE hDlg , id& , NumExpr
LISTVIEW SET OVERLAY hDlg , id& , item& , NumExpr
LISTVIEW SET STYLEXX hDlg , id& , NumExpr
LISTVIEW SET TEXT hDlg , id& , item& , col& , StrExpr
LISTVIEW SET USER hDlg , id& , item& , NumExpr

Description

There are 4 general display modes available with a LISTVIEW control. The initial display mode is established at the time the control is created, as a part of the control style parameter. It may be changed from time to time with LISTVIEW SET MODE.

Mode 0

Icon Mode - String data items are displayed left to right, wrapped to multiple lines as necessary. If a small icon IMAGELIST is attached to the LISTVIEW control, images from that list are displayed with each data item.

Mode 1

Report Mode - String data items are displayed as a list, top to bottom, one item per line. The control may have one or more columns, with header text to describe each of them. Additional sub-items may be displayed in each column, by specifying a column number greater than one. This is the most frequently used ListView mode, and the default mode if not specified at the time the control is created. In this mode, it's often convenient to think of the item number as a row number. If a small icon IMAGELIST is attached to the LISTVIEW control, images from that list are displayed with each data item.

Mode 2

Small Icon Mode - String data items are displayed left to right, wrapped to multiple lines as necessary. If a small icon IMAGELIST is attached to the LISTVIEW control, images from that list are displayed with each data item.

Mode 3

List Mode - String data items are displayed as a list, top to bottom, one item per line. This mode is very similar in appearance to a standard LISTBOX control. In this mode, it's often convenient to think of the item number as a row number. If a small icon IMAGELIST is attached to the LISTVIEW control, images from that list are displayed with each data item.

In all of the following descriptions, the LISTVIEW control which is the subject of the statement is identified by the handle of the dialog that owns the LISTVIEW ( hDlg ), and the unique control identifier ( id& ) you gave it upon creation in CONTROL ADD LISTVIEW.

Each data item (or sub-item) is referenced by a combination of its item number ( item& ) and its column number ( col& ). A primary data item always has a column number of 1, while sub-items always have a column number greater than 1. Sub-items are only displayed in Report Mode. In all other display modes, they are hidden from view.

It's important to note that both primary item numbers ( item& ) and sub-item column numbers ( col& ) start at 1. The first=1, the second=2, and so forth.

LISTVIEW DELETE COLUMN hDlg , id& , col&

The column specified by col& , including its associated header text (if any), is deleted from the LISTVIEW control. The column number ( col& ) is indexed to 1 (1=first, 2=second, etc.). Column one of a list-view control cannot be deleted. If you must delete column one, insert a zero length dummy column one and delete column two and above. This is a limitation of the Microsoft Windows Listview control and not a ScharfBASIC limitation.

LISTVIEW DELETE ITEM hDlg , id& , item&

The data item specified by item& is deleted from the LISTVIEW control. The row number ( item& ) is indexed to 1 (1=first, 2=second, etc.).

LISTVIEW FIND hDlg , id& , item& , StrExpr TO datav&

Strings in the first column of a LISTVIEW are searched to find the first string which begins with the data in StrExpr , regardless of any characters which follow. Comparisons are not case-sensitive. Strings are searched beginning with the string specified by item& , and ending with the last string in the LISTVIEW. Searching does not wrap to the beginning of the list. The row number ( item& ) is indexed to 1 (1=first, 2=second, etc.). To search the entire LISTVIEW starting with the first string, item& should be set to one (1). If a matching string is found, the index value of the match is assigned to the variable specified by datav& . If no match is found, the value zero (0) is assigned to it.

LISTVIEW FIND EXACT hDlg , id& , item& , StrExpr TO datav&

Strings in the first column of a LISTVIEW are searched to find the first string which exactly matches the data in StrExpr . Comparisons are not case-sensitive. Strings are searched beginning with the string specified by item& , and ending with the last string in the LISTVIEW. Searching does not wrap to the beginning of the list. The row number ( item& ) is indexed to 1 (1=first, 2=second, etc.). To search the entire LISTVIEW starting with the first string, item& should be set to one (1). If a matching string is found, the index value of the match is assigned to the variable specified by datav& . If no match is found, the value zero (0) is assigned to it.

LISTVIEW FIT CONTENT hDlg , id& , col&

The width of the column specified by col& is adjusted to fit the width of the data items displayed in that column. The column number ( col& ) is indexed to 1 (1=first, 2=second, etc.).

LISTVIEW FIT HEADER hDlg , id& , col&

The width of the column specified by col& is adjusted to fit the width of the rows displayed in that column, and the header text at the top of that column. The column number ( col& ) is indexed to 1 (1=first, 2=second, etc.). If the specified column is the last column, its width is set to fill the remaining width of the list-view control.

LISTVIEW GET COLUMN hDlg , id& , col& TO datav&

The width of the designated column is retrieved from the ListView and assigned to the variable specified by datav& . The width is specified in either pixels or dialog units , depending upon which was used at creation. The value col& specifies the column number (1=first, 2=second, etc.).

LISTVIEW GET COUNT

hDlg , id& TO datav&

The number of rows in the LISTVIEW is retrieved, and assigned to the long integer variable specified by datav& .

LISTVIEW GET HEADER hDlg , id& , col& TO txtv$

Column header text is retrieved from the LISTVIEW and assigned to the string variable specified by txtv$ . The value col& specifies the column number (1=first, 2=second, etc.).

LISTVIEW GET HEADERID hDlg , id& TO hLV , idv&

The handle of the LISTVIEW control and the ID of HEADER control (a child of the LISTVIEW) are retrieved and assigned to the variables represented by hLV and idv& respectively. These two items may then be used with the HEADER statement for advanced handling of the header control which is embedded in the LISTVIEW.

LISTVIEW GET MODE hDlg , id& TO datav&

The display mode of the specified LISTVIEW control is retrieved and assigned to the variable designated by datav& . Possible mode values are 0=icon mode, 1=report mode, 2=small icon mode, 3=list mode.

LISTVIEW GET SELCOUNT hDlg , id& TO datav&

The LISTVIEW is interrogated to determine the number of primary data items which are currently selected. This count is assigned to the long integer variable specified by datav& . To determine the count of sub-items selections, you must execute LISTVIEW GET STATE on every active sub-item.

LISTVIEW GET SELECT hDlg , id& [, item& ] TO datav&

The LISTVIEW is interrogated to determine the next primary data item which is currently selected. The parameter item& specifies the starting item number for the search, to facilitate retrieving multiple selected items. To start at the beginning, use an item& of one (1), or just omit that parameter. The selected item number is assigned to the long integer variable specified by datav& . If no selected items are found, the value zero (0) is returned. To find selected sub-items, you must execute LISTVIEW GET STATE on remaining active sub-items.

LISTVIEW GET STATE hDlg , id& , item& , col& TO datav&

A data item is tested to see if it is currently selected. The values of item& / col& specify the position of the data item (1=first, 2=second, etc.). If the item is selected, -1 ( true ) is assigned to the variable specified by datav& . Otherwise, 0 ( false ) is assigned to it.

LISTVIEW GET STYLEXX hDlg , id& TO datav&

ListView controls offer a number of optional additional style attributes which are unique and specific to a ListView. This statement retrieves the current setting of this special extended style, and assigns it to the long integer variable specified by datav& . A list of the available extended styles can be found under LISTVIEW SET STYLEXXX. This special extended style is named STYLEXX to distinguish it from the primary style and extended style specified in CONTROL ADD LISTVIEW.

LISTVIEW GET TEXT hDlg , id& , item& , col& TO txtv$

A string data item is retrieved from the LISTVIEW control and assigned to the string variable specified by txtv$ . The values of item& / col& specify the position of the data item (1=first, 2=second, etc.).

LISTVIEW GET USER hDlg , id& , item& TO datav&

Each row in a LISTVIEW may have a long integer user value associated with it at the discretion of the programmer. This user value is retrieved with LISTVIEW GET USER. The numeric value item& specifies which user value is requested, 1 for the first row, 2 for the second row, etc. The returned user value is assigned to the long integer variable specified by datav& . LISTVIEW user values are assigned with the LISTVIEW SET USER statement. In addition to these LISTVIEW user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER .

LISTVIEW INSERT COLUMN hDlg , id& , col& , StrExpr , ColWidth& , format&

A new vertical column is defined for Report Mode of this LISTVIEW control. The value col& specifies the column number (1=first, 2=second, etc.). StrExpr describes the text name of the column header. The value ColWidth& specifies the width of the column in either dialog units or pixels, depending upon which was specified at creation. The value format& describes the format and justification of the text: 0=left, 1=right, 2=center. Column 1 is always left-justified, regardless of what is requested here. When inserting a new column 1, the contents of the original column 1 are copied to the new column 1. This only occurs when inserting a new left most column, when inserting other columns, no data is copied to the new column. This is a limitation of the Microsoft Windows Listview control and not a ScharfBASIC limitation.

LISTVIEW INSERT ITEM hDlg , id& , item& , image& , StrExpr

A new row is added to this LISTVIEW control. The value item& specifies the row number (1=first, 2=second, etc.), and StrExpr tells the text to be displayed in the first column. The remaining columns are empty, but you can fill them by executing LISTVIEW SET TEXT. If an IMAGELIST has been attached to this control, the parameter image& specifies which image should be displayed (1=first, 2=second, etc.). If no image is needed, the value 0 should be used.

LISTVIEW RESET hDlg , id&

All data items are deleted from the specified LISTVIEW control. Any columns, and their associated headers, which may have been defined for Report Display mode are retained without change.

LISTVIEW SELECT hDlg , id& , item& [, col& ]

The string data item specified by item& / col& is chosen as selected text for the LISTVIEW control and the item is highlighted. The values of item& / col& = 1 for the first item, 2 for the second item, etc. If the optional parameter col& is not given, the default value of 1 is used to select the primary data item.

LISTVIEW SET COLUMN hDlg , id& , col& , NumExpr

The width of a LISTVIEW column is changed to that designated by the NumExpr . The value is specified in either dialog units or pixels, depending upon which was used at creation. The value col& specifies the column number (1=first, 2=second, etc.). If NumExpr is -1, then the column width is adjusted to fit the data items in that column. If NumExpr is -2, the column width is adjusted to fit both the data items and the header text. These options are functionally identical to LISTVIEW FIT CONTENT and LISTVIEW FIT HEADER.

LISTVIEW SET HEADER hDlg , id& , col& , StrExpr

New column header text is displayed above the specified column on the LISTVIEW control. The string expression StrExpr specifies the new header text, while the value col& specifies the column number (1=first, 2=second, etc.).

LISTVIEW SET IMAGE hDlg , id& , item& , NumExpr

The image specified by NumExpr (1=first, 2=second, etc.) is displayed next to the item specified by item& . If no IMAGELIST is attached to the LISTVIEW, nothing is displayed.

LISTVIEW SET IMAGE2 hDlg , id& , item& , NumExpr

The image specified by NumExpr (1=first, 2=second, etc.) is displayed as a secondary "status" image next to the primary image. If NumExpr evaluates to zero, no secondary image is displayed. A secondary image is usually used to specify item status, with an image such as a check mark. Secondary images are generally not displayed in either of the icon modes. If no Status Image List is attached to the LISTVIEW (using the LISTVIEW IMAGELIST statement), nothing is displayed. A maximum of 15 status images are supported, so NumExpr must evaluate in the range of 1-15.

LISTVIEW SET IMAGELIST hDlg , id& , hLst , NumExpr

The IMAGELIST specified by hLst is attached to this LISTVIEW control. The value of NumExpr specifies the type of IMAGELIST:

%LVSIL_NORMAL

Large icons

%LVSIL_SMALL

Small icons

%LVSIL_STATE

Status images

Up to three IMAGELIST structures may be attached to each LISTVIEW to display images as needed with each data item. Depending upon the mode in effect, icons are extracted from either the large icon or small icon list for that purpose. If a status image list is also attached, the LISTVIEW SET IMAGE2 statement may be used to display a secondary image. When the LISTVIEW control is destroyed, any attached IMAGELIST is automatically destroyed unless the %LVS_SHAREIMAGELISTS style was specified at the time the LISTVIEW was created.

LISTVIEW SET MODE hDlg , id& , NumrExpr

The display mode of the specified LISTVIEW control is changed to that designated by the value of NumExpr . The possible mode values are 0=icon mode, 1=report mode, 2=small icon mode, 3=list mode.

LISTVIEW SET OVERLAY hDlg , id& , item& , NumExpr

The overlay image specified by NumExpr (1=first, 2=second, etc.) is displayed on top of the image specified by item& . If NumExpr evaluates to zero, or if no IMAGELIST is attached to the LISTVIEW, no overlay is displayed.

LISTVIEW SET STYLEXX hDlg , id& , NumExpr

ListView controls offer a number of optional additional style attributes which are unique and specific to a ListView. This statement allows you to alter the current setting of this special extended style. This special extended style is named STYLEXX to distinguish it from the primary style and extended style specified in CONTROL ADD LISTVIEW. NumExpr defines the new style from any combination of the following extended styles:

%LVS_EX_GRIDLINES

Grid lines added in report mode

%LVS_EX_SUBITEMIMAGES

Icons added to sub-items in report mode

%LVS_EX_CHECKBOXES

Enables checkboxes to items

%LVS_EX_TRACKSELECT

Enables hot track selection

%LVS_EX_HEADERDRAGDROP

Enables drag-drop reordering of columns in report mode

%LVS_EX_FULLROWSELECT

Selection highlights full row in report mode

%LVS_EX_ONECLICKACTIVATE

Notification sent on single click

%LVS_EX_TWOCLICKACTIVATE

Notification sent on double click

%LVS_EX_FLATSB

Enables flat scroll bars

%LVS_EX_REGIONAL

Sets ListView region to icons and text

%LVS_EX_INFOTIP

Listview does InfoTips for you

%LVS_EX_UNDERLINEHOT

Hot items have underlined text

%LVS_EX_UNDERLINECOLD

Non-hot items have underlined text

%LVS_EX_MULTIWORKAREAS

Will not auto-arrange until work areas defined

%LVS_EX_LABELTIP

Listview unfolds partly hidden labels

%LVS_EX_BORDERSELECT

Border selection style instead of highlight

%LVS_EX_DOUBLEBUFFER

Paints via double-buffering and reduces flicker

%LVS_EX_HIDELABELS

Hides labels in Icon and Small Icon mode

%LVS_EX_SINGLEROW

Display a single row

%LVS_EX_SNAPTOGRID

Icons automatically snap to grid

%LVS_EX_SIMPLESELECT

Changes overlay rendering to top right

LISTVIEW SET TEXT hDlg , id& , item& , col& , StrExpr

The text, if any, for the specified data item is replaced by the new text in StrExpr . You must keep in mind that this statement does not create a new item (horizontal row), but changes existing text, if any, to new text. To create a new data item (horizontal row), use LISTVIEW INSERT ITEM instead. The values of item&/col& specify the position of the data item (1=first, 2=second, etc.).

LISTVIEW SET USER hDlg , id& , item& , NumExpr

Each row in a LISTVIEW may have a long integer user value associated with it at the discretion of the programmer. This user value is assigned with LISTVIEW SET USER, and retrieved with LISTVIEW GET USER. The numeric value item& specifies which user value is to be accessed, 1 for the first item, 2 for the second item, etc. The value specified by NumExpr is saved for later retrieval. In addition to these LISTVIEW user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER.

Restrictions

Under Windows 95/98/ME, a ListView is limited to 32,767 items. In all versions of Windows, the actual string data contained by the ListView is limited only by available memory.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD LISTVIEW
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • HEADER
  • IMAGELIST


LPRINT ATTACH - ScharfBASIC Help

LPRINT ATTACH

Connect to a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LPRINT ATTACH device$

Description

LPRINT ATTACH attempts a direct connection to the specified [line] printer device. A line printer is one that will accept standard ASCII text and any device-specific control codes, such as CR, LF, and FF.

A line printer is named by the port to which it is attached (LPT1, etc.) because the data is sent directly to the port, not through a device driver. That is, LPRINT communicates directly with the attached line printer device, bypassing the spooler and printer driver. Therefore, any settings such as "work offline" in the Printer Properties dialog will be ignored.

Once the printer is attached by LPRINT ATTACH, print data can be sent to it with the LPRINT statement.

LPRINT ATTACH allows you to change the printer device used by LPRINT operation. When executed, the current connection (if any) is closed and the new connection is established. No colon is used in the device name. For example, to connect to LPT2:

LPRINT ATTACH "LPT2"

or to a printer on a network server:

LPRINT ATTACH "\\SERVER\HPLJ5"

device$ must be a valid device name and cannot exceed 32 characters in length. In some circumstances, such as with the Novell network client, LPRINT ATTACH with a UNC name may be rejected, and the LPRINT ATTACH will be unsuccessful, and a subsequent LPRINT$ test will return an empty string.

If LPRINT ATTACH is not successful, an Error 68 ("Device unavailable") is generated and LPRINT$ returns a nul (empty) string . If no LPRINT ATTACH is ever executed (successful or not), ScharfBASIC will attempt to connect to the line printer at LPT1. Once any LPRINT ATTACH is attempted, no default to LPT1 will be presumed.

Care must be used with line printers in Windows, since if there is no available printer attached to the port, program execution may be suspended, with no errors. So, it is wise to use LPRINT ATTACH to explicitly connect the intended printer device, and test for the successful connection by the examination of LPRINT$ and ERR . For example:

ERRCLEAR

LPRINT ATTACH "LPT3"

IF ERR OR LPRINT$ = "" THEN PRINT "Connection failed"

Once all the data has been sent to the printer, detach the printer so other applications can use it., with the LPRINT CLOSE statement

Note : The Win32 API call EnumPrinters can give you a list of all valid printers and print devices, or you can enumerate the list of printers with the PRINTERCOUNT and PRINTER$ functions.

Restrictions

If device$ is an empty string, the current connection (if any) is detached. This is equivalent to the LPRINT CLOSE statement.

See Also

  • LPRINT
  • LPRINT CLOSE
  • LPRINT FLUSH
  • LPRINT FORMFEED
  • LPRINT$
  • XPRINT
  • XPRINT ATTACH


LPRINT CLOSE - ScharfBASIC Help

LPRINT CLOSE

Disconnect the current

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LPRINT CLOSE

Description

LPRINT CLOSE detaches the currently selected printer connection (established with the LPRINT ATTACH statement) from LPRINT operations, allowing the spooler subsystem to commence print operations. Once a connection is closed, LPRINT$ will return an empty printer device name string until a new connection is established.

LPRINT CLOSE is equivalent to using LPRINT ATTACH with an empty printer device name string.

Restrictions

LPRINT CLOSE is an essential step in the print process. To ensure the printer device is available to other applications, printers should always be closed when not in use. Failing to close a connection may cause significant delays before printing commences. In some cases, some or all of the print data may be lost.

See Also

  • LPRINT
  • LPRINT ATTACH
  • LPRINT FLUSH
  • LPRINT FORMFEED
  • LPRINT$
  • XPRINT
  • XPRINT ATTACH


LPRINT FLUSH - ScharfBASIC Help

LPRINT FLUSH

Flush any remaining

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LPRINT FLUSH

Description

LPRINT FLUSH forces the operating system to flush any buffered data and begin printing. Use LPRINT FLUSH to ensure print data is submitted to the printer as soon as possible, rather than waiting for any timeout period to elapse first. Depending upon the printer and its drivers, printing may begin immediately, or it may be delayed until execution of an LPRINT CLOSE statement.

Typically, an LPRINT FLUSH statement is preceded with a FORMFEED statement, so ensure that the print job is ejected normally from the printer device.

See Also

  • LPRINT
  • LPRINT ATTACH
  • LPRINT CLOSE
  • LPRINT FORMFEED
  • LPRINT$
  • XPRINT
  • XPRINT ATTACH


LPRINT FORMFEED - ScharfBASIC Help

LPRINT FORMFEED

Send a formfeed (page eject) character to an attached

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LPRINT FORMFEED

Description

For direct connections, LPRINT FORMFEED sends a form-feed character ( ASCII character 12, $FF, or CHR$ (12)) to the attached line printer device, to ensure the current page will be ejected. For host-based connections, ScharfBASIC signals to the printing subsystem to perform the page eject operation.

Typically, an LPRINT FORMFEED is performed before a LPRINT FLUSH and LPRINT CLOSE .

See Also

  • LPRINT
  • LPRINT ATTACH
  • LPRINT CLOSE
  • LPRINT FLUSH
  • LPRINT$
  • XPRINT
  • XPRINT ATTACH


LPRINT$ - ScharfBASIC Help

LPRINT$

Syntax

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

device$ = LPRINT$

Description

LPRINT$ returns the name of the currently attached printer device used by the LPRINT statement. If there is no attached device, an empty string is returned.

LPRINT$ is primarily used to detect if an LPRINT ATTACH operation was successful.

See Also

  • LPRINT
  • LPRINT ATTACH
  • LPRINT CLOSE
  • LPRINT FLUSH
  • LPRINT FORMFEED
  • XPRINT
  • XPRINT ATTACH

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Lprint

mov   edx,0x203a54
call   0x201b6c
call   0x201f1a
call   0x201fdd

Variant 2: Lprint Spc

mov   eax,0x5
call   0x201f78
mov   edx,0x203a54
call   0x201b7c
call   0x201f2a
call   0x201fed

Variant 3: Lprint Tab

mov   eax,0xa
call   0x201fa7
mov   edx,0x203a54
call   0x201b7c
call   0x201f2a
call   0x201fed


MENU ADD POPUP - ScharfBASIC Help

MENU ADD POPUP

Add a popup child

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU ADD POPUP, hMenu , txt$ , hPopup [AS id ], state& [, AT [BYCMD] position& ]

Description

A popup menu is a small window that "pops up" when a menu item is highlighted. This allows nesting, and gives the user an opportunity to choose from "sub-menu" items.

Handle of the parent menu which holds the popup.

Text displayed in the parent menu. An ampersand (&) may be used in the string to make the following letter into a control accelerator (hot-key). The letter appears underscored to signify that it is an accelerator.

hPopup

Handle of the child popup menu to be added.

If the option AS ID is included, id is a unique numeric identifier for this popup menu. id may be used later with a BYCMD option to reference this popup. id is an integral numeric value in the range of -32768 to +32767.

state&

The initial state of the menu item. It can be one of the following:

%MFS_DISABLED

Disable the item so that it cannot be selected.

%MFS_ENABLED

Enable the item so that it can be selected.

position&

Indicates the position in the parent menu where the popup child menu is to be inserted. If the BYCMD option is used, the popup menu is inserted prior to the menu item ID specified by position& . Otherwise, the popup menu is inserted at the physical position& within the parent menu, where position& = 1 for the first position, position& = 2 for the second, and so on. If position is not specified then the popup menu is appended to the end of the menu.

See Also

  • Dynamic Dialog Tools
  • ACCEL ATTACH
  • Menus
  • MENU ADD STRING
  • MENU ATTACH
  • MENU CONTEXT
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU ADD STRING - ScharfBASIC Help

MENU ADD STRING

Add a string

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU ADD STRING, hMenu , txt$ , id& , state& [, AT [BYCMD] position& ] [, CALL callback ]

Description

A string may contain an optional command accelerator key, and also describe an equivalent keyboard accelerator combination.

Handle of the parent menu to which the string should be added.

Text to display in the parent menu. An ampersand (&) may be used in the string to make the following letter into a command accelerator (hot-key). The letter is underscored to signify that it is an accelerator. To create a horizontal separator instead of a text string, set txt$ = "-", id& = 0, state& = 0.

Keyboard accelerators, as described in the ACCEL ATTACH statement, can be indicated in the text of a menu item, for the reference of the user. To include a keyboard accelerator description in a menu string, separate it from the menu item text with a $TAB { CHR$ (9)} character. For example:

MENU ADD STRING, hMenu, "Cu&t" & $TAB & "CTRL+X", id&, mstate&

The unique numeric identifier for the menu item. When a menu item is selected, id& is sent to the parent dialog Callback Function to notify the dialog which option was selected.

state&

The initial state of the menu item. It can be one or more of the following, combined together with the OR operator to form a bitmask:

%MFS_CHECKED

Place a checkmark next to the item.

%MFS_DEFAULT

The default menu item, displayed in bold. Only one item may be the default.

%MFS_DISABLED

Disable the menu item so that it cannot be selected.

%MFS_ENABLED

Enable the menu item so that it can be selected.

%MFS_GRAYED

Disable the menu item so that it cannot be selected, and draw it in a "grayed" state to indicate this.

%MFS_HILITE

Highlight the menu item.

%MFS_UNCHECKED

Do not place a checkmark next to the item.

%MFS_UNHILITE

Item is not highlighted.

A state value of zero (0) provides %mfs_enabled, %mfs_unchecked, and %mfs_unhilite.

position&

Optional position in the parent menu, where the menu item should be inserted. If the BYCMD option is used, the menu item is inserted prior to the menu item ID specified by position& . Otherwise, the menu item is inserted at the physical position& within the parent menu, where position& = 1 for the first position, position& = 2 for the second, and so on. If position is not specified then the popup menu is appended to the end of the menu.

callback

Optional name of a Callback Function that will be called when the menu item is selected. This callback will be ignored when used with MENU CONTEXT as it returns the id of the selected menu item.

Restrictions

The application must call the MENU DRAW BAR statement whenever a menu changes, whether or not the menu is in a displayed dialog.

See Also

  • Dynamic Dialog Tools
  • ACCEL ATTACH
  • Menus
  • MENU ADD POPUP
  • MENU ATTACH
  • MENU CONTEXT
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU ATTACH - ScharfBASIC Help

MENU ATTACH

Attach a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU ATTACH hMenu , hDlg

Description

Attaches a menu to a dialog, replacing any existing menu. The dialog is redrawn to accommodate the new menu.

Handle of the menu to be attached.

Handle of the dialog which holds the menu.

See Also

  • Dynamic Dialog Tools
  • ACCEL ATTACH
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU CONTEXT - ScharfBASIC Help

MENU CONTEXT

Create a floating context

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU CONTEXT hContext , x& , y& , flags& TO CmdVar

Description

A context menu is a floating popup menu which is shown until the user makes a selection or dismisses it. It can appear anywhere on the screen.

hContext

Handle of a menu created with MENU NEW POPUP .

x&, y&

The parameters x& and y& specify the location of the context menu, in pixels , relative to the upper left corner of the desktop .

flags&

May be combined, as appropriate, to specify the characteristics of the context menu.

%TPM_LEFTBUTTON

Tracks the left button.

%TPM_RIGHTBUTTON

Tracks the right button.

%TPM_LEFTALIGN

Left side of the menu is aligned with x& .

%TPM_CENTERALIGN

Centers horizontally with x& .

%TPM_RIGHTALIGN

Right side of the menu is aligned with x& .

%TPM_TOPALIGN

Top of the menu is aligned with y& .

%TPM_VCENTERALIGN

Centers vertically with y&.

%TPM_BOTTOMALIGN

Bottom of the menu is aligned with y& .

CmdVar

Long integer variable where the id of the selected menu item is returned. If an optional callback is defined for a menu item with MENU ADD STRING it will be ignored when used with MENU CONTEXT.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD STRING
  • MENU ADD POPUP
  • MENU NEW POPUP


MENU DELETE - ScharfBASIC Help

MENU DELETE

Delete a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU DELETE hMenu , [BYCMD] position&

Description

If the menu item is a popup child menu, the menu is destroyed and its memory is released.

Handle of the menu holding the item you are deleting.

position&

Position of the item within the menu. If BYCMD is specified, position& refers to the unique menu identifier. Otherwise, position& is the position of the menu item, where position& = 1 for the first position, position& = 2 for the second, and so on.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU DRAW BAR - ScharfBASIC Help

MENU DRAW BAR

Redraw the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU DRAW BAR hDlg

Description

This operation should be performed when a menu is altered dynamically after the dialog has been initially created, without regard to the visible state of the dialog.

Handle of the dialog that owns the menu to be redrawn.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU DELETE
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


Menu Example - ScharfBASIC Help

Menu Example

In the following code example, we create a dialog with a menu, outlining the concepts discussed in this chapter. Feel free to use this code as a base for your own DDT projects. This example is also av

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

'===========================================================

' Simple example of an application that has a menu and

' requires absolutely no API calls!

'===========================================================


MENU GET STATE - ScharfBASIC Help

MENU GET STATE

Return the state of a specified

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU GET STATE hMenu , [BYCMD] position& TO state&

Description

Retrieves the menu flags associated with the specified menu item.

Handle of the menu containing the item to examine.

position&

Position within the menu of the menu item to examine. If the BYCMD option is specified, position& specifies the unique menu item identifier of the item to examine. Otherwise, position& indicates the physical position of the menu item within the menu, where position& = 1 for the first position, position& = 2 for the second position, and so on.

state&

Long integer variable where the menu state will be placed. If the item does not exist, the result is -1. Otherwise the result is a bitmask containing one or more of the following, combined together with the OR operator to form the bitmask:

%MFS_CHECKED

Menu item has a checkmark next to it.

%MFS_DEFAULT

Menu item is the default item.

%MFS_DISABLED

Menu item is disabled and cannot be selected.

%MFS_ENABLED

Menu item is enabled and can be selected.

%MFS_GRAYED

Menu item is disabled and cannot be selected, and is drawn in a "grayed" state.

%MFS_HILITE

Menu item is highlighted.

%MFS_UNCHECKED

Menu item does not have a checkmark next to it.

%MFS_UNHILITE

Menu item is not highlighted.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU GET TEXT - ScharfBASIC Help

MENU GET TEXT

Return the text associated with a given

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU GET TEXT hMenu , [BYCMD] position& TO txt$

Description

Return the text displayed in the menu item identified by position& .

Handle of the menu that contains the menu item to be examined.

position&

Position of the menu item to examine. If BYCMD is specified, position& refers to the unique menu item identifier of the item to examine. Otherwise, position& indicates the physical position of the menu item within the menu, where position& = 1 for the first position, position& = 2 for the second position, and so on.

variable where the text from the menu item will be placed.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU NEW BAR - ScharfBASIC Help

MENU NEW BAR

Create a new

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU NEW BAR TO hMenu

Description

Items may be added to the menu using the MENU ADD POPUP and MENU ADD STRING statements.

Double-word or Long-integer variable where the handle of the new menu bar will be placed.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW POPUP
  • MENU SET STATE
  • MENU SET TEXT


MENU NEW POPUP - ScharfBASIC Help

MENU NEW POPUP

Create a new popup

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU NEW POPUP TO hPopup

Description

Once created, items may be added to the popup menu using the MENU ADD POPUP and MENU ADD STRING statements.

hPopup

Double-word or Long-integer variable where the handle of the new popup menu will be placed.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU CONTEXT
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU SET STATE
  • MENU SET TEXT


MENU SET STATE - ScharfBASIC Help

MENU SET STATE

Set the state of a specified

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU SET STATE hMenu , [BYCMD] position& , state&

Description

Change the state of the menu item identified by position& .

Double-word or Long-integer variable containing the handle of the menu that contains the item to change.

position&

Position within the menu, of the menu item to be changed. If the BYCMD option is specified, position& refers to the unique menu item identifier of the item. Otherwise, position& indicates the physical position of the menu item within the menu, where position& = 1 for the first position, position& = 2 for the second position, and so on.

state&

The new state of the menu item. This must be one or more of the following items, combined together with the OR operator to form a bitmask:

%MFS_CHECKED

Place a checkmark next to the item.

%MFS_DEFAULT

The default menu item, displayed in bold. Only one item may be the default.

%MFS_DISABLED

Disable the menu item so that it cannot be selected.

%MFS_ENABLED

Enable the menu item so that it can be selected.

%MFS_GRAYED

Disable the menu item so that it cannot be selected, and draw it in a "grayed" state to indicate this.

%MFS_HILITE

Highlight the menu item.

%MFS_UNCHECKED

Removes any checkmark next to the item.

%MFS_UNHILITE

Removes the highlight from the item.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU CONTEXT
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET TEXT


MENU SET TEXT - ScharfBASIC Help

MENU SET TEXT

Set the text of a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MENU SET TEXT hMenu , [BYCMD] position& , txt$

Description

Set the text of the menu item identified by position& .

Handle of the menu that contains the menu item to change.

position&

Position within the menu, of the menu item to be changed. If the BYCMD option is used, position& specifies the unique menu item identifier of the item to change. Otherwise, position& indicates the physical position of the menu item within the menu, where position& = 1 for the first position, position& = 2 for the second position, and so on.

The new text for the menu item.

See Also

  • Dynamic Dialog Tools
  • Menus
  • MENU ADD POPUP
  • MENU ADD STRING
  • MENU ATTACH
  • MENU CONTEXT
  • MENU DELETE
  • MENU DRAW BAR
  • MENU GET STATE
  • MENU GET TEXT
  • MENU NEW BAR
  • MENU NEW POPUP
  • MENU SET STATE


Menu State - ScharfBASIC Help

Menu State

The MENU ADD statements provide for an ItemState& parameter. For popup menus, this may be either %MFS_ENABLED or %MFS_DISABLED. For menu items, the state may be one of %MFS_ENABLED, %MFS_DISABLED, %MF

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

A DDT menu requires the parent DDT dialog to contain at least one child control for the menu to operate correctly. This control may be a BUTTON or LABEL , etc, and the control may be located out of the visible client area of the dialog if necessary.

In addition to creating menus dynamically, DDT provides a rich set of additional menu functions to allow you to manipulate your menus at run-time. The following is a brief summary of these functions:

Delete (remove) a menu item from a menu, or a popup menu from a menu bar.

Redraw the menu bar for a given menu. This must be used if a menu is changed at run-time, regardless of whether the menu is visible or not.

Obtain the current state of a menu item (%MF_ENABLED, etc). If the menu item is a separator, the returned value will be %MF_SEPARATOR.


Menu Walkthrough - ScharfBASIC Help

Menu Walkthrough

In order to create an example menu for our DDT dialog, we will need one Double-word variable to hold the handle of the menu, and one for each of the popup menu levels that our menu will contain. In th

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

To begin creating our menu, we use the MENU NEW BAR statement:

MENU NEW BAR TO hMenu

The value returned in hMenu is termed the menu handle. We use this handle to attach each of our popup menus. In order to create these popup menus, we will also need to create a handle:

MENU NEW POPUP TO hPopup1

Now we will "glue" our new popup menu to the menu bar. We do this using the MENU ADD POPUP statement, which results in an entry on the menu bar labeled " File ", complete with a command accelerator:

MENU ADD POPUP, hMenu, "&File", hPopup1, %MF_ENABLED

The ampersand character in " &File " means that pressing ALT+F on the keyboard, in addition to the conventional mouse click, can open the menu. The hPopup1 parameter instructs the DDT engine to attach the menu to the menu bar ( hMenu ), and it is initially enabled.


Menus - ScharfBASIC Help

Menus

Just like regular GUI windows and dialog boxes , DDT dialogs can use menus too. With just a handful of statements, you can create a menu and add or remove items, depending on the context of your appli

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

A menu bar is positioned just below the caption bar of a dialog box. From this menu bar, popup menus (or sub-menus as they are also known) can be displayed, each containing commands. Popup menus may contain even deeper levels of popup menus.

Menus are constructed in a hierarchical manner: the top-most level is positioned on the menu bar, and the lower levels of the menu are the popup portions. The items on the menu bar are always visible, but the popup menus are never visible until a menu bar item is either clicked by the mouse, or activated by a command accelerator (hot-key) which is indicated by an underscored character in the menu item text.

Please note that command accelerators differ slightly from keyboard accelerators. The latter are configured and described in the ACCEL ATTACH statement topic.

Typically, a popup menu contains a range of associated commands. For example, a FILE popup menu usually contains a range of commands to permit the opening, saving and closing of files, etc.

When the user activates a popup menu item, and a command is selected, a %WM_COMMAND message is sent to the dialog Callback Function to notify the program that a menu item has been selected.


More on the Menu - ScharfBASIC Help

More on the Menu

When adding new menu items to a menu, additional parameters may be included in the following statements:

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

MENU ADD POPUP, hMenu , txt$ , hPopup , state& [, AT [BYCMD] position& ]

MENU ADD STRING, hMenu , txt$ , hPopup , state& [, AT [BYCMD] position& ] [, CALL callback ]

An optional position parameter that allows the programmer to specify an absolute position of the menu item within the popup menu, inserted immediately before the value of position& . Omitting this parameter causes the menu item to be appended to the menu at the "current position". Position values are indexed to 1. For example:

' Insert a new menu item at position 3 in the popup menu hPopup

MENU ADD STRING, hPopup, "&Print", %id_Print, _

ItemState&, AT position&


Options Dialog - ScharfBASIC Help

Options Dialog

This topic describes the options available to customize the output of the source code generated by the ScharfBASIC COM Browser.

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Always use an Interface Prefix

This option prefixes all Interface names with the text specified in the Interface Prefix textbox. This is useful when using multiple type libraries in a project and there are conflicts with duplicate Interface names.

Only When the Interface contains an illegal name

This option prefixes Interface names, only when they contain illegal characters or conflict with a reserved keyword.

This is the prefix used for Interface names.

Prefix ProgIDs,ClassIds, and IIds with Library Name

This option will prefix ClassIDs, ProgIDs, and IIDs with the library name. This option is used when you have multiple type libraries with conflicting names in one application.


PRINTER$ - ScharfBASIC Help

PRINTER$

Retrieve printer names and printer port names.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

device$ = PRINTER$([NAME | PORT], printernum& )

Description

printernum& specifies the printer number, from 1 to PRINTERCOUNT . If the NAME option is specified in the first position, the printer name is returned. If the PORT option is specified instead, the port name (e.g., LPT1) is returned.

See Also

  • LPRINT ATTACH
  • PRINTERCOUNT
  • XPRINT ATTACH


PRINTERCOUNT - ScharfBASIC Help

PRINTERCOUNT

Retrieve the number of available (installed) printers.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ncPrinters& = PRINTERCOUNT

See Also

  • LPRINT ATTACH
  • PRINTER$
  • XPRINT ATTACH


PROGRESSBAR GET POS - ScharfBASIC Help

PROGRESSBAR GET POS

Manipulate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PROGRESSBAR GET POS hDlg , id& TO datav&
PROGRESSBAR GET RANGE hDlg , id& TO LoDatav& , HiDatav&
PROGRESSBAR SET POS hDlg , id& , position&
PROGRESSBAR SET RANGE hDlg , id& , lolimit& , hilimit&
PROGRESSBAR SET STEP hDlg , id& , stepval&
PROGRESSBAR STEP hDlg , id& [, incramt& ]

Description

In each of the following samples and descriptions, the PROGRESSBAR control that is the subject of the statement is identified by the handle of the dialog that owns the ProgressBar ( hDlg ), and the unique control identifier you gave it upon creation in CONTROL ADD PROGRESSBAR. To alter the color of the bar or the background, use CONTROL SET COLOR .

PROGRESSBAR GET POS hDlg , id& TO datav&

The current position of the ProgressBar is retrieved and assigned to the variable designated by datav& .

PROGRESSBAR GET RANGE hDlg , id& TO LoDatav& , HiDatav&

The current range of the ProgressBar is retrieved and assigned to the variables designated by LoDatav& and HiDatav& . Upon ProgressBar creation, the default range is 0 to 100.

PROGRESSBAR SET POS hDlg , id& , position&

The current position of the ProgressBar is set to the value of the parameter position& , and the bar is redrawn to reflect the new position.

PROGRESSBAR SET RANGE hDlg , id& , lolimit& , hilimit&

The range for the ProgressBar is specified to be from lolimit& to hilimit& . If lolimit& is greater than hilimit& , the results are undefined.

PROGRESSBAR SET STEP hDlg , id& , step&

The default increment value to be used by PROGRESSBAR STEP is specified by the stepval& parameter.

PROGRESSBAR STEP hDlg , id& [, incramt& ]

The ProgressBar is "stepped". The current position is advanced by the step increment, and the bar is redrawn to reflect the new position. If the optional incramt& expression is included, the position is advanced by that amount instead. The default step increment is 10, and the default range is from 0 to 100.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD PROGRESSBAR
  • CONTROL SET COLOR
  • CONTROL SET FONT


SCROLLBAR GET PAGESIZE - ScharfBASIC Help

SCROLLBAR GET PAGESIZE

Manipulate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SCROLLBAR GET PAGESIZE hDlg , id& TO datav&
SCROLLBAR GET POS hDlg , id& TO datav&
SCROLLBAR GET RANGE hDlg& , id& TO LoDatav& , HiDatav&
SCROLLBAR GET TRACKPOS hDlg , id& TO datav&
SCROLLBAR SET PAGESIZE hDlg , id& , pagesize&
SCROLLBAR SET POS hDlg , id& , position&
SCROLLBAR SET RANGE hDlg , id& , lolimit& , hilimit&

Description

In each of the following samples and descriptions, the SCROLLBAR control that is the subject of the statement is identified by the handle of the dialog that owns the ScrollBar ( hDlg ), and the unique control identifier you gave it upon creation in CONTROL ADD SCROLLBAR. To alter the color of the bar or the background, use CONTROL SET COLOR .

SCROLLBAR GET PAGESIZE hDlg , id& TO datav&

The current page size of the ScrollBar is retrieved and assigned to the variable designated by datav& . Upon ScrollBar creation, the default page size is 10.

SCROLLBAR GET POS hDlg , id& TO datav&

The current position of the ScrollBar is retrieved and assigned to the variable designated by datav& . Upon ScrollBar creation, the default position is 0.

SCROLLBAR GET RANGE hDlg , id& TO LoDatav& , HiDatav&

The current range of the ScrollBar is retrieved and assigned to the variables designated by LoDatav& and HiDatav& . Upon ScrollBar creation, the default ScrollBar range is 0 to 100.

SCROLLBAR GET TRACKPOS hDlg , id& TO datav&

The current position of the scroll box, being dragged by the user, is retrieved and assigned to the variable designated by datav& . This is normally read while responding to the %SB_THUMBPOSITION or the %SB_THUMBTRACK messages. The TRACKPOS is then used to move the scroll position with SCROLLBAR SET POS.

SCROLLBAR SET PAGESIZE hDlg , id& , pagesize&

The current page size of the ScrollBar is set to the value of the parameter pagesize& , and the bar is redrawn to reflect the new position.

SCROLLBAR SET POS hDlg , id& , position&

The current position of the ScrollBar is set to the value of the parameter position& , and the bar is redrawn to reflect the new position.

SCROLLBAR SET RANGE hDlg , id& , lolimit& , hilimit&

The range for the ScrollBar is specified to be from lolimit& to hilimit& . If lolimit& is greater than hilimit& , the results are undefined.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD SCROLLBAR
  • CONTROL SET COLOR


STATUSBAR SET PARTS - ScharfBASIC Help

STATUSBAR SET PARTS

Manipulate a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

STATUSBAR SET PARTS hDlg , id& , x& [, x& ...]
STATUSBAR SET TEXT hDlg , id& , item& , style& , text$

Description

In each of the following samples and descriptions, the STATUSBAR control which is the subject of the statement is identified by the handle of the dialog that owns the STATUSBAR ( hDlg ), and the unique control identifier you gave it upon creation in CONTROL ADD STATUSBAR.

The value item& refers to the position of the text data item on the STATUSBAR, and is always indexed to one. The first string is position 1, the second is position 2, and so forth.

STATUSBAR SET PARTS hDlg , id& , x& [, x& ...]

The STATUSBAR control is partitioned into as many as 32 sections, each of which can be used to display some particular status data to the user. The statement contains from 1 to 32 width parameters ( x& ), which specify the pixel or dialog unit size of that section. You can use a very large number for the last parameter to signify that the section should extend all the way to the right side of the window.

STATUSBAR SET PARTS hDlg, id&

, 50, 50, 9999

For example, the above statement would create a status bar with 2 sections of 50 pixels each, and a third section of the remaining width.

STATUSBAR SET TEXT hDlg , id& , item& , style& , text$

The text for the data item specified by item& is replaced with the new text in text$ . The value of item& = 1 for the first item, 2 for the second item, etc. The status bar style value can be the default value of zero (0), or one of the other style values formed as a bitmask:

Zero (0) default

Text with a border to appear lower than the window.

%SBT_NOBORDERS

The text is drawn without any borders.

%SBT_POPOUT

Text with a border to appear higher than the window.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD STATUSBAR
  • CONTROL SET FONT


Syntax Custom Color Selector - ScharfBASIC Help

Syntax Custom Color Selector

Basic Colors

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Set of basic colors determined by the display driver.

Displays any custom colors you have already defined. To Change a custom color, click on it and then click the Define Custom Colors button. When you have selected the color click the Add to Custom Colors button. To define a new custom color, click on an empty custom color and then click the Define Custom Colors button. Select the new color and then click the Add to Custom Colors button.

Displays the Color Map.

A color map based on the current display color-depth, to facilitate easy selection of custom colors. To choose a color, click on the desired point in the color map.

Displays the color selected in the Color Map.


TCP PRINT - ScharfBASIC Help

TCP PRINT

Write a string to a nominated

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TCP PRINT [#] fNum& , string_expression [;]

Description

Write the data in string_expression to the fNum& TCP/IP port. If the optional semi-colon is not specified, a carriage-return and linefeed pair ( $CRLF or CHR$ (13,10)) is also sent.

The TCP PRINT statement does not return until string_expression has been sent, or an error occurs. That is, TCP PRINT is a synchronous or "blocking" statement. If a time-out occurs, ERR will be set to indicate a run-time Error 24 ("Device timeout"). See TCP OPEN to specify the TCP socket timeout value.

See Also

  • TCP and UDP communications
  • TCP ACCEPT
  • TCP CLOSE
  • TCP LINE INPUT
  • TCP NOTIFY
  • TCP OPEN
  • TCP RECV
  • TCP SEND
  • UDP OPEN


Thread Control - ScharfBASIC Help

Thread Control

The following functions are used to create and manage threads:

Kind | Keyword
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Releases the thread handle of this thread.

Compares the specified object to determine if it references the same object as this object.

Retrieves the handle of the thread for use with Windows API functions.

Retrieves the ID of the thread for use with Windows API functions.


TOOLBAR ADD BUTTON - ScharfBASIC Help

TOOLBAR ADD BUTTON

A

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TOOLBAR ADD BUTTON hDlg , ID , image& , cmd& , style& , text$ [AT item& ] [CALL callback ]
TOOLBAR ADD SEPARATOR hDlg , ID , size& [, cmd& ] [AT item& ]
TOOLBAR DELETE BUTTON hDlg , id& , [BYCMD] item&
TOOLBAR GET STATE hDlg , ID , [BYCMD] item& TO datav&
TOOLBAR GET COUNT hDlg , ID TO datav&
TOOLBAR SET IMAGELIST hDlg , ID , hLst , ListType&
TOOLBAR SET STATE hDlg , ID , [BYCMD] item& , state&

Description

A TOOLBAR control contains one or more buttons, each of which normally corresponds to a menu item. It is generally placed at the top of the client area of a dialog. When the user "presses" a tool bar button, the program reacts in the same way as if the command had been selected from a menu. It simply acts as a shortcut to common menu commands.

In each of the following descriptions, the TOOLBAR is referenced by the dialog handle ( hDlg ) and id&. In some cases a specific button is chosen with the item& parameter. If the BYCMD option is included, item& specifies the command id number of the button to be used. If not, item& describes the button by its position on the TOOLBAR. Since separators are considered to be a special class of button by the operating system, they must be counted when you calculate a position item number. Positions are always indexed to one (1=first, 2=second, and so on).

TOOLBAR ADD BUTTON hDlg , ID , image& , cmd& , style& , text$ [AT item& ] [CALL callback ]

A button is added to this TOOLBAR. The image to be displayed is selected from the attached IMAGELIST based upon the parameter image& (1=first, 2=second, etc.). The cmd& parameter specifies the command id number to be executed (with %WM_COMMAND) when the button is pressed. The style& parameter describes the style of the button from the following most often used attributes:

%BTNS_AUTOSIZE

The width of the button is calculated by the system, based upon the text and the image.

%BTNS_BUTTON

The button behaves like a standard push button.

%BTNS_CHECK

The button is dual-state which toggles between the pressed and nonpressed state each time it's clicked.

%BTNS_GROUP

Defines a group of buttons. When combined with the check style, it creates a button that stays pressed until another button in the group is pressed. This is similar to an option button or radio button.

%BTNS_CHECKGROUP

A combination of check and group styles.

%BTNS_DROPDOWN

Creates a drop-down style button that can display a list when clicked. Drop-down buttons send a %TBN_DROPDOWN notification instead of %WM_COMMAND.

%BTNS_NOPREFIX

The button text will not have an accelerator prefix associated with it.

The text$ parameter specifies the text to be displayed on the button.

If the optional "AT item& " clause is included, the button is inserted at the designated position (1=first, 2=second, etc.). Otherwise, it is added to the end of the list.

If the optional "CALL callback " clause is included, it specifies the name of a Callback Function that receives %WM_COMMAND messages when the button is clicked. If not specified, these command messages are sent to the dialog callback specified in DIALOG SHOW . Message routing by button allows you to easily determine which button generated the event.

If the Callback Function processes a message, it should return TRUE (non-zero) to prevent the message being passed unnecessarily to the dialog callback (if one exists). The dialog callback should also return TRUE if the notification message is processed by that Callback Function. Otherwise, the DDT engine processes unhandled messages.

TOOLBAR ADD SEPARATOR hDlg , ID , size& [, cmd& ] [AT item& ]

A separator is added to this TOOLBAR. It separates two buttons by the number of pixels specified in size& . It may be used to separate and distinguish two adjacent button groups (%tbstyle_group), or to just enhance the visual appearance. If the optional cmd& parameter is included, it's a unique numeric identifier for this separator. Of course, a separator can't be pressed like a button, so it doesn't literally allow a command to be sent. However, it may be used later with a BYCMD option in TOOLBAR DELETE, TOOLBAR SET STATE, etc. If the "AT item& " clause is included, the separator is inserted at the designated position (1=first, 2=second, etc.). Otherwise, it is added to the end of the list.

TOOLBAR DELETE BUTTON hDlg , ID , [BYCMD] item&

A BUTTON or SEPARATOR, specified by item& , is deleted from the TOOLBAR. The parameter item& may be positional, or it may represent a command id number with BYCMD.

TOOLBAR GET COUNT hDlg , ID to datav&

The number of buttons (and separators) on the TOOLBAR is retrieved and assigned to the long integer variable specified by datav& .

TOOLBAR GET STATE hDlg , ID , [BYCMD] item& TO datav&

The state descriptor bits for a specific button are retrieved and assigned to the variable designated by datav& . The parameter item& tells which button to check -- it may be positional, or it may be the command id number when used with BYCMD. The descriptor bits may consist of one or more of:

%TBSTATE_DISABLED

The button is disabled and grayed. (value=0)

%TBSTATE_CHECKED

The button is checked.

%TBSTATE_PRESSED

The button is pressed.

%TBSTATE_ENABLED

The button is enabled.

%TBSTATE_HIDDEN

The button is hidden.

%TBSTATE_INDETERMINATE

The button is indeterminate and grayed.

%TBSTATE_MARKED

The button is highlighted.

TOOLBAR SET IMAGELIST hDlg , ID , hLst , type&

The IMAGELIST specified by hLst is attached to this TOOLBAR control. The value of ListType& specifies the type of IMAGELIST:

Default images

Disabled images

Hot images

The graphical images contained in the IMAGELIST are displayed on the TOOLBAR buttons. Up to three IMAGELIST structures may be attached to each TOOLBAR control. The image to be displayed is determined by the specification made in TOOLBAR ADD BUTTON, and the current state of the button. When the TOOLBAR control is destroyed, any attached IMAGELIST is automatically destroyed.

TOOLBAR SET STATE hDlg , ID , [BYCMD] item& , state&

The state descriptor bits for the specified button are applied from the expression state& . The parameter item& tells which button to set -- it may be positional, or it may be the command id number when used with BYCMD. The descriptor bits state& may consist of:

%TBSTATE_DISABLED

The button is disabled and grayed. (value=0)

%TBSTATE_CHECKED

The button is checked.

%TBSTATE_PRESSED

The button is pressed.

%TBSTATE_ENABLED

The button is enabled.

%TBSTATE_HIDDEN

The button is hidden.

%TBSTATE_INDETERMINATE

The button is indeterminate and grayed.

%TBSTATE_MARKED

The button is highlighted.

See Also

  • DIALOG SHOW MODAL
  • DIALOG SHOW MODELESS
  • Dynamic Dialog Tools
  • CONTROL ADD TOOLBAR
  • CONTROL SET FONT
  • IMAGELIST


TREEVIEW DELETE - ScharfBASIC Help

TREEVIEW DELETE

A

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TREEVIEW DELETE hDlg , id& , hItem
TREEVIEW GET BOLD hDlg , id& , hItem TO datav&
TREEVIEW GET CHECK hDlg , id& , hItem TO datav&
TREEVIEW GET CHILD hDlg , id& , hItem TO datav&
TREEVIEW GET COUNT hDlg , id& TO datav&
TREEVIEW GET EXPANDED hDlg , id& , hItem TO datav&
TREEVIEW GET NEXT hDlg , id& , hItem TO datav&
TREEVIEW GET PARENT hDlg , id& , hItem TO datav&
TREEVIEW GET PREVIOUS hDlg , id& , hItem TO datav&
TREEVIEW GET ROOT hDlg , id& TO datav&
TREEVIEW GET SELECT hDlg , id& TO datav&
TREEVIEW GET TEXT hDlg , id& , hItem TO txtv$
TREEVIEW GET USER hDlg , id& , hItem TO datav&
TREEVIEW INSERT ITEM hDlg , id& , hPrnt , hIAftr , image& , simage& , txt$ TO hItem
TREEVIEW RESET hDlg , id&
TREEVIEW SELECT hDlg , id& , hItem
TREEVIEW SET BOLD hDlg , id& , hItem , flag&
TREEVIEW SET CHECK hDlg , id& , hItem , flag&
TREEVIEW SET EXPANDED hDlg , id& , hItem , flag&
TREEVIEW SET IMAGELIST hDlg , id& , hLst
TREEVIEW SET TEXT hDlg , id& , hItem , txt$
TREEVIEW SET USER hDlg , id& , hItem , NumExpr
TREEVIEW UNSELECT hDlg , id&
hItem

Description

TREEVIEW DELETE hDlg , id& , hItem

The data item specified by the handle hItem is deleted from the TREEVIEW control.

TREEVIEW GET BOLD hDlg , id& , hItem TO datav&

The bold attribute for the data item hItem is retrieved and assigned to the variable datav& . If the item is bold, the value true (-1) is assigned. If not bold, the value false (0) is assigned.

TREEVIEW GET CHECK hDlg , id& , hItem TO datav&

The checkmark attribute for the data item hItem is retrieved and assigned to the variable datav& . If the checkbox is checked, the value true (-1) is assigned. If not checked, the value false (0) is assigned.

TREEVIEW GET CHILD hDlg , id& , hItem TO datav&

The parent data item specified by hItem is scanned for child data items. If any are found, the handle of the first child is assigned to the variable specified by datav& . If none are found, the value zero (0) is assigned to datav& .

TREEVIEW GET COUNT hDlg , id& TO datav&

The number of data items in the TREEVIEW is retrieved, and assigned to the long integer variable specified by datav& .

TREEVIEW GET EXPANDED hDlg , id& , hItem TO datav&

The expanded attribute for the data item hItem is retrieved and assigned to the variable datav& . If the item is expanded, displaying its child data items, the value true (-1) is assigned. If the item is collapsed, the value false (0) is assigned.

TREEVIEW GET NEXT hDlg , id& , hItem TO datav&

The data item specified by hItem is scanned for sibling data items. The handle of the next sibling is assigned to the variable specified by datav& . If no next sibling is found, the value zero (0) is assigned to datav& .

TREEVIEW GET PARENT hDlg , id& , hItem TO datav&

The data item specified by hItem is scanned for its parent data item. The handle of the parent is assigned to the variable specified by datav& . If no parent is found, the value zero (0) is assigned to datav& .

TREEVIEW GET PREVIOUS hDlg , id& , hItem TO datav&

The data item specified by hItem is scanned for sibling data items. The handle of the previous sibling is assigned to the variable specified by datav& . If no previous sibling is found, the value zero (0) is assigned to datav& .

TREEVIEW GET ROOT hDlg , id& TO datav&

The handle of the very first data item (topmost) in the TREEVIEW is retrieved, and assigned to the variable specified by datav& .

TREEVIEW GET SELECT hDlg , id& TO datav&

The handle of the data item currently selected in the TREEVIEW is retrieved, and assigned to the variable specified by datav& . If there is no current selection, the value zero (0) is assigned.

TREEVIEW GET TEXT hDlg , id& , hItem TO txtv$

The text of a specific data item (specified by the handle hItem ) is retrieved from the TREEVIEW control and assigned to the string variable designated by txtv$ .

TREEVIEW GET USER hDlg , id& , hItem TO datav&

Each item in a TREEVIEW may have a long integer user value associated with it at the discretion of the programmer. This user value is assigned with TREEVIEW SET USER and retrieved with TREEVIEW GET USER. The parameter hItem specifies the handle of the user item to be accessed. The returned user value is assigned to the long integer variable specified by datav& . In addition to these TREEVIEW user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER .

TREEVIEW INSERT ITEM hDlg , id& , hPrnt , hIAftr , image& , selimage& , txt$ TO hItem

A new data item is added to this TREEVIEW control. The parameter hPrnt specifies the parent of this item, or zero if item is to be inserted at the root. The parameter hIAftr specifies the handle of the item after which this new item is to be inserted, or %TVI_FIRST (at the beginning), %TVI_LAST (at the end), %TVI_SORT (alphabetical order). If an IMAGELIST has been attached, the parameters image& and selimage& specify which image should be displayed (1=first, 2=second, etc.) for normal and selected items. If no image is needed, the value(s) 0 should be used. The parameter txt$ designates the text string which should be displayed. If the operation is successful, the handle to the new data item is assigned to the variable designated by hItem . If the operation fails, the value zero is assigned to hItem .

TREEVIEW RESET hDlg , id&

All data items are deleted from the specified TREEVIEW control.

TREEVIEW SELECT hDlg , id& , hItem

The data item specified by the handle hItem is chosen as selected text for the TREEVIEW control, and the selected text is scrolled into a visible position.

TREEVIEW SET BOLD hDlg , id& , hItem , flag&

The bold attribute for the data item specified by hItem is set based upon the value of the flag& parameter. If flag& is true (non-zero), it is displayed in bold format. If flag& is false (zero), it is displayed in normal format.

TREEVIEW SET CHECK hDlg , id& , hItem , flag&

The optional checkbox for the data item specified by hItem is set based upon the value of the flag& parameter. If flag& is true (non-zero), it is checked. If flag& is false (zero), it is unchecked.

TREEVIEW SET EXPANDED hDlg , id& , hItem , flag&

The expanded attribute for the data item specified by hItem is set based upon the value of the flag& parameter. If flag& is true (non-zero), it is displayed in expanded format, with its child items visible. If flag& is false (zero), it is displayed in collapsed format.

TREEVIEW SET IMAGELIST hDlg , id& , hLst

The IMAGELIST specified by hLst is attached to this TREEVIEW control. The images it contains are displayed as needed with each data item. When the TREEVIEW control is destroyed, any attached IMAGELIST is automatically destroyed.

TREEVIEW SET TEXT hDlg , id& , hItem , txt$

The text of a specific data item (specified by the handle hItem ) is replaced by the text in the string expression txt$ .

TREEVIEW SET USER hDlg , id& , hItem , NumExpr

Each item in a TREEVIEW may have a long integer user value associated with it at the discretion of the programmer. This user value is assigned with TREEVIEW SET USER, and retrieved with TREEVIEW GET USER. The parameter hItem specifies the handle of the user item to be accessed, while NumExpr is the user value saved for later retrieval. In addition to these TREEVIEW user values, every DDT control offers an additional eight user values which can be accessed with CONTROL GET USER and CONTROL SET USER.

TREEVIEW UNSELECT hDlg , id&

All items in the TREEVIEW control are set to an unselected state.

See Also

  • Dynamic Dialog Tools
  • CONTROL ADD TREEVIEW
  • CONTROL SET COLOR
  • CONTROL SET FONT
  • IMAGELIST


WINDOW GET HANDLE - ScharfBASIC Help

WINDOW GET HANDLE

Manipulate a Window in the program, which may include setting or retrieving data. The target window may be of any class, including a CONTROL

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

WINDOW GET HANDLE hWin , ID& TO DataVar&
WINDOW GET ID hWin TO DataVar&
WINDOW GET PARENT hWin TO DataVar&
WINDOW GET STYLE hWin TO DataVar&
WINDOW GET STYLEX hWin TO DataVar&
WINDOW GET USER hWin TO DataVar&

Description

The WINDOW statement may be used with any type of window in your program, including a Control or Dialog. Generally speaking, the window to be manipulated or tested is identified by its handle ( hWin ), which is often obtained at the time it is created. However, since a control is usually accessed by a "Parent / ID" combination, you must use WINDOW GET HANDLE or CONTROL HANDLE to retrieve its handle for this purpose. If the operation fails, the value zero (0) is assigned to the result variable.

WINDOW GET HANDLE hWin , ID& TO DataVar&

This statement retrieves the handle of a Window, translating from the parent handle and the specific integral control ID given at the time it was created. hWin is the handle of the parent, ID& is the control ID, and DataVar& represents the variable which receives the desired window handle.

WINDOW GET ID

hWin To DataVar&

The integral ID of the window hWin is retrieved and assigned to the variable designated by DataVar& . Generally, only a CONTROL will have an ID, so windows of other classes will normally return the value zero.

WINDOW GET PARENT hWin To DataVar&

The handle of the parent is retrieved and assigned to the variable designated by DataVar& .

WINDOW GET STYLE hWin TO DataVar&

The window style value of the window specified by the handle hWin is retrieved and assigned to the variable designated by DataVar& .

WINDOW GET STYLEX hWin TO DataVar&

The extended window style value of the window specified by the handle hWin is retrieved and assigned to the variable designated by DataVar& .

WINDOW GET USER hWin TO DataVar&

The 32-bit user data value associated with the window specified by the handle hWin is retrieved and assigned to the variable designated by DataVar& . This particular user data value is associated with every window in your program, and is maintained by the Windows operating system. It is separate and apart from user data maintained by DDT for each dialog and control created with DDT.

See Also

  • CONTROL HANDLE
  • WINDOW SET


WINDOW SET ID - ScharfBASIC Help

WINDOW SET ID

Manipulate a Window in the program, which may include setting or retrieving data. The target window may be of any class, including a CONTROL

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

WINDOW SET ID hWin , NewVal& TO OldValVar&
WINDOW SET STYLE hWin , NewVal& TO OldValVar&
WINDOW SET STYLEX hWin , NewVal& TO OldValVar&
WINDOW SET USER hWin , NewVal& TO OldValVar&

Description

The WINDOW SET statement may be used with any type of window in your program, including a Control or Dialog. However, you must use care due to possible side effects. Generally speaking, the window to be manipulated is identified by its handle ( hWin ), which is often obtained at the time it is created. However, since a control is usually accessed by a "Parent / ID" combination, you must use WINDOW GET HANDLE or CONTROL HANDLE to retrieve its handle for this purpose.

WINDOW SET ID hWin , NewVal& To OldValVar&

The integral ID of the window hWin is changed to NewVal& . The prior ID value is assigned to the variable designated by OldValVar& . If the operation fails, the value zero (0) is assigned to OldValVar& . As a general rule, you should not change the ID of a Window, Dialog, or Control created with DDT as it will cause unpredictable results.

WINDOW SET STYLE hWin , NewVal& TO OldValVar&

The window style value of the window hWin is changed to NewVal& . The prior style value is assigned to the variable designated by OldValVar& . If the operation fails, the value zero (0) is assigned to OldValVar& .

WINDOW SET STYLEX hWin , NewVal& TO OldValVar&

The extended window style value of the window hWin is changed to NewVal& . The prior extended style value is assigned to the variable designated by OldValVar& . If the operation fails, the value zero (0) is assigned to OldValVar& .

WINDOW SET USER hWin , NewVal& TO OldValVar&

The 32-bit user data value associated with the window specified by the handle hWin is changed to NewVal& . The prior user data value is assigned to the variable designated by OldValVar& . This particular user data value is associated with every window in your program, and is maintained by the Windows operating system. It is separate and apart from user data maintained by DDT for each dialog and control created with DDT. If the operation fails, the value zero (0) is assigned to OldValVar& . However, this is not a certain indication of failure, since the prior user value might have been zero.

See Also

  • CONTROL HANDLE
  • WINDOW GET


XPRINT ARC - ScharfBASIC Help

XPRINT ARC

Draw an arc on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT ARC ( x1! , y1! ) - ( x2! , y2! ), arcStart! , arcEnd! [, r gbColor& ]

Description

An arc is a section of a circle or an ellipse. To specify a particular arc, you would first define the full circle or ellipse of which it is a part, and then specify the points on the ellipse where the arc starts and stops.

The full circle or ellipse is defined by its bounding rectangle, which is the smallest rectangle which can be drawn around the circle or ellipse. For example, if the circle is centered at position (400,400), with a radius of 100 pixels, the upper left corner (x1,y1) of the bounding rectangle is (300,300), and the lower right corner (x2,y2) is (500,500).

The start point and end point of the arc are specified by their angle, which must be given in radians. A complete circle or ellipse is 2*pi radians. On a 12-hour clock-face, the values 0 and 2*pi both refer to the position of 3 o'clock, while the value 1*pi refers to the position of 9 o'clock. Other positions are specified by a radian value relative to these. In ScharfBASIC, arcs are always drawn counter-clockwise from the starting point to the ending point.

Prior to any XPRINT operations, a host printer must first be selected with XPRINT ATTACH . The coordinate points are specified in pixels (or world coordinates, if those were chosen with XPRINT SCALE ). Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . Because of the nature of an arc, XPRINT ARC neither uses, nor updates, (last point referenced). If executed without a host printer attached, error 57 is generated.

x1! , y1!

The upper left corner of the bounding rectangle of the full circle or ellipse.

x2! , y2!

The lower right corner of the bounding rectangle of the full circle or ellipse.

ArcStart!

The starting angle of the arc, in radians, from 0 to 2*pi.

ArcEnd!

The ending angle of the arc, in radians, from 0 to 2*pi radians. Note that arcs are always drawn counter-clockwise from arcStart! to arcEnd! . Compared with a 12-hour clock-face, 0 or 2*pi radians is at 3 o'clock, and 1*pi radians is at 9 o'clock.

rgbColor&

Optional RGB color for the arc. If omitted (or -1), the current foreground color for the host printer page is used.

See Also

  • Built In RGB Color Equates
  • XPRINT ATTACH
  • XPRINT COLOR
  • XPRINT ELLIPSE
  • XPRINT PIE
  • XPRINT STYLE
  • XPRINT WIDTH


XPRINT ATTACH - ScharfBASIC Help

XPRINT ATTACH

Connect a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT ATTACH {DEFAULT | PrinterName$ } [, JobName$ ]
XPRINT ATTACH CHOOSE [USING Flags& ] [, JobName$ ]

Description

XPRINT ATTACH connects to a host-based (Windows-only or GDI-based) printer for use with subsequent XPRINT operations. Host-based printing is device-independent and performed through the Windows printing system and printer driver. Device independence can be achieved because the printer driver handles the task of converting text into the manufacturers proprietary binary format used by the printer.

To send device-dependent print data (such as plain text) to a line printer device, use the LPRINT ATTACH statement instead.

XPRINT ATTACH allows you to change the printer device used by XPRINT operation. When executed, the current connection (if any) is closed and the new connection is established.

DEFAULT

If DEFAULT is specified, the default printer (as set in the Printers applet in Control Panel) is used. For example:

XPRINT ATTACH DEFAULT

CHOOSE

If CHOOSE is specified, the Choose Printer common dialog is opened, allowing the user to select from the list of installed printers. For example:

XPRINT ATTACH CHOOSE

With CHOOSE, you may elect to include an optional numeric expression called Flags& . This value consists of one or more of the following equates to control the execution of the Printer Dialog:

%PD_ALLPAGES

"All Pages" button is the default.

%PD_SELECTION

"Selection" button is the default.

%PD_PAGENUMS

"Numbered Pages" button is the default. (Only one of the above is allowed)

%PD_NOSELECTION

Disables the "Selection" button.

%PD_NOPAGENUMS

Disables the "Numbered Pages" button.

%PD_COLLATE

"Collate" option is checked.

%PD_PRINTTOFILE

"Print To File" option is checked.

%PD_DISABLEPRINTTOFILE

Disables the "Print To File" option.

%PD_HIDEPRINTTOFILE

Hides the "Print To File" option.

PrinterName$

The name of the printer to attach (as shown in the Printers applet in Control Panel, or returned by the PRINTER$ function). printername$ must be a valid device name and cannot exceed 259 characters in length. For example:

XPRINT ATTACH "HP LaserJet 5MP"

JobName$

The name of the print job. This will be shown in the print spooler. If you do not supply a name, "Printjob" is used by default.

If XPRINT ATTACH is not successful, XPRINT$ returns an empty string . Error 68 ("device unavailable") is generated if an invalid printer was specified. No error is generated if the user cancels the Choose Printer dialog (with XPRINT ATTACH CHOOSE). Therefore, for host-based printing, applications should always use XPRINT ATTACH to explicitly select the intended host-based printer, then test for a successful selection with the XPRINT$ and ERR functions to ensure the host-based printer selection was successful.

Unlike direct printing (LPRINT ATTACH), host-based printing is handled by a printer driver and the operating system's spooler subsystem. Therefore, spooler settings such as "work offline" in the Printer Properties dialog will not impede the creation of a spooled print job. Once all the data has been sent to the printer, detach the printer so other applications can use it., with the XPRINT CLOSE statement.

Host-based printers use proprietary control protocols, unlike line printers, so it is usually not possible to send them printer-dependent control codes. To attach a line printer, use LPRINT ATTACH instead of XPRINT ATTACH.

Note: You can enumerate the available printers with the PRINTERCOUNT and PRINTER$ functions.

See Also

  • LPRINT ATTACH
  • PRINTER$
  • XPRINT CANCEL
  • XPRINT CLOSE
  • XPRINT GET ATTACH
  • XPRINT GET PAGES
  • XPRINT GET SELECTION


XPRINT BOX - ScharfBASIC Help

XPRINT BOX

Draw a box with square or rounded corners on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT BOX ( x1! , y1! ) - ( x2! , y2! ) [, [ corner& ] [, [ rgbColor& ] [, [ fillcolor& ] [, [ fillstyle& ]]]]]

Description

Prior to any XPRINT operations, a host printer must first be selected with XPRINT ATTACH . The coordinate points are specified in pixels (or world coordinates, if those were chosen with XPRINT SCALE ). Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . Because of the nature of a box, XPRINT BOX neither uses, nor updates, (last point referenced). If executed without a host printer attached, error 57 is generated.

Windows graphic conventions consider the bottom and right coordinates of a BOX to be exclusive. The pixels at the bottom and right edges are not drawn unless OVERLAP MODE is enabled. See XPRINT SET OVERLAP for details.

x1! , y1!

The upper left corner of the box.

x2! , y2!

The lower right corner of the box.

corner&

The percentage of roundness of the corners, in the range of 0 to 100. A value of zero creates square corners, while 100 creates a circle/oval. A value of 20 being most common for a pleasant, rounded appearance. If corner& is omitted, the default is 0, which creates a rectangle with square corners.

rgbColor&

Optional RGB color of the box edge. If omitted (or -1), the edge color defaults to the current foreground color for the host printer page.

fillcolor&

Optional RGB color of the box interior. If fillcolor& is omitted (or -2), the interior of the box is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color for the host printer page. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • XPRINT ATTACH
  • XPRINT COLOR
  • XPRINT LINE
  • XPRINT SET OVERLAP
  • XPRINT STYLE
  • XPRINT WIDTH


XPRINT CANCEL - ScharfBASIC Help

XPRINT CANCEL

Cancel a print job on the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT CANCEL

Description

XPRINT CANCEL deletes the current print job and detaches the host printer, as long as XPRINT CLOSE has not yet been executed. This function is generally used to abort the print process when an error occurs.

See Also

  • XPRINT ATTACH
  • XPRINT CLOSE


XPRINT CLOSE - ScharfBASIC Help

XPRINT CLOSE

Detach a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT CLOSE

Description

XPRINT CLOSE detaches the printer from the current process, and allows printing to a HOST printer to begin. If XPRINT CLOSE is not executed, printed data may be lost.

See Also

  • XPRINT ATTACH
  • XPRINT CANCEL


XPRINT Code Group - ScharfBASIC Help

XPRINT Code Group

The XPRINT

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT DirectorWord [ params ]
XPRINT DirectorWord [ params ] TO ReturnVariable(s)
Function Form:
ReturnVariable = XPRINT( DirectorWord [, params ] )
ReturnVariable$ = XPRINT$( DirectorWord [, params ] )

Description

Some of the functionality of the XPRINT group was available in prior versions of ScharfBASIC, but it has now been expanded. Some XPRINT Procedures (namely those which return a single value) may be used in two forms, a statement with a TO clause, or a function which may be used as a term in an expression:

XPRINT GET LINES TO LineCountVar&

LineCountVar& = XPRINT(LINES)

The two examples above are functionally identical. The choice is simply a matter of your personal preference. If you use the second form (as a function which returns a value), it can be a term in any expression of any complexity. When a function form is available, it is labeled with the prefix "Function Form".

Some XPRINT procedures return two or more values. As it is not possible to simultaneously inject multiple terms into a valid expression, the function option is not available for them.

PIXELS and POINTS

For the purposes of this discussion on XPRINT, the terms PIXELS and POINTS are considered to be synonyms. They may be used interchangeably.

XPRINT STREAM

The XPRINT Stream is the connection between XPRINT code and a host printer page. The XPrint Stream is created when you attach a particular printer with XPRINT ATTACH . From that moment forward, all XPrint code acts on that selected printer. This continues until such time as you end your print job with XPRINT CLOSE .

PAGE UNITS

PAGE UNITS are used to measure the size of a graphical item, or to define a particular position on an XPrint page. You can define page units to be points or scaled units of your choice.

Initially, each XPrint session begins with Page Units set to points. You can change this to scaled world coordinates of your choice with XPRINT SCALE .

By default, the upper left corner of a printer page is considered to be the X,Y position 0,0 and grows larger to the right or downward. The X axis is horizontal, while the Y axis is vertical. Whenever an X,Y position is given, the X value is stated first.

XPRINT POSITION (POS)

Each time you draw text or graphics, it is displayed at the current XPrint position (POS). Upon completion, the POS is updated to the last point referenced. You can draw a relative distance from the POS (using a STEP option), or set an entirely new position with XPRINT SET POS .

TEXT CELL (ROW/COLUMN POSITION)

For ease of programming, a few procedures specify text position by row and column. In this case, the position is measured in text cells, which is the space occupied by one character. This works well with fixed width fonts, which is recommended. If a variable width font is chosen, ScharfBASIC must use the average character size for these calculations, which can give imprecise results.

For compatibility with most current and prior versions of BASIC (ScharfBASIC included), code which references text rows and columns names the vertical term first (ROWS, COLUMNS). Rows and columns are always numbered from one upward.

See Also

  • Printing
  • Printing Commands


XPRINT COLOR - ScharfBASIC Help

XPRINT COLOR

Set the foreground

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT COLOR foreground& [, background& ]

Description

Colors are expressed as RGB values, or use -1 for the default color. If the background parameter is -2, the background is made transparent. If either parameter is -3, the existing color is not changed. A host printer must first be connected with XPRINT ATTACH . If a host printer is not attached, error 57 is generated.

See Also

  • Built In RGB Color Equates
  • XPRINT
  • XPRINT ATTACH


XPRINT COPY - ScharfBASIC Help

XPRINT COPY

Copy a bitma

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT COPY hbmpSource??? , id& [, style& ]
XPRINT COPY hbmpSource??? , id& TO ( x! , y! ) [, style& ]
XPRINT COPY hbmpSource??? , id& , ( x1! , y1! )-( x2! , y2! ) TO ( x! , y! ) [, style% ]

Description

You can copy a complete bitmap, or a portion of it, to the host printer page. The expression hbmpSource??? specifies the handle of the source bitmap or window. The expression id& is the unique control i dentifier in the range 1 to 65535, as assigned with the CONTROL ADD GRAPHIC statement. id& must be 0 for a GRAPHIC WINDOW or a bitmap . The destination of the copy operation is the host printer page. You must use care that your parameters are valid for the specified bitmaps, or results of the operation are undefined.

The first form of the XPRINT COPY statement copies the complete bitmap, positioning it at (0,0), which is the upper left corner of the destination.

The second form of XPRINT COPY also copies the complete bitmap, but positions it at the point specified by the parameter ( x! , y! ).

The third form copies a portion of the bitmap, positioning it at the point specified by the parameter ( x! , y! ). If style& is included, it is one of the following values:

%mix_Blackness

Pixel is always 0 (black).

%mix_NotMergeSrc

Pixel is the inverse of the MergeSrc color.

%mix_MaskNotSrc

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%mix_NotCopySrc

Pixel is the inverse of the pen color.

%mix_MaskSrcNot

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%mix_Not

Pixel is the inverse of the pixel color.

%mix_XorSrc

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%mix_NotMaskSrc

Pixel is the inverse of the MaskSrc color.

%mix_MaskSrc

Pixel is a combination of the colors common to both the source and the pixel.

%mix_NotXorSrc

Pixel is the inverse of the XorSrc color.

%mix_Nop

Pixel remains unchanged.

%mix_MergeNotSrc

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_CopySrc

Pixel is the source color (default).

%mix_MergeSrcNot

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_MergeSrc

Pixel is a combination of the source color and the pixel color.

%mix_Whiteness

Pixel is always 1 (white).

A host printer must first be connected with XPRINT ATTACH . If a host printer is not attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT RENDER
  • XPRINT STRETCH
  • XPRINT SET STRETCHMODE


XPRINT ELLIPSE - ScharfBASIC Help

XPRINT ELLIPSE

Draw an ellipse or a circle on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT ELLIPSE ( x1! , y1! ) - ( x2! , y2! ) [, [ rgbColor& ] [, [ fillcolor &] [, [ fillstyle& ]]]]

Description

A host printer must first be connected with XPRINT ATTACH . The coordinate points are specified in pixels (or world coordinates, if those were defined with an XPRINT SCALE statement). Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . Because of the nature of an ellipse, which has no obvious beginning or end, XPRINT ELLIPSE neither uses, nor updates, the last point referenced (POS). If executed without a host printer attached, error 57 is generated.

The coordinate pair define an invisible bounding rectangle which would enclose the ellipse to be drawn. It tells both the size and the proportions of the ellipse. Windows graphic conventions consider the bottom and right coordinates of it to be exclusive. The pixels at the bottom and right edges are ignored, unless Overlap Mode is enabled. See XPRINT SET OVERLAP for details.

x1! , y1!

The upper left corner of the bounding rectangle.

x2! , y2!

The lower right corner of the bounding rectangle.

rgbColor&

Optional RGB color of the ellipse edge. If omitted (or -1), the edge color defaults to the current foreground color for the host printer page.

fillcolor&

Optional RGB color of the ellipse interior. If fillcolor& is omitted (or -2), the interior of the ellipse is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color for the host printer page. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT COLOR
  • XPRINT LINE
  • XPRINT PIE
  • XPRINT SET OVERLAP
  • RINT STYLE
  • XPRINT WIDTH


XPRINT FORMFEED - ScharfBASIC Help

XPRINT FORMFEED

Start a new page for the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT FORMFEED

Description

XPRINT FORMFEED causes the current print page to be ejected, and a new page started. If XPRINT FORMFEED is unsuccessful, an error is generated. Note that some printers do not eject a page if it is blank.

See Also

  • XPRINT ATTACH
  • XPRINT CLOSE


XPRINT GET MARGIN - ScharfBASIC Help

XPRINT GET MARGIN

Retrieve the margin sizes for the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET MARGIN TO nLeft! , nTop! , nRight! , nBottom!

Description

XPRINT GET MARGIN retrieves the size of the margins (the non-printable area) of the printer page. This is important because some printers do not provide equal margins on each side of the page. This is more common on the vertical coordinate, but could be found in either or both directions. The size of the four margins are specified in pixels (or world coordinates, if those were defined with an XPRINT SCALE statement). If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET CLIENT
  • XPRINT GET PPI
  • XPRINT GET SIZE


XPRINT GET PAGES - ScharfBASIC Help

XPRINT GET PAGES

Retrieves the XPRINT

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET PAGES TO FromPage& , ToPage&

Description

You may elect to limit a particular print job to a subset of the total number of pages. This can be accomplished under program control by executing XPRINT SET PAGES , or the user can make the appropriate choice in the Print Dialog which is displayed when XPRINT ATTACH is executed with the CHOOSE option. When the pages are limited in this way, ScharfBASIC handles all the details of print suppression for you.

Normally, XPRINT pages are numbered from one. The parameter FromPage& specifies the first page of the full report which will be printed, while ToPage& specifies the last page.

If XPRINT GET PAGES is executed without a host printer attached, an error 57 is generated.

See Also

  • XPRINT PREVIEW
  • XPRINT GET SELECTION
  • XPRINT SET PAGES


XPRINT GET SCALE - ScharfBASIC Help

XPRINT GET SCALE

Retrieve the current

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET SCALE TO x1! , y1! , x2! , y2!

Description

XPRINT SCALE allows you to define your own world coordinate system for subsequent XPR INT statements. World coordinates may be floating point values, with the only requirement that x1! not equal x2!, and y1! not equal y2!.

XPRINT GET SCALE retrieves the coordinate limits, which may be either custom world coordinates (if an XPRINT SCALE has been executed), or else default pixel coordinates. This allows you to save and restore a previous set of coordinates.

See Also

  • XPRINT SCALE
  • XPRINT SCALE PIXELS


XPRINT IMAGELIST - ScharfBASIC Help

XPRINT IMAGELIST

Prints an image from an

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT IMAGELIST ( x! , y! ), hLst , index& , overlay& , style&

Description

One of the images stored in an IMAGELIST is printed on the attached host printer. The parameters x! , y! define the upper left corner of the position of the image. hLst is the handle of the IMAGELIST and index& is the selector of the image to be displayed (1=first, 2=second, etc.). If overlay& is non-zero, it specifies an overlay image to be added to the printed image from the image list. The parameter style& may be one of the following style bits:

%ILD_NORMAL

Draws the image using the background color of the image list. If the background color is the default value %CLR_NONE (defined in the Commctrl.inc file), the image is drawn transparently.

%ILD_TRANSPARENT

Draws the image transparently if there is a mask.

%ILD_MASK

Draws the mask.

%ILD_BLEND25

If there is a mask, the image is drawn blending 25% with the system highlight color.

%ILD_BLEND50

If there is a mask, the image is drawn blending 50% with the system highlight color.

See Also

  • XPRINT ATTACH
  • IMAGELIST


XPRINT LINE - ScharfBASIC Help

XPRINT LINE

Draw a line on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT LINE [STEP] [( x1! , y1! )] - [STEP] ( x2! , y2! )[, rgbColor& ]

Description

The line is drawn from the first point, up to, but not including the second point. Coordinate points are specified in pixels, unless optional world coordinates have been defined with an XPRINT SCALE statement. Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . If executed without a host printer attached, error 57 is generated.

Windows graphic conventions consider the final x2 and y2 coordinates to be exclusive. Therefore, by default, the final pixel is not drawn unless Overlap Mode is enabled. See XPRINT SET OVERLAP for details.

x1! , y1!

Optional values which define the starting point of the line. If this optional first point is omitted, the line begins at the last point referenced (POS ) in a preceding statement. If the first STEP option is included, the x1! and y1! starting coordinates are relative to the last point referenced (POS) on the host printer page.

x2! , y2!

The ending point of the line. If the second STEP option is included, the x2! and y2! ending coordinates are relative to the starting coordinates.

rgbColor&

Optional RGB color value for the line. If rgbColor& is omitted (or -1), the line color defaults to the current foreground color for the host printer page.

See Also

  • Built In RGB Color Equates
  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT BOX
  • XPRINT COLOR
  • XPRINT ELLIPSE
  • XPRINT PIE
  • XPRINT POLYGON
  • XPRINT POLYLINE
  • XPRINT SET MIX
  • XPRINT SET OVERLAP
  • XPRINT STYLE
  • XPRINT WIDTH


XPRINT PIE - ScharfBASIC Help

XPRINT PIE

Draw a pie section on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT PIE ( x1! , y1! ) - ( x2! , y2! ), arcStart! , arcEnd! [, [ rgbColor& ] [, [ fillcolor& ] [, [ fillstyle& ]]]]

Description

A pie section is an arc, with a line drawn from each end point to the center of the circle or ellipse. To specify a pie section, you would first define the full circle or ellipse of which it is a part, and then specify the points on the ellipse where the arc starts and stops.

The full circle or ellipse is defined by its bounding rectangle, which is defined as the smallest rectangle which can be drawn around the circle or ellipse. For example, if the circle is centered at position (400,400), with a radius of 100 pixels, the upper left corner (x1,y1) of the bounding rectangle is (300,300), and the lower right corner (x2,y2) is (500,500).

The start point and end point of the arc are specified by their angle, which must be given in radians. A complete circle or ellipse is 2*pi radians. On a 12-hour clock-face, the values 0 and 2*pi both refer to the position of 3 o'clock, while the value 1*pi refers to the position of 9 o'clock. Other positions are specified by a radian value relative to these. In ScharfBASIC, arcs are always drawn counter-clockwise from the starting point to the ending point.

Prior to any XPRINT operations, a host printer must first be selected with XPRINT ATTACH . The coordinate points are specified in pixels (or world coordinates, if those were chosen with XPRINT SCALE ). Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . Because of the nature of a pie section, XPRINT PIE neither uses, nor updates, (last point referenced). If executed without a host printer attached, error 57 is generated.

x1! , y1!

The upper left corner of the bounding rectangle of the full circle or ellipse.

x2! , y2!

The lower right corner of the bounding rectangle of the full circle or ellipse.

ArcStart!

The starting angle of the arc, in radians, from 0 to 2*pi.

ArcEnd!

The ending angle of the arc, in radians, from 0 to 2*pi radians. Note that arcs are always drawn counter-clockwise from arcStart! to arcEnd! . Compared with a 12-hour clock-face, 0 or 2*pi radians is at 3 o'clock, and 1*pi radians is at 9 o'clock.

rgbColor&

Optional RGB color of the pie edge. If omitted (or -1), the edge color defaults to the current foreground color for the host printer page.

fillcolor&

Optional RGB color of the pie interior. If fillcolor& is omitted (or -2), the interior of the pie is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color for the host printer page. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

See Also

  • Built In RGB Color Equates
  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT BOX
  • XPRINT COLOR
  • XPRINT ELLIPSE
  • XPRINT LINE
  • XPRINT STYLE
  • XPRINT WIDTH


XPRINT POLYGON - ScharfBASIC Help

XPRINT POLYGON

Draw a polygon on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT POLYGON points [, [ rgbColor& ] [, [ fillcolor& ] [, [ fillstyle& ] [, fillmode& ]]]]

Description

The coordinate points are specified in pixels, unless optional world coordinates have been defined with an XPRINT SCALE statement. Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . XPRINT POLYGON neither uses, nor updates, the last point referenced (POS ). If executed without a host printer attached, error 57 is generated.

points

User-defined type that defines the number of vertices and the location of each. There must be at least two, and no more than 1024 vertices. The first member is a long integer point count, followed directly by the appropriate number of single precision floats to specify the actual coordinates. Floating point coordinates are required, because of the possibility of their use as world coordinates with XPRINT SCALE. You can use a type with a scalar list, like this:

TYPE PolyPoints

count as long

x1 as single

y1 as single

x2 as single

y2 as single

x3 as single

y3 as single

END TYPE

Or, you can create an array using point types, like this:

TYPE PolyPoint

x as single

y as single

END TYPE

TYPE PolyArray

count as long

xy(1 TO 3) as PolyPoint

END TYPE

rgbColor&

Optional RGB color of the polygon edge. If omitted (or -1), the edge color defaults to the current foreground color for the host printer page.

fillcolor&

Optional RGB color of the polygon interior. If fillcolor& is omitted (or -2), the interior of the ellipse is not filled, allowing the background to show through. If fillcolor& is -1, the interior is painted with the same color as the edge. Otherwise, fillcolor& specifies the RGB color to be used.

fillstyle&

Optional fill style (pattern) to be used. If fillstyle& is omitted, the default fill style is solid (0). If a hatch pattern is chosen (1 to 6), the foreground color is specified by the fillcolor& , while the background is specified by the default background color for the host printer page. The optional fillstyle& may be:

Solid (default)

Horizontal Lines

Vertical Lines

Upward Diagonal Lines

Downward Diagonal Lines

Crossed Lines

Diagonal Crossed Lines

fillmode&

If fillmode& is missing (or zero), the winding mode is selected. This fills any region with a non-zero winding value. If fillmode& is non-zero, the alternate mode is selected. This fills the area between odd-numbered and even-numbered polygon sides on each scan line. That is, it fills the area between the first side and the second side, between the third side and fourth side, etc.

See Also

  • Built In RGB Color Equates
  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT BOX
  • XPRINT COLOR
  • XPRINT ELLIPSE
  • XPRINT LINE
  • XPRINT POLYLINE


XPRINT POLYLINE - ScharfBASIC Help

XPRINT POLYLINE

Draw a series of connected lines on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT POLYLINE points [ , rgbColor& ]

Description

The coordinate points are specified in pixels, unless optional world coordinates have been defined with an XPRINT SCALE statement. Line width can be set using XPRINT WIDTH . If line width is set to 1 (the default), the line style can be set with XPRINT STYLE . XPRINT POLYLINE neither uses, nor updates, the last point referenced (POS ). If executed without a host printer attached, error 57 is generated.

Windows graphic conventions consider the final x2 and y2 coordinates to be exclusive. Therefore, by default, the final pixel is not drawn unless Overlap Mode is enabled. See XPRINT SET OVERLAP for details.

points

User-defined type that defines the number of vertices and the location of each. There must be at least two, and no more than 1024 vertices. The first member is a long integer point count, followed directly by the appropriate number of single precision floats to specify the actual coordinates. Floating point coordinates are required, because of the possibility of their use as world coordinates with SCALE. You can use a type with a scalar list, like this:

TYPE PolyPoints

count as long

x1 as single

y1 as single

x2 as single

y2 as single

x3 as single

y3 as single

END TYPE

Or, you can create an array using point types, like this:

TYPE PolyPoint

x as single

y as single

END TYPE

TYPE PolyArray

count as long

xy(1 TO 3) as PolyPoint

END TYPE

rgbColor&

Optional RGB color of the polygon edge. If omitted (or -1), the edge color defaults to the current foreground color for the host printer page.

See Also

  • Built In RGB Color Equates
  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT BOX
  • XPRINT COLOR
  • XPRINT ELLIPSE
  • XPRINT LINE
  • XPRINT POLYGON
  • XPRINT SET OVERLAP
  • XPRINT STYLE
  • XPRINT WIDTH


XPRINT PREVIEW - ScharfBASIC Help

XPRINT PREVIEW

Display a replica of a printed document on the screen.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT PREVIEW hWin , ID [, CALL xxx ]
XPRINT PREVIEW CLOSE

Description

Print Preview is a powerful concept which should be considered in most application programs which provide printed reports. Briefly, the idea involves displaying a printed report on the screen before it is committed to printing on paper.

XPRINT PREVIEW allows you to redirect output from XPRINT statements to a graphic , control , or window so that it may be displayed on the screen. When XPRINT PREVIEW CLOSE is executed, XPRINT output reverts back to the host printer so that a repeat of the XPRINT code is now sent to the printer for completion of the printed report.

XPRINT PREVIEW selects the graphic target, and should be executed directly after the printer is selected with XPRINT ATTACH . The target is identified by the handle and ID given when it was created. You can optionally specify a callback function which is called upon every execution of an XPRINT FORMFEED or XPRINT CLOSE.

XPRINT PREVIEW must be executed immediately after XPRINT ATTACH or an error 98 "XPrint Preview Error" will be generated at run time. No XPRINT statements (other than the XPRINT$ function) may be executed between XPRINT ATTACH and XPRINT PREVIEW.

If you include the CallBack option, the callback procedure must be a simple SUB with no parameters and no return value. It is called automatically by the XPRINT engine at the completion of each preview page (upon execution of XPRINT FORMFEED or XPRINT PREVIEW CLOSE. This Sub can perform all sorts of housekeeping help, such as copying the preview bitmap for separate storage, counting pages in the report, or most anything else needed by your program. Copying the bitmap is important in multi-page reports as XPRINT FORMFEED erases the graphic target for preview of the next page.

See Also

  • XPRINT ATTACH
  • XPRINT CLOSE
  • XPRINT FORMFEED


XPRINT PRINT - ScharfBASIC Help

XPRINT PRINT

Output text to be printed on the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT PRINT [ EXPRLIST ] [POS( n )] [SPC( n )] [TAB( n )] [,] [;]...
XPRINT [ EXPRLIST ] [POS( n )] [SPC( n )] [TAB( n )] [,] [;]...

Description

Prior to any XPRINT operations, you should be certain that a printer has been selected with XPRINT ATTACH . The text foreground and background color are set with XPRINT COLOR . Text which extends beyond the bounds of the page is clipped. The size of the text to be printed can be determined in advance with XPRINT TEXT SIZE , and formatted to fit a particular field with XPRINT SPLIT . Drawing begins at the last point referenced by another statement, or the point specified by XPRINT SET POS . The upper left corner of the text is positioned at the POS.

XPRINT PRINT has the following parts, which may occur in any order and quantity, within a single statement:

EXPRLIST

String and/or numeric expression(s) which are written to the page. A semicolon can be used as separator between multiple expressions in the same statement. Upon completion, the POS is moved to the left margin of the next line.

POS( n )

An optional function used to set the POS to the horizontal page unit ( pixel , scaled unit, etc.) specified by the numeric argument, Multiple uses of the POS function is permitted in a single statement. The vertical position is unchanged.

SPC( n )

An optional function used to insert n spaces into the printed output. Multiple uses of SPC is permitted in a single statement. Values of n less than 1 are ignored.

TAB( n )

An optional function used to tab to the n th column before printing the next expression. Multiple use of TAB is permitted in a single statement. Since TAB references columns, rather than pixels, it can give unpredictable results when used with a variable width font . It is best used with a fixed width font.

Special characters that determine the position of the next text item printed. A semicolon (;) means the next text item is printed immediately; a comma (,) means the next text item is printed at the start of the next print zone. Print zones begin every 14 columns.

If the final argument is a semicolon or comma, the POS is maintained at the current location, rather than the default action of moving to the start of the next line. For example:

XPRINT PRINT "Hello";

XPRINT PRINT " world!";

...produces the contiguous result "Hello world!"

If you omit all arguments, XPRINT PRINT just moves the POS to the left margin of the next line. Any control codes, such as Carriage Return, Line-Feed, and Backspace are not interpreted. They will display as symbols in the current selected font.

USING$ is a separate function, which may be included in the ExprList . See the USING$() function for more information.

It is not possible to print a User-Defined Type (UDT), a Variant , an object variable, or an entire array . Individual member values must be extracted with the appropriate function before they can be displayed.

See Also

  • FONT NEW
  • LPRINT
  • XPRINT ATTACH
  • XPRINT CELL
  • XPRINT CHR SIZE
  • XPRINT COLOR
  • XPRINT CLOSE
  • XPRINT SET FONT
  • XPRINT GET POS
  • XPRINT SET POS
  • XPRINT SET WORDWRAP
  • XPRINT SET WRAP
  • XPRINT SPLIT
  • XPRINT TEXT SIZE

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x207a54
call   0x202afc
call   0x201f2c
call   0x20358e
call   0x2035cf


XPRINT RENDER - ScharfBASIC Help

XPRINT RENDER

Render an image on a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT RENDER BmpName$ , ( x1! , y1! )-( x2! , y2! )

Description

Renders an image (bitmap or icon), loaded from a resource or a disk file, to a host printer page. The parameter BmpName$ contains the name of the image to be loaded. If BmpName$ contains a period, it is presumed to be the name of a disk file. Otherwise, an attempt is made to load it from the program's resource data; if not found, it is then presumed to be a disk file. The parameters x1!,y1! define the upper left corner of the destination rectangle, while x2!,y2! define the lower right corner of that rectangle. If the destination rectangle is larger or smaller than the original, the image is stretched or condensed to the requested size. If XPRINT RENDER is unsuccessful, an appropriate error is generated.

The following code will retrieve the natural size of an image in a bitmap file, in pixels:

nFile& = FREEFILE

OPEN "myimage.bmp" FOR BINARY AS nFile&

GET #nFile&, 19, nWidth&

GET #nFile&, 23, nHeight&

CLOSE nFile&

See Also

  • XPRINT ATTACH
  • XPRINT COPY
  • XPRINT STRETCH
  • XPRINT SET STRETCHMODE


XPRINT SCALE - ScharfBASIC Help

XPRINT SCALE

Define a custom world coordinate system for a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SCALE ( x1! , y1! )-( x2! , y2! )
XPRINT SCALE PIXELS

Description

XPRINT SCALE lets you define your own world coordinate system f or all subsequent XPRINT statements. World coordinates may be floating point values, with the only requirement that x1! not equal x2!, and y1! not equal y2!. If either pair are equal, an error 5 is generated. The custom coordinates remain with the printer page until XPRINT SCALE is repeated, or the host printer is detached. If executed without a host printer attached, error 57 is generated.

If x2! is greater than x1! , coordinates grow larger as they move to the right. Otherwise, they grow larger as they move to the left.

If y2! is greater than y1! , coordinates grow larger as they move downward. Otherwise, they grow larger as they move upward.

By default, the position x2 !/ y2! translates to the first pixel which is outside of the client area , and therefore not drawn. However, if OVERLAP MODE is enabled by XPRINT SET OVERLAP , x2!/y2! translates to the final pixel in the client area and is drawn.

XPRINT SCALE PIXELS sets or resets the coordinate system to pixel coordinates.

Note: XPRINT SCALE will not work with negative numeric values - all numeric arguments must be positive.

See Also

  • XPRINT ATTACH
  • XPRINT GET SCALE
  • XPRINT SET OVERLAP statement


XPRINT SET CLIP - ScharfBASIC Help

XPRINT SET CLIP

Establishes margins around the outer edges of the print page.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET CLIP LeftMargin! , TopMargin! , RightMargin! , BottomMargin!

Description

This statement establishes margins on any or all sides of the selected printer . All subsequent XPRINT operations are "clipped" on these boundaries, so that no additional text or graphics are written in these protected areas.

Each of the 4 parameters is specified in the PAGE UNITS currently in effect. However, as this changes the target space available to you, the page units are immediately set to pixels/points. The upper left corner of the clip area is now addressed as point (0,0), while the right and bottom limits are reduced by the size of the margins. If you would prefer to use new Scaled Page Units for this revised clip area, you must executes a new XPRINT SCALE .

XPRINT SET CLIP is particularly useful for displaying text, where enclosing "white space" improves the appearance a good deal.

You can disable a clip area by executing XPRINT SET CLIP 0,0,0,0.

See Also

  • XPRINT GET CANVAS
  • XPRINT GET CLIENT
  • XPRINT GET SCALE
  • XPRINT SCALE


XPRINT SET COLLATE - ScharfBASIC Help

XPRINT SET COLLATE

Change the XPRINT collate status.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET COLLATE numrexp

Description

XPRINT allows you to set the collate status, if the printer driver supports both multiple copies and collate capability. XPRINT SET COLLATE enables or disables collating, depending upon the value of the numrexp (1=true 0=false). The following equates are predefined in the compiler to symbolically represent the possible status:

%DMCOLLATE_FALSE = 0

%DMCOLLATE_TRUE = 1

If the printer does not support collating, or other values are used, error 5 is generated. If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET COLLATE


XPRINT SET COLORMODE - ScharfBASIC Help

XPRINT SET COLORMODE

Changes the XPRINT colormode status.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET COLORMODE numrexp

Description

XPRINT allows you to set the color or monochrome print mode if the printer driver supports it. XPRINT SET COLORMODE expects a numeric expression which evaluates to one of the following listed values. The following equates are predefined in the compiler to symbolically represent the possible status:

%DMCOLOR_MONOCHROME = 1

%DMCOLOR_COLOR = 2

If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET COLORMODE


XPRINT SET COPIES - ScharfBASIC Help

XPRINT SET COPIES

Change the XPRINT copy count.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET COPIES numrexp

Description

XPRINT SET COPIES allows you to set the number of copies to be automatically printed, if it is supported by the printer driver. The default value is one (1). If multiple copies are not supported by the printer driver, or the count requested is greater than that supported by the printer driver, error 5 is generated. If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET COPIES


XPRINT SET DUPLEX - ScharfBASIC Help

XPRINT SET DUPLEX

Change the XPRINT duplex status.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET DUPLEX numrexp

Description

XPRINT allows you to set the duplex status, if the printer supports printing on both sides of a page. XPRINT SET DUPLEX changes the mode to that specified by the numrexp . The following equates are predefined in the compiler to symbolically represent the possible duplex status:

%DMDUP_SIMPLEX = 1 (single sided printing)

%DMDUP_VERTICAL = 2 (page flipped on the vertical edge)

%DMDUP_HORIZONTAL = 3 (page flipped on the horizontal edge)

If the printer does not support duplex printing, error 5 is generated. If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET DUPLEX


XPRINT SET FONT - ScharfBASIC Help

XPRINT SET FONT

Select a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET FONT FontHndl&

Description

The font specified by FontHndl& is selected to be used by XPRINT statements. This is the most efficient way to change fonts and their general appearance (size, style, etc.). If you specify a FontHndl& of zero, the font is changed back to the original default font chosen by ScharfBASIC.

You can predefine virtually any number of fonts and attributes by executing FONT NEW statements for each of them. That makes them ready for immediate use when selected by XPRINT SET FONT.

Prior to any XPRINT operations, a specific printer must first be selected with XPRINT ATTACH . If no specific font is selected, the default font is Courier New with no style attributes.

See Also

  • FONT NEW
  • XPRINT
  • XPRINT ATTACH
  • XPRINT CHR SIZE
  • XPRINT TEXT SIZE


XPRINT SET MIX - ScharfBASIC Help

XPRINT SET MIX

Set the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET MIX mode&

Description

Prior to any graphical operations, a host printer must first be selected with XPRINT ATTACH . There are 16 mix modes available to use for mixing the drawing color with the color that already exists at the drawing location. The default mix mode is 13, %mix_CopySrc. The mix mode equates are predefined in ScharfBASIC.

%MIX_BLACKNESS

Pixel is always 0 (black).

%MIX_NOTMERGESRC

Pixel is the inverse of the MergeSrc color.

%MIX_MASKNOTSRC

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%MIX_NOTCOPYSRC

Pixel is the inverse of the pen color.

%MIX_MASKSRCNOT

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%MIX_NOT

Pixel is the inverse of the pixel color.

%MIX_XORSRC

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%MIX_NOTMASKSRC

Pixel is the inverse of the MaskSrc color.

%MIX_MASKSRC

Pixel is a combination of the colors common to both the source and the pixel.

%MIX_NOTXORSRC

Pixel is the inverse of the XorSrc color.

%MIX_NOP

Pixel remains unchanged.

%MIX_MERGENOTSRC

Pixel is a combination of the source color and the inverse of the pixel color.

%MIX_COPYSRC

Pixel is the source color (default).

%MIX_MERGESRCNOT

Pixel is a combination of the source color and the inverse of the pixel color.

%MIX_MERGESRC

Pixel is a combination of the source color and the pixel color.

%MIX_WHITENESS

Pixel is always 1 (white).

See Also

  • XPRINT ATTACH
  • XPRINT GET MIX


XPRINT SET ORIENTATION - ScharfBASIC Help

XPRINT SET ORIENTATION

Set the paper orientation for a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET ORIENTATION orent&

Description

XPRINT SET ORIENTATION sets the orientation of the paper in the host printer. The value 1 indicates portrait mode, while 2 indicates landscape mode. If a host printer is not attached, or does not support setting the orientation, error 57 is generated.

See Also

  • FONT NEW
  • XPRINT ATTACH
  • XPRINT GET ORIENTATION
  • XPRINT SET FONT


XPRINT SET OVERLAP - ScharfBASIC Help

XPRINT SET OVERLAP

Enables or disables XPRINT Overlap Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET OVERLAP [ NumrExpr& ]

Description

XPRINT SET OVERLAP enables or disables overlap mode for the host printer which is currently attached to the XPRINT stream . It has no effect on any other XPRINT target. If NumrExpr& is true (non-zero), overlap mode is enabled. If false (zero), overlap mode is disabled. If NumrExpr& is missing, the default is to enable Overlap Mode.

With Overlap Mode, you can control how ScharfBASIC treats XPRINT operations which involve a bounding rectangle (RECT structure) in their definition. Windows maintains unique conventions for a RECT. The bottom and right coordinates of a RECT are exclusive. In other words, the pixels at the bottom and right edges lie immediately outside the rectangle. They are ignored. For example:

XPRINT BOX (0,0) - (50,50)

In this case, a box is drawn from 0,0 to 49,49. The final pixels at the bottom and right edge are simply not drawn. However, if Overlap Mode is enabled, the box is drawn from 0,0 to 50,50.

The Overlap Mode affects all XPRINT functions which take a bounding rectangle as a parameter. This includes XPRINT SCALE , XPRINT BOX , XPRINT ELLIPSE , XPRINT LINE , XPRINT POLYLINE , etc.

See Also

  • XPRINT BOX
  • XPRINT ELLIPSE
  • XPRINT GET OVERLAP
  • XPRINT LINE
  • XPRINT POLYLINE
  • XPRINT SCALE


XPRINT SET PAGES - ScharfBASIC Help

XPRINT SET PAGES

Sets the XPRINT page number limits for this

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET PAGES FromPage& , ToPage&

Description

You may elect to limit a particular print job to a subset of the total number of pages. This can be accomplished under program control by executing XPRINT SET PAGES, or the user can make the appropriate choice in the Print Dialog which is displayed when XPRINT ATTACH is executed with the CHOOSE option. When the pages are limited in this way, ScharfBASIC handles all the details of print suppression for you.

Normally, XPRINT pages are numbered from one. The parameter FromPage& specifies the first page of the full report which will be printed, while ToPage& specifies the last page.

If XPRINT SET PAGES is executed without a host printer attached, an error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET PAGES
  • XPRINT SET COPIES


XPRINT SET PAPER - ScharfBASIC Help

XPRINT SET PAPER

Sets a new

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET PAPER papertype&

Description

XPRINT SET PAPER changes the paper style for the host printer to that designated by papertype& . The paper style is identified by an integral value given in the expression papertype&. The following equates are predefined in the compiler, and represent the most common paper styles:

%DMPAPER_LETTER = 1 Letter 8.5 x 11 inches

%DMPAPER_TABLOID = 3 Tabloid 11 x 17 inches

%DMPAPER_LEDGER = 4 Ledger 17 x 11 inches

%DMPAPER_LEGAL = 5 Legal 8.5 x 14 inches

%DMPAPER_STATEMENT = 6 Statement 5.5 x 8.5 inches

%DMPAPER_EXECUTIVE = 7 Executive 7.25 x 10.5 inches

%DMPAPER_A3 = 8 A3 297 x 420 mm

%DMPAPER_A4 = 9 A4 210 x 297 mm

%DMPAPER_A5 = 11 A5 148 x 210 mm

%DMPAPER_B4 = 12 B4 250 x 354 mm

%DMPAPER_B5 = 13 B5 182 x 257 mm

%DMPAPER_FOLIO = 14 Folio 8.5 x 13 inches

%DMPAPER_QUARTO = 15 Quarto 215 x 275 mm

%DMPAPER_10X14 = 16 10x14 10 x 14 inches

%DMPAPER_11X17 = 17 11x17 11 x 17 inches

%DMPAPER_NOTE = 18 Note 8.5 x 11 inches

%DMPAPER_ENV_9 = 19 9 Envlp 3.875 x 8.875 inches

%DMPAPER_ENV_10 = 20 10 Envlp 4.125 x 9.5 inches

Other paper style codes may be defined by Windows or printer suppliers. You can use XPRINT GET PAPERS to obtain a list of all the paper styles supported by the attached host printer.

If the printer does not support the paper style specified, error 5 is generated. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET PAPER
  • XPRINT GET PAPERS


XPRINT SET PIXEL - ScharfBASIC Help

XPRINT SET PIXEL

Set the

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET PIXEL [STEP] ( x! , y! ) [, rgbColor& ]

Description

XPRINT SET PIXEL draws a single pixel on the host printer page. The optional color parameter is an RGB value; if not included, the color defaults to the current foreground color for the host printer. If the STEP option is included, the x! and y! coordinates are relative to the last point referenced (POS ). The coordinate points are specified in pixels, unless world coordinates were set with an XPRINT SCALE statement. If no host printer is attached, error 57 is generated.

See Also

  • Built In RGB Color Equates
  • XPRINT ATTACH
  • XPRINT COLOR
  • XPRINT GET PIXEL


XPRINT SET POS - ScharfBASIC Help

XPRINT SET POS

Set the last point referenced (POS) by an XPRINT

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET POS [STEP] ( x! , y! )

Description

XPRINT SET POS allows you to set the last point referenced (POS) by XPRINT statements. If the STEP option is included, the x! and y! coordinates are relative to the prior POS. The coordinate points are specified in pixels (or world coordinates, if those were defined with an XPRINT SCALE statement). If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET POS


XPRINT SET QUALITY - ScharfBASIC Help

XPRINT SET QUALITY

Set the print quality for a

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET QUALITY qual&

Description

XPRINT SET QUALITY sets the print quality setting for the host printer. The value 1 is draft mode, 2 is low resolution, 3 is medium resolution, and 4 is high resolution. It should be noted that some printers only allow higher resolutions to be set from the printer dialog (in XPRINT ATTACH CHOOSE ). If no host printer is attached, or the printer does not support print quality settings, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET QUALITY


XPRINT SET STRETCHMODE - ScharfBASIC Help

XPRINT SET STRETCHMODE

Sets the default bitmap stretching mode for the current

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET STRETCHMODE ModeExpr

Description

There are several operations in ScharfBASIC which involve stretching or condensing images on bitmaps, most notably XPRINT STRETCH . As individual pixels must be added or removed, there is a good chance that the quality of the image will be degraded. However, if you describe the nature of the image by defining a StretchMode, you can substantially enhance the appearance.

The default StretchMode is maintained individually for each DC. You can set the default mode with this statement, or retrieve it with XPRINT GET STRETCHMODE . Of course, you can also override the default StretchMode when you execute one of the affected statements.

The 4 stretch mode equates are predefined in ScharfBASIC.

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

See Also

  • XPRINT COPY
  • XPRINT GET STRETCHMODE
  • XPRINT RENDER
  • XPRINT STRETCH


XPRINT SET TRAY - ScharfBASIC Help

XPRINT SET TRAY

Sets a new active

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET TRAY numrexp

Description

XPRINT SET TRAY changes the active paper tray on the host printer to that specified by numrexp . The following equates are predefined in the compiler, and represent the most common paper trays:

%DMBIN_UPPER = 1

%DMBIN_LOWER = 2

%DMBIN_MIDDLE = 3

%DMBIN_MANUAL = 4

%DMBIN_ENVELOPE = 5

%DMBIN_ENVMANUAL = 6

%DMBIN_AUTO = 7

%DMBIN_TRACTOR = 8

%DMBIN_SMALLFMT = 9

%DMBIN_LARGEFMT = 10

%DMBIN_LARGECAPACITY = 11

%DMBIN_CASSETTE = 14

%DMBIN_FORMSOURCE = 15

Other tray codes may be defined by Windows or printer suppliers, so your program should be written to consider that possibility. You can use XPRINT GET TRAYS to obtain a list of all the paper trays supported by the attached host printer.

If the printer does not support the tray change requested, error 5 is generated. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET TRAY
  • XPRINT GET TRAYS


XPRINT SET WORDWRAP - ScharfBASIC Help

XPRINT SET WORDWRAP

Enables or disables XPRINT WordWrap Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET WORDWRAP [ NumrExpr& ]

Description

XPRINT SET WORDWRAP enables or disables WordWrap mode for the host printer which is currently attached to the XPRINT stream . It has no effect on any other printer. If NumrExpr& is true (non-zero), WordWrap mode is enabled. If false (zero), WordWrap mode is disabled. If NumrExpr& is missing, the default is to enable WordWrap Mode.

With WordWrap Mode, you can control how ScharfBASIC prints text on an XPRINT page when it reaches the end of a line. Since a host printer operates on a full page basis, the default is to ignore text which is printed past the end of the line.

When WordWrap mode is enabled, it affects only XPRINT PRINT operations. If XPRINT PRINT attempts to display a word beyond the end of a row, the entire word is automatically wrapped to the first column of the next row.

See Also

  • XPRINT CELL
  • XPRINT GET WORDWRAP
  • XPRINT PRINT
  • XPRINT SET WRAP
  • XPRINT SPLIT


XPRINT SET WRAP - ScharfBASIC Help

XPRINT SET WRAP

Enables or disables XPrint Wrap Mode.

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SET WRAP [ NumrExpr& ]

Description

XPRINT SET WRAP enables or disables wrap mode for the host printer which is currently attached to the XPrint stream . It has no effect on any other printer. If NumrExpr& is true (non-zero), wrap mode is enabled. If false (zero), wrap mode is disabled. If NumrExpr& is missing, the default is to enable Wrap Mode.

With Wrap Mode, you can control how ScharfBASIC prints text on an XPRINT PAGE when it reaches the end of a line. Since a host printer operates on a full page basis, the default is to ignore text which is printed past the end of the line.

When Wrap Mode is enabled, it affects only XPRINT PRINT operations. If XPRINT PRINT attempts to display a character beyond the end of a row, it is automatically wrapped to the first column of the next row.

See Also

  • XPRINT CELL
  • XPRINT GET WRAP
  • XPRINT PRINT
  • XPRINT SET WORDWRAP
  • XPRINT SPLIT


XPRINT SPLIT - ScharfBASIC Help

XPRINT SPLIT

Splits a string

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT SPLIT [WORD] MainStr , Part1Len TO Part1Var , Part2Var

Description

Generally speaking, XPRINT SPLIT allows you to determine how much text will fit on a line (or a line section), so you don't overrun the end. This is critical with variable-width fonts . Since these text characters have different widths, you cannot rely on a simple character count.

XPRINT SPLIT separates the MainStr string expression into two parts, which are then assigned to the two string variables specified by Part1Var and Part2Var . The numeric expression Part1Len specifies the maximum width of the print field, using page units (pixels/points, scaled units). After completion of XPRINT SPLIT, the Part1Var will contain those characters which can be safely printed in the print field. The Part2Var will contain the remaining characters, which might be printed on following lines.

Since this operation creates a "line break" not contemplated in the original text, you may have to modify the results in order to obtain the best appearance. For example, it's usually best to remove any leading spaces from Part2Var before printing it.

If the WORD option is included, ScharfBASIC guarantees that Part1 will not end on a partial word. This may require that Part1Len is adjusted to a smaller value. In that case, Part2Var would be assigned these characters to compensate.

See Also

  • XPRINT CELL
  • XPRINT SET FONT
  • XPRINT SET WORDWRAP
  • XPRINT SET WRAP


XPRINT STRETCH - ScharfBASIC Help

XPRINT STRETCH

Copy and resize a bitmap

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT STRETCH hBmp , ID , ( x1 , y1 )-( x2 , y2 ) TO ( x3 , y3 )-( x4 , y4 ) [, Mix , Stretch ]
XPRINT STRETCH PAGE hBmp , ID [, Mix , Stretch ]

Description

You can copy a complete bitmap, or a portion of it, to the XPRINT page, while resizing it to a larger or smaller size. The handle variable hBmp specifies the handle of the source bitmap or window . The parameter ID is the control identifier (1 to 65535) assigned with CONTROL ADD GRAPHIC . ID must be zero (0) for a GRAPHIC WINDOW or a bitmsp . The destination of the stretch operation is always the attached XPRINT page. The bitmap is automatically resized to fit the destination parameters. You must use care that your parameters are valid for the specified bitmaps, or result of the operation is undefined.

The second form, XPRINT STRETCH PAGE, is a shortcut for copying a complete bitmap to the clip or client area of the host printer page. The image is automatically stretched or condensed to fit the target appropriately.

If the Mix parameter is included, it is one of the values in the following table. If not specified, a default of %MIX_COPYSRC is presumed. There are 16 mix modes available to use for mixing drawing colors with the colors which already exist at the at the drawing location. The mix mode equates are predefined in ScharfBASIC.

%mix_Blackness

Pixel is always 0 (black).

%mix_NotMergeSrc

Pixel is the inverse of the MergeSrc color.

%mix_MaskNotSrc

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%mix_NotCopySrc

Pixel is the inverse of the pen color.

%mix_MaskSrcNot

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%mix_Not

Pixel is the inverse of the pixel color.

%mix_XorSrc

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%mix_NotMaskSrc

Pixel is the inverse of the MaskSrc color.

%mix_MaskSrc

Pixel is a combination of the colors common to both the source and the pixel.

%mix_NotXorSrc

Pixel is the inverse of the XorSrc color.

%mix_Nop

Pixel remains unchanged.

%mix_MergeNotSrc

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_CopySrc

Pixel is the source color (default).

%mix_MergeSrcNot

Pixel is a combination of the source color and the inverse of the pixel color.

%mix_MergeSrc

Pixel is a combination of the source color and the pixel color.

%mix_Whiteness

Pixel is always 1 (white).

Stretch

If the Stretch parameter is included, it is one of the values in the following table. If not included, or it is the value zero (0), the stretch mode is unchanged. An appropriate choice of stretch mode can substantially enhance the quality of bitmaps which are changed in size. The stretch mode equates are predefined in ScharfBASIC.

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

See Also

  • XPRINT COPY
  • XPRINT RENDER
  • XPRINT SET MIX
  • XPRINT SET STRETCHMODE


XPRINT STYLE - ScharfBASIC Help

XPRINT STYLE

Set the line style to be used by various XPRINT

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT STYLE linestyle&

Description

XPRINT STYLE determines the line style which will be used when drawing various graphical objects, while the width value is set to 1. When the width value is greater than one, Windows always interprets the style as 0 (solid).

Available line styles are:

Solid (default)

DashDot

DashDotDot

See Also

  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT BOX
  • XPRINT ELLIPSE
  • XPRINT LINE
  • XPRINT PIE
  • XPRINT WIDTH


XPRINT WIDTH - ScharfBASIC Help

XPRINT WIDTH

Set the graphic line width to be used by various XPRINT

Kind | Statement
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT WIDTH ncPixels&

Description

XPRINT WIDTH determines the line width which will be used when drawing various graphical objects. The default width is 1 pixel. The width is always specified in pixels, regardless of any XPRINT SCALE option. When the width is set to a value greater than 1, XPRINT STYLE parameters are always interpreted as 0 (solid).

See Also

  • XPRINT ARC
  • XPRINT ATTACH
  • XPRINT BOX
  • XPRINT ELLIPSE
  • XPRINT LINE
  • XPRINT PIE
  • XPRINT STYLE


XPRINT$ - ScharfBASIC Help

XPRINT$

Retrieve the name of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET ATTACH TO PrinterVar$
Function Form:
PrinterVar$ = XPRINT$(ATTACH)
PrinterVar$ = XPRINT$

Description

XPRINT GET ATTACH returns the name of the attached host printer, which is the printer that would be used by XPRINT statements. If there is no attached host printer, an empty string is returned. XPRINT$ is typically used to detect if an XPRINT ATTACH operation was successful.

See Also

  • XPRINT ATTACH


XPRINT$(PAPERS) - ScharfBASIC Help

XPRINT$(PAPERS)

Retrieves a list of supported

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET PAPERS TO PapersVar$
Function Form:
PapersVar$ = XPRINT$(PAPERS)

Description

XPRINT GET PAPERS retrieves a string which contains a list of all of the paper types supported by the attached host printer. This string is assigned to the string variable specified by PapersVar$.

The string contains a comma-delimited list of papertype , papername ... repeated as many times as necessary. For example:

"1,Letter,5,Legal,7,Executive,20,Envelope #10"

You can use PARSECOUNT to determine the number of delimited fields in the string, and PARSE$() to easily extract the type numbers and names. The following equates are predefined in the compiler, and represent the most common paper styles:

%DMPAPER_LETTER = 1 Letter 8.5 x 11 inches

%DMPAPER_TABLOID = 3 Tabloid 11 x 17 inches

%DMPAPER_LEDGER = 4 Ledger 17 x 11 inches

%DMPAPER_LEGAL = 5 Legal 8.5 x 14 inches

%DMPAPER_STATEMENT = 6 Statement 5.5 x 8.5 inches

%DMPAPER_EXECUTIVE = 7 Executive 7.25 x 10.5 inches

%DMPAPER_A3 = 8 A3 297 x 420 mm

%DMPAPER_A4 = 9 A4 210 x 297 mm

%DMPAPER_A5 = 11 A5 148 x 210 mm

%DMPAPER_B4 = 12 B4 250 x 354 mm

%DMPAPER_B5 = 13 B5 182 x 257 mm

%DMPAPER_FOLIO = 14 Folio 8.5 x 13 inches

%DMPAPER_QUARTO = 15 Quarto 215 x 275 mm

%DMPAPER_10X14 = 16 10x14 10 x 14 inches

%DMPAPER_11X17 = 17 11x17 11 x 17 inches

%DMPAPER_NOTE = 18 Note 8.5 x 11 inches

%DMPAPER_ENV_9 = 19 9 Envlp 3.875 x 8.875 inches

%DMPAPER_ENV_10 = 20 10 Envlp 4.125 x 9.5 inches

Other paper style codes may be defined by Windows or printer suppliers. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET PAPERS
  • XPRINT SET PAPER


XPRINT$(TRAYS) - ScharfBASIC Help

XPRINT$(TRAYS)

Retrieves a list of supported

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET TRAYS TO TrayVar$
Function Form:
TrayVar$ = XPRINT$(TRAYS)

Description

XPRINT GET TRAYS retrieves a string which contains a list of all of the paper trays supported by the attached host printer. This string is assigned to the string variable specified by TrayVar$.

The string contains a comma-delimited list of traytype, trayname... repeated as many times as necessary. For example:

"1,Upper,2,Lower,5,Envelope"

You can use PARSECOUNT to determine the number of delimited fields in the string, and PARSE$() to easily extract the tray numbers and names. The following equates are predefined in the compiler, and represent the most common trays:

%DMBIN_UPPER = 1

%DMBIN_LOWER = 2

%DMBIN_MIDDLE = 3

%DMBIN_MANUAL = 4

%DMBIN_ENVELOPE = 5

%DMBIN_ENVMANUAL = 6

%DMBIN_AUTO = 7

%DMBIN_TRACTOR = 8

%DMBIN_SMALLFMT = 9

%DMBIN_LARGEFMT = 10

%DMBIN_LARGECAPACITY = 11

%DMBIN_CASSETTE = 14

%DMBIN_FORMSOURCE = 15

Other paper style codes may be defined by Windows or printer suppliers. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET TRAY
  • XPRINT SET TRAY


XPRINT(CANVAS.X) - ScharfBASIC Help

XPRINT(CANVAS.X)

Retrieves the writable size of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET CANVAS TO WidthVar! , HeightVar!
Function Form:
WidthVar! = XPRINT(CANVAS.X)
HeightVar! = XPRINT(CANVAS.Y)

Description

XPRINT GET CANVAS retrieves the logical size of the client area (printable area) for the attached host printer. This is the size of the page, minus the unprintable margins, without any reductions for a CLIP area. The size is specified in Page Units , so it could return scaled values if they were applied with XPRINT SCALE . This is very similar to XPRINT GET CLIENT , with the single exception that scaled values (set by XPRINT SCALE) are returned if they have been utilized. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT GET CLIENT
  • XPRINT GET CLIP
  • XPRINT GET SIZE
  • XPRINT GET SCALE
  • XPRINT SCALE


XPRINT(Cell.Size.X) - ScharfBASIC Help

XPRINT(Cell.Size.X)

Retrieve the character

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT CELL SIZE TO WidthVar , HeightVar!
Function Form:
WidthVar! = XPRINT(Cell.Size.X)
HeightVar! = XPRINT(Cell.Size.Y)

Description

XPRINT CELL SIZE retrieves the size of one character cell, for the current font , on the attached printer . The returned cell size is specified in PAGE UNITS , and allows you to calculate the number of text lines which will fit in a particular space. The height value is the size of the displayed character, including external leading (if any) for this particular font.

If the font is a fixed-width font, like Courier New or Lucida Console,the sizes returned are as exact as possible, given the fractional rounding approximations necessary for some scaled units. If the font is proportional, like Arial or Times New Roman, the width will be the average size for the entire font.

External leading is the vertical distance from the bottom of one character to the top of the character below it. This value is specified by the font in use. It may vary from zero to a larger value, depending upon the font and point size. To retrieve the exact height of characters without external leading, use XPRINT CHR SIZE .

See Also

  • XPRINT CELL
  • XPRINT CHR SIZE
  • XPRINT SET FONT
  • XPRINT TEXT SIZE


XPRINT(Chr.Size.X) - ScharfBASIC Help

XPRINT(Chr.Size.X)

Retrieve the character size for the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT CHR SIZE TO WidthVar! , HeightVar!
Function Form:
WidthVar! = XPRINT(Chr.Size.X)
HeightVar! = XPRINT(Chr.Size.Y)

Description

The character size is specified in the same terms ( pixels or scaled units ) as originally stated. The height value retrieved is the actual size of the printed character without including any external leading for this particular font.

If the font is a fixed-width font, like Courier New or Lucida Console, the sizes returned are as exact as possible, given the fractional rounding approximations possible when converting from pixels to other coordinates. If the font is proportional, like Arial or Times New Roman, the width will be the average size for the entire font.

External leading is the vertical distance from the bottom of one character to the top of the character below it. This value is specified by the font in use. It may vary from zero to a larger value, depending upon the font and point size. To retrieve the total row height including external leading, use XPRINT CELL SIZE.

See Also

  • XPRINT
  • XPRINT ATTACH
  • XPRINT CELL SIZE
  • XPRINT SET FONT
  • XPRINT TEXT SIZE


XPRINT(Client.X) - ScharfBASIC Help

XPRINT(Client.X)

Retrieves the size of the client area (printable area) on the host printer page.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET CLIENT To WidthVar! , HeightVar!
Function Form:
WidthVar! = XPRINT(Client.X)
HeightVar! = XPRINT(Client.Y)

Description

XPRINT GET CLIENT retrieves the physical size of the client area (printable area) for the attached host printer. The size is always specified in Pixels (points). This is very similar to XPRINT GET CANVAS , with the single exception that scaled values (set by XPRINT SCALE ) are not utilized. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET CANVAS
  • XPRINT GET CLIP
  • XPRINT GET MARGIN
  • XPRINT GET PPI
  • XPRINT GET SIZE


XPRINT(Clip.X) - ScharfBASIC Help

XPRINT(Clip.X)

Retrieves the size of the clip area on the selected printer.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET CLIP TO WidthVar! , HeightVar!
Function Form:
WidthVar! = XPRINT(Clip.X)
HeightVar! = XPRINT(Clip.Y)

Description

The clip area of the printer is that space where print operations can be written. That is, the clip area is that portion of the client area which is not protected (clipped) by the XPRINT SET CLIP statement.

XPRINT GET CLIP retrieves the size of the clip area, and assigns these values to the variables specified by WidthVar! and HeightVar! . The size is specified in PAGE UNITS ( pixels /points or scaled units). If no printer is selected, the values 0,0 are returned.

See Also

  • XPRINT GET CANVAS
  • XPRINT GET CLIENT
  • XPRINT SET CLIP


XPRINT(COL) - ScharfBASIC Help

XPRINT(COL)

Sets or retrieves the next print position (LPR - Last Point Referenced), based upon the row and column position of a

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT CELL = RowValue& , ColValue&
XPRINT CELL TO RowVar& , ColVar&
XPRINT COL TO ColVar&
XPRINT ROW TO RowVar&
Function Form:
ColVar& = XPRINT(COL)
RowVar& = XPRINT(ROW)

Description

XPRINT CELL is used to set or retrieve the print position, based upon the row and column position of a Text Cell. That is the row and column position where the next printed text will be displayed. RowValue& specifies the horizontal screen row (starting at 1) at which to position the cursor. ColValue& specifies the vertical screen column (starting at 1) at which to position the cursor. Since row and column numbers start at one (1), the upper left corner of the page is considered to be cell 1,1.

The first form of XPRINT CELL moves the print position to the desired row and column. If a value given is zero (0), that parameter is ignored and that position is not changed. The second form of XPRINT CELL retrieves the current print position, and assigns the values to the variables specified by RowVar& and ColVar& .

The remaining forms allow you to retrieve just a single value, either row or column, and are supported in both statement and function form.

See Also

  • XPRINT CELL SIZE
  • XPRINT SET FONT
  • XPRINT SET WORDWRAP
  • XPRINT SET WRAP
  • XPRINT SPLIT


XPRINT(COLLATE) - ScharfBASIC Help

XPRINT(COLLATE)

Retrieves the XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET COLLATE TO CollateVar&
Function Form:
CollateVar& = XPRINT(COLLATE)

Description

XPRINT allows you to set the collate status, if the printer driver supports both multiple copies and collate capability. XPRINT GET COLLATE retrieves the collate status, assigning the value to the long integer variable specified by CollateVar& . The following equates are predefined in the compiler to symbolically represent the possible collate status:

%DMCOLLATE_FALSE = 0

%DMCOLLATE_TRUE = 1

If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT SET COLLATE


XPRINT(COLORMODE) - ScharfBASIC Help

XPRINT(COLORMODE)

Retrieves the XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET COLORMODE TO ColorVar&
Function Form:
ColorVar& = XPRINT(COLORMODE)

Description

XPRINT allows you to set the color or monochrome print mode if the printer driver supports it. XPRINT GET COLORMODE retrieves the colormode status, assigning the value to the long integer variable specified by ColorVar& . The value zero may be returned if colormode is not supported by the printer driver. The following equates are predefined in the compiler to symbolically represent the possible status:

%DMCOLOR_MONOCHROME = 1

%DMCOLOR_COLOR = 2

If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT SET COLORMODE


XPRINT(COPIES) - ScharfBASIC Help

XPRINT(COPIES)

Retrieves the XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET COPIES TO CopyVar&
Function Form:
CopyVar& = XPRINT(COPIES)

Description

XPRINT allows you to set the number of copies to be automatically printed, if it is supported by the printer driver. XPRINT GET COPIES retrieves the copy count, assigning the value to the long integer variable specified by CopyVar& . The default value is one (1). If this statement is executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT SET COPIES


XPRINT(DC) - ScharfBASIC Help

XPRINT(DC)

Retrieve the handle of the device context (DC) for the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET DC TO hDC
Function Form:
hDC = XPRINT(DC)

Description

If no host printer is currently attached , zero is returned. The DC handle may be used with various Windows API functions to perform specialized operations on the host printer page.

See Also

  • XPRINT ATTACH


XPRINT(DUPLEX) - ScharfBASIC Help

XPRINT(DUPLEX)

Retrieve the XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET DUPLEX TO DuplexVar&
Function Form:
DuplexVar& = XPRINT(DUPLEX)

Description

XPRINT allows you to get/set the duplex status, if the printer supports printing on both sides of a page. XPRINT GET DUPLEX retrieves the duplex status, assigning the value to the long integer variable specified by DuplexVar& . The following equates are predefined in the compiler to symbolically represent the possible duplex status:

%DMDUP_SIMPLEX = 1 (single sided printing)

%DMDUP_VERTICAL = 2 (page flipped on the vertical edge)

%DMDUP_HORIZONTAL = 3 (page flipped on the horizontal edge)

If the printer does not support duplex printing, the value zero (0) is returned. If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT SET DUPLEX


XPRINT(LINES) - ScharfBASIC Help

XPRINT(LINES)

Retrieve the number of lines that can be printed.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET LINES To LineVar&
Function Form:
LineVar& = XPRINT(LINES)

Description

XPRINT GET LINES retrieves the number of lines of text which can be printed on the host printer page, given the current selected font . Since XPRINT statements do not generate an automatic formfeed when text is printed on the last line, this statement can be used to determine when your program should execute an XPRINT FORMFEED to move to the next printed page on a host printer. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT
  • XPRINT ATTACH
  • XPRINT SET FONT
  • XPRINT FORMFEED


XPRINT(MIX) - ScharfBASIC Help

XPRINT(MIX)

Retrieve the color mix mode for a

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET MIX To MixVar&
Function Form:
MixVar& = XPRINT(MIX)

Description

Prior to any XPRINT operations, a host printer must first be selected with XPRINT ATTACH . There are 16 mix modes available to use for mixing the drawing color with the color that already exists at the drawing location. The mix mode equates are predefined in ScharfBASIC. If executed without a host printer attached, error 57 is generated.

%MIX_BLACKNESS

Pixel is always 0 (black).

%MIX_NOTMERGESRC

Pixel is the inverse of the MergeSrc color.

%MIX_MASKNOTSRC

Pixel is a combination of the colors common to both the pixel and the inverse of the source.

%MIX_NOTCOPYSRC

Pixel is the inverse of the pen color.

%MIX_MASKSRCNOT

Pixel is a combination of the colors common to both the source and the inverse of the pixel.

%MIX_NOT

Pixel is the inverse of the pixel color.

%MIX_XORSRC

Pixel is a combination of the colors in the source and in the pixel, but not in both.

%MIX_NOTMASKSRC

Pixel is the inverse of the MaskSrc color.

%MIX_MASKSRC

Pixel is a combination of the colors common to both the source and the pixel.

%MIX_NOTXORSRC

Pixel is the inverse of the XorSrc color.

%MIX_NOP

Pixel remains unchanged.

%MIX_MERGENOTSRC

Pixel is a combination of the source color and the inverse of the pixel color.

%MIX_COPYSRC

Pixel is the source color (default).

%MIX_MERGESRCNOT

Pixel is a combination of the source color and the inverse of the pixel color.

%MIX_MERGESRC

Pixel is a combination of the source color and the pixel color.

%MIX_WHITENESS

Pixel is always 1 (white).

See Also

  • XPRINT ATTACH
  • XPRINT SET MIX


XPRINT(ORIENTATION) - ScharfBASIC Help

XPRINT(ORIENTATION)

Retrieve the paper

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET ORIENTATION To OrentVar&
Function Form:
OrentVar& = XPRINT(ORIENTATION)

Description

XPRINT GET ORIENTATION retrieves the orientation of the paper in the host printer, assigning the value to the long integer variable specified by OrentVar& . The value 1 indicates portrait mode, while 2 indicates landscape mode. If the printer does not support paper orientation, 0 is returned. If a host printer is not attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT SET ORIENTATION


XPRINT(OVERLAP) - ScharfBASIC Help

XPRINT(OVERLAP)

Retrieves the status of XPrint

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET OVERLAP To OverlapVar&
Function Form:
OverlapVar& = XPRINT(OVERLAP)

Description

XPRINT GET OVERLAP retrieves the status of overlap mode and assigns it to the variable specified by OverlapVar& . If Overlap Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the host printer which is currently attached to the XPrint stream .

With Overlap Mode, you can control how ScharfBASIC treats XPrint operations which involve a bounding rectangle (RECT structure) in their definition. Windows maintains unique conventions for a RECT. The bottom and right coordinates of a RECT are exclusive. In other words, the pixels at the bottom and right edges lie immediately outside the rectangle. They are ignored. For example:

XPRINT BOX (0,0) - (50,50)

In this case, a box is drawn from 0,0 to 49,49. The final pixels at the bottom and right edge are simply not drawn. However, if Overlap Mode is enabled with XPRINT SET OVERLAP , the box is drawn from 0,0 to 50,50.

The Overlap Mode affects all XPRINT functions which take a bounding rectangle as a parameter. This includes XPRINT SCALE , XPRINT BOX , XPRINT ELLIPSE , XPRINT LINE , XPRINT POLYLINE , etc.

See Also

  • XPRINT SET OVERLAP


XPRINT(PAPER) - ScharfBASIC Help

XPRINT(PAPER)

Retrieves the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET PAPER TO PaperVar&
Function Form:
PaperVar& = XPRINT(PAPER)

Description

XPRINT GET PAPER retrieves the paper style for which the host printer is currently configured. The paper style is identified by an integral value which is assigned to the long integer variable specified by PaperVar&. The following equates are predefined in the compiler, and represent the most common paper styles:

%DMPAPER_LETTER = 1 Letter 8.5 x 11 inches

%DMPAPER_TABLOID = 3 Tabloid 11 x 17 inches

%DMPAPER_LEDGER = 4 Ledger 17 x 11 inches

%DMPAPER_LEGAL = 5 Legal 8.5 x 14 inches

%DMPAPER_STATEMENT = 6 Statement 5.5 x 8.5 inches

%DMPAPER_EXECUTIVE = 7 Executive 7.25 x 10.5 inches

%DMPAPER_A3 = 8 A3 297 x 420 mm

%DMPAPER_A4 = 9 A4 210 x 297 mm

%DMPAPER_A5 = 11 A5 148 x 210 mm

%DMPAPER_B4 = 12 B4 250 x 354 mm

%DMPAPER_B5 = 13 B5 182 x 257 mm

%DMPAPER_FOLIO = 14 Folio 8.5 x 13 inches

%DMPAPER_QUARTO = 15 Quarto 215 x 275 mm

%DMPAPER_10X14 = 16 10x14 10 x 14 inches

%DMPAPER_11X17 = 17 11x17 11 x 17 inches

%DMPAPER_NOTE = 18 Note 8.5 x 11 inches

%DMPAPER_ENV_9 = 19 9 Envlp 3.875 x 8.875 inches

%DMPAPER_ENV_10 = 20 10 Envlp 4.125 x 9.5 inches

Other paper style codes may be defined by Windows or printer suppliers. You can use XPRINT GET PAPERS to obtain a list of all the paper styles supported by the attached host printer.

If the printer does not support paper style changes, the value zero is returned. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET PAPERS
  • XPRINT SET PAPER


XPRINT(PIXEL...) - ScharfBASIC Help

XPRINT(PIXEL...)

Retrieves the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET PIXEL [STEP] (x!, y!) TO PixelVar&
Function Form:
PixelVar& = XPRINT(PIXEL [STEP], x! , y! )

Description

Not all printer drivers support the ability to retrieve the color of a pixel. If this feature is not supported, or if the coordinates are outside the printer client area, an invalid color value of -1 is returned. If no host printer is attached, error 57 is generated.

See Also

  • Built In RGB Color Equates
  • XPRINT ATTACH
  • XPRINT COLOR
  • XPRINT SET PIXEL


XPRINT(POS.X) - ScharfBASIC Help

XPRINT(POS.X)

Retrieves the last point referenced (POS) by an XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET POS TO XVar! , YVar!
Function Form:
XVar! = XPRINT(POS.X)
YVar! = XPRINT(POS.Y)

Description

XPRINT GET POS allows you to retrieve the last point referenced (POS) by XPRINT statements. The coordinate points are specified in Page Units . If executed without a host printer attached , an error 57 is generated, and the values 0,0 are returned.

See Also

  • XPRINT ATTACH
  • XPRINT SET POS


XPRINT(PPI.X) - ScharfBASIC Help

XPRINT(PPI.X)

Retrieves the resolution of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET PPI TO XVar& , YVar&
Function Form:
XVar& = XPRINT(PPI.X)
YVar& = XPRINT(PPI.Y)

Description

XPRINT GET PPI retrieves the resolution (points per inch) of the host printer page. The resolution is always specified in pixels, regardless of any XPRINT SCALE option. If executed without a host printer attached, error 57 is generated, and the values 0,0 are returned. This statement is particularly useful in drawing items such as rulers and graphs to a particular physical size. There are 25.4 millimeters per inch, so just divide by 25.4 to convert from pixels per inch to pixels per millimeter.

See Also

  • XPRINT ATTACH
  • XPRINT GET CLIENT
  • XPRINT GET MARGIN
  • XPRINT GET SIZE


XPRINT(QUALITY) - ScharfBASIC Help

XPRINT(QUALITY)

Retrieves the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET QUALITY To QualVar&
Function Form:
QualVar& = XPRINT(QUALITY)

Description

XPRINT GET QUALITY retrieves the print quality setting for the host printer. The value 1 is draft mode, 2 is low resolution, 3 is medium resolution, and 4 is high resolution. If the printer does not support print quality settings, 0 is returned. If no host printer is attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT SET QUALITY


XPRINT(SELECTION) - ScharfBASIC Help

XPRINT(SELECTION)

Retrieves the status of the SELECTION flag.

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET SELECTION TO SelectVar&
Function Form:
SelectVar& = XPRINT(SELECTION)

Description

You may elect to limit a particular print job to just that part of the total which is selected/highlighted. If so, it is the programmer's responsibility to limit XPRINT output to just the selected region.

The selection flag can only be set by the user in the Print Dialog which is displayed when XPRINT ATTACH is executed with the CHOOSE option. It cannot be set under program control. This flag is maintained only to give the programmer information about the user's request. If you do not wish to honor this option, you should disable it in XPRINT ATTACH CHOOSE.

If XPRINT GET SELECTION is executed without a host printer attached, an error 57 is generated.

See Also

  • XPRINT ATTACH


XPRINT(SIZE.X) - ScharfBASIC Help

XPRINT(SIZE.X)

Retrieve the total size of the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET SIZE TO WidthVar& , HeightVar&
Function Form:
WidthVar& = XPRINT(SIZE.X)
HeightVar& = XPRINT(SIZE.Y)

Description

XPRINT GET SIZE allows you to retrieve the full size of the host printer page, including both the printable client area and any unprintable margins. The sizes are specified in pixels (points). If no host printer is attached, error 57 is generated, and the values 0,0 are returned.

See Also

  • XPRINT ATTACH
  • XPRINT GET CLIENT
  • XPRINT GET MARGIN
  • XPRINT GET MIX
  • XPRINT GET PPI


XPRINT(STRETCHMODE) - ScharfBASIC Help

XPRINT(STRETCHMODE)

Retrieves the default bitmap stretching mode for the attached

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET STRETCHMODE TO ModeVar&
Function Form:
ModeVar& = XPRINT(STRETCHMODE)

Description

There are several operations in ScharfBASIC which involve stretching or condensing images on bitmaps, most notably XPRINT STRETCH . As individual points must be added or removed, there is a good chance that the quality of the image will be degraded. However, if you describe the nature of the image by defining a StretchMode, you can substantially enhance the appearance.

The default StretchMode is maintained individually for each DC. You can retrieve the default mode with this statement, or set it with XPRINT SET STRETCHMODE . Of course, you can also override the default StretchMode when you execute one of the affected statements.

The 4 stretch mode equates are predefined in ScharfBASIC.

%BLACKONWHITE

This is the default Windows stretch mode, and is most appropriate for monochrome bitmaps, or those with blocks of color. Performs a boolean OR of eliminated and existing pixels. It preserves black pixels at the expense of white pixels.

%WHITEONBLACK

Performs a boolean OR of eliminated and existing pixels. It preserves white pixels at the expense of black pixels.

%COLORONCOLOR

Deletes eliminated lines of pixels without trying to preserve their information.

%HALFTONE

This provides the highest quality for complex color bitmaps. The average color of the destination pixel block is kept approximately the same as the source pixel block.

See Also

  • XPRINT COPY
  • XPRINT RENDER
  • XPRINT STRETCH
  • XPRINT SET STRETCHMODE


XPRINT(TEXT.SIZE.X...) - ScharfBASIC Help

XPRINT(TEXT.SIZE.X...)

Calculate the size of text to be printed on a

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT TEXT SIZE txt$ To nWidth! , nHeight!
Function Form:
WidthVar! = XPRINT(TEXT.SIZE.X, txt$ )
HeightVar! = XPRINT(TEXT.SIZE.Y, txt$ )

Description

This statement calculates the total size of the printed text, based upon the current font for the host printer. The sizes returned are specified in Page Units .

This allows you to easily calculate the appropriate print position, particularly when using a proportional font. If this statement is executed without a host printer attached , error 57 is generated.

See Also

  • XPRINT CELL SIZE
  • XPRINT CHR SIZE
  • XPRINT SET FONT


XPRINT(TRAY) - ScharfBASIC Help

XPRINT(TRAY)

Retrieves the

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET TRAY TO TrayVar&
Function Form:
TrayVar& = XPRINT(TRAY)

Description

XPRINT GET TRAY retrieves the paper tray which is active on the host printer . A descriptive value is assigned to the long integer variable specified by TrayVar& . The following equates are predefined in the compiler, and represent the most common paper trays:

%DMBIN_UPPER = 1

%DMBIN_LOWER = 2

%DMBIN_MIDDLE = 3

%DMBIN_MANUAL = 4

%DMBIN_ENVELOPE = 5

%DMBIN_ENVMANUAL = 6

%DMBIN_AUTO = 7

%DMBIN_TRACTOR = 8

%DMBIN_SMALLFMT = 9

%DMBIN_LARGEFMT = 10

%DMBIN_LARGECAPACITY = 11

%DMBIN_CASSETTE = 14

%DMBIN_FORMSOURCE = 15

Other tray codes may be defined by Windows or printer suppliers, so your program should be written to consider that possibility. You can use XPRINT GET TRAYS to obtain a list of all the paper trays supported by the attached host printer.

If the printer does not support the tray change requested, error 5 is generated. If executed without a host printer attached, error 57 is generated.

See Also

  • XPRINT ATTACH
  • XPRINT GET TRAYS
  • XPRINT SET TRAY


XPRINT(WORDWRAP) - ScharfBASIC Help

XPRINT(WORDWRAP)

Retrieves the status of XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET WORDWRAP TO WrapVar&
Function Form:
WrapVar& = XPRINT(WORDWRAP)

Description

XPRINT GET WORDWRAP retrieves the status of wordwrap mode and assigns it to the variable specified by WrapVar& . If WordWrap Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the attached printer.

With WordWrap Mode, you can control how ScharfBASIC prints text on an XPRINT page when it reaches the end of a line. Since XPRINT operates on a full page basis, the default is to ignore text which is printed past the end of the line. This can be modified under program control by using XPRINT SET WORDWRAP .

When WordWrap mode is enabled, it affects only XPRINT print operations. If XPRINT print attempts to display a word beyond the end of a row, the entire word is automatically wrapped to the first column of the next row.

See Also

  • XPRINT CELL
  • XPRINT GET WRAP
  • XPRINT SET WORDWRAP
  • XPRINT SET WRAP
  • XPRINT SPLIT


XPRINT(WRAP) - ScharfBASIC Help

XPRINT(WRAP)

Retrieves the status of XPRINT

Kind | Function
Category | UI, Graphics & DDT
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

XPRINT GET WRAP TO WrapVar&
Function Form:
WrapVar& = XPRINT(WRAP)

Description

XPRINT GET WRAP retrieves the status of wrap mode and assigns it to the variable specified by WrapVar& . If Wrap Mode is enabled, the value true (non-zero) is assigned. If it's disabled, the value false (zero) is assigned instead. The value returned reflects the status of the attached printer.

With Wrap Mode, you can control how ScharfBASIC prints text on an XPRINT page when it reaches the end of a line. Since XPRINT operates on a full page basis, the default is to ignore text which is printed past the end of the line. This can be modified under program control by using XPRINT SET WRAP .

When Wrap Mode is enabled, it affects only XPRINT print operations. If XPRINT print attempts to display a character beyond the end of a row, it is automatically wrapped to the first column of the next row.

See Also

  • XPRINT CELL
  • XPRINT GET WORDWRAP
  • XPRINT SET WORDWRAP
  • XPRINT SET WRAP
  • XPRINT SPLIT


BEEP - ScharfBASIC Help

BEEP

Sound a tone through the computer's speaker.

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

BEEP

Description

BEEP plays the default Windows waveform sound, typically a ¼ second tone, through either the built-in speaker; or a sound card if installed (in which case the Windows "Default Beep" sound is played). The Default Beep can be configured in the Sounds section of Control Panel.

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201af0
call   0x201afc


COMMAND$ - ScharfBASIC Help

COMMAND$

Return the command-line arguments used to start the program.

Kind | Function
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = COMMAND$
s$ = COMMAND$( ArgNum )

Description

COMMAND$ returns everything that was typed following the program name. Some operating system manuals refer to this text as the trailer or command tail. You can use COMMAND$ to collect run-time arguments, like filenames, and program options.

Depending upon the optional argument number, COMMAND$ will return either the complete trailer, or just one of the arguments. If the ArgNum is zero (0), or not present, the complete trailer is returned. If the ArgNum is greater than zero, the trailer is parsed to return an individual argument (1 = first argument. 2 = second argument, etc.). If the ArgNum is greater than the number of arguments, a null string (zero-length) is returned.

Arguments are delimited by one or more blank spaces. If blank spaces are significant, you should enclose the argument in double quotes ("). Any such double-quotes are stripped from the return value by COMMAND$. If a zero-length quoted string ("") is found, it is ignored entirely.

For example, consider a program named FASTSORT.EXE that reads data from one file, sorts it, and puts the result in a new file. Using COMMAND$ lets you specify the input and output file names when the program is invoked:

FASTSORT.EXE cust.dta cust.new

When FASTSORT begins execution, COMMAND$ or COMMAND$(0) would return:

cust.dta cust.new

COMMAND$(1) would return:

cust.dta

COMMAND$(2) would return:

cust.new

Restrictions

In some recent versions of Windows, file association and drag-drop file operations cause filenames to be enclosed with double-quote marks when they are passed in COMMAND$. It would be wise to ensure that your applications are prepared for this possibility. Some operating systems automatically enclose the command-line in double-quote marks.

ScharfBASIC imposes no arbitrary limits on the length of the string returned by COMMAND$ but, the operating system may impose limits. Such limits may become evident, for example, when attempting to Drag and Drop a large number of files onto an EXE within Windows Explorer. Usually, attempting to drop more files than the operating system permits will result in an operating system warning message.

Within the IDE , a COMMAND$ command-line parameter can be specified for the purposes of testing in both Compile and Execute and Compile and Debug modes.

See Also

  • JOIN$
  • PARSE
  • PARSE$
  • PARSECOUNT
  • PATHNAME$
  • PATHSCAN$
  • WINMAIN

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201d40
lea   ebx,[ebp-0xa0]
call   0x2018b0
call   0x201f4b
call   0x201e7c


ENVIRON$ - ScharfBASIC Help

ENVIRON$

Retrieve information from the current program's environment table.

Kind | Function
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

s$ = ENVIRON$({ parameter_string | n })

Description

parameter_string is a string expression denoting which environment parameter is to be retrieved. n is an integral expression, starting at 1.

If a string argument is used, ENVIRON$ returns the text that follows parameter_string (after the equal sign) in the environment table. If parameter_string is not found, or no text follows the equal sign in the environment string table, an empty string is returned.

If the numeric argument is used, it acts as an index into the environment table. ENVIRON$ returns a string containing the n th parameter from the start of the table. If there is no n th parameter, an empty string is returned. If the index is negative, private Windows variables are returned.

When launching a program from within the IDE , ScharfBASIC sets the "PBIDE" environment variable with the IDE name and version number. For example, "CCEDIT 5.00" or "PBEDIT 9.00". Similarly, when running in the debugger , the "PBDEBUG" environment string will return the IDE name and version.

Programs can use these environment strings to detect their "mode" of operation, for example, to signal a program to save internal data to a disk file, and when to display helpful debugging information. DLLs created with PB/Win can also examine these environment strings and adapt behavior accordingly. This will be of particular interest to 3rd-party DLL programmers who create libraries and add-ons for other ScharfBASIC programmers.

Restrictions

When a program (process) starts, it is given its own local environment table, which is typically a copy of the parent program's environment table. ENVIRON$ works with this local table, not the parent's table.

See Also

  • ENVIRON

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x201ff4
call   0x201a50
call   0x201997
lea   ebx,[ebp-0xa0]
call   0x201a18
call   0x201f77
call   0x201ea8


INPUTBOX$ - ScharfBASIC Help

INPUTBOX$

INPUTBOX$ displays a dialog box containing a prompt. INPUTBOX$ waits for the user to enter text, and accept or cancel the dialog. INPUTBOX$ returns the contents of the text box.

Kind | Function
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

sResult$ = INPUTBOX$( prompt$ [[, title$ ], default$ ] [, xpos% , ypos% ])

Description

Prompt$ is the text prompt displayed in the Inputbox dialog.

Title$ is the caption for the Inputbox dialog and is optional.

Default$ is the default result text displayed in the edit section of the Inputbox dialog, and is optional.

xpos% and ypos% specify the location on the screen to display the Inputbox, in dialog units . If these are not specified, the Inputbox dialog is centered on the screen.

Restrictions

The returned string value is limited to 255 characters.

See Also

  • MSGBOX function
  • MSGBOX statement
  • TXT pseudo-object


MOUSEPTR - ScharfBASIC Help

MOUSEPTR

Change the mouse pointer (cursor) to a new shape.

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MOUSEPTR style [TO var& ]


MSGBOX - ScharfBASIC Help

MSGBOX

Display a message box containing a text string

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

MSGBOX txt$ [, [ style% ], title$ ]
? txt$ [, [ style% ], title$ ]

Description

The MSGBOX statement comprises the following elements:

Text to display within the message box.

style&

Optional parameter which determines the appearance of the message box. Some styles may be combined ( OR 'ed together) to specify the button and icon displayed in the message box. If style& is omitted, ScharfBASIC substitutes %MB_OK. The following are some of the more common styles used with the MSGBOX statement (also see the MSGBOX function for more information):

%MB_OK

Display OK button (default)

%MB_ICONERROR

Display Error icon (stop sign)

%MB_ICONINFORMATION

Display Information icon ("i")

%MB_ICONWARNING

Display Warning icon (exclamation)

%MB_APPLMODAL

Application Modal - Despite the name, the user can continue to interact with other dialogs without dismissing the MSGBOX.

%MB_SYSTEMMODAL

System Modal - Operates identically to %MB_APPLMODAL, except the MSGBOX is given the %WS_EX_TOPMOST style so that it remains above all other windows and dialogs.

%MB_TASKMODAL

Task Modal - All top-level windows belonging to the current application are disabled until the MSGBOX is dismissed. %MB_TASKMODAL is commonly used to display a truly modal MSGBOX. (default)

Additional styles may be found in WIN32API.INC , in the section prefixed with %MB_. If you are interested in which button the user selects, use a MSGBOX function rather than a MSGBOX statement.

title$

Determines the title to be displayed in the caption of the message box. If title$ is not specified, "ScharfBASIC" is used automatically.

The MSGBOX statement may be represented by the query (?) character as a shortcut. This is similar to the behavior in the ScharfBASIC Console Compiler (PB/CC), where the query character is recognized as a synonym for the PRINT statement. This can simplify the creation of certain test code, since the query character provides similar functionality in both compilers.

Restrictions

Strings displayed by the MSGBOX function are displayed only up to the first $NUL character, if any.

See Also

  • INPUTBOX$
  • MSGBOX function
  • TXT pseudo-object

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201f90
call   0x201f13
mov   edx,0x202a60
call   0x201f90
mov   eax,0x12000
mov   edx,0x202a6c
call   0x201f90
call   0x201986
call   0x201978
call   0x2018d8
call   0x201e44


PLAY WAVE - ScharfBASIC Help

PLAY WAVE

Play a sound under program control.

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PLAY WAVE ResourceID$ [, descriptors ...] [TO ResultVar& ]
PLAY WAVE END

Description

The PLAY statement allows you to play a previously created WAVE resource or WAVE file. It's generally advantageous to use the resource form. Access is typically faster and the need for extra files is reduced. The first form of PLAY WAVE starts the sound, while PLAY WAVE END stops any waveform sound which is currently playing.

ResourceID$ is a string expression which tells either the Resource ID of the waveform data, or the disk file where it can be found. If the resource ID is numeric, just precede the number with #, such as "#12345". If the Resource ID contains a period, it is presumed to be the name of a disk file. Otherwise, an attempt is made to load it from a resource -- if not found, it is then presumed to be a disk file. If the waveform data cannot be found, an error 53 (File Not Found) is generated.

If you include the optional TO clause, a success value is assigned to the ResultVar& . If the operation succeeds, the value True (non-zero) is assigned. If it fails, the value False (zero) is assigned.

The default method is to play the waveform data in the background. That is, the Play statement returns immediately so the application can execute other code while the sound is playing.

By default, the new sound takes precedence over any other sound currently playing. When PLAY WAVE is executed, any other sound playing is stopped immediately. The new sound is played to replace it. This default methodology can be altered with options described later.

The optional descriptor words (one or more) may be added to control the way in which the sound is played. The descriptors available are:

The sound is played repeatedly in the background. It plays forever, until PLAY WAVE END is executed, or the program terminates.

NoStop

If another sound is playing, the new sound is discarded and not played. The value False (zero) is returned to the ResultVar& to let you know that the operation failed. You can try again to play the new sound at your convenience.

The sound plays in synchronous mode, commonly known as the foreground. The application waits for the sound to complete before continuing execution of other code. The sound and the code are synchronized.

YieldMS( TimeOut& )

If another sound is playing, the new sound yields and allows the first sound to complete. The numeric expression TimeOut& tells the maximum number of milliseconds (approximate) to wait before giving up. If the Timeout period expires and the first sound is still playing, the new sound is aborted. If the Timeout period is zero (0), the program will wait an unlimited amount of time for the first sound to finish. The maximum TimeOut& permitted is one hour.

See Also

  • #RESOURCE


PROFILE - ScharfBASIC Help

PROFILE

Capture a profile report detailing total execution times of the

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

PROFILE diskfilename$

Description

At the time the PROFILE statement is executed, a standard sequential file of the specified file name diskfilename$ is created. For the best results in executable files, the PROFILE statement should be the last statement executed in the PBMAIN / WINMAIN function.

The profile report contains a list of every procedure within the same module (EXE or DLL ), the number of times it was called, and the total elapsed time (in milliseconds) spent executing all instances of the procedure. These statistics appear in the disk file in that specific order on each line:

, ,

The profile report only describes procedures that physically reside within the module (EXE or DLL) where the PROFILE statement is located. Procedures in an external EXE or DLL are not profiled individually; however, the time taken to call other procedures and DLL/API functions is included in the accumulated execution time of the calling procedure.

It is highly recommended that you close all other applications when profiling a ScharfBASIC application. When an application is being profiled, ScharfBASIC must generate a considerable amount of extra code to gather all of the needed information. This extra code is generated whenever a valid PROFILE statement appears in your program, regardless of whether it is actually executed.

For final production code, use the #TOOLS OFF metastatement is used to ensure the highest performance levels.

Interpreting a profile report

The execution time of nested procedures needs to be understood in order to obtain a clear "picture" of the execution times. For example, consider the following results:

Procedure

MySubA,

MySubB,

At first glance, these results may suggest a "bottleneck" in MySubA since it took MySubA 11016 milliseconds to execute just one call, whereas the average time for MySubB was only about 100 milliseconds per call (10014 mSec / 100 calls = 100.14 mSec).

However, if MySubB is actually called by MySubA , the results need to be assessed differently. For example, we could say: " MySubB took 10014 milliseconds of the 11016 milliseconds of the time spent in MySubA ". Or to put it another way: " Of the 11016 milliseconds MySubA took to execute, 10014 milliseconds of that time was spent executing MySubB ".

Interpolating these results, it can be easily calculated that the code in MySubA only took 1002 milliseconds to run, yet this blossomed to 11016 milliseconds because of its dependence on MySubB .

Therefore, improving the performance of MySubB would clearly improve the overall speed of MySubA , and the profile results of both functions would be improved accordingly.

Restrictions

Profiling is "enabled" when the first procedure that contains a PROFILE statement begins execution. All procedures subsequently executed from within that procedure are profiled.

It is not possible to profile the actual PBMAIN or WINMAIN functions. If a PROFILE statement occurs within PBMAIN/WINMAIN, all procedures that are called from PBMAIN/ LIBMAIN are profiled normally.

Therefore, if PBMAIN/WINMAIN contains code that requires profiling, simply rename the function and create a new PBMAIN/WINMAIN function that immediately calls the renamed function and then executes a PROFILE statement. See the example below.

For application code with nested and lengthy procedure calls, adding up the total number of milliseconds in the last column of a PROFILE disk file will usually produce a number that is far larger than the actual time it took your program to execute.

The time resolution of the profile report is limited by the Quantum supported by the operating system (Win95/98 is 54 mSec, and WinNT/2000/XP is 10 mSec), and can be influenced by any other applications which run concurrently. Nonetheless, PROFILE can offer a great insight as to which code may be consuming the most CPU time, and where optimization efforts should be concentrated.

See Also

  • #TOOLS
  • CALLSTK
  • CALLSTK$
  • CALLSTKCOUNT
  • FUNCNAME$
  • TRACE


SHELL - ScharfBASIC Help

SHELL

Run an executable program synchronously. The SHELLing thread of the calling program is suspended until the SHELLed program ends.

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SHELL [HANDLES,] CmdString [, WndStyle , EXIT TO exitcode& ]

Description

The SHELL statement has the following parts:

HANDLES

This option, if present, allows the child process to inherit (and access) the Windows file handles of all open files in the parent process. These are not ScharfBASIC file numbers, but system file handles and you must use OPEN HANDLE to access them.

CmdString

The name of the program to execute ("child process"), along with and any required arguments or command-line switches.

WndStyle

A number corresponding to the style of the window in which the program is to be executed. If WndStyle is omitted, the program is opened normal with focus , the same as WndStyle = 1.

The following table identifies the values for WndStyle and the resulting style of window:

WndStyle

Window style

Hide window

Normal with focus (default)

Minimized with focus

Maximized with focus

Normal without focus

Minimized without focus

Use ERR to detect the success of the SHELL function. The HANDLES option allows the child process to inherit the file handles opened by your program. This affects only Windows handles, not ScharfBASIC file identifiers. It is an advanced option, for those who know it works and why they need it.

exitcode&

The exit code of the child process (the value returned by the WinMain function) is assigned to the long integer variable specified by exitcode& .

Restrictions

The SHELL statement executes the child process synchronously. That is, SHELL will not return control to your program until the child program finishes.

To use internal DOS commands like DIR and COPY, you must run the DOS command processor, passing the DOS command as a parameter. See the example below.

If the program name in CmdString does not include an explicit path, Windows will search for the file in the following paths: the directory where the current program is located, the default directory, the 32-bit Windows system directory, the 16-bit Windows system directory, the Windows directory, and any directories listed in the PATH environment variable.

If the SHELL statement is not executed successfully, an appropriate error is generated. The ERR function can be used to detect it.

See Also

  • ERR
  • SHELL function

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   edx,0x203a54
call   0x201ee4
mov   eax,0x1
or   eax,0x8000
call   0x2019d4
call   0x2018b8
call   0x201e2c


SLEEP - ScharfBASIC Help

SLEEP

Pause the current thread of the application for a specified number of milliseconds (

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

SLEEP m&

Description

m& is the number of milliseconds (1 millisecond = 1/1000th of a second) to pause the application. Only the current thread pauses. If other threads are present, they will continue to execute. During the SLEEP period, all time-slices for the current thread are given to other threads and processes.

If m& is zero, the remainder of the current time-slice is relinquished. If there are no other threads of equal priority, execution continues immediately.

The time-slice duration (also known as the Quantum) can vary from version to version of Windows, ranging from 20 mSec to 120 mSec. Therefore, the Quantum can affect the performance of applications when SLEEP 0 is overused. That is, excessive use of SLEEP 0 can cause an application to cede much of its available processor time, causing a significant drop in application performance.

When code is running in a tight loop, it is quite possible to use up 100% of the available CPU time, so the occasional use of SLEEP 0 within a tight loop is often beneficial to overall performance of the target PC. For example, it may not be necessary to use SLEEP 0 for every iteration of a loop, but every second or third instead.

See Also

  • THREAD CREATE
  • TIMER

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x64
call   0x201f61
call   0x202880


TIMER - ScharfBASIC Help

TIMER

Return the number of seconds that have elapsed since midnight.

Kind | Function
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

y = TIMER

Description

TIMER returns the number of seconds since midnight as a Double-precision floating-point value. The resolution is about 1/100 of a second on NT-based platforms, or 1/18th of a second on earlier platforms.

See Also

  • DATE$
  • TIME$
  • TIX

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201d88
lea   ebx,[ebp-0xa4]
call   0x201d0b
call   0x201b10
fistp   QWORD PTR [ebp-0x6c]
mov   edi,DWORD PTR [ebp-0x6c]
call   0x201c3c


TIX - ScharfBASIC Help

TIX

Measures elapsed CPU cycles.

Kind | Statement
Category | Utilities
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

TIX QuadVar
TIX END QuadVar

Description

The TIX statement offers you the ability to measure elapsed CPU cycles, the smallest timing increment possible. Modern processors typically execute billions of cycles per second. This can be beneficial for comparing the execution speed of various styles of coding in ScharfBASIC.

TIX QuadVar

The first form of the TIX statement retrieves the current value of the cycle counter and assigns it to the Quad Integer variable.

TIX END QuadVar

The second form of the TIX statement retrieves the current value of the cycle counter. The value in the QuadVar is subtracted from it, and the result is assigned to QuadVar.

To measure the total cycle count for a particular set of statements, you would write:

TIX CycleCount&&

' statements to measure go here

TIX END CycleCount&&

At this point, CycleCount&& contains the elapsed number of CPU cycles.

See Also

  • #ALIGN
  • TIMER


DIM - ScharfBASIC Help

DIM

Declare and dimension

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DIM var [( subscripts )] [AS [GLOBAL | INSTANCE | LOCAL | STATIC | THREADED] type ] [PTR | POINTER] [AT address ] [, ...]
DIM var[( subscripts )] ' var may include a type-specifier
Scalar variables:
DIM var AS [GLOBAL | INSTANCE | LOCAL | STATIC | THREADED] type [PTR |POINTER] [, ...]
DIM var ' var must include a type-specifier

Description

DIM declares var to be a variable or array whose type is specified by appending a type-specifier to the name or by using the AS type keyword. If the AS clause is used, the variable name cannot end with a type-specifier character.

DIM can only be used inside a SUB , FUNCTION , METHOD , or PROPERTY . Outside of Subs, Functions, Methods, or Properties, use GLOBAL or INSTANCE to declare variables and arrays.

DIM can also be used to dimension an "absolute array" - one that occupies a specific location in memory. This can be useful to dynamically "superimpose" one type of array directly over the top of an existing block of memory (which could be another type of array, or data structure). This would form a Union-like overlay structure. See below.

In addition, it is possible to create an array of pointers with the DIM statement, and it is also possible to do so at a specific location in memory. This is termed an " absolute pointer array ".

Dimensioning arrays

subscripts may take one of the following forms for each array dimensioned:

(a) A comma-delimited list of one or more Long-integer expressions, each defining a dimension of the array . This form is used to declare arrays whose subscript (index) range starts at 0. For example, the following lines are equivalent ways of dimensioning the same array:

DIM lArray(20) AS LONG ' With an AS type clause

DIM lArray&(20) ' With a type-specifier

Both lines above define a one dimension Long-integer array that has 21 elements, from lArray(0) to lArray(20) inclusive. The second line uses a type-specifier symbol to specify the data ty pe , and this uses a simplified syntax (trailing clauses/keywords are not permitted). The simplified syntax is only valid for data types that have a type-specifier symbol ($, !, @, @@, #, ##, %, &, &&, ?, ??, ???), or the specifier can be omitted if there is a DEF type statement in effect. The specifier must be omitted if #DIM ALL is in effect.

Declarations of multiple-dimension arrays take the following forms:

DIM sArray(20,40,2) AS STRING

DIM sArray$(20,40,2)

These two lines of code define a dynamic string array with three dimensions, 21 elements by 41 elements by 3 elements, totaling 2583 string elements. As before, the second line uses the simplified syntax form.

(b) A comma-delimited list where both the upper and lower subscript bounds are explicitly declared for each dimension of the array. For each dimension, the lower bound is listed first, followed by the TO keyword, followed by the upper bound. For example:

DIM MyArray(1 TO 20) AS LONG

defines an array of one dimension that has 20 elements, from MyArray(1) to MyArray(20). The lower bound does not have to be zero or one; for example:

DIM SalesByYear(1980 TO 2000) AS INTEGER

DIM SalesByYear%(1980 TO 2000)

Each array can access elements in the range of -2,147,483,648 to 2,147,483,647. It is recommended that an explicit variable scope clause ( GLOBAL / LOCAL / STATIC , THREADED, INSTANCE ) be added to each DIM statement that uses an explicit type clause. See Restrictions below.

Array Initialization and Absolute Arrays

ScharfBASIC generates an error message when it encounters an array that hasn't been dimensioned. If the array has already been dimensioned, the DIM statement is ignored. A new array is not created and a run-time error is not generated.

When a program is first executed, ScharfBASIC sets each element of a numeric array to zero, and sets each element of regular string arrays to a null string (length zero). However, when an absolute array is Dimensioned (at a specific location in memory using the AT address syntax), ScharfBASIC does not initialize the memory occupied by the array. Further, when an absolute array is erased, the memory is not released either. This provides a powerful mechanism to create Union -like overlay structures in memory.

The most common use of an absolute array is when manipulating Visual Basic arrays directly from a DLL. This involves obtaining a pointer to the array, the element size, and the number of elements. With this information, an absolute array can be dimensioned in ScharfBASIC and the array memory manipulated directly. Another common use involves using a large dynamic or fixed-length string memory block, overlaid with an absolute numeric array.

Care must be exercised when using absolute arrays, since the contents of an absolute array can only be valid for the scope of the memory the array references. If an absolute array references memory that is LOCAL to the procedure, the array contents become invalidated if the target memory block is released. For example, by either explicitly deallocating the memory block, or exiting the procedure itself. Attempting to access absolute array memory that has been deallocated will likely trigger a General Protection Fault (GPF). On this basis, absolute arrays should be LOCAL to the procedure in which they are to be used.

While ScharfBASIC supports LBOUND values that are non-zero, ScharfBASIC generates the most efficient code if the LBOUND parameter is omitted (i.e., the array uses the default LBOUND of zero). You should also avoid specifying an explicit LBOUND of zero, since this imposes a small efficiency penalty with no meaningful benefits

Declaring scalar (non-array) variables

If you have specified #DIM ALL or OPTION EXPLICIT , you have to declare all variables used in your programs. ScharfBASIC provides a variation of the DIM statement for this job, because of the reduced level of syntax required for scalar variables. The following is a simplified syntax for DIM that just applies to scalar variables:

DIM var AS [GLOBAL | INSTANCE | LOCAL | STATIC | THREADED] type [PTR | POINTER] [, ...]

DIM var ' var must include a type-specifier

Here are some sample variable declarations:

DIM a AS LOCAL INTEGER

DIM b AS STATIC WORD

DIM c AS GLOBAL DOUBLE POINTER

DIM d AS STRINGZ * 255

DIM e AS THREADED STRING

DIM f AS INSTANCE SINGLE

AS type

INTEGER

Integer

Double-word

Long-integer

Quad-integer

SINGLE

Single-precision floating-point

DOUBLE

Double-precision floating-point

Extended-precision floating-point

EXTENDED

Extended-precision floating-point

Currency

CURRENCY

Currency

Extended-currency

CURRENCYX

Extended-currency

STRING

Dynamic (variable-length) string

WSTRING

Unicode Dynamic string

STRING * x

Fixed-length string

ASCIIZ * x

Nul-terminated string

ASCIZ * x

Nul-terminated string

STRINGZ * x

Nul-terminated string

WSTRINGZ * x

Unicode Nul-Terminated string

Pointer

Pointer

Pointer

VARIANT

Variant

IAUTOMATION

Automation Interface

IDISPATCH

Dispatch Interface

IUNKNOWN

Direct Interface

16-byte GUID string

Field string

Restrictions

LOCAL ASCIIZ, LOCAL fixed-length strings, and LOCAL UDTs are created on the stack frame of the Sub/Function/Method/Property in which they are declared. You must therefore use caution so that the combined local variable size does not exceed the allocated stack size. Unless you declare otherwise, ScharfBASIC sets a default stack size of 1MB. If more stack space is required, you can allocate it with the #STACK metastament. There are no such limitations with GLOBAL, INSTANCE , THREADED , or STATIC variables.

When a DIM statement is used ( without an explicit scope clause ), to declare a variable in a procedure, and an identical variable has already been declared as GLOBAL, the variable in the procedure will be given GLOBAL scope. For example:

GLOBAL xyz AS LONG

SUB MySub

DIM xyz AS LONG

' Here, xyz is a GLOBAL variable

END SUB

To ensure that the variable scope is LOCAL to the Sub/Function/Method/Property, use a LOCAL statement rather than a DIM statement. Alternatively, add an explicit scope clause to the DIM statement. For example:

GLOBAL xyz AS LONG

[ statements ]

SUB MySub

DIM xyz AS LOCAL LONG

' Here, xyz is a LOCAL variable

END SUB

Declaring pointer variables

A pointer must be declared before it can be used. You use the DIM statement to declare pointers, and describe the type of data to which they point. When a pointer is declared, it is automatically initialized to a value of zero. This is known as a null-pointer. You must remember to initialize it to a valid address, or you will get a General Protection Fault (GPF). The syntax for declaring pointer variables is similar to that of regular variables:

DIM var[(subscripts)] AS [GLOBAL | INSTANCE | LOCAL | STATIC | THREADED] type [PTR | POINTER] [, ...]

Here are some examples of pointer variable declarations:

DIM a AS BYTE PTR

DIM b AS INTEGER POINTER

DIM c AS STRING PTR * 25

DIM d AS MyType POINTER

DIM e(500) AS INTEGER PTR

Pointers themselves are stored as DWORD values.

See Also

  • #DIM
  • ARRAYATTR
  • ERASE
  • GLOBAL
  • INSTANCE
  • Just what is COM?
  • LOCAL
  • REDIM
  • RESET
  • STATIC
  • THREADED
  • Variables
  • Variable Scope
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Dim

mov   esi,0x64
mov   di,0x32
mov   DWORD PTR [ebp-0x98],esi

Variant 2: Dim Array

push   0x201087
mov   ecx,0x23
push   0x10a0008
lea   ebx,[ebp-0x110]
call   0x2018a8
call   0x201dec

Variant 3: Dim String

push   0x201087
call   0x201af0

Variant 4: Dim String Array

push   0x201087
mov   ecx,0x23
push   0x12e0008
lea   ebx,[ebp-0x110]
call   0x2018c8
push   0x12e0008
lea   ebx,[ebp-0x110]
call   0x2018c8
call   0x201e0c


REGISTER - ScharfBASIC Help

REGISTER

To define

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

REGISTER variable [AS type ] [, variable [AS type ]]

Description

The REGISTER statement is used to define certain local variables as Register variables - that is, variables which are stored directly in specific CPU registers, rather than in application memory. Since data in a CPU register can be accessed much faster, and with less code, Register variables are valuable optimization tools.

Register variables are always local to the procedure where they appear. In the current version of ScharfBASIC, there may be up to two integral-class variables ( Word / Dword / Integer / Long ) and up to four Extended-precision floats . It is possible that future versions of the compiler will change these limits, so you may declare an unlimited number of them. Any "extra" Register variables are automatically reclassified as locals during compilation.

The REGISTER statement allows you to choose which variables will be classified as Register variables. If you do not make the choice in a particular procedure, the compiler will attempt to choose for you. By default, the compiler will always assign any integral-class local variables available. Extended-precision float variables will be automatically assigned only in Functions that contain no external Function calls.

Integral class Register variables are most efficient for variables that are updated or used often, such as For/Next loop counter variables, and variables that are used repeatedly as array indexes.

Floating-point Register variables should generally be chosen with a bit more caution, since the compiler must generate code to save and restore them to conventional memory around each call to a procedure. In some rather rare cases, it is possible that floating-point Register variables could actually reduce execution speed. However, they are extremely valuable with intensive floating-point calculations in Functions that have few references to other procedures.

Due to the design of FPUs (floating point units), and the instruction sets available, the first float register variable declared in your program has far more optimization possibilities than the others do. Use care in choosing the variable which is used most within floating-point expressions (that is, on the right side of the '=' assignment operator), in order to gain the greatest advantage in execution speed. Also, remember it is typically valuable to assign floating-point constants to Register variables when they are used in repetitive or intensive calculations.

You must use care with Inline Assembler floating-point opcodes in Functions that enable Register variables. Floating-point Register variables may occupy up to four of the FPU registers, so you must limit your use of the x87 registers to the remaining four. Further, floating-point Register variables may never be referenced by name from Inline Assembler code, as the compiler cannot always track the register locations with absolute certainty.

Restrictions

VARPTR cannot be used on a Register variable.

ScharfBASIC transparently prevents the automatic register conversion of the variable used in the TO clause of the DIALOG SHOW MODAL and DIALOG SHOW MODELESS statements. If the target variable is explicitly declared as a register variable, ScharfBASIC raises a compile-time Error 491 ("Invalid register variable"). This is necessary as the result values stored in such variables may be assigned from the context of other procedures, and this may only occur with a memory variable.

See Also

  • #REGISTER
  • Optimizing your code


Array storage requirements - ScharfBASIC Help

Array storage requirements

A ScharfBASIC array may contain up to 4,294,967,295 elements, and the data may occupy as much as all available memory. However, all individual index numbers must fall within the range of a Long-integer

Kind | Keyword
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

ScharfBASIC stores array data in main memory for all array types (including LOCAL arrays). Therefore, there is no arbitrary array size limit imposed by the amount of free stack space, such as can be experienced with large LOCAL nul-terminated , and Fixed-length string variables. The availability of main memory is the prime consideration (typically up to 2 Gb can be used). However, LOCAL arrays do require the storage of around 128 bytes on the stack for the array descriptor table.

Multidimensional arrays

Internal representations of arrays

Arrays within User-Defined Types


DATA - ScharfBASIC Help

DATA

Declare

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

DATA ["] item ["] [[, ["] item ["]] ...]

Description

DATA statements may only appear inside of Subs , Functions , Method , or Properties , and are visible only to the code in the procedure in which they appear. Each procedure may therefore have its own private data.

Data may consist of virtually any text characters. Data items may be enclosed in quotes to preserve leading/trailing spaces, which are otherwise stripped during compilation.

Restrictions

There is a limit of 64 Kilobytes and 16384 separate data items per procedure. Previous versions of ScharfBASIC ignored plain text located immediately after a quoted literal up to the next comma or end-of-line; however, this is no longer acceptable and generates an Error 477 ("Syntax error").

DATA statements cannot extend across more than one physical source code line using line continuation characters. Special care should be used when formatting DATA statements, especially if the data is to contain underscore and/or colon characters. The following examples highlight data items in blue:

If an underscore appears after a comma, it is treated as the start of a quoted data string, rather than a line continuation character:

' Three data items exist in this line:

DATA "Tom", "Dick", _Harry

The colon (statement separator) character, when used within unquoted string data, performs as a regular statement separator:

' Two data items and a separate statement

DATA "Tom","Dick" : Harry& = 1

However, if a colon character appears within a quoted data string, it is treated as part of the data string:

' 3 data items

DATA "Tom",Dick,":Harry& = 1"

See Also

  • DATACOUNT
  • READ$
  • VAL

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x20108d
call   0x201af0


Default Variable Typing - ScharfBASIC Help

Default Variable Typing

In most older versions of BASIC (including ScharfBASIC for DOS ), all variables without a TypeID (%, !, &, etc.) are automatically considered to be single precision floating point . Other compilers hav

Kind | Keyword
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

To avoid this ambiguity, ScharfBASIC asks you to make this determination instead. You can use the DEF statement to specify your preferred default variable type to be applied to untyped variable names. For example, to mimic the single precision default of PB/DOS, simply add a DEFSNG statement to the top of your program:


ERASE - ScharfBASIC Help

ERASE

Deallocate

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

ERASE array [()] [, array [()]] ...

Description

Any memory assigned to the individual elements (if they are dynamic strings , Objects , Variants , etc.) is also released. ERASE deallocates all the memory for LOCAL , STATIC , and GLOBAL arrays. After an array is erased, attempting to access the array may produce a General Protection Fault (GPF). Local arrays are implicitly erased upon exit from the Sub / Function / Method / Property that created them.

The name of the array to deallocate. Parentheses are optional, but are recommended for clarity of the source code.

One method to check if an array has been dimensioned without triggering a GPF is to use the LBOUND and UBOUND functions, as follows:

IF UBOUND(array) - LBOUND(array) = -1 THEN

' array() is not allocated

END IF

ERASE can deallocate an array that was passed as a parameter to a procedure, but only if the array was passed by reference (BYREF). To clear the contents of an array back to its initialized state, use REDIM or RESET .

Restrictions

Absolute arrays (those created by DIM...AT ) are handled differently by ERASE. An explicit ERASE will release the individual elements of an absolute array, if needed, but the full data block is left as-is because no assumptions can be made as to its origin. It is the programmer's responsibility to ensure that the memory block overlaid by the absolute array is handled correctly. In an implied ERASE (Sub/Function/Method/Property exit) of a LOCAL absolute array, the internal array descriptor is deactivated, but no changes of any kind are made to the individual data elements or the full block. RESET may be used to set arrays to zeroes or empty strings without releasing the data block.

See Also

  • ARRAYATTR
  • DIM
  • REDIM
  • RESET

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

call   0x201908
mov   eax,0x8
call   0x201a58


GLOBAL - ScharfBASIC Help

GLOBAL

Declare global (shared)

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

GLOBAL variable [()] [ AS type ] [, variable [()]] [, ...]
GLOBAL variable [()] [, variable [()]] [, ...] AS type

Description

GLOBAL declares the specified variable(s) as global to the entire program. This gives a procedure access to variable(s), without having to pass them as parameters. To declare an array as a global variable, use an empty set of parentheses in the variable list:

GLOBAL MyArray%()

GLOBAL StringArray() AS STRING

You must then use the DIM or REDIM statements to dimension the array inside a procedure. A good place to do this is inside your WINMAIN or PBMAIN function.

If an array is defined as GLOBAL outside a procedure, you should include the GLOBAL keyword in the DIM statement for clarity, and compatibility with future versions of ScharfBASIC:

GLOBAL a() AS STRING

FUNCTION PBMAIN

DIM a(1 TO 500) AS GLOBAL STRING

[ statements ]

END FUNCTION

The GLOBAL statement may accept a list of variables, all of which are defined by the type descriptor keywords which follow them. For example:

GLOBAL aaa, bbb, ccc AS INTEGER

GLOBAL vptr, aptr() AS LONG PTR

Restrictions

GLOBAL variables are not shared between programs and DLLs or between multiple instances of the same DLL. That is, a GLOBAL variable is only global within its own module. The simplest way to expose a variable to a DLL is to pass the variable BYREF (by reference) to the target DLL. DEF type has no effect on variables defined by a GLOBAL statement.

See Also

  • DIM
  • INSTANCE
  • LOCAL
  • STATIC
  • THREADED

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   DWORD PTR ds:0x202a50,0x64
mov   WORD PTR ds:0x202a54,0x32
mov   eax,DWORD PTR ds:0x202a50
mov   DWORD PTR [ebp-0x98],eax


INSTANCE - ScharfBASIC Help

INSTANCE

Declare

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

INSTANCE variable [()] [AS type ] [, variable [()]]
INSTANCE variable [()] [, variable [()]] [, ...] AS type

Description

INSTANCE statements are used to declare instance variables for an object. A unique set of instance variables is created for every new object, which may only be referenced from within that object. INSTANCE statements may only be placed at the beginning of a CLASS/END CLASS block, preceding all INTERFACE blocks.

INSTANCE will optionally accept a list of variables, each of which are defined by the descriptor which follows it:

INSTANCE x as integer, y as long

INSTANCE will also accept a list of variables, all of which are defined by the single descriptor at the end of the list;

INSTANCE aaa, bbb, ccc AS INTEGER

INSTANCE vptr, aptr() AS LONG PTR

To declare an array as an instance variable, use an empty set of parentheses in the variable list: You can then use the DIM statement to dimension the array .

See Also

  • GLOBAL
  • INTERFACE (Direct)
  • LOCAL
  • STATIC
  • THREADED
  • What is an object, anyway?

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   ebx,DWORD PTR [ebp+0x8]
mov   ebx,DWORD PTR [ebx+0x4]
add   ebx,0x3c
mov   DWORD PTR [ebx],0x64
mov   ebx,DWORD PTR [ebp+0x8]
mov   ebx,DWORD PTR [ebx+0x4]
add   ebx,0x3c
mov   DWORD PTR [ebp-0x98],eax
ret   0x4


LET - ScharfBASIC Help

LET

Assign a value to a

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

[LET] variable = expression
[LET] variable += expression
[LET] variable -= expression
[LET] variable *= expression
[LET] variable /= expression
[LET] variable \= expression
[LET] variable &= expression
[ LET] variable AND= expression
[LET] variable OR= expression
[LET] variable EQV= expression
[LET] variable IMP= expression
[LET] variable MOD= expression
[LET] variable XOR= expression

Description

Simple assignment

variable is a string or numeric variable, and expression is of a suitable type (that is, a string expression for string variables and numeric expression for numeric variables).

The word LET is optional in assignment statements. It is allowed to provide compatibility BASIC source files written for early versions of BASIC. In practice, the word LET is very rarely used.

To allow easy conversion, ScharfBASIC allows a User-Defined Type in a string expression . The User-Defined Type is simply copied, byte for byte, into the expression. However, to assign a string back to a User-Defined Type, you should use the TYPE SET statement.

DIM abc as MyType

MyString$ = abc

Please refer to the following sections of the LET statement for special information regarding assignment using Object variables, Variant variables, and User-Defined Type variables.

Compound assignment

A compound assignment statement combines a binary arithmetic operator , a binary bitwise operator , or a binary string operator (concatenation) as an integral part of the assignment. This offers the programmer a "shortcut" in your source code, and can even result in more efficient code generation. That's because the target variable is evaluated only once, even if an array or pointer calculation could have a side effect which changes it.

Compound assignments are available for the standard arithmetic operations of add, subtract, multiply, divide, int-divide, and modulo (+ - * / \ MOD ), the bitwise operations ( AND , OR , XOR , EQV , IMP ), and the concatenation operators (+ &). Each are represented by one of the following tokens:

Each of the following pairs of code are functionally identical:

x = x + 1

x += 1

x = x / y

x /= y

x = x XOR 3

x XOR= 3

x(7) = x(7) AND 5

x(7) AND= 5

x$ = x$ + y$

x$ += y$

See Also

  • BUILD$
  • JOIN$
  • LET (with Objects)
  • LET (with Variants)
  • LET (with Types)
  • TYPE SET


LOCAL - ScharfBASIC Help

LOCAL

Declare local

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

LOCAL variable [()] [AS type ] [, variable [()]] [...]
LOCAL variable [()] [, variable [()]] [, ...] AS type

Description

The LOCAL statement is valid only inside a Sub, Function, Method, or Property. Local variables lose their values when the procedure ends. Storage space for local variables is allocated on the stack , and each local variable is initialized to zero (or, for string variables, an empty string) each time the enclosing procedure is called.

To declare an array as a local variable, use an empty set of parentheses in the variable list: You can then use the DIM statement to dimension the array .

LOCAL MyArray%()

LOCAL StringArray() AS STRING

The LOCAL statement may, optionally, accept a list of variables, all of which are defined by the type descriptor keyword that follows them. For example:

LOCAL aaa, bbb, ccc AS INTEGER

LOCAL vptr, aptr() AS LONG PTR

Restrictions

DEF type has no effect on variables defined by a LOCAL statement.

See Also

  • DIM
  • GLOBAL
  • INSTANCE
  • STATIC
  • THREADED

Compiled Assembler Code (x86)

The compiler generates different x86 code depending on the exact usage form. These patterns have been observed in compiled output:

Variant 1: Local

mov   esi,0x64
mov   di,0x32
mov   DWORD PTR [ebp-0x98],esi

Variant 2: Local String

push   0x201087
call   0x201af0


Multidimensional arrays - ScharfBASIC Help

Multidimensional arrays

Arrays can have one or more dimensions, up to a maximum of eight. A one-dimensional array such as payments is a simple list of values. A two-dimensional array represents a table of numbers with rows a

Kind | Keyword
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

DIM one!(15) ' a one-dimensional list

DIM two!(15,20) ' a two-dimensional table

DIM three!(7,9,1) ' an 8 by 10 game board with room in the third

' dimension for 2 items: piece type and color

Arrays of four to eight dimensions are possible, but they become more difficult to conceptualize and keep straight. You can define:

DIM five%(5,5,10,20,3) ' a five-dimensional array

but it's probably better to redesign this array into several smaller ones with fewer dimensions, or use an array of User-Defined Types .

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   eax,0x2


OPTION EXPLICIT - ScharfBASIC Help

OPTION EXPLICIT

Force explicit declaration of all

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

OPTION EXPLICIT

Description

Using OPTION EXPLICIT in a program has the same effect as using the #DIM ALL metastatement. That is, it requires that all variables be declared before they are used.

When this option is used, the compiler generates a compile-time error if a variable or array is used without being explicitly declared.

See Also

  • #DIM


READ$ - ScharfBASIC Help

READ$

Retrieve string

Kind | Function
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

value$ = READ$( n %)

Description

The READ$ function is used to retrieve a specified string data item from a local DATA list, and returns the data in string format. READ$ offers a simple technique for random-access of local DATA.

An integral expression, constant , or variable , which specifies an index position in the local DATA list. n% = 1 for the first data item, n% = 2 for the second, and so on. READ$ accesses the DATA statements in the order in which they appear in the source program, from left to right.

If n% is greater than DATACOUNT , READ$ returns an empty string, but no run-time error occurs.

value$

READ$ places the DATA string into value$.

If the target DATA statement is enclosed in quotes, READ$ preserves any leading or trailing spaces that it may contain; otherwise, READ$ trims leading and trailing spaces and returns a trimmed string. See DATA for more information on data item formatting.

If numeric data needs to be stored in DATA statements and retrieved with READ$, the VAL function can be used to convert the return values from READ$ into numeric values.

Restrictions

There is a limit of 64 Kilobytes and 16384 separate data items per Sub , Function , Method , or Property , and it is not possible to read DATA from outside of the scope of current procedure. Restrictions apply to using colon and underscore characters in DATA statements - see DATA for more information.

See Also

  • DATA
  • DATACOUNT


REDIM - ScharfBASIC Help

REDIM

Used at the Procedure level

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

REDIM [PRESERVE] array ([ subscripts ] ) [AS type ] [AT address ] [, ...]

Description

The REDIM statement allows dynamic arrays (including string arrays ) to be erased and re-dimensioned. It is really just a shortcut for the two-step process ERASE x (), followed by DIM x (). REDIM uses the same basic syntax as the DIM statement.

array is the name of the array, and subscripts is either a group of single integers (one per dimension of a particular array), or a group of ranges (REDIM arr1(5 TO 25, 1 TO 4, 3 TO 8)), separated by commas.

AS type

The AS type clause is optional, but It is recommended that an explicit variable scope clause (LOCAL/STATIC/GLOBAL/THREADED/INSTANCE) be added to each REDIM statement that uses an explicit type clause.

AT address

The AT address clause indicates the array is to be an absolute array. Absolute arrays are not reset by the REDIM statement, nor are they reset when the Sub / Function / Method / Property exits, but they can be reset with the RESET statement. See the discussion in the DIM topic for more information on absolute arrays.

PRESERVE

The PRESERVE keyword tells the compiler to preserve the values of all existing elements in the array. For example, if you REDIM PRESERVE an array with 10 elements to 20 elements, the first 10 elements will retain their original value. The remaining 10 elements will be initialized to zero (or null/empty in the case of a string array). If the array is resized to be smaller, the specified number of elements is preserved, and the remaining elements are discarded. When PRESERVE is specified, you can resize only the upper boundary of the last (outer) dimension of the array . Arrays of only one dimension can always be resized.

In a procedure, you can use REDIM to re-dimension an array that was passed as an argument. That is, when the complete array was passed to the procedure:

CALL RemoveDuplicates( CustomerNames$() )

' more code here

SUB RemoveDuplicates( a$() )

' Remove duplicate array values

REDIM PRESERVE a$(1 TO NewCount&)

END SUB

REDIM may also be used to alter the size of Static , Global , and Instance arrays.

When used with no subscript parameters, REDIM will erase all contents of an array and deallocate the memory used:

REDIM xyz&() ' Equivalent to ERASE xyz&()

Restrictions

When PRESERVE is specified, only the upper bound of the last (outer) dimension may be redefined.

When a REDIM statement is executed, the location of the array elements always moves in memory; however, the array's Descriptor location ( VARPTR ( arrayname ()) will remain fixed at the original location. When using REDIM, your code must be sure to refresh any pointers that target the array data memory locations ( STRPTR ( arrayname ( subscript )) for dynamic string arrays, and VARPTR( arrayname ( subscript )) for all other array types).

While ScharfBASIC supports lower boundary values that are non-zero, ScharfBASIC generates the most efficient code if the lower boundary parameter is omitted (i.e., the array uses the default lower boundary of zero).

See Also

  • ARRAYATTR
  • DIM
  • ERASE
  • RESET

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

push   0x20108b
mov   ecx,0x41
call   0x201928
lea   ebx,[ebp-0x188]
call   0x201a78
lea   ebx,[ebp-0x188]
call   0x201928
call   0x201e6c


STATIC - ScharfBASIC Help

STATIC

Declare

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

STATIC variable [()] [AS type ] [, variable [()]]
STATIC variable [()] [, variable [()]] [, ...] AS type

Description

The STATIC statement is valid only inside a procedure. Static variables retain their values even after the procedure ends. A static variable is local to its procedure, and can have the same name as other variables in other parts of the program without conflict.

To declare an array as a static variable, use an empty set of parentheses in the variable list: You can then use the DIM statement to dimension the array.

STATIC MyArray%()

STATIC StringArray() AS STRING

The STATIC statement may, optionally, accept a list of variables, all of which are defined by the type descriptor keyword that follows them. For example:

STATIC aaa, bbb, ccc AS INTEGER

STATIC vptr, aptr() AS LONG PTR

Restrictions

DEF type has no effect on variables defined by a STATIC statement.

See Also

  • DIM
  • GLOBAL
  • LOCAL
  • THREADED

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

inc   DWORD PTR ds:0x202a50
mov   eax,0x1
movsx   ecx,WORD PTR ds:0x202a54
mov   WORD PTR ds:0x202a54,ax
mov   eax,DWORD PTR ds:0x202a50
mov   DWORD PTR [ebp-0x98],eax


String arrays - ScharfBASIC Help

String arrays

The elements of string arrays hold strings instead of . Each string can be a different length. For example DIM words$(50) creates a sequence of 51 independent string variables:

Kind | Keyword
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

words$(0) = "Daniel likes cats." ' 18-character string

words$(1) = "" ' a null string

words$(2) = "Nicki is a sweet child." ' 23-character string

' assign more array values here

words$(50) = SPACE$(200) ' 200-character string

Multidimensional arrays


Subscripts - ScharfBASIC Help

Subscripts

Individual array elements are selected with subscripts or index numbers, which are Long-integer expressions within parentheses to the right of an array variable's name. For example, payments (3) and p

Kind | Keyword
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

' This DIM statement declares a 56-element array

' with subscript bounds of 0 TO 55.

DIM payments1(55) AS CURRENCY

' This DIM statement declares a 56-element array

' with subscript bounds of 1 TO 56

DIM payments2(1 TO 56) AS CURRENCYX

You must DIM all arrays before you can use them. This is a different approach then that used by some BASIC dialects, which assume that an array contains 10 elements (0 to 9) if the array is not explicitly dimensioned.

ScharfBASIC allows you to define a range of subscript values rather than just setting an upper limit. The statement:

DIM clouds(50 TO 60, 25 TO 45) AS LONG


THREADED - ScharfBASIC Help

THREADED

Declare thread-local variables.

Kind | Statement
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Syntax

THREADED variable [()] [AS type ] [, variable [()]]
THREADED variable [()] [, variable [()]] [, ...] AS type

Description

Threaded variables are global to every Sub , Function , Method , and Property but are not shared across threads. Each thread has its own independent set of thread-local variables .

To declare an array as a threaded variable, use an empty set of parentheses in the variable list: You can then use the DIM statement to dimension the array.

THREADED MyArray%()

THREADED StringArray() AS STRING

The THREADED statement may, optionally, accept a list of variables, all of which are defined by the type descriptor keyword that follows them. For example:

THREADED aaa, bbb, ccc AS INTEGER

THREADED vptr, aptr() AS LONG PTR

Restrictions

DEF type has no effect on variables defined by a THREADED statement.

See Also

  • DIM
  • GLOBAL
  • INSTANCE
  • LOCAL
  • STATIC

Compiled Assembler Code (x86)

The compiler generates the following x86 machine code for this command:

mov   ebx,0x80
call   0x201bea
mov   DWORD PTR [ebx],0x64
mov   ebx,0x84
call   0x201bea
mov   WORD PTR [ebx],0x32
mov   ebx,0x80
call   0x201bea
mov   DWORD PTR [ebp-0x98],eax


Variable scope - ScharfBASIC Help

Variable scope

The scope of a variable is defined as its visibility and its lifetime. Visibility means what parts of your program can access it. Lifetime defines when it is created and when it is destroyed. In Power

Kind | Keyword
Category | Variables & Scope
ScharfBASIC | AVAILABLE
Notes | ScharfBASIC-compatible ScharfBASIC command

Details

Numeric variables are initialized to zero (0). Dynamic strings , Field strings , and nul-terminated strings are initialized to a length of zero (no characters). Fixed-length strings and UDTs are filled with CHR$ (0). ScharfBASIC automatically destroys every variable at the appropriate time, so you never need worry about this type of memory leak.

Local variables are only accessible within a single SUB , FUNCTION , METHOD , or PROPERTY . They are automatically created and initialized each time you enter the procedure. They are automatically destroyed when you exit the procedure. This is the default variable scope unless you declare otherwise.

Static variables are only accessible within a single SUB, FUNCTION, METHOD, or PROPERTY. They are initialized when your program starts, but retain their value regardless of how many times the procedure is entered and exited. They are destroyed only when the program ends.

Instance variables are accessible from any method or property in a class. Each object will have its own unique copy of them. They are created and initialized when an object is created. They are destroyed when the object is destroyed.

Threaded variables are accessible from anywhere in your program, but each thread within your program will have its own unique copy of them. They are created and initialized when a thread is created. They are destroyed when the thread ends. Threaded variables are commonly called Thread Local Storage (TLS). They serve a purpose similar to global variables, but never require synchronization since they can't be accessed across threads.


/ASMOUT Startup Switch - ScharfBASIC Help

/ASMOUT Startup Switch

Write a diagnostic evidence file and exit without compiling.

Kind | Startup Switch
Category | Compiler
ScharfBASIC | EXTENSION
Notes | MVP implementation; writes evidence header only

Syntax

ScharfBASIC.exe /ASMOUT:filename source.bas

Description

The /ASMOUT:Filename switch is recognized by the ScharfBASIC compiler as a native startup option. When present, the compiler creates Filename, writes a diagnostic evidence header, and exits cleanly without producing an .EXE.

This switch is intended for troubleshooting and compiler evidence collection. It does not perform a full compile or generate executable output.

Example

ScharfBASIC.exe /ASMOUT:myfile.asm /Q MyProgram.bas

This creates myfile.asm containing:

; ScharfBASIC /ASMOUT native compiler switch
; Status: switch recognized inside ScharfBASIC.exe
; Next step: expand this native path from MVP header to full PE/ASM section dump.

Behavior

  • The switch is recognized in both /ASMOUT:Filename and -ASMOUT:Filename forms.
  • The filename may be optionally quoted: /ASMOUT:"my file.asm".
  • If no filename is provided after the colon, normal compilation proceeds.
  • The compiler exits with code 0 after writing the file.

See Also

  • Command-Line Options


Command-Line Options - ScharfBASIC Help

Command-Line Options

Startup switches and command-line arguments for the ScharfBASIC compiler.

Kind | Reference
Category | Compiler
ScharfBASIC | AVAILABLE
Notes | All switches are case-insensitive

Syntax

ScharfBASIC.exe [switches] sourcefile.bas

Switch Reference

Switch | Description
/Q | Quiet compile. Suppresses the startup dialog and compiles without user interaction.
/L | Write listing. Generates a .lst listing file during compilation.
/C | Compile only. Performs compilation without linking to produce an executable.
/I path | Adds path to the include search path for #INCLUDE files.
/D name | Defines a conditional-compilation equate name at startup.
/T:n | Sets the thread stack size to n bytes.
/ASMOUT:file | Writes a diagnostic evidence file and exits without compiling. See /ASMOUT for details.

Examples

' Quiet compile with listing
ScharfBASIC.exe /Q /L MyProgram.bas

' Compile only, add include path
ScharfBASIC.exe /C /I C:\MyIncludes MyProgram.bas

' Diagnostic evidence output
ScharfBASIC.exe /ASMOUT:evidence.asm /Q MyProgram.bas

Startup Dialog

When ScharfBASIC is launched without the /Q switch and without a source file argument, a startup dialog appears allowing you to:

  • Select the source .bas file via a text box or browse button.
  • Toggle /Q (Quiet compile), /L (Write listing), and /C (Compile only) checkboxes.
  • Review available text-argument options (/I, /D, /T:n, /ASMOUT) shown in the dialog tip.

See Also

  • /ASMOUT Startup Switch
  • Compiler Overview