Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by lennart

  1. This is a common Delphi problem. Virus killers etc. Are sloppy and quite a few get flagged with this, until they bother to check more than just the header checksum or verisign resource. The binaries are safe, and we refuse to pay microsoft for a verisign license, because they do this on purpose to force developers to buy expensive signing certificates. We oppose such things on principle. The binaries are clean, checked and double checked. They are buildt in isolation with both microsoft security + virus killers active. We use bought and valid Delphi editions, and the few components we use are likewise clean and properly licensed. So this is a false negative. Please report this to your virus-killer so they can mark it as safe. They just do a checksum compare and often windows will react if you dont have a verisign resource embedded. Most Delphi developers find MS forced policy on this completely unacceptable.
  2. Its on now https://jonlennartaasenden.wordpress.com/2018/09/28/delphi-developer-competition/
  3. lennart

    Send an email ?

    You can force a click on a "a href:mailto" using RTL functionality, but for proper email sending i would write a micro-service in node and delegate it there.
  4. Ah yes this is a classic one. When we made the label control the whole font thing came up and bit us in the bottom. Because Delphi fonts and HTML fonts are very different. You have the "normal" font stuff, but you also have something called CSS fonts, which a lot of people uses. So to avoid killing the option for smart users using css-fonts (and glyphs) in their labels, I isolated the underline/bold etc as a function you call with the caption. If you look in the font class, all the way back to TW3CustomFont (unit System.Fonts), you find this function: function StyleText(const Text: string): string; virtual; What you do is the following: Set the font styles you need Assign the caption via the function above, like this: Label.Caption := StyleText("This is styled text"); I think its time we get rid of this and instead go for "normal" delphi styling. It will require a bit more scaffolding for CSS glyphs and fonts, but at least people can set styles as they are used to. As for the cursor, this is a bug. The label contains sub-constructs that somehow "hide" the underlying element where the cursor is set. So we just need to tell these constructs to inherit whatever cursor the parent has, and it will be gone. So Ill try to get this done in our next update
  5. lennart

    "inline" Keyword?

    Inline is interesting but we have no immediate plans for it. The way JS contexts work makes sub-procedures and anonymous procedures more or less the same thing. Macros in the C/C++ style or templates is much more interesting. Procedure TForm1.Something; var x, y, z: integer; procedure SomethingElse(const CB: TProcedureRef); begin if assigned(CB) then CB(); end; begin SomeThingElse( procedure () begin writeln("Not sure we need inline under JS"); end); end;
  6. lennart

    memo lines ?

    Look at the definition Memo.Lines is defined as an array of string. So you can do: for item in w3memo1.lines do begin writeln(item); end;
  7. lennart


    Awesome! Very interested in this! Cant wait to see more!
  8. TW3Sprite is not really meant for traditional game sprites like you and me know them. The first thing that comes to mind is wrapping the image-change in a TW3Dispatch.RequestAnimationFrame(), but there is no guarantee that it wont flicker. For "real sprites" I added a DrawTile() and DrawPart() functions in TW3Canvas. If you imagine a tile grid over a picture, say 32x32 pixels per tile, you can draw a spesific tile very quickly to the canvas. It will calculate the row/column based on the tile-size + tile number. So if you draw tile #32, and the tileset picture is 640 x 480 pixels in size, and the tile is 32x32 pixels, you get: rows := height div tileheight; if rows * tileheight < height then inc(Rows); cols:= width div tilewidth; if cols * tilewidth < width then inc(cols); RowEntry := tilenumber div rows; ColEntry := tilenumber mod cols; RowEntry := RowEntry * TileHeight; ColEntry := ColEntry * TileWidth; The above is done automatically for you, so you just need to count the tile# and use that. Here is an article predating the canvas update, but it gives some insight into where we took the ideas from. https://jonlennartaasenden.wordpress.com/2014/01/27/codef-for-smart-mobile-studio/
  9. lennart

    parseInt question

    I was about to write that the snippet simply copies 2 by 2 hex characters and then converts that to an integer number. In pure pascal it would be a bit messy since pascal's StrToInt doesnt support hex (unless prefixed by $). ASM sections are very much needed, they might not be pretty (not too fond on them myself) but there are some fundamental code sections that would never work if we used pascal only. Speed is also a factor to keep in mind, especially for procedures that you will call many times. But you seem all set so i'll leave you to it! Happy coding!
  10. Use resourcestrings in a separate unit, easier
  11. Omg.. i am now a shade of pink. I am so sorry about that, ill have it removed asap!
  12. Hi David! The good news is that all the ordinary rules of html apply, everywhere. So you can for example set the text of a line with inline html (see listbox.items.add or listbox.add depending on version): ’<p style=«background-color: #ff0000»>hello red</p>’ The DOM will recognize this and inject it as is, which is both easy and fun. If you need more elaborate styling you might want to check the SmartCL.%css% units. There is a global stylesheet where you can inject full styles and then use that instead of inline styling. let me know if you run into difficulty
  13. This we found our culprit: procedure TW3CanvasFont.ReadFontInfo; begin end; It doesnt parse the font information and expects to inherit from the container. This works fine on visual controls (TW3GraphicControl) but will naturally be a problem on a raw device context
  14. Hm, this is strange. The exposed "font" property of TBitmap is just a proxy, it relays the font property of TW3Canvas - which is the HTML5 canvas for that context. The canvas/bitmap stuff was a bit tricky because under HTML5 its completely opposite of what we have in Delphi or FPC. We are used to creating a bitmap and then attaching a TCanvas to that bitmap -- but in html5 the canvas holds the data while the context delegates access. But then again, everything in the JS world is topsy turvey at times. Its a bit like going from ordinary physics to quantum physics - you can throw your old notions of solid reality out the window This should be easy enough to fix. The legacy unit was initially something I made for a demo earlier, but since it made porting delphi code easier I figured it could also help others. This is why it has escaped the more hard-core testing that we did on the visual components and low-level namespaces. But ok, lets fix this and get it out Also -- there is no need to go via the handle, the old "font" text property was just renamed to "FontStyle" since that's what it does. We had to do this to make room for TFont.
  15. Have a look in SmartCL.System, scroll down to line 1113, there you will find the class TW3URLObject: TW3URLObject = static class public class function GetObjectURL(const Text, Encoding, ContentType, Charset: string): string; overload; class function GetObjectURL(const Text: string): string; overload; class function GetObjectURL(const Stream: TStream): string; overload; class function GetObjectURL(const Data: TAllocation): string; overload; class procedure RevokeObjectURL(const ObjectUrl: string); // This cause a download in the browser of an object-url class procedure Download(const ObjectURL: string; Filename: string); overload; class procedure Download(const ObjectURL: string; Filename: string; const OnStarted: TProcedureRefS); overload; end; This should make it easier. Also look at TAllocationHelper, which targets TAllocation - used by TMemoryStream and TBinaryData (system.memory.buffer).
  16. In all probability "something" in the project causes the background compiler to go bananas and kills the thread. This has happened in some rare cases when inline JS is used, but i think we have seen 2-3 of these over 8 years, so very rare. Like Jarto says its impossible to figure out "what" causes this from a stack-trace, that only tells is the entrypoint in the IDE which in all likelyhood is not the culprit. We really want to find out what this is so we can get rid of the behavior, so if you can share the code that would really help!
  17. You dont do threads in JS unless its exceptionally important. Server side you delegate work between processes, as in shell-execute and then passing work to it via node's message channel. So lets say you have a heavy duty server and for some reason need threading, you would write the thread code as a completely separate node application. In the server you would then start the process on demand and then pass the socket-handle (the request object) to the newly created process. This is the same as threading but easier to build up on since you are using the outer layer of shell/os. You can also use web-workers, which are threads, but still need to pass the request object (or whatever else you need) via messages, so most people just spawn a new process and pass in the request to handle it. So a low down would be: Server accepts request Server creates a process for handling the request Server pass the http/websocket request to the process process does whatever its designed to do Server is notified when the process is done or have failed So its more or less the same. I should underline that the whole point of ASYNC coding is to avoid threading as much as possible, but i realize that this mindset can be a bit alien for beginners in Smart Pascal - so you can evolve with it safely as you get more into it When it comes to DB then yes, absolutely - but im not sure there is a SQL server wrapper for it. But node supports just about every DB engine out there. Its one of the engines I will write a connection class for in our next 2 updates. SQLite is already there (actually we have 2, one via node and one we compiled to asm.js ourselves), mariadb (mysql), MSSQL, Firebird and oracle is on my list. Simply google if node.js can do it -- if it can, we can do it also. But when importing modules like this, someone have to write a wrapper. Its like delphi when using a dll file, you have to write defines for the methods etc. and load in the module before using it. So its fairly identical to how you work with external code in delphi. Visit NPM and have a look, there are quite a bit to pick from https://www.npmjs.com/search?q=SQLServer
  18. The & is as you say, just to make it not collide with reserved names
  19. lennart


    Good write! Also make sure the IE patch is included when using this code, since "array.indexOf()" doesnt exist in pre Edge browsers. "inherited" also has no meaning when using JObject etc. because they are compiled without a VMT and are thus without inheritance in the object pascal/C++ way of thinking
  20. lennart

    Freeing objects?

    The parent of a control will always release the child elements. So you dont have to release buttons added to a toolbar for example. When writing custom-controls however, it is good practice to clean up in the FinalizeObject() method. But the container control at the root of the RTL will clean up any lingering components that exists on a control.
  21. lennart

    loading images

    It is a standard property available for JS developers. There was no other reason for adding it than making it available also to Smart developers. It was unfortunate that it was initialized with "anonymous", which sadly is the cause of this mess. My apologies
  22. One thing I noticed is that you pass TRUE as the second parameter of RegisterForm -- This should only be done once. The TRUE defines that the registered form is the "main" form. So only one should have TRUE while all the others should be false. I also suspect that you should wait for the instance to finish before jumping (since you have modified the start code directlt): TW3Dispatch.WaitFor([form1,form2,form3], procedure () begin Application.GotoForm(bla bla bla); end);
  23. Its actually one of the coolest things about node.js! Node also has clang (c++ compiler) built-in, so if you use native packages it will actually re-compile node.js on the spot (!) But the majority of modules are raw JS and can be safely copied between systems. So you can write a server on windows, and just copy it to linux without any change
  24. Have you installed the websocket package in the output directory? You write "I installed nodejs websocket" but it has to be the "ws" package and it has to be in the same folder as the project compiled file. 1. Open shell (CMD) and cd to the project folder 2. CD into the output folder (just compile to create it) 3. in the shell window, type "npm install ws". Npm (node package manager) will now download and place the ws (websocket) package files relative to the compiled *.js file (your compiled project file). 4. then run the project Note: To build a dependency file, add the "--save" param to the NPM command, it will then create a packages file. This is cool when you want to push your code to amazon etc. because node will then notice this and install all the dependencies in one-go I tested your code and it worked on the first try after i installed the ws library
  25. The system.dateutils unit have everything you need
  • Create New...