Where I’m starting to hang out most often

Lately I’d been hanging out on some alternative Xojo discussion venues.

The one I’m finding useful is IfNotNil as they permit discussions of ANY topics which lead to cross platform development. So you can talk about Rust, Go, B4X products, LiveCode, Web and other toolsets you might use for cross platform software development.

Using events as a way to pass information to instances

Most of the time when we talk about events the first thing that pops into someones head isa UI control and the events is has for interaction with the user. A pushbuttons Action (or Pressed) event for instance. Or the various events on listboxes for selecting rows, handling mouse clicks, keyboard events and the myriad of other user interface and interaction related things listboxes handle.

But thats not the only way to use events 🙂

Sometimes you may write a control and it needs to get data from the layout its on or from something else outside its control. So how do you get access to this ?

You could, as I’ve seen in some code, make everything PUBLIC and then the specific control just gets its parent control and grabs what ever property or calls whatever parent method it needs.

This is, IMHO, a bad practice as it makes your code more fragile since a change in the method or property you’re accessing this way could cause unrelated code to break. And because it destroys any encapsulation you might have created. Its a huge violation of the Law Of Demeter I wrote about before. You should only use things that are passed to you as parameters, that you own and control, or that are declared in your code. Reaching way outside to the parent control would definitely violate this principle.

So what can you do ?

As discussed before, subclasses CAN create NEW events and you could use an event to ask the containing layout for whatever property value or reference to something else the layout has access to.

We’ll create a small project to demonstrate the idea. What we will have is a custom canvas control that will ask the outside world for the color that it should draw itself as. You might normally do this as a simple property but I am NOT going do that to demonstrate. The other thing we will have on the layout is yet another custom canvas that acts simply as a color picker.

I’m using 2019r1.1 so some things may be different if your using a newer version

First start a new desktop project

Add a new subclass of Canvas by dragging the canvas control from the Library over to the Navigator (or you can add a new class and set its super to Canvas in the inspector). Name this new class ColorSelectorSwatch.

Add a public property called FillColor as Color

We’ll add the MouseUp event handler and put the following code in it

  Dim c As Color
  
  If SelectColor(c, "Select a color") Then
    Me.FillColor = c
    Me.Invalidate
    RaiseEvent Updated
  End If

Also add the Mouse Down event handler and put this code in it

  Return True

Also add a new Event Definition and name it Updated

Thats it for our little color selector swatch

Add an instance of our ColorselectorSwatch to the default layout, Window1, by dragging it from the Navigator on to the layout Window1. By default its name will be ColorSelectorSwatch1

Add the event handler for the new Updated event. We’re not going to put any code in it just yet. We’ll return to this later once we create our other custom control.

Now add another canvas subclass to your project. Again you can do this by dragging or by simply adding a class and changing the superclass in the inspector. Name this class CustomCanvas. This is the one we’re going to add the event to that will ask the outside world what color it should draw itself in.

Add the Event handler for the Paint event to the CustomCanvas.

Also add a new event definition colorToDrawWith() As color.

Note that this event handler has a return value that is a color. When we need to get the color we’ll raise this event, get whatever return value, and then paint our canvas with this color. *

The code for the Paint event is fairly simple

Dim c As Color

c = RaiseEvent ColorToDrawWith // call the event to get the color 
                               // from the outside world

g.ForeColor = c
g.FillRect 0,0, g.width, g.height

Drag an instance of this custom canvas onto the default window and make sure it does not overlap your other canvas. By default it will be named CustomCanvas1.

Now we’ll add the handler for the ColorToDrawWith event. All we need is one line

return ColorSelectorSwatch1.FillColor

Now return to the Updated event of ColorSelectorSwatch1. In there we need one line to make it so our CustomCanvas will know to redraw itself when the color selector swatch gets a new color selected. In the Updated event put

CustomCanvas1.Invalidate

And run. Every time you select a new color in the color swatch the other canvas will update and redraw itself. And, to do so we have used an event to return information to the control instance that tells it what color to draw with.

Here’s my completed sample

*Of note one of the things that got added in versions after 2019r1.1 is a way to tell IF the event is implemented. You could use this to know whether you should redraw with the color returned or not.

The only change would be to make the Paint event of CustomCanvas read as follows

If IsEventImplemented("ColorToDrawWith") Then
  Dim c As Color 
  
  c = RaiseEvent colorToDrawWith
  
  g.ForeColor = c
  g.FillRect 0,0, g.width, g.height
End If

Exercise caution with catch clauses

Xojo now generally uses exceptions to handle errors.

And with that comes some things you should know about how exceptions work that you need to be aware of before you cause yourself problems.

First off, in my opinion, you should put your try catch blocks as close to the code that causes the error. While Xojo lets you use one EXCEPTION or CATCH block at the end of any method like the following


// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 
// do a bunch of code 


Catch foo As RuntimeException // or Exception foo as RuntimeException
Break

I would suggest you avoid this form. It’s not obvious unless your methods are VERY short and it on one screen of code. For instance, does the following method have a catch ? Without actually looking at the very end you cannot tell (In fact it does but that isnt clear)

As well using a single consistent form is probably a better practice than sometimes using this form and sometimes using other forms. Even if the entire method is surrounded in a TRY CATCH block its more obvious. This is the exact same method with the addition of the TRY keyword at the very beginning and “END TRY” at the very end

try
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  // do a bunch of code 
  
  
Catch foo As RuntimeException 
    Break
End Try

The other thing to be careful about is how you write your catch statements. The documentation shows a legal CATCH statement as

Catch [[ErrorParameter] [As ErrorType]]

Note that EVERYTHING except the CATCH keyword is optional. Again I would suggest you almost NEVER use just a CATCH by itself as you will catch every type of exception, perhaps even those you cannot actually handle.

The other thing that is often confusing is if you write

Catch someException

which is legal what you have in fact got is

Catch someException as RuntimeException

and the local variable is name someException. Save yourself the grief and ALWAYS use the fully spelled out form of CATCH like

Catch <localVariableUsableInTheExceptionHandlingCode> as <ExceptionType>

Using it this way insures you are never surprised at catching more than you were prepared to handle. Also note that the localVariableUsableInTheExceptionHandlingCode is in fact defining a local variable that you can use in the body of this specific CATCH block. What that means is code like

Catch iox as IOException
   system.debuglog iox.errormessage

is legal and, in this case, iox is usable within the rest of the code following that catch until you get to another catch, the finally block, or the end try. The following WOULD NOT be legal

Catch iox as IOException
   system.debuglog iox.errormessage
Catch oob as OutOfBoundsException
   system.debuglog iox.errormessage

iox would not be in scope in the code following the catch of the out of bounds exception. Nor would oob be usable in the block handling the IOException.

And this last example shows something you can legally do. You can have more than one catch statement. The only thing you need to be careful about here is not catching the most general types before the more specific ones. What do I mean by that ?

Since all exceptions are descendants of RuntimeException they are more specific types of exceptions than RuntimeException is. If your code was like

Try
  Raise New nilobjectexception
  
Catch rte As RuntimeException
  Break
Catch noe As NilObjectException
  Break
End Try

you would find that any code following the catch of the NilObjectException would NOT get executed. Because NilObjectException is descended from RuntimeException the first catch block will handle EVERY exception. Changing this code to

Try
  Raise New nilobjectexception
  
Catch noe As NilObjectException
  Break
Catch rte As RuntimeException
  Break
End Try

will now execute the NilObjectException code since that matches the more specific type. Note this is not peculiar to try catch statements but a general thing to keep in mind when dealing with if then else, select case and other kinds of statements that use boolean values to determine if their code should execute.

Now go catch stuff 🙂

Shifts ahoy !

Bit shifting can be troublesome. Especially if you’re not sure WHY they can be troublesome.

So some recommend only using UNSIGNED integers for such operations. And using *2 and \2 to do bit shifting.

At a very low level most modern CPUs implement certain numerical standards in various instructions. And, of note, nearly every last one has two (or more) forms of shifts. One is a logical shift, and one is an arithmetic shift.

The difference between them is VERY subtle – but important.

It turns out that this is the reason that you SHOULD use unsigned integers IF you use * 2 and \ 2 to do bit shifting. When you multiply by 2 a modern compiler might realize this is a simple arithmetic shift and write the machine code to perform exactly that operation. An arithmetic shift will preserve the sign. And so when you do a \2 operation you do not get a result that flips signs. The sign bit (left most bit) is preserved. For instance

Dim i as int8 = -8 // this is &b11111000 in binary 
                   // MSB is 1 indicating a negative value

dim j as int8 = i \ 2 
// j is now -4 which is &b11111100 in binary
// note the MSB is STILL set so the result did NOT change sign

Arithmetic shifts generally preserve the sign esp when the sign bit is initially set. Otherwise you get odd sign changes.

But the same is not true when you do a LOGICAL shift. This just moves bits without regard to signs. Starting with almost the same code, but using BITWISE.ShiftRight instead of \2 we get very different results IF you expect to get a value you can use as a number.

Dim i As Int8 = -8 // this is &b11111000 in binary 

Dim j As Int8 = BitWise.ShiftRight(i,1,8)
// j is now 124 which is &b01111100 in binary

The shift this time made NO effort to preserve the sign bit as we were doing logical shifts which make no effort to preserve the sign bit.

So when, or if, you need to do any bit manipulation make sure you understand whats going on at a low level and IF you use * and \ to do shifting use unsigned values.

Shifts away !

Prepared statements

Had an interesting discussion the other day and in the course of the discussion the use of prepared statements came up. Turned out that a few people had never used them and did all the leg work to created their own mechanism to concatenate strings.

For a long time in REALbasic. and REALStudio this was a requirement. Prepared statements didnt exist. But once they did I always recommended people use them instead of trying to roll their own set up.

Why? What are the advantages to using prepared statements instead of a roll your own set up using string concatenation?

First off security is a BIG reason to use them. SQL injection attacks used to be common simply because there were so many ways to cause them and trying to manually handle every case, even for a single database, could be difficult. There maybe cases where control characters are allowed and others where they are not and knowing the difference in any code that applied replacement patterns would grow into a very large body of code to deal with.

With string concatenation you run the risk of someone crafting an input string just so and wiping out your database. Hackers are very clever & skilled at this. So when a database has a mechanism designed to thwart them, like prepared statements, we should use it.

Specifically suppose you just made sure that you wrapped user input in quotes and passed that along.

   dim sql as string = "select * from table where column = " + WrapInQuotes(userInput)

and all WrapInQuotes did was

Function WrapInQuotes(inputString) as string
  // this is deliberately VERY naive to illustrate the point
  return """" + inputString + """"
End Function

This is deliberately VERY naive but it shows the reason prepared statements are used 

Some database will let you execute more than one statement as part of their API – which Xojo uses. If a “hacker” were to put in, as user input,

      "; delete from table;

and you used the above code you would find that the sql end up as

    select * from table where column = ""; delete from table;"

and you just might find your table no longer has data in it. And despite your and my cleverness there are so many screwy little edge cases that its almost impossible to get any kind of code with replaceall to work right in all cases.

Prepared statements avoid all this as the statement doesnt get parsed in the same way as a full sql statement that has all the values stated. The parameters are basically marked as “not present” but they know the type, position (or a name) and the execution of the statement then passes those values to the DB engine via its API. What it does NOT do is reparse the sql every time and it also makes no attempt to “interpret” the data values as if they were part of the commands.

They are JUST data and cannot be part of a command – and so the engine doesnt try to use them as commands which it does do in our previous example because it has to understand the statement(s) in order to execute them

The other upside to prepared statements in many databases is that they can do the leg work to create the query plan for the specific statement once and then reuse it over & over as you pass new variables. Not all databases can do this when using the various Xojo API’s but some do.

So there can be speed benefits to using them as well

But, lets be careful out there

Bin, hex and oct

Xojo’s BIN, HEX and OCT methods and their new counterparts, ToBinary, ToHex, and ToOctal should do a better job than they do.

If you pass in an 8 bit value you _may_ get an 8 bit binary representation back – or not. And this is true for ALL numeric types. The string you get back may not represent the full value esp if the upper bits are 0. This can be a problem sometimes especially if you’re trying to debug an algorithm that flips bits and you want to see all of them in a string representation (see this bug report)

If you’re trying to use the newer API 2 style then you’ll fnd that single and double values have no ToBinary, ToHex, or ToOctal extensions (see this bug report )

And BIN, HEX and OCT do not work on currency values and it also has no extension methods (see this bug report)

So to fill this gap and fix these shortcomings I have created a module that you can add to your projects that will give you the proper representations AND that will allow you to convert a currency to binary, hex or octal and then convert that back to a currency.

Enjoy !

Things you should not rename in Xojo

There aren’t a lot of items in a Xojo desktop project that you can’t rename. You can change the name of the App instance, the default window, the default menu bar and many many others.

But there are a handful that, if you do rename them, you may inadvertently break your application. This is entirely due to how the Xojo framework works, and in part how macOS itself works.

One group of items you should not rename is several Edit Menu items. Do not rename EditCut, EditPaste, EditClear, and EditSelectAll. The reason is, that if you do, then certain classes in the Xojo framework will no longer handle those menu items by default.

The simplest demo of this is to

  • start a new desktop project
  • add a TextArea to the default window – Window1
  • run

Now if you type in text to the text area and press the shortcut for Select All (⌘-A or Ctrl-A) the text area will automatically handle selecting all the text.

Quit your little demo app and in the menu editor rename EditSelectAll to MyEditSelectAll.

Run the small sample again. Perform the same test by adding a bunch of text and trying to use the shortcut. This time the menu shortcut is NOT automatically handled and likely just beeps at you.

Several controls have behaviour that is pre-configured to rely on the Edit Menu items being named in a specific way. I’ve written about how you can do this as well before. Renaming the Edit Menu items then breaks that automatic configuration.

The other thing that renaming is specific to macOS. On macOS the OS will automatically add new menu items, the ones for Start Dictation and Emoji & Symbols, to the edit menu IF it the TEXT of the for the Edit Menu title is “Edit”.

If you alter it to anything else then macOS will not find the correct menu to insert these items and they will not be added to your Edit Menu.

Again this is easy to test with the tiny sample app we have so far. Just change the Edit menus text to Edit followed by a space and run. When you click on the Edit menu you will not longer have the 2 automatically added items.

New resources

This looks like it could be a nice forum as a place to learn about and discuss cross-platform app development, not specifically focused on Xojo (although that will be one of the topics I’m sure)

As an alternative to the Xojo forums where you cannot discuss other products etc this one is focused on cross platform – regardless of toolset

I’ll give it a chance. You should as well.

If you’re updating with every release

A small handful of changes in 2019r3.1

Module Color
alpha changed to Integer
Function CMY(cyan As Double, magenta As Double, yellow As Double, alpha As Integer = 0) As Color

ColorGroup
gained operator_compare
Function Operator_Compare(otherColor As Color) As Integer

Module Crypto
added PBKDF2 with HashAlgorithms parameter
Function PBKDF2(salt As String, data As MemoryBlock, iterations As Integer, desiredHashLength As Integer, hashAlgorithm As HashAlgorithms) As MemoryBlock

Class DatabaseColumn
now has a destructor
Sub Destructor()

Class DatabaseRow
added Column setter method
Sub Column(name As String, Assigns value As Variant)

added Destructor
Sub Destructor()

Module String
new overloads for IndexOf
Function IndexOf(Extends s As String, startPosition As Integer, searchString As String, options As ComparisonOptions = ComparisonOptions.CaseInsensitive, locale As Locale = Nil) As Integer

Function IndexOf(Extends s As String, searchString As String, options As ComparisonOptions = ComparisonOptions.CaseInsensitive, locale As Locale = Nil) As Integer

new method LastField
Function LastField(Extends s As String, separator As String) As String

Class TextArea
changed type of SelectionAlignment type
Property SelectionAlignment As TextAlignments

Cant say that so far I’ve used it much.

Creating custom controls

Xojo makes it possible for anyone to create custom controls for their projects. And its not really that hard. Yet many people don’t bother to take advantage of this capability and then try to place many independent instances on a layout and make several controls behave as though they are a single control.

This quick tutorial is aimed at trying to convince you that it really is worth investing the little bit of time required to create your own custom controls and then reuse them as many times as you want.

Often you can get away with just creating a new subclass of which ever control you want and then customizing how it behaves. Maybe you just need some custom drawing in a listbox. It may not make sense to create anything but a new subclass in that case.

In this example because we want to create something that does not exist and is a composite of other controls we are going to start with a CONTAINER CONTROL.

At this point, depending on what control you want to create you would add which ever controls you need to your container control.
In this example we want a label and a canvas because we’re going to make something that is like the color picker seen in the inspector. Make sure that when you place them on the container you set their SCOPE is set to PRIVATE.

Personally I always do this as code outside the container should NOT reach in and manipulate the controls in our container directly. If you find you think you need something like that add a method or event to make it possible for code outside to get a reference to the control or set a property instead.

Make sure you give the container control a good name as this name WILL show up in the library *. Use a descriptive name for your custom control. Naming it “fooControl” probably isn’t useful unless it literally has something to do with “foo” – whatever that might be. In this case since we’re making a “labeled color picker” we’ll name it labeledColorPicker

Now we’ll add properties that can be set in the inspector that will influence how our control works. We’ll add a label property, as string, that will be the text show in our control. As well we’ll add a currentColor property, as Color, that will be the current color the color picker shows in the canvas. Both of these should be added as COMPUTED PROPERTIES.

We will need a variable to store the value for our currentColor property that we can hold the value in and that we can return when the value is queried. Since we’re using a canvas for this purpose and it does NOT have a property we can use we will need to add a PRIVATE property to our ContainerControl to hold this. Add a PRIVATE property, mCurrentColor as Color, to the labeledColorPicker container control.

In the GET portion of the currentColor computed property put in the code
return mCurrentColor
In the SET portion of the currentColor computed property put in the code
mCurrentColor = value

The LABEL DOES have a property we can use so we aren’t going to need to add a property to our custom control. WE can make use of the LABEL’s text property
In the GET portion of the label computed property put in the code
return label1.text
In the SET portion of the label computed property put in the code
label1.text = value

Now to make it so we can expose these two custom added properties we need to RIGHT CLICK the labeledColorPickerControl in the navigator (the left hand list in the IDE)


In the contextual menu you should see an option for “Inspector Behaviour”. Select that item and you will a panel that will allow you to customize which properties are seen in the inspector.

**** WARNING **** DO NOT DISABLE ANY check boxes UNLESS you are using TEXT or XML projects as in binary projects getting them re-enabled is VERY difficult (see **)

To make a property, including computed properties, visible make sure the check box at the left is ENABLED

Now if you drag an instance of your custom control to a layout you will see the properties we just exposed in the inspector along with all the others the container normally has.

Note that at this point our control is NOT making full use of our new properties yet. Due to how the IDE works it does NOT give you a full WYSIWYG experience for custom controls. It does NOT execute your custom code for setting the newly added properties when it draws the layout. Changing the label text property or the currentColor will not redraw the IDE’s representation using those values. You MUST run the project to see any changes.

Lets make it so when the currentColor is changed that we see this change in the control at runtime. In our labeledColorPickerControl we’ll edit the SET method for the currentColor computed property. What we are going to do is SET the mCurrentColor property, which is already in place, AND make sure that the canvas shows this color change by making it redraw itself.

Make the currentColor SET method in the labeledColorPickerControl read as follows
mCurrentColor = value
canvas1.Invalidate

As well we need to add the PAINT event to the canvas control on the labeledColorPickerControl so the color is shown. Add the PAINT event to Canvas1 and in that event put
g.ForeColor = mCurrentColor
g.FillRect 0, 0, g.width, g.height

Now if you change the currentColor in the inspector & run you will see that color used in the canvas at runtime. And if you put code elsewhere that changes the currentColor of this custom control you will also see the change reflected at runtime. The same is true if you were to change the label text.

Congratulations – you have just created your first custom control. More complex examples abound but the principles are still much the same regardless of whether you start with a Canvas subclass that draws itself specially, or something more complex that uses a container control for a more complex UI element.

Foot Notes

(*)you can hide things from the library
if, for some reason, you DO NOT want you control to show in the library you can add an attribute to your control called HideFromLibrary and it will not show

(**) Note that IF you disable one getting it re-enabled is VERY difficult because of a bug in the IDE