Category Archives: Technology

B4X: Responsive containers in ABMaterial 4.25


Next to the normal responsive page behaviour, in ABMaterial 4.25 for B4J, you will be able to do this with containers too!

Let’s watch it at work first:

This may not sound super special, but it’s a biggie! There are very few frameworks out there that can do this, so I’m very proud of this one.

Nice but that must ask for a lot of control code, no?“, I hear you ask.
Well, here it is:

gridContainer.IsResponsiveContainer = True

Done! ūüôā

Just by setting gridContainer.IsResponsiveContainer = True, you just made the ABMContainer device responsive just like a page. This means you can from now on actually create controls that behave differently depending on the device you are on.

For example, setting this grid on a container, the last 5 cells will wrap differently on a phone, tablet or desktop:


I also added some powerful tools to adjust the layout of your WebApp according to the device you are on:

Returns the current page size (phone, tablet, desktop). You can use this method e.g. in ConnectPage to determine the state of the current page size and act accordingly.

public Sub ConnectPage()
   Log("Current page size: " & page.GetCurrentPageSize)
End Sub

An event Page_SizeChanged will return the same value in the ‘current’ parameter if the user changes the window size. (It also returns the ‘previous’ state).

Note that this event is NOT raised at load time! Use Page.GetCurrentPageSize to check that.

Sub Page_SizeChanged(previous As String, current As String)
   Log(previous & " -> " & current)
   Select Case current
       Case "phone"
           gridContainer.MarginLeft = "0px"
       Case "tablet"
           gridContainer.MarginLeft = "210px"
           gridContainer.SetFixedWidth("calc(100% - 210px)")
       Case "desktop"
           gridContainer.MarginLeft = "210px"
           gridContainer.SetFixedWidth("calc(100% - 610px)")
   End Select
End Sub

Containers on a fixed position:
Next to setting a fixed with and height of an ABMContainer, you can now also set a fixed position. This can be handy to create ‘floating’ sidebars for example.

compContainer.SetFixedPosition("0px", "", "56px", "")

Params: left, right, top,bottom

Set a parameter to empty string when you don not want to set it.

These 3 new features used together give you an immense power over how your WebApp should behave depending on the device it is running on, with very little effort.

Another year has passed:

2017 has been a great year for B4X and ABMaterial!

B4X has grown to be a very powerful player in develop land.  The already productive RAD IDE has received a couple of very innovative features to help you even more with your app development. Anywhere Software is always right on top of all the new stuff Android, iOS and all the other supported platforms throw at us.  And being stable and reliable makes this a unique environment. The growth of the forum and the quality of the messages/responses are the real proof of this.  Thanks a lot Erel for this beautiful tool.  It is without a doubt the best cross-platform tool one can use for the moment!

And ABMaterial is lucky to be able to stand on the shoulders of this giant.¬† ABM has surpassed my biggest expectations this year.¬† It is great to see a lot of you are using it to make amazing webapps and even can make a living out of it.¬† This was definitely the ‘year of speed‘.¬† Very few frameworks can match ABM when it comes to develop and execution time. And there is a lot more in the pipeline for the upcoming months!

Thank you all for following my blog!  You inspire me every day to push the limits of the tools and frameworks I make.

Rest me only to wish you all the very best and I hope to see you back in 2018!


Click here to Donation and support ABMaterial

Or make a donation with Bitcoins:

BTC: 13x7b12GonCj6iphnjLuonrwURK2jCgMdE

This is my bitcoin address as a QR code. It is possible to send bitcoins to me from mobile wallets by scanning this code.



B4X: ABMaterial 3.75 Public/4.00 Donators released


ABMaterial Dragonfly (4.00) for B4X is available. Yes, it has a new name! What started as version 3.81 got upgraded to a new major version, especially since it uses a new cache control system.

ABMaterial has always been one of the fastest RADs from its start, now over 2 years ago.¬† But with 4.00, we’ll take it to a whole new level!

Mindful and I have spend 5 days (and nights) checking out how we could cache ABMaterial to the extreme without losing any of its functionality.¬† The results are just ridiculous…

Finish times are less than 10% of the time on the second and next loads. So on 3G, on the users next visit(s), the WebApp is almost just as fast as on high speed cable!

And this system not only works with the same page. Once one page has been loaded, all the other pages can take gain of this system. Even when the user revisits your app much later.

Furthermore there is the new debug feature to check how your apps work on different device sizes.  See it at work here:

Add this snippet to you main module, AFTER starting the server:

' in debug mode, start the browser and open the app on all devices (DOES NOT WORK IF EDGE IS YOUR DEFAULT BROWSER!)
ABM.ViewerOpenAllDevices("http://localhost:" & port & "/" & ABMShared.AppName & "/", 100)

' or open a specific device as default (DOES NOT WORK IF EDGE IS YOUR DEFAULT BROWSER!)
'ABM.ViewerOpenDevice("http://localhost:" & port & "/" & ABMShared.AppName & "/", 300, ABM.VIEWER_TABLET)

' or just open de browser, no multiple devices (should work in Edge)
'ABM.ViewerOpen("http://localhost:" & port & "/" & ABMShared.AppName & "/")
#End If

Lots of new theme properties! Check out the demo on how to use¬† them in the new Dragonfly theme.¬† As winter is coming and days are getting shorter (at least here in the northern hemisphere), I went for a ‘Night’ theme this time.

ABMaterial DragonFly is now available on 750+ locations worldwide on CDN!  If you use the CDN, you do not need to upload the css/js/fonts folders to your own server anymore!

This means only your own assets (images etc) from the www folder have to be available on your server. De demo running on for example is working like this.


ABM.ActivateUseCDN("DONATORKEY", "")

The over 20 new fixes and fulfilled wishes make ABMaterial 4.00 very stable, just like its ‘parent’ programming language: B4X.¬† It is a real joy knowing one can depend on a strong, bug free environment.¬† Erel from Anywhere Software rulez!

Happy programming!


Click here to Donation and support ABMaterial

Or make a donation with Bitcoins:

BTC: 13x7b12GonCj6iphnjLuonrwURK2jCgMdE

This is my bitcoin address as a QR code. It is possible to send bitcoins to me from mobile wallets by scanning this code.


Windows October Update ODBC export Excel problems


Windows updates, you gotta love them! This October update has a lot of developers scratching their head.

Here at OneTwo, we became first aware of the problem when some clients called our support team with the same remark: “Exporting the data to Excel does not work!”¬† After going through the usual procedure following the directions of Roy Trenneman from the IT crowdhave you tried turning it on and off again?“, we quickly became aware there was something more going on…

Indeed, Microsoft had rolled out a new update.¬† “Drop everything, we have a KB hunt on our hands!”¬† A time consuming thing to do, and in the meantime a lot of worried users.¬† Google and the MSDN site had to do overtime too.


Quite some time later, we found the little buggers. Here is the list for anyone out there banging his head aginst the wall asking himself why his code, which has been running for years, suddenly stopped working:

  • Windows 7: KB4041681
  • Windows 8.1: KB40416393
  • Windows 10: KB4040724/KB4041676

Uninstall them and reboot. Hooray, code is working again!


It looks like Windows keeps insisting to run the update.  Here is a more permanent solution.

1. Find prior version (4.0.9801.0) of msexcl40.dll

2. Place in another directory. They suggest the application directory, but since in the next step you will modify registry to point to this older version, it can probably go anywhere.

3. Update registry key HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel\win32 to point to the location from step 2.

You don’t even have to restart your PC.

Have a great weekend, my fellow IT minions!


Click here to Donation and support ABMaterial

Or make a donation with Bitcoins:

BTC: 13x7b12GonCj6iphnjLuonrwURK2jCgMdE

This is my bitcoin address as a QR code. It is possible to send bitcoins to me from mobile wallets by scanning this code.


B4X: An experiment for practical use of IoT on the shop floor


At OneTwo, we are always searching for ways to make things easier on the workfloor.  For nearly a decade, we introduced barcode scanners everywhere! From architects and accountants, over carpenters and contractors, to farmers and gardeners are now using our small barcode scanners to record times, jobs and used materials.

The last couple of weeks, I’ve been investigating how we could tackle another common issue, but now on the factory shop floor.¬† Working on a specific step in the development of a product demands the constant focus of the operator so using a barcode scanner to get the instructions is, well, just not practical if you have your hands full.

Time to get to the lab! Provided with heaps of coffee, some unhealthy snacks and an open mind we started putting some ideas together on the whiteboard.  We wanted to give as much feedback to the operator as possible using monitors,  beamer projections at the workstation and personal instructions on phones and tablets.

The key to deliver hyper-contextual content to the users is knowing the location of every chess piece in the game: the workstation, the machine that is going to be build and the operator(s).  The underlying communication technology was going to be Bluetooth Low Energy (BLE). The Raspberry Pi has it and so does almost any phone or tablet. By attaching a cheap BLE Beacon to the machine we could understand the location of all the players.

Using B4X for this project was a no-brainer, as Erels toolbox is just made to build stuff like this! One important link in the chain was missing:  the BLE reader in B4J for the Raspberry Pi.  However, writing some small scripts and calling it using jShell and a couple of timers did the job just fine.

Scripts code:

Two scripts to discover BLE devices around the Raspberry Pi.  Each one runs in its own jShell in B4J. First one scans for devices, second one reads whatever they broadcast.

# Beacon Scan by Alain Bailleul 2017
sudo timeout -s SIGINT 5s hcitool lescan

# Beacon Scan by Alain Bailleul 2017
sudo timeout -s SIGINT 5s hcidump -X > scan.txt

Also, as the Raspberry Pi has to be a BLE beacon itself (so the Android Native app can discover it), I had to write another little script:

# Beacon Scan by Alain Bailleul 2017

sudo hciconfig hci0 leadv 3
sudo hcitool -i hci0 cmd 0x08 0x0008 19 02 01 06 03 03 aa fe 11 16 aa fe 10 00 02 6f 6e 65 2d 74 77 6f 07 $1 $2 $3 00 00 00 00 00 00
sudo hciconfig

IPN=$(ip addr show eth0 | awk ‘/inet / {print $2}’ | cut -d/ -f 1)
IPW=$(ip addr show wlan0 | awk ‘/inet / {print $2}’ | cut -d/ -f 1)
MACN=$(ip link show eth0 | awk ‘/ether/ {print $2}’)
MACW=$(ip link show wlan0 | awk ‘/ether/ {print $2}’)

echo “$MACW;$IPW;$MACN;$IPN;END” > macip.txt

For anything related to presenting the instructions, we could use ABMaterial.

Alright! We’ve got everything we needed to set up a test scenario for a workstation so time to bring out the cool slide:

How it works

Although there are a lot of physical components and different OS’s in play, B4X has all the tools to make them¬†seamlessly talk to each other using one language.¬† For the native Android part, I wrote my own BLE discovery library based on the altbeacons library. (Note, there is a library available in B4A to discover BLE devices).

For the video demonstration, things you have to keep in mind:


  1. OneTwo box + BLE beacon: represents a machine arriving on the workstation
  2. Raspberry Pi (under the table): represents the workstation
  3. Android Phone: represents an operator/visitor at the workstation


  1. On the monitor, for each ‘machine’ some info is presented (e.g. a serial number, to what country it has to be shipped, etc)
  2. On the phone: specific instructions for the operator(s) for this ‘machine’, or a greeting to a visitor.
  3. On the workstation, projected global instructions for the operator(s) for this ‘machine’ with a beamer.

Let’s have a look how all of this plays out:

This turned out to work all very well for a first trial! For real world usage, the project will need some more work (like improving the algorithms to discover the BLE devices, setting thresholds or calculating them without calibration, etc…).¬† But we are very excited with the possibilities this low-cost solution can already show in such a short time.

Next step will be setting this up on a real workstation on the shop floor in a real factory later this month.

Until next time,


Click here to Donation and get the latest ABMaterial first!



B4J:Programming LEGO Mindstorms EV3


I was wondering if it would be possible to use B4J to program the Lego Mindstorms EV3 Brick for some time. So, some weeks ago, I finally spend a couple of evenings looking into it. And yes, B4J goes Robotics! It uses a modified LeJOS Firmware.

I upgraded LeJOS to support Java 1.8, which is probably the most technical part of the project.  I cannot provide it here, as it depends on your Java version but if you follow the next steps, you can build your own.  This is done on a Windows PC:

Upgrading the LeJOS Firmware to use Java 1.8

The following procedure will install the java 8 environment compatible with leJOS 9.0 from windows 7. The only extra tool needed is 7ZIP (a free tool) which can generate tar and gz format.  In the following I use a temporary directoyr as F:\temp. Replace it with your own temp directory wherever it appears.

  1. Go to java site … 82511.html
  2. Create an account if you dont have one then Accept Licensee agreement and download ejdk-8-xxxxxxx-linux-arm-sflt-xxxxxxxx.tar.gz or the latest java8 jre for EV3.
  3. Unzip this file in your F:\temp directory. For simpler process you may rename the extracted directory  as ejdk8. Run 7zip as administrator!
  4. Go to directory ejdk8\ejdk1.8.0\bin. Save the file jrecreate.bat. Now right click on jrecreate.bat and select “modify”.¬† Add one first line to the bat file as SET JAVA_HOME=C:\Progra~2\Java\jdk1.8.xxxx.¬† this is where java8 is installed on my system. Program~2 stand for Program Files (x86) but is easier to type.
  5. Start a command window: Start->All prog->Accessory->commands.
  6. In this window type in the following commands
    cd temp
    cd ejdk8\ejdk1.8.0\bin
    jrecreate.bat –dest newjre –profile compact2 –vm clientIt should start creating the new jre files in the directory “newjre” under ejdk8\ejdk1.8.0\bin
    Wait for the final message.
    Close the command window.
  7. With file explorer go to F:\temp\ejdk8\ejdk1.8.0\bin. Copy “newjre” directory back to F:\temp
  8. Rename the “newjre” directory as something expected by LeJOS such as
  9. Right click on it. Open with 7ZIP and add to archive. Select tar format. It will create ejre-8-b132-linux-arm-sflt.tar file.
  10. Right click on tar copy then add archive with gzip format. It will create ejre-8-b132-linux-arm-sflt.tar.gz. You have created the JRE file for java8 expected by EV3.
  11. Insert your SD card and format it.
  12. Copy the ejre-8-b132-linux-arm-sflt.tar.gz under the sd card top directory.
  13. Go to C:\Program Files\leJOS EV3
  14. Now remove the SD from PV and insert the card into the EV3 brick then power it. Wait for the end of the install (about 10mn).

If anything goes wrong, format again the SD, empty the F:\temp directory and restart at step 3.  if it persist try another SD card.

Your brick is ready!

Next I wrote a B4J wrapper for the basics like motors, sensors etc. This project is just a hobby and may grow in the future. But I just wanted to share this first video (badly directed so no Oscars here, unless…)

Obviously, I wanted to test out my code, but I had to build a bot first.¬† Well, I was in for a surprise! It took me over 3 hours to build EV3D4 and I can tell you, I’m not a very patient person so I may have taken some shortcuts in the construction.

What happens in the video:
1. I uploaded the B4J created .jar file to the brick via ssh and I’m ready to start it.
2. After some time, it runs (on the brick shows a disclamer and waits for a key).
3. I disconnect the brick, put it on the ground and press a button on the brick.
4. I programmed the IR sensor so if it sees a wall, it turns away, else it keeps going.

Fun fact is you can use B4J-Bridge.jar on the brick!

This is handy as debugging a Brick is a b*tch. You must have a lot of patience and prepared to restart your brick A LOT. This is not a B4J limitation, just to say how unstable programming a Brick is in general.

Coding is straightforward in B4J (this is all the code I wrote, including turning if it is about to hit a wall):

Sub Process_Globals
   Private StartTimer As Timer
   Public EV3 As ABLegoEV3
   Public LeftMotor As ABLLargeRegulatedMotor
   Public RightMotor As ABLLargeRegulatedMotor
   Public Sensor As ABLIRSensor
   Public sp As ABLSensorMode

   Public control As Int = 0
   Public distance As Int = 255
End Sub

Sub AppStart (Args() As String)

   LeftMotor.Speed = 400
   RightMotor.Speed = 400
   LeftMotor.Acceleration = 800
   RightMotor.Acceleration = 800

   Log("starting sensor")
   sp = Sensor.DistanceMode 


   StartTimer.Initialize("StartTimer", 100)
   StartTimer.Enabled = True
End Sub

Sub StartTimer_Tick
   ' read the sensor
   Dim sample(sp.sampleSize) As Float
   control = Sensor.getRemoteCommand(0)
   sp.fetchSample(sample, 0)
   distance = sample(0)
   Log("Control: " & control & " Distance: " & distance) 

   If distance < 70 Then
     Log("A wall!")

     LeftMotor.rotate2(-180, True) ' start Motor.B rotating backward
     RightMotor.rotate(-180)  ' rotate C farther To make the turn
     If Bit.And(DateTime.Now, 1) <> 0 Then
         LeftMotor.rotate2(-180, True) ' start Motor.B rotating backward
         RightMotor.rotate(180)  ' rotate C farther To make the turn
         RightMotor.rotate2(-180, True) ' start Motor.B rotating backward
         LeftMotor.rotate(180) ' rotate C farther To make the turn
     End If
     Log("Let's walk")

     LeftMotor.Speed = 400
     RightMotor.Speed = 400
     LeftMotor.Backward ' my motors are installed inverted on this robot
  End If
End Sub

Sub IntroMessage()
   Dim g As ABLGraphicsLCD = EV3.GraphicsLCD
   g.drawString("Bumper Car Demo", 5, 0, 0)
   g.Font = g.Font.SmallFont
   g.drawString("Demonstration of the Behavior", 2, 20, 0)
   g.drawString("subsumption classes. Requires", 2, 30, 0)
   g.drawString("a wheeled vehicle with two", 2, 40, 0)
   g.drawString("independently controlled", 2, 50, 0)
   g.drawString("motors connected to motor", 2, 60, 0)
   g.drawString("ports B and C, and an", 2, 70, 0)
   g.drawString("infrared sensor connected", 2, 80, 0)
   g.drawString("to port 4.", 2, 90, 0)

   ' Quit GUI button:
   g.Font = g.Font.SmallFont
   Dim y_quit As Int = 100
   Dim width_quit As Int = 45
   Dim height_quit As Int = width_quit/2
   Dim arc_diam As Int = 6
   g.drawString("QUIT", 9, y_quit+7, 0)
   g.drawLine(0, y_quit,  45, y_quit) ' top line
   g.drawLine(0, y_quit,  0, y_quit+height_quit-arc_diam/2) ' left line
   g.drawLine(width_quit, y_quit,  width_quit, y_quit+height_quit/2) ' right line
   g.drawLine(0+arc_diam/2, y_quit+height_quit,  width_quit-10, y_quit+height_quit) ' bottom line
   g.drawLine(width_quit-10, y_quit+height_quit, width_quit, y_quit+height_quit/2) ' diagonal
   g.drawArc(0, y_quit+height_quit-arc_diam, arc_diam, arc_diam, 180, 90)

   ' Enter GUI button:
   g.fillRect(width_quit+10, y_quit, height_quit, height_quit)
   g.drawString2("GO", width_quit+15, y_quit+7, 0,True)

   If (EV3.Button.ESCAPE.isDown()) Then
   End If
End Sub

As I said, this is just for fun. No idea how far this will go.  You can download the source code for the B4J library from my Github.



B4J: ABTelegram bots library

Bots are the next hot thing in 2016! So in my spare-spare time I’ve been working on a wrapper for the Telegram API v2.0. It has a rather unconventional API but I’m reworking it to make it very easy to write bots in B4J.

Bots could be very useful as yet another way to ‘talk’ with IoT devices. You can control LEDs, temperatures, ask for stats etc right from within the Telegram Chat App (which runs on about every kind of platform, being the desktop, a browser, iOS, Android, etc…). Or you can, like I did to test the wrapper, write a little game:


Note: this library is in very early stages so the wrapper is not available for download yet. Full source code of the game will also be available when released.

Some sample code to show you how easy it is to write a bot in B4J (this is not the game code, just some tests):

Code to initialize the library:

Sub Process_Globals
   Dim ABT As ABTelegram
End Sub

Sub AppStart (Args() As String)
   Dim b As MyBot

End Sub

Code for the Bot:

'Class module
Sub Class_Globals
Dim ABT As ABTelegram
Public Bot As ABTLongPollingBot
Private botToken As String = &quot;207189xxxx:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&quot;
Private botUserName As String = &quot;zzzzzzzzzBot&quot;
'Private callbackCounter As Int
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
Bot.Initialize(&quot;Bot&quot;, Me, botToken, botUserName)
Dim upds As List = Bot.botgetUpdates
For i = 0 To upds.Size - 1
Dim upd As ABTUpdate = upds.Get(i)
Log(&quot;Go update: &quot; &amp; upd.UpdateId)
End Sub

Sub Bot_UpdateReceived(update As ABTUpdate)
Log(&quot;Got an update&quot;)
If update.hasMessage Then
Dim msg As ABTMessage = update.GetMessage
Log(&quot;Message: &quot; &amp; msg.Text)

'        Dim userPhotos As ABTUserProfilePhotos = Bot.BotGetUserProfilePhotos(
'        Log(&quot;photos: &quot; &amp; userPhotos.TotalCount)
'        Dim Photos As List = userPhotos.Photos
'        For i = 0 To Photos.Size - 1
'            Dim photoSizes As ABTPhotoSizes = Photos.Get(i)
'            For j = 0 To photoSizes.Sizes.Size - 1
'                Dim photoSize As ABTPhotoSize = photoSizes.Sizes.Get(j)
'                Dim photoFile As ABTFile = Bot.BotGetFile(photoSize.FileId)
'                Log(photoFile.FilePath)
'                Dim job1 As HttpJob
'                job1.Initialize(&quot;Job&quot; &amp; j, Me)
'                job1.Tag = photoFile.FilePath.Replace(&quot;photo/&quot;, &quot;&quot;)
'                Dim url As String = &quot;; &amp; botToken &amp; &quot;/&quot; &amp; photoFile.FilePath
'                   job1.Download(url)
'               Next
'        Next

'        callbackCounter = callbackCounter + 1
'        Bot.BotSendMessageAsync(callbackCounter, msg.ChatId, &quot;Alweer hallo &quot; &amp; msg.Chat.FirstName)

Bot.BotSendMessage(msg.ChatId, &quot;Using an Emoji &quot; &amp; &quot;:grinning: in the message!&quot;) ' see for a list of emojis

'        Bot.BotSendPhoto(True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;telegram.png&quot;)

'        callbackCounter = callbackCounter + 1
'        Bot.BotSendDocumentAsync(callbackCounter, True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;mydocument.pdf&quot;, &quot;mydocument.pdf&quot;)

'        Bot.BotSendDocument(True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;mydocument.pdf&quot;, &quot;mydocument.pdf&quot;)

Bot.BotSendAudio(True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;myaudio.mp3&quot;)

'        Bot.BotSendVideo(True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;myvideo.mp4&quot;)

'        Bot.BotSendSticker(True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;mysticker.webp&quot;)

'        Bot.BotSendContact(msg.ChatId, &quot;+32496000000&quot;, &quot;Alain&quot;)

'        Bot.BotSendChatAction(msg.ChatId, ABT.CHATACTIONTYPE_TYPING)

'        Bot.BotSendLocation(msg.ChatId, 50.8492, 2.8779)

'        Bot.BotSendVenue(msg.ChatId, 50.8492, 2.8779, &quot;my venue&quot;, &quot;Grote markt 1&quot;)

Bot.BotSendVoice(True, msg.ChatId, File.DirApp &amp; &quot;/&quot; &amp; &quot;telegram.ogg&quot;)

'        Dim keyb As ABTReplyKeyboard
'        Dim rows As List
'        rows.Initialize
'        Dim tmpRow As ABTInlineKeyboardRow
'        tmpRow.Initialize
'        tmpRow.AddButton(&quot;test button&quot;, &quot;;, &quot;&quot;, &quot;&quot;)
'        rows.Add(tmpRow)
'        keyb.InitializeAsInlineKeyboardMarkup(rows)
'        Bot.BotEditMessageTextEx(msg.ChatId, msg.MessageId, 0, &quot;Extended test&quot;, ABT.PARSEMODE_HTML, False, keyb)

Dim rkeyb As ABTReplyKeyboard
Bot.BotSendMessageEx(msg.ChatId, &quot;some test: reply please&quot;, ABT.PARSEMODE_HTML, False, False, 0, rkeyb)

'        Dim rkeyb2 As ABTReplyKeyboard
'        Dim rows2 As List
'        rows2.Initialize
'        For i = 1 To 100
'            Dim tmpRow2 As ABTKeyboardRow
'            tmpRow2.Initialize
'            tmpRow2.AddButton(&quot;Press me&quot;)
'            rows2.Add(tmpRow2)
'        Next
'        rkeyb2.InitializeAsReplyKeyboardMarkup(rows2,False, False, False)
'        Bot.BotSendMessageEx(msg.ChatId, &quot;some test: press the button&quot;, ABT.PARSEMODE_HTML, False, False, 0, rkeyb2)

'        Dim rkeyb3 As ABTReplyKeyboard
'        Dim rows3 As List
'        rows3.Initialize
'        Dim tmpRow3 As ABTInlineKeyboardRow
'        tmpRow3.Initialize
'        tmpRow3.AddButton(&quot;Show image&quot;, &quot;&quot;, &quot;showimage&quot;, &quot;&quot;)
'        rows3.Add(tmpRow3)
'        rkeyb3.InitializeAsInlineKeyboardMarkup(rows3)
'        Bot.BotSendMessageEx(msg.ChatId, &quot;some test: press the button&quot;, ABT.PARSEMODE_HTML, False, False, 0, rkeyb3)
End If
If update.hasCallbackQuery Then
Dim cquery As ABTCallbackQuery = update.GetCallbackQuery
Log(&quot;CallbackQuery: &quot; &amp;
Select Case cquery.Data
Case &quot;showimage&quot;
Dim msg As ABTMessage = cquery.Message

Bot.BotSendPhotoEx(True, msg.ChatId , File.DirApp &amp; &quot;/&quot; &amp; &quot;myphoto.jpg&quot;, &quot;A new photo of darth vader!&quot;,False, 0, Null )
Bot.BotSendLocation(msg.ChatId, 50.8492, 2.8779)
Bot.BotEditMessageText(msg.ChatId, msg.MessageId, &quot;&quot;, &quot;Shown&quot;)
End Select
End If
If update.hasInlineQuery Then
Dim ciquery As ABTInlineQuery = update.GetInlineQuery
Log(&quot;InlineQuery: &quot; &amp; ciquery.Query)
If ciquery.Query = &quot;loc&quot; Then
Dim lstResults As List
Dim myanswer As ABTInlineQueryResult
myanswer.InitializeAsLocation(&quot;1&quot;, 50.8492, 2.8779, &quot;Your location&quot;)
Bot.BotAnswerInlineQuery(ciquery.Id, lstResults)
End If
End If
If update.hasChosenInlineResult Then
Dim ccresult As ABTChosenInlineResult = update.GetChosenInlineResult
Log(&quot;ChosenInlineResult: &quot; &amp; ccresult.Query)
End If
End Sub

Sub Bot_AsyncSendReceived(methodType As String, callbackId As String, success As Boolean, asyncObject As ABTObject)
Log(&quot;Async method: &quot; &amp; callbackId &amp; &quot; &quot; &amp; methodType &amp; &quot; &quot; &amp; success)
If success And asyncObject &amp;lt;&amp;gt; Null Then
If asyncObject.objectType=&quot;ABTMessage&quot; Then
Dim message As ABTMessage = asyncObject
Log(&quot;Async callback: &quot; &amp; message.MessageId)
End If
End If
End Sub

Sub JobDone (Job As HttpJob)
Log(&quot;JobName = &quot; &amp; Job.JobName &amp; &quot;, Success = &quot; &amp; Job.Success)
If Job.Success = True Then
Dim fSave As OutputStream = File.OpenOutput(File.DirApp, Job.tag, False)
File.Copy2(Job.GetInputStream, fSave)
Log(&quot;Error: &quot; &amp; Job.ErrorMessage)
End If
End Sub


Click here to Donation if you like my work


B4R (Basic4Arduino) is coming!

Excellent news from Erel (CEO of Anywhere Software).  The excellent B4X suite will support yet another platform: Arduino!  Next to support for all desktop platforms, webapps, Raspberry Pi, Android and iOS this new addition is another great step from Anywhere Software towards the most simple framework to make IoT applications.

Unlike the other platforms which generate Java, B4R will generate native C.  Users will be able to write their own libraries or use inline C for specific functionalities.  More on this later, but make sure you check out the video!



%d bloggers like this: