Recent Posts

Pages: 1 2 3 4 5 6 7 8 9 10
1
In larger Projects like this: Blender-Buttonbar for Python Scripts
when you start working, you just choose names for Variables. Later you want to get a System for these.
In Reality of larger Projects, changing Variable Names is not "just a Find and Replace" Task.
You may have constructs like "$crlf$$crlf$" which is a System-Constant for a Linefeed and not a Variable "$crl".
With Labels its even more difficult. Assum you have a Label:
Code: [Select]
:Lab
' and you want to replace it with
:Lab_failed
A simple Replace Operation would just make a endless "Lab_Lab_Lab ..." out of it.  So there is some more behind, but its ready for use.
You can now in the Editor see "Which Variables are used "How often and where". And the same with Labels.
Also you can Jump to that Line with a Click on the "Goto Button". And Replace them with another Name.
Also Duplicate Labels will be marked as well as "Marcro local Labels".
2
News and Announcements / NEW TEXT-Commands for the SPR.
« Last post by Theo Gottwald on October 18, 2020, 09:00:25 AM »
Sometimes its all about processing LOG-Files. Or other Text-Files. Maybe large files with a Million lines. Maybe searching something or maybe comparing many files.

How it was before:
Originally you would simply have used the LFF. (Line from File) Command
Code: [Select]
LFF.(Linenumber|(Variable for Result)and just get  "Line by Line" from any Textfile.

However internally the LFF. - Command will read the Textfile until it comes to the Line you have specified and then get this line for you.
Means if you want to read Line 500 the LFF. would read All Lines up to 500 and then give the Line 500 to you.
Going through a file like this works fine until the file-size exceeds some 100 Lines.
Then it will just get too slow. Because, before you reach Line 1000 internally the Robot has read nearly a Million Lines from the harddisk (Buffers).
Thats because the LFF.-Command  was designed for getting Single Lines, not going through a file.

Also there is the FEL.-Command. FOR EACH LINE. This was designed for "Going through a file".
It will hand you out "Line by Line" from any file.

However if you want to skip between Lines in the Textfile, you can not use it and you are back to LFF.

SO here we had a gap and this is now filled with the new TXT./LOF./LFT.commands.

First there are LOF. (Load Text File)  and LFT. (Line from Text-File).
These two commands serve for that purpose. They work "in memory".
The textfile is "loaded into Memory" and LFT. will give you any line from there.
So no harddisk involved. Maximum speed. No measurable difference wether you get Line 10 or Line 100000.

Generally here you will Load the Textfile with LOF. directly into Memory.
And then with LFT. you will get each Line "by number" directly "from memory" so this is maximum speed.
Processing Text Files in this way, the Script can handle several thousand Lines per second.
I have tested that with an Python Identation checker that was done with the SPR.
It processed 6000 Codelines in 4 seconds, correcting any Identation errors.

This command can store up to 1287 different files, which you reference with a number (from 1 to 128)
so you can compare the content of these files with Line-based Algorhytms.

This command can be used together with the LOF. - command to process Text files faster.
It has two Working-Modes:

1. Get Line from File
LFT. with a number from 1 to (Number of Lines), will return the Line with that number in $$RET:
Code: [Select]
LFT.$$IND|$$NUM|$RET
2. Get number of Lines in File
LFT. with a number -1, will return the number of stored Lines from that file with that Index-Number.
Code: [Select]
LFT.$$IND|-1|$$RET
If you call LFT. with a Number larger then the number of Lines in that File, the returned Variable will be empty.

Currently you can load up to 128 Textfiles into the Buffer at the same time, each having its own Index-Number from 1 to 128. This is very good if you need to work on multiple Text-Files at the same time, but you do not want to access the harddrive so often. Using LOF. the file is buffered and all further Operations using LFT. are done in memory.

Usage is simple:

Code: [Select]
VAR.$$FIL=?path\Test.txt
' Read the File into Memory
LOF.$$IND|$$FIL
'The Index Number for this file is now in $$IND
LFT.$$IND|-1|$$RET
'Using LFT. with " -1" as Linenumber, we get the Number of
'Lines in return (here in $$RET).
' Now we enumerate through the File without accessing
' the harddrive, at maximum Speed
FOR.$$LOP|1|$$RET
  LFT.$$IND|$$LOP|$$LIN
  PRT.$$LIN
NEX.
MBX.Ready
ENR.

But thats just the beginning of this topic.
Then we have the new TXT.-Commands. These Commands are specially designed for fast analyzing, changing and doing anything with a Textfile.
Just in case if there is more to do then just loading a file "Line by line".

These commands are the easy way to work through Textfiles. What you can do:

  • Load and Save Textfiles
  • Process Textfiles from an internal Cache without need to access the Filesystem
  • Store Textfile in Variable (with or without Filename)
  • Restore Textfile from Variable (with or without Filename)
  • Get the Linenumber of a Byte-Position in a textfile
  • Get the complete Line of specified a Linenumber
  • Get all Lines from specific  line to the start or end of text
  • Get the start or end of a Line from a specified Byte-Position
  • Change specfied Lines (replace with a specified line)
  • Get Textfile from the LOF./LFT.-Command or
  • Move a textfile to the LOF./LFT.-Command
  • several Replace Operations
  • and more.

Here is a Quick Overview on the Commands.
Unlike the LOF.-Command, the TXT.-Commands do only work with just ONE Textfile at the time.
Therefore you do not need to specify an "Index" Value like with LFT.
If you want to switch to another file this can easily be done in several ways.
You can just transfer the file into a variable, or get another file from a variable.
Or you can exchange the files with LOF. and this way access all files that are stored in the LOF.-Buffers.

  "ltf","load_textfile"
Load a Textfile int othe internal Buffer for Processing
  ' $$FIL - Filename
  ' $$RES (optional) Returns Number of loaded lines
  TXT.Load_Textfile|$$FIL[|$$RES]

  "clr","clear"
Clear the internal Buffer
  TXT.Clear
 
  "gfn","get_filename"
' Get Filename of File in Buffer
  TXT.gfn|$$FIL

  "gtl","get_lenght"
' Get lenght of loaded Text in Bytes
  TXT.gtl|$$LAC

  "tov","to_var" 
' Move Textfile including  Filename to Variable
  TXT.To_Var|$$VAR

  "toc","to_var_and_clear"
' Move Textfile including  Filename to Variable and clear internal Buffer
  TXT.To_Var|$$VAR

  "frv","from_var"
' Get Textfile including Filename from Variable
  TXT.From_Var|$$VAR

  "lpt","load_pure-Text"
' Load Pure-Textfile and Filename from 2 Variables
  TXT.lpt|$$TXT[|$$FIL]
 
  "gpt","get_pure_text"
' "Get Pure Text". Only Textfile into $$TXT. If available, $$FIL returns the Filename
  TXT.gpt|$$TXT[|$$FIL]]

  "glc","get_line_count"
' "Get Line Count". Get number of loaded lines.
  TXT.glc|$$CNT
 
"gel","get_line"
' Get Line Number $$NUM into $$LIN
' TXT.gel|$$NUM|$$LIN

  "gll","get_line_lefttrim"
' Return Line $$LIN, like "gel" but left side trimmed (all ASC 0-32 removed)
  TXT.gll|$$LIN|$$RES

  "glt","get_line_trimmed"
' Return Line $$LIN, like "gel" but both sides trimmed (all ASC 0-32 removed)
  TXT.glt|$$LIN|$$RES

"slt","set_line_to"
' Overwrite Line $$NUM with new Line $$NEW (Replace Line)
  TXT.slt|$$NUM|$$NEW

  "glp","get_line_position"
' Get position of first and last character of line $$NUM into $$POS and last into $$POE
  TXT.glp|$$NUM|$$POS|$$POE

  "lnp","linenumber_from_position"
' Get linenumber from Byte-Position $$POS into $$LIN
  TXT.lnp|$$POS|$$LIN

  "lsp","line_Start_end_by_position"
' Get start/end of Line by Byte-Position in Text
  TXT.lsp|$$LIN|$$STR|$$END

  "flw","find_line_with"
' Find Line with String. Search first occurence of $$SEA in Textfile, return the Line-Number which has it in $$LIN.
' Falls angegeben suche ab (inkl.) Zeile $$STA
  TXT.flw|$$SEA|$$LIN[|$$STA]

  "fit","Find_Text"
' $$SEA - Searchstring
' $$FRO - Search from (B)yte or (L)ine
' Returns:
' |$$POT - Postion in Text
' |$$POL - Postion in Line
' |$$LIN - Complete Line
' |$$LNN - Linenumber
  TXT.fit|$$SEA|$$FRO[|$$POT][|$$LIN][|$$LNN]
 

  "gbl","get_before_line"
' "Get Before Line". Get all Text that is before and without the specified line into $$BLT.
  TXT.gbl|$$LIN|$$BLT

  "gal","get_after_line"
' "Get After Line". Get all Text that is After and without the specified line into $$ALT.
  TXT.gal|$$LIN|$$ALT

  "gts","get_to_start"
' Get all Text from and including the specified line until the start of the text
  TXT.gts|$$LIN|$$TXT
 
  "gte","get_to_end"
' Get all Text from and including the specified line until the end of the text
  TXT.gte|$$LIN|$$TXT

  "sav","save_file"
' Save Text under the Filename with which it was loaded from, or if specified with the specified Filename
' Leaves a result on the TOS, NTFSD-Enabled
  TXT.Save[|$$FIL]

  "gfl","get_from_lof"
' Get from LOF # will load Textfile from LOF. Index Number $$IND
  TXT.get_from_lof|$$IND

  "tol","to_lof"
' To lof cache # will put Textfile into LOF. Cache Index Number $$IND
  TXT.To_Lof|$$IND

  "rit","replace_in_text"
' "replace_in_text". Do a replace over the complete text using a Equalcase-Replace Algo.
' TXT.rit|$$OLD|$$NEW

  "ril","replace_in_line"
' "replace_in_line". Do a replace only in the specified Line using a Equalcase-Replace Algo.
  TXT.ril|$$LIN|$$OLD|$$NEW[|$$STA]

"rep","Replace"
Search a Text in the TXT.-internal Buffer and replace it with a given other sequence. Will replace all occurrences.

"tra","Translate_Chars"
 Using TXT.tra there is a 1:1 relation between the characters in $$OLD and the characters in $$NEW.
 So if a character in $$OLD is found its replaced with the corresponding Character in $$NEW
 Therefore both - $$OLD and $$NEW - MUST have the same lenght, esle there will be no changes and you will get the Timeout Flag set.
  TXT.tra|$$OLD|$$NEW[|$$STA][|$$END]


  "luf","load_unicode_file"
' Load and convert Unicode-File to ANSI
  TXT.luf|$$FIL

  "sau","save_as_unicode"
' Convert ANSI-File to Unicode and save (using default codepage)
  TXT.sau[|$$FIL]

  "ctu","convert_to_unicode"
' Convert ANSI-String to Unicod with default Codepage
  TXT.cta|$$ANS|$$UNI

  "cta","convert_to_ansi"
' Convert Unicod with default Codepage to ANSI-String
  TXT.cta|$$UNI|$$ANS
3
News and Announcements / NEW STACK-Commands for the SPR.
« Last post by Theo Gottwald on October 18, 2020, 08:39:21 AM »
Who used FORTH several years ago or had a calculator in UPN-Notation, knows the importance of a STACK.
A stack that can be used with all commands, that will take the result of operations also if you do not take them.
The SPR has two such stacks, a LOCAL Stack and a GLOBAL stack.
For these some new commands have been added and will be available with the next Update.

How to use the Stack with the SPR?
Any command that returns a result will place it on the TOS (Top of stack) when you do not give a variable for the result.
But don't worry the stack will not "overflow" it has a builtin maximum size".
Also you can add values, or strings, or formulas, or whatever to the stack using "PUV.","POV." and now new: "PSS.","PVS." and more commands.
You can get them back using the POP. Command.

There has been a general change about this in the Past.

In early times, Variables were just pushed onto the stack and eventually expanded when you POP. the values from stack.
Now the POP.-Command does not do any variable expansion anymore.
That's why there are now several commands to place variables and values on the stack.
For example if you use "POV." to place a variablöe on teh stack like this:
Code: [Select]
$$TXT=Hallo
POV.$$TXT
and then return it somewhere using
Code: [Select]
POP.$$VARthen you will have "$$TXT" inside of $$VAR, as PUV. does not do any variable expansion and POP. will also not.
This way you can just "transfer a variable name". Which you could use (to return some result) or expand it later using
Code: [Select]
VAV.$$RES=$$TXTIf you use "PUV." instead, the variable will be expanded before its placed on the stack.
So you will find "Hallo" on the TOS and not the Name of the Variable ($$TXT).

While PVS. and PUS. explicitly does NOT resolve variables and special-folder, POP. also does not,  PUV. PSS., PNS do just that.
PVS. - Put Variable-Name on Stack without resolving anything
PSS. - Resolve Variables and Special-Folders before putting the Variable on Stack
PNS. - Do a numerical resolution and calculate Formulas in the Variable (if they are in ()). Then put the result on TOS.
PUV. - Do a Variable-Type dependent Variable resolution. Variables that are defined in some way have a Variable-Type (See GVT.-Command)
PUS. - Put Variable-Name on Stack without resolving anything. Unlike PVS., Variables will not be split if separated with |"|". Just the whole Parameter will be placed on TOS.




4
Smart-Package Robot Tipps and Code / The Smart-Package-Robot Speed-Table
« Last post by Theo Gottwald on October 15, 2020, 08:35:36 PM »
I guess most users have never seen that it even exists.
Its hidden behind the DMP.-Command.
You may know "DMP.6" which will give you a Picture of the STACK.
But using "DMP.1" you will get the "Speed Table" of the currently running Script.

It shows for every executed Line:
- how many CPU Ticks it has needed totally
- how often it was executed

Also you can see all Macros expanded. Therefore this is a nice helper in debugging Scripts.
Because you can just look "If a line was executed or not" and even how often.
You will also see which parts of the Script need most time.

As you can see in the Script below, an empty line needs on my computer between 14 and 30 CPU-Ticks including the Time for the Single-Step Debug in the Editor. Do not forget to compile as EXE before doing real measurement about Speed. Because the Editor will add too much tolerance to all commands.
5
Smart-Package Robot Tipps and Code / Change Line in Source-Code
« Last post by Theo Gottwald on October 15, 2020, 08:06:45 PM »
I am using the SPR to start PB-Compiler via Commandline.
So I need to change a Single line in the Code before starting the automatic Build (of the SPR itself).
This Macro will check the complete Sourcefile for a Line:
%Quicktest=
and will replace it with a
%Quicktest=1
or
%Quicktest=0
depending on Parameter 2. This way the Build can run completely automatic.
Due to the new "TXT." Commands of the SPR, the most work is done in just 4 lines.
Could also have used "TXT.Replace" then it would have been one line less.
But i wanted to catch the case if the line is not found and eventually stop the process.
Here is a short explanation of the Code.

Generally its a Macros-Definiton with 2 Parameters (that is the Part between ": %F_Set_Quicktest 2" and "END%".
that will call a Subroutine (using GSB. = GOSUB).
Note that the MACRO as well as the GSB. take each 2 Parameters.
The SAV.-Command makes all following Variables LOCAL Variables means they are saved and later restored (with SAV.Restore).

The work is done in just 4 Lines:
TXT.Load_Textfile|$$BAF  - > Wil load the whole Sourcefile into an internal Buffer
TXT.Find_Line_with|$$SEA||$$LIN -> Will find the Line with "%Quicktest=" and return the Linenumber and Position 1-based.
TXT.Set_Line_To|$$LIN|$$NEW  -> This will set the Line to whatever we want (in $$NEW)
and finally
TXT.Save  -> Will save the file to the Filename where it was loaded.

Finally the Macro can be used in the SPR-Code like this (with 2 Parameters split with the |-Pipe Sign):

Code: [Select]
%F_Set_Quicktest $$FIQ|0
Code: [Select]
'#######################################################################
'#######################################################################
' Parameter sind P1: Source-File, P2: 0 oder 1  (Quicktest-Value)
: %F_Set_Quicktest 2
GSB.F_Set_QTest|§§§01|§§§02
END%
'#######################################################################
:F_Set_QTest
SAV.Save|$$BAF|$$NUM|$$SEA|$$LIN|$$NEW
$$BAF=§§_01
$$NUM=§§_02
VBT.$$NUM
VBT.$$BAF
TXT.Load_Textfile|$$BAF
VAR.$$SEA=%Quicktest=
TXT.Find_Line_with|$$SEA||$$LIN
JIZ.$$LIN|Itsfine
$$NEW=%Quicktest=$$NUM
TXT.Set_Line_To|$$LIN|$$NEW
:Itsfine
TXT.Save
RET.
6
Smart-Package Robot Tipps and Code / COPY / Verify Macro for SPR
« Last post by Theo Gottwald on October 15, 2020, 10:10:33 AM »
This Macro will copy a file, check if it has been authentic.
It will delete an eventually available Destination File.
Between all steps it will check that these files are accesibel and not open.

Code: [Select]
'
'SPR Script-file: Batch Library
'Purpose: Copy Files and verify checksum of Source/Dest
'Author: Theo Gottwald
'Creation date: 01-07-2017 at 21:49:54
'===========================================================
' Usage: Source/Destination
%F_Copy_Verify $$SRC|$$DES
ENR.
'#######################################################################
'#######################################################################
'#######################################################################

: %F_Copy_Verify 2
GSB.F_Copy_Verify|§§§01|§§§02
END%

:F_Copy_Verify
SAV.Save|$$FIA|$$FIB|$$CSA|$$CSB
VAF.$$FIA=§§_01
VAF.$$FIB=§§_02
'MBX.$$FIA->$crlf$$$FIB
IEF.$$FIA
  GMD.vf|$$FIA|$$CSA
  DEL.$$FIB
  WFF.<>$$FIB|10
  JIT.erol
  COP.$$FIA|$$FIB
  GMD.vf|$$FIB|$$CSB
  JIV.$$CSA!$$CSB|eroc
EIF.
SAV.Restore
RET.

:erol
MBX. Ein Fehler beim Löschen ist aufgetreten
END.
:eroc
MBX. Ein Fehler beim Kopieren ist aufgetreten$crlf$$$FIB
END.
'#######################################################################
'#######################################################################
'#######################################################################
ENR.
7
ActiveX Hosting / Re: Microsoft Flex Grid Control
« Last post by Jassim Kareem on October 11, 2020, 12:08:05 AM »
It worked.. Thanks for your generosity
Here is the result
8
ActiveX Hosting / Re: Microsoft Flex Grid Control
« Last post by José Roca on October 10, 2020, 11:42:10 PM »
Code: [Select]
DIM pPicture AS IPictureDisp
OleCreatePictureDisp(hBmp, %PICTYPE_BITMAP, %TRUE, pPicture)
pGrid.putref_CellPicture(pPicture)
9
ActiveX Hosting / Re: Microsoft Flex Grid Control
« Last post by Jassim Kareem on October 10, 2020, 10:43:11 PM »
Thanks for your prompt reply..
Based on it, is this the right code to load a picture in a MSFlexgrid cell?
Code: [Select]
       
                   ' Get a reference to the Grid control
                   pGrid = OC_GetDispatch(hGrid)
                   .
                   .
                   .
                   .
                    LOCAL hbmp AS LONG
                    LOCAL ImgPath as string
                     ImgPath=EXE.PATH$ & "Beany.bmp"
                     hBmp=LoadImage(%NULL, ImgPath, %IMAGE_Bitmap, 256, 256,0)
                     'I am not really sure of the code
                     DIM p AS LONG PTR
                     pGrid.putref_CellPicture =OleCreatePictureDisp(hBmp,%PICTYPE_ICON,%TRUE,@p)
                     
                     
10
ActiveX Hosting / Re: Microsoft Flex Grid Control
« Last post by José Roca on October 10, 2020, 08:12:37 PM »
The following function, included in the Ole2Utils.inc file of my headers, creates an IPictureDisp object:

Code: [Select]
' ========================================================================================
' Creates a standard IPictureDisp object.
' ========================================================================================
FUNCTION OleCreatePictureDisp ( _
   BYVAL hPicHandle AS DWORD, _               ' __in  Handle of the icon or bitmap
   BYVAL picType AS DWORD, _                  ' __in  Picture type: %PICTYPE_BITMAP or %PICTYPE_ICON
   BYVAL fOwn AS INTEGER, _                   ' __in  %TRUE or %FALSE
   BYREF pPicture AS IDispatch _              ' __out The picture object
   ) AS LONG                                  ' HRESULT

   LOCAL tpd AS PICTDESC
   LOCAL riid AS GUID

   riid = $IID_IDispatch
   IF hPicHandle = 0 THEN FUNCTION = %E_POINTER : EXIT FUNCTION

   SELECT CASE picType
      CASE %PICTYPE_BITMAP        ' Bitmap
         tpd.hbitmap = hPicHandle
      CASE %PICTYPE_ICON          ' Icon
         tpd.hicon = hPicHandle
      CASE ELSE
         FUNCTION = %E_INVALIDARG
         EXIT FUNCTION
   END SELECT

   tpd.cbSizeOfStruct = SIZEOF(PICTDESC)
   tpd.picType = picType
   IF fOwn THEN fOwn = -1
   FUNCTION = OleCreatePictureIndirect(tpd, riid, fOwn, pPicture)

END FUNCTION
' ========================================================================================
Pages: 1 2 3 4 5 6 7 8 9 10