Monthly Archives: September 2010

Turning ten !

If you take a quick look to the history page on www.purebasic.com, you will see this:

PureBasic 1.60 (AmigaOS) (09/09/2000)

9 september 2000. Seriously. So PureBasic is officially haunting the web since 10 years, which is kind of amazing, for different reasons. Let’s try to step back, catch a time machine, and see what and how it happened.

I got the chance to have a computer very young, at twelve. It was an amstrad CPC 6128, with a very low resolution but colored screen and strange disk format. My main attract was games, games and games. I spent countless hours playing many games (Barbarian anyone ?!). On a side note, in the book sold with the computer, there were some listings to type yourself a game using the build-in BASIC (an old school one, without procedure or even label, so you have to specify the line number to jump at when using GOTO or GOSUB). Out of curiousity, i tried to make it work. It was a ‘dart’ game, and it took forever to type back the printed listing to the computer. The result was rather disappointing, and the game was pretty bad.

A few years later, a friend got an Amiga 500 and when i looked at the games running on it, it was just unbelievable. The graphics and the sounds were way above anything else, and the games availables were just stunning. After a lot of negotiations, my brother and I get the precious, and a brand new Amiga 500+ hit our desk ! We used it a lot as an advanced gaming console, and had a lot of fun. Then the number of games released on the platform decreased to almost zero very quickly due to Commodore bankruptcy, and then my main point of interest changed.

I started programming somewhen in 1994. At first, it was some small tools programmed in, guess it, Basic. When the PureBasic project started, early in 1998, it was a quick attempt to support new PowerPC processors freshly available on the Amiga in a Basic language, with a syntax based on BlitzBasic which was discontinued. It was very small, with few features and very tied to the AmigaOS. It got about 200 build-in commands, an ‘IDE’ which was mostly only a text editing area and a ‘Compile/Run’ menu and a rudimentary runtime debugger. The whole commands were programmed in 680×0 asssembly code, which was the rules on the Amiga to have optimized code. And as the AmigaOS didn’t have memory protection, better check your code twice before running it, especially when dealing with pointers, or it will immediately reboot ! So far i got some positive comments from the internet community (yes, we had internet in 1998, even if it wasn’t fast) about PureBasic and the choice was made to do a Windows and Linux version as soon as possible. I was studing computer science and learned the C programming language, so it was a good time to recode everything in a ‘portable’ way. I didn’t knew so much about real world programming and i made a lot of mistake when porting it in C, and hopefully learned quite a bit from it.

Late in 2000, we publicly released the first Windows version and it was a real achievement, for me and for the future of PureBasic. The real deal started here, as the Windows audience was way larger than the AmigaOS one. We got a lot of feedback (compared to what i expected) and it was a great source of motivation. André jumped into the boat and since then handle the german part of PureBasic. The plan was to add as much as commands as possible to reach the critical mass which could attract users and let them do a complete software without hassle. The releases iteration was much faster than what it is now, because the shipped code was lower quality and we didn’t do synchronized releases between platforms. The development of the different versions on linux, windows and amigaos was very time consuming, as the build was not unified and nothing was virtualized. On Windows, all the libraries were coded in x86 assembly, which was obviously a wrong choice: much longer/harder to develop, not significant size/speed gain most of the time and more important not portable on x64. Timo joined the team and helped a lot to refactor the libs and the build structure.

Then we added quite a number of features, dealing with a lot of API and we reached in 2006 another important mark in PureBasic history: the 4.00 release.  I think than the project took a professional turn at this point. It took 6 years to reach it but then we had some interesting features:

– Flexible commandset, with more than 900 build in commands
– Support for the 3 major operating system (Windows, Linux, OS X), with an high compatibility level
– Buildin unicode & thread support
– Full featured, modern IDE
– Robust debugger, which comes in 3 flavours (console, standalone GUI and IDE integrated)

Four years later, we are at 4.51, which is a general refinement of 4.00. More commands, more stability, more fun. Internally, we have enhanced many things, making our development easier, faster and more robust. Time flies, but it’s great to see what have been achieved. We have very high expectations for the future, there is so much things left to do !

So far, thank you to all the PureBasic folks which are actually using it and make all this possible. See you in 10 years…

API Programming: What’s behind the PB GUI objects

For Windows, this question is quickly answered: HWND. Pretty much everything is of this basic “window”-type and most API commands that deal with windows can be used on most GUI objects. You can also find many code examples on the forums that deal with a lot of common API tasks. The situation is different for Linux and OSX. Here, different Gadgets may have different underlying objects and so it is not entirely clear what functions can be used. There are also a lot less examples around for these systems. Of course when developing programs that run on multiple OS, you will need solutions for all of them.

To help this situation a bit, i have compiled a list of what are the underlying objects behind the PB gadgets and other GUI objects. You can get access to these using functions such as GadgetID(), WindowID(), etc.

Disclaimer:

This information is internal stuff. While many of these things haven’t changed in many years, it is still possible that we decide to change something in the future. Also some Gadgets are heavily modified for PB with custom subclasses or callbacks which also may change in the future and break your code. So as usual: Feel free to use this information, but if it breaks, its not our problem.

So here it goes:
Windows Linux OSX
WindowID() HWND GtkWindow WindowRef
MenuID() HMENU GtkMenuBar / GtkMenu MenuRef
StatusBarID() HWND GtkHBox ControlRef (UserPane)
ToolBarID() HWND GtkToolbar HIToolbarRef
FontID() HFONT PangoFontDescription PB internal pointer
ImageID() HBITMAP GdkPixbuf CGImageRef
GadgetID() HWND GtkWidget ControlRef
ButtonGadget “Button” GtkButton / GtkToggleButton PushButton / BevelButton
ButtonImageGadget “Button” GtkButton / GtkToggleButton PushButton / BevekButton
CalendarGadget “SysMonthCal32” GtkCalendar HIView
CheckBoxGadget “Button” GtkCheckButton CheckBox
ComboBoxGadget “ComboBox” / WC_COMBOBOXEX GtkComboBox / GtkComboBoxEntry PopupButton / HIComboBox
ContainerGadget custom class GtkFixed UserPane
DateGadget DATETIMEPICK_CLASS GtkEntry UserPane
EditorGadget RICHEDIT_CLASS GtkTextView UserPane (rendering a TNXObject)
ExplorerComboGadget WC_COMBOBOXEX GekComboBoxEntry HIComboBox
ExplorerListGadget WC_LISTVIEW GtkTreeView DataBrowser
ExplorerTreeGadget WC_TREEVIEW GtkTreeView DataBrowser
Frame3DGadget “Button” / “Static” GtkFrame GroupBox / UserPane / Separator
HyperLinkGadget “Static” GtkButton UserPane
IPAddressGadget WC_IPADDRESS GtkEntry EditUnicodeText
ImageGadget “Static” GtkImage UserPane
ListIconGadget WC_LISTVIEW GtkTreeView DataBrowser
ListIconGadget “ListBox” GtkTreeView DataBrowser
MDIGadget “MDICLIENT”
OptionGadget “Button” GtkRadioButton RadioButton
PanelGadget “SysTabControl32” GtkNotebook Tabs
ProgressBarGadget PROGRESS_CLASS GtkProgressBar ProgressBar
ScrollAreaGadget custom class GtkScrolledWindow UserPane
ScrollBarGadget “SCROLLBAR” GtkVScrollBar / GtkHScrollBar ScrollBar
ShortcutGadget HOTKEY_CLASS GtkEntry EditUnicodeText
SpinGadget UPDOWN_CLASS + “Edit” GtkHBox containing others UserPane containing others
SplitterGadget custom class GtkVPaned / GtkHPaned UserPane
StringGadget “Edit” GtkEntry EditUnicodeText
TextGadget “Static” GtkLabel StaticText
TrackBarGadget TRACKBAR_CLASS GtkVScale / GtkHScale Slider
TreeGadget WC_TREEVIEW GtkTreeView DataBrowser
WebGadget custom class + ActiveX control GtkMozEmbed HIWebView
Notes:
  • Gadgets all have the same basic type noted in the GadgetID() row. However, Gadgets are devided into “window classes” on Windows, or subclasses of the general GtkWidget on Linux.
  • For Gadgets on Windows: If the entry is noted in “” then this is the class name, if it is not then this is the symbolic constant for the class name. You’ll have to look up the text value in the appropriate header files.
  • On OSX, there are no classes for the controls, its all a ControlRef. The names i noted here are derived from the control creation functions (ie CreateTabsControl()). If you are looking for information, you should start there.
  • Gadgets may have multiple classes depending on the flags on creation.
  • On Linux, many gadgets are placed inside their own container to add a frame or catch events. (GtkFrame, GtkEventBox). The GadgetID() command returns the real gadget in this case, not the container.
  • On OSX, the UserPane controls are drawn by PB itself, so you don’t have much ways to modify them other than the PB commands.

Thats it. I hope this information is useful to some people, and hopefully we will see some more cross-platform API examples on the forum in the future 🙂