Added:
- Native unicode support
- Added subsystems support
- Unlimited length strings in both ascii and unicode mode
- Thread safe commandset and strings
- Character type added (.c)
- Double type added (.d)
- Quad type added (.q)
- Added 'XOr' and 'Not' logicals operators
- Fixed string type added (String${#Number})
- Macro/EndMacro - single and complex mode
- With/EndWith for cleaner code
- Added assign possibility to Static (quite important), Protected and Global: "Global a = 5"
- It's now possible to create a linkedlist of pointer
- Support for Global, Protected, Static and Shared arrays and linkedlist: "Global NewList MyList.l()". NewList alone does not make the list global anymore
- Added #PB_Compiler_File, #PB_Compiler_Line, #PB_Compiler_Version, #PB_Compiler_Home,
#PB_Compiler_Debugger, #PB_Compiler_ThreadSafe, #PB_Compiler_Unicode
- Added CompilerError "Message" directive
- Added @Procedure() and ?Label support in Data.l directive
- Added optional parameters for procedures, interfaces methods, and prototypes
- Added /CONSTANT Test=Value switch to declare constants on the compiler line
- Added Swap keyword to quickly swap 2 variables or elements (Swap a,b).
- Compiles only really used Procedures
- Added multiple 'Case' for Select/EndSelect: Case 1, 2, 6 To 20
- Added 'Prototype' keyword to declare functions pointers easily
- Added 'ProcedureC' keyword to declare cdecl procedure easily
- Procedure parameters can now have the same name than a global variable (automatically protected)
- Added EnableExplicit/DisableExplicit: variables must be declared with Define, Global, Protected, Shared or Static.
- Added Defined(Name, Type) compiler function. Type can be #PB_Constant, #PB_Variable, #PB_Array, #PB_LinkedList, #PB_Structure, #PB_Interface
- Added ReDim for single and multi-dimensionned arrays
- Added Import/ImportC/EndImport to import functions and variables from external .lib
- LinkedList and Arrays can now be passed as procedure parameters
- Added /LINKER flags to provide a command file directly to the linker
- Added PseudoTypes: p-ascii, p-unicode and p-bstr to use with 'Prototype' and 'Interface'
- Assembler and Linker errors for CLI compiler are now directly displayed
- Added NT4 subsystem for multimedia applications (DirectX 3)
- Added OpenGL subsystem for multimedia applications (can be combined with NT4 one)
- Added full alphachannel support for Sprite3D library (trough PNG and TIFF)
- Added Subsystem() compiler directive to check if a subsystem is in use
- Resident files now supports quad, double, macros and prototypes
- Added exponent form for constant float: 123.5e-20
- Added: local variables aliases are generated when using '!' raw assembly to ease their referencing (in form p.v_variable)
- Added: 'Step over' and 'Step out' features to the debugger
Optimized:
- Smaller executable footprint: 1,5 kb instead of 2,5 kb for the smallest one
- Faster float and litteral numeric mixing
- File library completely rewritten and now handle a read/write cache for very fast performances. Also support for 64 bits files.
- Procedures are now as small as possible, which should give some speed increase
Changed:
- Console library commands can now fully redirected (ie: possible to use them for CGI for example)
- When a numeric parameter is expected, it's not possible to pass a string anymore
- Temporary purebasic.exe name aren't random anymore, because it could cause slowdown with some firewalls
- 'DefType' renamed to 'Define'
- Update the OGRE engine to 1.0.6 version
Fixed:
- Internal system functions no more trash reserved registers
- Mouse is automatically released in windowed mode when the window loose focus
- KeyboardInkey() now handle shift/alt modifiers correctly
- IsScreenActive() works correctly for windowed mode as well
Library Changes
Default Parameters
Procedure a(a, b, c=2)
Debug c
EndProcedure
a(10, 12) ; or
a(10, 12, 15)
top
Macro Examples
Macro InStr
FindString
EndMacro
Debug InStr("test","s",1) ; Returns 3
Macro Assert(Expression)
If (Expression)
Debug "#True : " + "Expression"
Else
Debug "#False : " + "Expression"
EndIf
EndMacro
x = 5
Assert(x = 5)
Assert(x < 2)
Assert(x = 10)
Assert(x > 2)
Macro AnotherMacro
UCase
EndMacro
Macro NewWorld(a=1, b=2, c="Test")
a#b#er("FAST", AnotherMacro(c))
EndMacro
NewWorld(Message,Request)
; The '#' puts together the 2 parts in one word. So a#b#er becomes MessageRequester when you pass
; Message for a and Request for b.
; The assigning of the values to a and b is only to demonstrate
; the ability for optional parameters. It does not make sense in this example really, as
; NewWorld() would become:
12er("FAST", UCase("Haha"))
top
With / EndWidth
Point.POINT
With Point
\x = 1
\y = 2
EndWith
; same as
;
; Point\x = 1
; Point\x = 2
Debug Point\x
Debug Point\y
top
Import / EndImport
Import "Kernel32.lib"
MessageB(a,b$,c$,d) As "_MessageBoxA@16"
EndImport
MessageB(0,"Body","Test",0)
top
Labels/address in datasection
Interface MyObject
DoThis()
DoThat()
EndInterface
Procedure This(*Self)
MessageRequester("MyObject", "This")
EndProcedure
Procedure That(*Self)
MessageRequester("MyObject", "That")
EndProcedure
m.MyObject = ?VTable
m\DoThis()
m\DoThat()
DataSection
VTable:
Data.l ?Procedures
Procedures:
Data.l @This(), @That()
EndDataSection
top
Prototypes
Until now, you called a functionpointer through CallFunctionFast (for Dll, callback etc.)
The problem here is that CallFunctionFast() accepts any type and any number of parameters,
so you won't notice any error you made calling the function (ie forget a parameter, ...)
It is also problematic when it comes to return types. (ever tried to get a float from CallFunctionFast ?)
Prototypes solve all these problems. What you do is you define what a function
looks like (parameter type & count, return type)
This creates basically a new type, like a structure. Now when you declare a
variable of this type, what you actually do is just declare a pointer variable. You
can assign it any value you want.
The thing now is that if you call the function through this pointer, you do not do CallFunctionFast, but just
write "MyPointer(params...)" and this calls the function.
Now the compiler checks if your arguments are of the right type, and warns
of any errors.
Prototypes have even more advantages:
- functions are directly called, no overhead like with CallFunctionFast
- you can define default parameters (see example above) even for external functions.
- probably more, but i forgot
; Example:
Prototype.f ReturnFloatType()
Prototype.d ReturnDoubleType(Value.d, DefaultMultiply.d = 2)
Procedure.f ReturnFloat()
ProcedureReturn 12.34
EndProcedure
Procedure.d ReturnDouble(Double.d, DefaultMultiply.d)
ProcedureReturn Double*DefaultMultiply
EndProcedure
GetFloat.ReturnFloatType = @ReturnFloat()
GetTwiceDouble.ReturnDoubleType = @ReturnDouble()
Debug GetFloat()
Debug GetTwiceDouble(10.0)
top
Swap Statement
; SWAP
a = 10
b = 20
Swap a, b
Debug a
Debug b
top
Explicit
; Explicit
;
EnableExplicit
Define.l a
a = 5
; Even if the type is postfixed, it won't work with explicit. You have to declare
; the variables with Define, Global, Protected or Static.
;
; b.l = 0
top
Defined
; Defined() is a compiletime function (similar to #ifdef in C), that can be used
; in CompilerIf statements for example.
; Code:
#hello = 1
CompilerIf Defined(Hello, #PB_Constant) = 0
#hello = 5
CompilerEndIf
OpenConsole()
PrintN(Str(#hello))
Input()
End
Comment the first line, and it will print 5. This is very usefull together with the
/CONSTANT commandline switch. This way you can assign a default value
to a constant if it is not defined otherwise.
Also helps to only declare a structure if it was not allready declared at another place. (usefull for many included files)
Or lets say you have an IncludeFile that is reused in many projects, but it
contains some Global values that may not conflict with any others.
Now you can put this in the includefile:
Code:
CompilerIf Defined(ImportantGlobal, #PB_Variable)
CompilerError "Global Variable allready declared! (do not reuse this variable name!)"
CompilerEndIf
Global ImportantGlobal
If you have used the variable "ImportantGlobal" before including this file, you get the error message.
top
SubSystems
In fact you can create any directories in the subsystem dir which will contain one or many
pb libraries which maps the official libraries. When using the /SUBSYSTEM "yourpackage" flag,
it will first load all libs/residents found in the subsystem and then load the remaining libs
in the regular purelibraries\ drawer. For example we can imagine an 'OpenGL' subsystem which
redo all the sprite/sprite3D libs using opengl instead of DirectX (an using exactly the same
command syntax than the regular libs, of course).
top
Xor and Not Operands
a = 1
b = 0
If a = 1 XOr b = 1
Debug "Ok"
EndIf
If Not b
Debug "Ok"
EndIf
If a = 1 And Not b
Debug "Ok"
EndIf
If a = 1 And Not (b=1 or b=3)
Debug "Ok"
EndIf
top
Linkedlist and Array parameters
; Linkedlist and Array parameters
;
; List
;
NewList Test.Point()
AddElement(Test())
Test()\x = 1
AddElement(Test())
Test()\x = 2
Procedure DebugList(c.l, List.Point())
AddElement(List())
List()\x = 3
ForEach List()
MessageRequester("List", Str(List()\x))
Next
EndProcedure
DebugList(10, Test())
; Array
;
;
Dim Array.Point(10, 15)
Array(0,0)\x = 1
Array(1,0)\x = 2
Procedure TestIt(c.l, ParameterArray.Point(2))
ParameterArray(1, 2)\x = 3
ParameterArray(2, 2)\x = 4
EndProcedure
TestIt(10, array())
MessageRequester("Array", Str(array(1, 2)\x))
top
Multi case select
; Multi case select
;
a = 19
Select a
Case 1, 2, 3
Case 5, 7 To 20, 25
Debug "Exactly !"
Default
EndSelect
top
Pseudo types
Ok, here is a situation. Lets say you have a dll that supports a basic type
that PB cannot handle. (like the windows BSTR type), but you want to access
this function. Before now, you had to manually convert the PB type to the
external type and in some cases even use asm to get it on the stack (if the
types size was different from PB's one, like doubles before now).
All in all, no nice thing to do.
Now you can define the Prototype (here they are again) or Interface using such
a pseudo type. This means, that when you call a function through the prototype,
PB will automatically convert the PB type to the external one and then call the
function.
The difference to a normal type is that this ONLY works here. PB cannot handle
this type in other situations. It is only to access external stuff.
Another important use is that if you are in unicode mode, all PB strings are unicode,
you have no ascii strings available. To still access a dll that is not a unicode
one, you can use the "p-ascii" type, and voila, it will work.
The three pseudo types availables are:
* p-ascii: force the parameter to 8 bit ascii (ie: useful in unicode program)
* p-unicode: force the parameter to 16 bits unicode (ie: useful in ascii programs)
* p-bstr: convert the string parameter in a BSTR automatically.
; Example:
;
; The following code will work in both ascii and unicode mode
Prototype MessageBoxFunction(ParentWindow, Body.p-ascii, Title.p-ascii, Flags = #MB_ICONINFORMATION)
OpenLibrary(0, "user32.dll")
mb.MessageBoxFunction = GetFunction(0, "MessageBoxA")
mb(0, "Hello", "World")
Library: Image
removed : UseImage() - change UseImage(#Image) to ImageID(#Image) where just the ID is needed.
added : CreateImage(#Image, Width, Height [, Depth]) - New Parameter
added : LoadImage(#Image, FileName$ [, Flags]) - New Parameter
added : CatchImage(#Image, FileName$ [, Length [, Flags]]) - New Parameters
changed : ImageDepth(#Image) - new parameter
changed : ImageHeight(#Image) - new parameter
changed : ImageWidth(#Image) - new parameter
changed : ImageID(#Image) - new parameter
changed : ImageOutput(#Image) - new parameter
Note: Now, the images can be of display format (#PB_Image_DisplayFormat) or custom format (2, 4, 8, 16, 24, 32)
top
Library: String
added: StrD(Number [, NbDecimals])
added: StrQ()
added: HexQ()
added: BinQ()
added: StrU(): added a #PB_Quad flag
added: ValD(), ValQ()
top
Library: Thread
added : IsThread(Thread) - test if thread (still) exists.
added : CreateMutex() - create a mutex onject
added : FreeMutex(Mutex) - destroy the object
added : LockMutex(Mutex) - wait until mutex is available and lock it
added : TryLockMutex(Mutex) - lock mutex if available, otherwise return 0 immediately
added : UnlockMutex(Mutex) - unlock the mutex so other threads can lock it
The main objective of the mutex commands is thread syncronisation. They do not create
too much overhead, but they only work within one program, not system-wide.
A mutex is an object wich can only be "owned" or locked by one thread at a time,
so it is used to protect shared resources. Only the thread that has the mutex
locked may access a certain file, memory area, ...
Like this you can ensure that a shared object is never accessed from 2 threads at once.
The LockMutex() command aquires "ownership" of the mutex object.
It does that by waiting until any other thread that had a lock on the mutex has
unlocked it, and then locking the object.
So this command will halt thread execution until the mutex is available.
NOTE: If you forget to unlock a mutex and another thread tries to lock it,
it will wait forever.
About threadsafety:
First of all, all local variables in a thread are save to use. (strings only if
you compile with /THREADSAVE). Also local linkedlists and arrays are no problem.
For global stuff, the rule is that access to the numeric types is atomic, this
means if thread A does "a = 512" and thread B does "a = 123" at the exact
same time, one is actually fully completed before the other is executed.
(the reason is that threads never switch between the simple asm instructions
like mov, add, push, pop, ...)
So you will end up with either 512 or 123 (depending of what came last), but
there will never be any mixup or something.
Basically everything that gets more complex than this (and is done on global
things should be protected by a mutex.)
This also applies to global string variables. It would be too time consuming for
PB to make this save on each global string manipulation, so you have to make
sure of this yourself.
Also Arrays, Linkedlists are complex structures and should only be accessed
by one thread at any time.
Other PB objects: Images, Gadgets, ...
Basically the rule here is that multiple threads can read stuff from these
at once without problem (for example GetGadgetText...). However, as
soon as one thread is changing something on the object (ResizeImage, drawing on the image, ...)
all access that could occour on the same time (even reading) should be
protected by a mutex, as you could get strange results else.
top
Library: Process (NEW)
added : GetEnvironmentVariable(Name$) - get value of an en var
added : SetEnvironmentVariable(Name$, Value$) - set the value
added : RemoveEnvironmentVariable(Name$) - delete environment variaböe
added : ExamineEnvironmentVariables() - examine the currently set env variables
added : NextEnvironmentVariable() - get the next variable
added : EnvironmentVariableName() - get the variable name
added : EnvironmentVariableValue() - get the variable value
added : ProgramName() - get full path to executable
added : CountProgramParameters() - get parameters count
changed : ProgramParameter([Index]) - get next (or at position index) parameter
changed : RunProgram() with new Flags:
#PB_Program_Open - open the program communicate/get information
#PB_Program_Read - allow to read the programs output (STDOUT)
#PB_Program_Write - allow to write to the programs input (STDIN)
#PB_Program_Error - allow to catch messages on standard error (STDERR)
#PB_Program_Connect - connect another program's output to this program's input
added : IsProgram(Program) - check if Program is a valid program created with RunProgram
added : ProgramID(Program) - get the ProcessID of the program
added : ProgramRunning(Program) - returns 1 if the program is still running
added : WaitProgram(Program [, Timeout]) - waits for the program to quit (with optional timeout) returns 1 if the program has ended
added : KillProgram(Program) - forcibly terminates the program
added : ProgramExitCode(Program) - get the exitcode of the program (only valid after program has ended)
added : CloseProgram(Program) - close the interaction with the program
added : AvailableProgramOutput(Program) - returns the number of bytes available for reading
added : ReadProgramString(Program) - read a string from the program output
added : ReadProgramData(Program, *Buffer, size) - read data from the output
added : ReadProgramError(Program) - read a message from STDERR
added : WriteProgramString(Program, String$) - write to the programs input (string)
added : WriteProgramData(Program, *Buffer, size)- write datat to the programs input
The Process Lib allows you to execute an communicate with child processes. You can send input to a program or
catch its output, read its exitcode and pass values to it through environment variables (must be set up before the child
process is started.)
If you with to receive any data from a program (such as exitcode, or send/receive data), you must run it with
the #PB_Program_Open flag. In this case you must also close the "program object" with CloseProgram().
NOTE that CloseProgram() does not kill the child program. It only closes the PB program object. Use KillProgram to
terminate a program started with RunProgram().
If a PB Program uses the Console Print()/PrintN() without the graphical console mode, then you can catch
this output with #PB_Program_Read and ReadProgramString(). (same for writing to the program and it reading with Input())
Examples:
----------------------------------------------------------------------------------------
; runs the PB compiler and reads its help messages
;
Program = RunProgram("pbcompiler", "/?", "", #PB_Program_Open|#PB_Program_Read)
Text$ = ""
While ProgramRunning(Program)
Text$ + ReadProgramString(Program)
Wend
CloseProgram(Program)
MessageRequester("",Text$)
----------------------------------------------------------------------------------------
; More comples redirection of program data
;
; the windows grep port from UnixUtils:
Grep$ = "C:\Program Files\UnxUtils\usr\local\wbin\grep.exe"
; the #PB_Program_Open tells that you want to get information from the
; program (like track if it runs, read/write to it, or get the exitcode)
; in this case you must use CloseProgram() to tell that you are done with it.
;
Compiler = RunProgram("pbcompiler.exe", "/?", "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide)
; the #PB_Program_Connect tells the command to connect the output of another program
; (the other one must be started with _Open and _Read flag!) to the input of this program.
; We use the _Read flag here too, as we want to get the final output
;
Grep = RunProgram(Grep$, "FileName", "", #PB_Program_Open|#PB_Program_Read|#PB_Program_Connect|#PB_Program_Hide, Compiler)
If Compiler And Grep
Text$ = ""
While ProgramRunning(Grep)
Text$ + ReadProgramString(Grep) ; note: this call locks until data is available. use AvaliableProgramOutput() to avoid it
Wend
MessageRequester("Filtered by grep", Text$)
; note: CloseProgram() does not kill the process, it only closes PB's conection to it,
; use KillProgram() to kill it.
;
CloseProgram(Compiler)
CloseProgram(Grep)
Else
MessageRequester("","Error")
EndIf
End
----------------------------------------------------------------------------------------
top
Library: File
added: FileBuffersSize(#File, Size) - Change the size of the buffers for the specified file.
added: FileID(#File) - Returns the unique ID which identifies the file in the operating system.
added: FlushFileBuffers(#File) - Ensure than all buffered operations are written to disk.
removed : UseFile() - change UseFile(#File) to FileID(#File) where just the ID is needed.
changed: FileSeek(#File, NewPosition) - new parameter
changed: WriteData(#File) - new parameter
changed: ReadData(#File) - new parameter
changed: Lof(#File) - new parameter
changed: Loc(#File) - new parameter
changed: ReadByte(#File) - new parameter
changed: ReadWord(#File) - new parameter
changed: ReadLong(#File) - new parameter
changed: ReadFloat(#File) - new parameter
changed: ReadString(#File [,Format]) - new parameter
changed: ReadData(#File) - new parameter
changed: WriteByte(#File, Data) - new parameter
changed: WriteWord(#File, Data) - new parameter
changed: WriteLong(#File, Data) - new parameter
changed: WriteFloat(#File, Data) - new parameter
changed: WriteString(#File, Data [,Format]) - new parameter
changed: WriteStringN(#File, Data [,Format]) - new parameter
changed: WriteData(#File, Data, Length) - new parameter
added : ReadChar(#File)
added : ReadQuad(#File)
added : ReadDouble(#File)
added : WriteChar(#File, Value)
added : WriteQuad(#File, Value)
added : WriteDouble(#File, Value)
Same as for the Memory string commands, you can specify the format in which ReadString/WriteString work
with a flag: #PB_Ascii, #PB_Unicode or #PB_UTF8.
Note that when compiling with the unicode flag, the default for read/writestring is UTF8, not unicode.
top
Library: 2DDrawing
added : DrawAlphaImage()
added : TextHeight(Text$) - returns the height required for the string with the current drawing font/output
added : FillArea(x, y, BorderColor [, Color]) - if BorderColor = -1, it fills the area with the same color as on (x,y)
changed : FrontColor(Color) - joined the red, green, blue to only one color value. (add RGB() for a quick adjustion of old code)
changed : BackColor(Color) - joined the red, green, blue to only one color value.
changed : NewX = DrawText(x, y, Text$ [, FrontColor [, BackColor]]) - added x/y coordinates and optional color values
changed : TextLength(Text$) -> TextWidth(Text$) - renamed
removed : Locate(x, y) - no longer usefull.
top
Library: Palette
removed: UsePalette()
changed : GetPaletteColor(#Palette, Index) - new Parameter
changed : SetPaletteColor(#Palette, Index, Color) - new Parameter
top
Library: Module
changed : SetModulePosition(#Module, Position) - new Parameter
changed : GetModulePosition(#Module) - new Parameter
changed : GetModuleRow(#Module) - new Parameter
changed : StopModule(#Module) - new Parameter and -1 = stop all the modules
top
Library: Database
removed: UseDatabase()
changed : FirstDatabaseRow(#Database) - new Parameter
changed : PreviousDatabaseRow(#Database) - new Parameter
changed : NextDatabaseRow(#Database) - new Parameter
changed : GetDatabaseLong(#Database) - new Parameter
changed : GetDatabaseFloat(#Database) - new Parameter
changed : GetDatabaseString(#Database) - new Parameter
changed : DatabaseUpdate(#Database, Query$) - new Parameter
changed : DatabaseQuery(#Database, Query$) - new Parameter
changed : DatabaseColumnType(#Database, Column) - new Parameter
changed : DatabaseColumns(#Database) - new Parameter
changed : DatabaseColumnName(#Database, Column) - new Parameter
top
Library: Movie
removed: UseMovie()
changed : MovieAudio(#Movie) - new Parameter
changed : MovieHeight(#Movie) - new Parameter
changed : MovieWidth(#Movie) - new Parameter
changed : MovieInfo(#Movie) - new Parameter
changed : MovieLength(#Movie) - new Parameter
changed : RenderMovieFrame(#Movie) - new Parameter
changed : ResizeMovie(#Movie, x, y, Width, Height) - new Parameter
changed : ResumeMovie(#Movie) - new Parameter
changed : PauseMovie(#Movie) - new Parameter
changed : StopMovie(#Movie) - new Parameter
changed : MovieSeek(#Movie, Position) - new Parameter
changed : MovieStatus(#Movie) - new Parameter
top
Library: FileSystem
removed: UseDirectory()
added: FinishDirectory(#Directory)
added: DirectoryEntryType(#Directory)
added: DirectoryEntryDate(#Directory, DateType) - #PB_Date_Created, #PB_Date_Accessed, #PB_Date_Modified
added: GetFileDate(Filename$, DataType)
added: SetFileDate(Filename$, DataType)
changed : NextDirectoryEntry(#Directory) - new Parameter
changed : DirectoryEntryName(#Directory) - new Parameter
changed : DirectoryEntryAttributes(#Directory) - new Parameter
changed : DirectoryEntrySize(#Directory) - new Parameter
changed : IsFilename() to CheckFilename() - function name changed
Important Change:
NextDirectoryEntry() now no longer returns the type of entry (file/type). To be consistent
with other Examine...()/Next...() functions in PB, it now only returns 0 or 1 (0 means no more objects)
Use DirectoryEntryType() to find out the type of entry like you did before with the result of NextDirectoryEntry().
top
Library: Menu
added: GetMenuItemText(#Menu, ItemID)
added: GetMenuTitleText(#Menu, ItemID)
added: SetMenuItemText(#Menu, ItemID, Text$)
added: SetMenuTitleText(#Menu, ItemID, Text$)
changed : DisableMenuItem(#Menu, ItemID, State) - new Parameter
changed : MenuID(#Menu) - new Parameter
top
Library: Console
added: EnableGraphicalConsole(State)
added: RawKey()
added: Redirection and standard output support
changed : Inkey() - now returns only 1 char or nothing (instead of always 2), use RawKey() for the extra character
The old console lib used a graphical console mode, which did not output to stdout correctly.
(you could not call it from commandline like: myprogram.exe > test.txt)
Now you have the choise with EnableGraphicalConsole(State), and if you do
not explicitly set the graphical mode, the printed stuff should be properly sent to stdout, enabling
you to write better console tools. This also applies to stdin and the Input() command.
top
Library: AudioCD
changed: all function name from 'CDAudio' to 'AudioCD' (less french-english..)
top
Library: Toolbar
added: ToolBarHeight(#ToolBar)
added: ToolBarID(#ToolBar)
changed: ToolBarTooltip(#ToolBar, Button, Text$) - New parameter
changed: DisableToolBarButton(#ToolBar, Button, State) - New parameter
top
Library: Statusbar
added: StatusBarHeight(#StatusBar)
added: StatusBarID(#StatusBar)
top
Library: Font
removed: UseFont()
changed: FontID(#Font) - New parameter
changed: CloseFont() to FreeFont()
top
Library: Preferences
added : ability to add/change/delete keys to existing prefs files.
added : RemovePreferenceKey(Name$)
added : RemovePreferenceGroup(Name$)
added : ExaminePreferenceGroups() - get all the group names in the file
added : NextPreferenceGroup() - go to the next group name. (the group will be set as the current one)
added : PreferenceGroupName() - get the goup name.
added : ExaminePreferenceKeys() - get all key names in the current group
added : NextPreferenceKey() - go to the next key.
added : PreferenceKeyName() - get key name
added : ReadPreferenceQuad(Key$, Default)
added : ReadPreferenceDouble(Key$, Default)
added : WritePreferenceQuad(Key$, Value)
added : WritePreferenceDouble(Key$, Value)
Changes to PreferenceGroup() and non-existing groups:
In 3.94, the preference stuff was write only after CreatePreferences(),
and creating a new group with PreferenceGroup() had no reason to fail,
so it always returned 1.
Now, everything is read & write, so PreferenceGroup() has two functions (select an existing group or create a new one)
This is kind of a problem, as if you call PreferenceGroup() with a non-existing group,
did you try to look up a group and just did not find it, or want to create a new one ?
To solve this, PreferenceGroup() now returns 1 if the Group allready existed, and 0 otherwise.
If you use PreferenceGroup() on an existing Group, it selects this group and
every read & write call is performed on this group.
If you use PreferenceGroup() on a non-existing Group, it actually does nothing.
Following read calls will always return the default value (like it was in 3.94 too)
Only if you write a value to this group, it is actually created.
This way you can use PreferenceGroup() both to look up a group, and create new ones.
top
Library: Sprite
added : SpriteID(#Sprite)
added : FlipBuffer() - added a flag, to have a CPU optimized synchro in fullscreen mode
renamed: DisplayTranslucideSprite() to DisplayTranslucentSprite()
changed : TransparentSpriteColor(#Sprite, R, G, B) to TransparentSpriteColor(#Sprite, Color)
changed : ClearScreen(R, G, B) to ClearScreen(Color)
top
Library: Library
renamed : IsFunction() -> GetFunction()
top
Library: Network
added: GetClientIP()
added: GetClientPort()
added: EventServerNumber()
added: UDP support trough the flags #PB_Network_UDP and #PB_Network_TCP
renamed: NetworkClientID() -> EventClientNumber()
top
Library: Keyboard
added: #PB_Keyboard_International and #PB_Keyboard_AllowSystemKeys flags to KeyboardMode()
top
Library: Clipboard
changed: GetClipboardData(Type) to GetClipboardImage(#Image)
changed: SetClipboardData(Type, Data) to SetClipboardImage(#Image)
top
Library: Memory
added: Unicode conversion support to PeekS() and PokeS() between ascii, UTF8 and UTF16
added: PeekC(), PeekD(), PeekQ()
added: PokeC(), PokeD(), PokeQ()
added: MemorySize() - return size of a memory block
added: MoveMemory()
added: CompareMemoryString(*Text1, *Test2 [Mode [, MaxLength [, Flags]]]) - New flags parameter for UTF16/UTF8/Ascii compare
added: MemoryStringLength() - New flags parameter for UTF16/UTF8/Ascii support
The PeekS, PokeS, CompareMemoryString, MemoryStringLength now have a parameter that specifies the string format.
Possible options are: #PB_Ascii, #PB_Unicode or #PB_UTF8. This allows you do work with strings in memory
independant of the actual String mode the executable was compiled with (unicode or not).
top
Library: Engine3D
changed: CreateMesh(#Mesh,MaximumVertex) - new parameter
changed: MaterialAmbientColor(#Matrix1,-1) - -1 new parameter
added: EntityRenderMode()
added: WorldShadows(#PB_Shadow_Additive)
added: ParticleEmitterDirection()
added: GetEntityMass
added: SetEntityMass
added: GetEntityFriction
added: SetEntityFriction
added: EntityPhysicBody
added: ExamineWorldCollisions
added: NextWorldCollision
added: CheckWorldCollisionEntity
added: FirstWorldCollisionEntity
added: SecondWorldCollisionEntity
added: WorldGravity
added: EnableWorldCollision
added: EnableWorldPhysics
added: Parse3DScripts()
removed: RotateParticleEmitter() (was useless for now)
top
Library: Window
changed: WaitWindowEvent([Timeout]) - added optional timeout value
changed: ResizeWindow(#Window, x, y, width, height) - '-1' parameters must be changed to #PB_Ignore
changed: SetWindowCallback(@Procesure() [, #Window]) - added optional window parameter (to set callback for 1 window only)
changed: EventWindowID() is now EventWindow()
changed: EventGadgetID() is now EventGadget()
changed: EventMenuID() is now EventMenu()
changed: ResizeWindow(#Window, x, y, Width, Height) - now same as ResizeGadget()
removed: MoveWindow()
removed: DetachMenu()
removed: UseWindow()
changed: WindowID(#Window) - parameter no longer optional
changed: WindowHeight(#Window) - new parameter
changed: WindowWidth(#Window) - new parameter
changed: WindowX(#Window) - new parameter
changed: WindowY(#Window) - new parameter
changed: WindowMouseX(#Window) - new parameter
changed: WindowMouseY(#Window) - new parameter
changed: WindowOutput(#Window) - new parameter
changed: SetActiveWindow(#Window) - renamed ActivateWindow() and added parameter
added : GetActiveWindow() - returns the Window with the focus
added : DisableWindow(#Window, State) - disable user input to a window
added : GetWindowState(#Window) - get minimized/maximized state
added : SetWindowState(#Window, State)- set minimized/maximized state
added : StickyWindow(#Window, State) - make the window stay on top of all others even if disabled
added : SetWindowColor(#Window, Color)- set background color of the window
added : GetWindowColor(#Window) - get the current background color of the window
added : SmartWindowRefresh(#Window, State) - enable or disable the smart refresh feature
for Get/SetWindowState():
#PB_Window_Normal
#PB_Window_Maximize (also usable in OpenWindow())
#PB_Window_Minimize (also usable in OpenWindow())
Constants:
removed compatibility constants like #PB_EventCloseWindow (use the documented #PB_Event_CloseWindow instead)
top
Library: Gadget
changed: ActivateGadget(#Gadget) is now SetActiveGadget(#Gadget)
changed: ResizeGadget(#Gadget, x, y, width, height), -1 should now be changed to #PB_Ignore
added : GetActiveGadget() - returns the currently active Gadget
added : GadgetType(#Gadget) - returns a constant that identifies what kind of Gadget this is
added : SetGadgetData(#Gadget, Value) - associate a value with the Gadget (works for all Gadgets.)
added : GetGadgetData(#Gadget) - read the associated value
added : SetGadgetItemData(#Gadget, Item, Value) - associate value with gadget item (works for specific gadgets only)
added : GetGadgetItemData(#Gadget, Item)
added : SetGadgetColor(#Gadget, ColorType, Color)
added : GetGadgetColor(#Gadget, ColorType)
added : SetGadgetItemColor(#Gadget, Item, ColorType, color [, Column])
added : GetGadgetItemColor(#Gadget, Item, ColorType [, Column])
NOTE: Coloring functions work only for specific Gadget.. see below.
ColorType options:
#PB_Gadget_FrontColor
#PB_Gadget_BackColor
#PB_Gadget_LineColor
removed: #PB_String_MultiLine
Individual Gadget changes:
--------------------------
StringGadget:
- supports SetGadgetColor() for front and backcolor
TextGadget:
- Supports SetGadgetColor() for front and backcolor
ListViewGadget:
- Supports SetGadgetColor() for front and backcolor (not for individual items)
- Supprots SetGadgetItemData()
- new Flags:
#PB_ListView_Multiselect - allow multi selection
#PB_ListView_ClickSelect - multiselect + clicking and item selects/deselects it
ComboBoxGadget()
- Supports SetGadgetItemData()
ListIconGadget()
- Supports SetGadgetColor() for front and backcolor and #PB_Gadget_LineColor (for #PB_ListIcon_GridLines)
- Supports SetGadgetItemColor() for front and backcolor (can be set for each cell individually)
- Supports SetGadgetItemData()
- The event to detected a checkbox change is now #PB_EventType_Change
- Supports GetGadgetItemAttribute(#Gadget, 0, #PB_ListIcon_ColumnWidth, 2) ; return width of column 2
- Supports SetGadgetItemAttribute(#Gadget, 0, #PB_ListIcon_ColumnWidth, 100, 2) ; set width of column 2 to 100
- Supports GetGadgetItemText(#Gadget, -1, 2) ; return header text for column 2
- Supports SetGadgetItemText(#Gadget, -1, "New Text", 2) ; change header text for column 2
HyperLinkGadget()
- Supports SetGadgetColor() for frontcolor (background is always transparent)
- new Flag: #PB_Hyperlink_Underline - draw a line under the text (without the need for an underlined font)
ContainerGadget()
- supports SetGadgetColor() for backcolor
ProgressBarGadget()
- supports SetGadgetColor() for front & backcolor (not working with XP skins)
- supports SetGadgetAttribute() with #PB_ProgressBar_Minimum, #PB_ProgressBar_Maximum
ScrollBarGadget()
- Supports SetGadgetAttribute() with #PB_ScrollBar_Minimum, #PB_ScrollBar_Maximum, #PB_ScrollBar_PageLength
ScrollAreaGadget()
- supports SetGadgetColor() for backcolor
- new Flag: #PB_ScrollArea_Center - when the inner size is smaller than the outer, the inner area will be centered automatically
- new options for SetGadgetAttribute() #PB_ScrollArea_X/#PB_ScrollArea_Y to read/set the current scroll pos.
- now generates an event when being scrolled
CalendarGadget()
- supports SetGadgetColor() with the following
#PB_Gadget_BackColor - background
#PB_Gadget_FrontColor - text to display days
#PB_Gadget_TitleBackColor - background of month title
#PB_Gadget_TitleFrontColor - text color of month title
#PB_Gadget_GreyTextColor - color for days not of the current month
DateGadget()
- supports SetGadgetColor() with the same values as CalendarGadget to color the drop-down calendar
- the input area can not be colored at this time
EditorGadget()
- supports SetGadgetColor for front & backcolor
- new Flag: #PB_Editor_ReadOnly
- supports SetGadgetrAttribute() with #PB_Editor_ReadOnly to get/set the readonly flag
TrackBarGadget()
- supports SetGadgetAttribute() with #PB_TrackBar_Minimum, #PB_TrackBar_Maximum
SpinGadget()
- supports SetGadgetColor for front & backcolor (to color the edit area)
- supports SetGadgetAttribute() with #PB_Spin_Minimum, #PB_Spin_Maximum
- New Flags:
#PB_Spin_ReadOnly - The StringGadget is not editable, the number is only changeable by the arrows
#PB_Spin_Numeric - The SpinGadget will automatically update the text with value of the state, so SetGadgetText is not needed.
- EventType values:
1 - the up button was pressed
-1 - the down button was pressed
#PB_EventType_Change - the text in the edit box was changed
TreeGadget()
- Supports SetGadgetColor() for front & backcolor & #PB_Gadget_LineColor
- Supports SetGadgetItemColor() for front & backcolor
- changed management of items completly. There are no longer any nodes,
just a continuous list where each item has a "sublevel". The sublevels
of all items define the tree structure like this:
+ sublevel 0
+-+ sublevel 1
| | sublevel 1
| +-+ sublevel 2
| | sublevel 1
| sublevel 0
- new parameter to AddGadgetItem: AddGadgetItem(#Gadget, Position, Text$ [, ImageID [, Flags]])
The "Flags" parameter is always required for TReeGadget and specifies the
Sublevel in which to put this item.
To create the above three, you do this:
AddGadgetItem(#TreeGadget, -1, "sublevel 0", 0, 0)
AddGadgetItem(#TreeGadget, -1, "sublevel 1", 0, 1)
AddGadgetItem(#TreeGadget, -1, "sublevel 1", 0, 1)
AddGadgetItem(#TreeGadget, -1, "sublevel 2", 0, 2)
AddGadgetItem(#TreeGadget, -1, "sublevel 1", 0, 1)
AddGadgetItem(#TreeGadget, -1, "sublevel 0", 0, 0)
- new GetGadgetItemAttribute() with #PB_Tree_SubLevel (readonly) to get the sublevel of any item
- removed: OpenTreeGadgetNode()
- removed: CloseTreeGadgetNode()
- removed: TreeGadgetItemNumber() - can be easily emulated by GadgetItemID()+a run trough the item list
- removed: CountTreeGadgetNodeItems() - can be easily emulated by comparing the sublevel of the items
PanelGadget()
- added GetGadgetAttribute() with #PB_Panel_ItemWidth, #PB_Panel_ItemHeight (readonly)
(there must be at least 1 tab in the panel for this to work)
SplitterGadget()
- new flags for Get/SetGadgetAttribute(): #PB_Splitter_FirstGadget, #PB_Splitter_SecondGadget
With GetGadgetAttribute(), they return the #Gadget Number of the stored Gadget
With SetGadgetAttribute(), you can place a new Gadget in the Splitter.
NOTE: The Old Gadget will not be automatically freed! (it will be put out of the splitter and on the same window as the splitter)
So if you do not want the old gadget to remain, remove it with FreeGadget()
This allows you to switch Gadgets in a splitter without the need to re-create any of them.
NOTE: You cannot have a Gadget in 2 Splitters at once, so to move a Gadget from one splitter to another,
Replace it in the first splitter first, and then put it in the second one.
MDIGadget()
- The child windows of the MDIGadget are no longae "GadgetItems", but real PB Windows.
This means that you can use ANY command from the WindowLib with them (except StickyWindow()). This makes some of the MDIGadget
features obsolete, therefore there are some changes:
- The Gadget no longer sends any events: all close, resize, activate events are received as Window events
- GetGadgetAttribute(), Get/SetGadgetItemAttribute, Get/SetGadgetItemState(), Get/SetGadgetItemText
are all no longer supported. All this can be easily done through the Window lib commands.
- RemoveGadgetItem() no longer supported.. use CloseWindow()
The Commands useable with MDIGadget now are only these: (+ the whole windowlib!)
- ClearGadgetItemList() : closes all child windows
- CountGadgetItems() : get the number of child windows in the gadget
- GetGadgetState() : get the WindowID of the Window currently in the foreground of the gadget
- SetGadgetState() : get a specific window to the foreground or arrange the child windows (All like the old MDIGadget)
- AddGadgetItem() : create an MDI Child: works like this:
AddGadgetItem(#MDI, #Window, Title$ [, ImageID [, Flags]])
- #Window - Number for the new window (can be #PB_Any!)
- Title$ - new window title
- ImageID - Icon for the window (optional)
- Flags - Supports most of the flags for OpenWindow, if none are specified, the default MDI flags are used.
Unsupported Flags: #PB_Window_Borderless, #PB_Window_ScreenCentered, #PB_Window_WindowCentered
NOTE: you must now call CreateGadgetList() to add items to a MDI child, just like with normal windows.
New stuff:
- SetGadgetColor() can be used with #PB_Gadget_BackColor to set the MDI backcolor
- SetGadgetAttribute() can be used with #PB_MDI_Image to set a background image, #PB_MDI_TileImage can set the tile mode of the image on or off
ExplorerListGadget()
- supports SetGadgetColor() for front & backcolor & #PB_Gadget_LineColor
- Supports GetGadgetItemAttribute(#Gadget, 0, #PB_Explorer_ColumnWidth, 2) ; return width of column 2
- Supports SetGadgetItemAttribute(#Gadget, 0, #PB_Explorer_ColumnWidth, 100, 2) ; set width of column 2 to 100
- Supports GetGadgetItemText(#Gadget, -1, 2) ; return header text for column 2
- Supports SetGadgetItemText(#Gadget, -1, "New Text", 2) ; change header text for column 2
ExplorerTreeGadget()
- supports SetGadgetColor() for front & backcolor & #PB_Gadget_LineColor
top