yoy.be "Why-o-Why"

Freeware: --- [TreeBrowse] [DirDiff] [DirFind] [odo] [RE] [jsonDoc] [Connect 4] [CursorTime] [MetaClick] [MetaKeys][BarCode] [MailCount] [Ro] [Fa] [WebTop] [SideSwitch]

 actueel beurs coding computers dagboek delphi dotnet film internet muziek politiek tv weblog werk freeware | twitter github reddit linkedin stackoverflow facebook google+ tx

DirDiff v2.0.3.512

2017-10-27 00:19  DirDiff512  coding freeware  [permalink]

DirDiff v2.0.3.512

Fixed issue with UTF-8 sensitive characters in ANSI file.
Fixed issue with Ctrl+Shift+Up/Down past start/end of files list.
Enable switching checkboxes on tree view with space key press.

Spanje, ojÚ ojÚ

2017-10-19 19:33  ES2017  actueel dagboek politiek  [permalink]

O jee, wat zit dat scheef in Spanje! Het lijkt alsof ik nog niet zo lang uitvoerig het nieuws volg, en eigenlijk weet ik nog helemaal niet genoeg over geopolitiek, maar ik begrijp er genoeg van om te snappen dat wat nu gebeurt niet direct voor de beste sfeer zal zorgen in Catalonië. Naar mijn bescheiden mening is er momenteel maar één iets dat Madrid zou moeten doen: een nationaal referendum uitschrijven voor de gehele Spaanse bevolking om nauwkeurig te peilen wat iedereen er van denkt als Catalonië alleen op weg zou gaan. (Eventueel vanuit een uiteindelijke koninklijke opdracht.) Niet alleen weet je zo wat de rest van het land precies erover denkt, maar ook in Catalonië zelf heb je zo misschien een iets accuratere peiling dan de half illegale, half onderdrukte volksbevraging die er nu al geweest was. Daarenboven kan je er mee aan de opstandigen echt laten merken dat je het meent met de zoektocht naar een geweldloze oplossing die voor alle betrokkenen de best mogelijke resultaten belichaamt.

Maar néé, ze lijken precies de tegenovergestelde richting uit te gaan, jammer genoeg. Ik begrijp dat een natie zijn territoriale integriteit wil beschermen, maar als er een constitutioneel bezwaar onder de gemiddelde bevolking leeft, moet die daar toch ook rekening mee houden? Soit de vrees voor gewapend conflict begint er zo wat in te zitten, toch hier in de rest van Europa. Plus dat Europa zelf liever niet heeft dat nu de ene na de andere regio afscheidingsdrang gaat uitwerken. Territoriale drang is zo nu wel bijna een eeuw uit de mode, maar als ik het goed begrijp, en zoals we in Oost-Oekraïne hebben gezien, vanaf voedselprijzen lokaal fel gaan stijgen en andere levensmiddelen ook schaars beginnen te worden, kan het snel nog veel slechter worden.

Update 27/10: volgende fase: er blijkt nu echt onafhankelijkheid uitgeroepen te zijn.

RIP AIM

2017-10-13 13:08  ripaim  [permalink]

Verge: AIM shutting down after 20 years instant messenger

Oh my. Things come and go. But they're inspired by some things, and get replaced by others. I'm not sure this has been written down anywhere, so I feel compulsed to do it here: what's the relation to microblogging and instant messaging?

Ever since we've been hooking up computers to eachother, we've been sending messages. (Just like we did before that, without computers.) At first there were bulletin board systems and then later the internet with e-mail and things, but those slow out-of-sync messages had to have an 'instant' synchronized counterpart. So there was IRC and ICQ and others, each with their specifics that made them interesting.

But when people grow up, there's less to talk about. To remind us why we're not talking, most instant message platforms had something you could write why you're not to be disturbed, that gets to be displayed next to your name in the contacts-list of the people you're listed with. Some people were really creative with this. It would be interesting and enjoyable to look up the history of these messages of these people, just for a laugh or because you could trace where they've been. It was fashionable to change your status several times a day.

Then came Twitter. It hit after the sweet spot right there in the middle. It completely dropped the instant message thing and was a list of status-updates, complete with the limit on the length of the message. Ofcourse people would still (ab)use it to react or reply, so '@' mentions and re-tweets were born and soon after the '#' prefix that would show as a link to the search-list with that lemma. #hastag!  From there it grew into a phenomenon of its own, and gradually lost it implication of an indication of what you're up to.

Er was eens... (Over politiek en statistiek)

2017-10-09 18:03  Polistiek  actueel dagboek politiek  [permalink]

Er was eens een televisieprogramma. Eerst was een politicus aan het woord, legt zijn standpunt uit en haalt cijfers aan van een onderzoek om dat te staven. Daarna krijgt een andere politicus het woord, die een tegenovergesteld gedachtengoed genegen is, legt uit hoe zijn standpunt afwijkt, en haalt ander cijferwerk aan als ondersteuning.

Poef. Beide heren zijn hun geloofwaardigheid kwijt. Dat is toch bij mij het geval. In de grote grijze massa van het legislatief moeras waar we allen de verantwoordelijkheid dragen een scheiding aan te brengen tussen goed en kwaad, botsen we keer op keer op het vrij mogen vormen van een mening. Om toch een akkoord te bekomen over hoe het verder moet, lijkt het soms normaal dat je de ander dan overtuigt van jouw mening. Ik laat het als oefening voor de lezer om te onderzoeken hoe het anders kan, maar als er dan toch moet overtuigd worden, moet er boven al geargumenteerd worden.

Argument per argument sluip je dichter bij het ongelijk van je tegenstander. Een argument staat nergens zonder het cijferwerk. Onderzoeken, statistieken, berekeningen. Die vind je niet zomaar en zijn soms duur om vakkundig op te (laten) stellen. Wil het toeval nu dat allerhande organisaties en stuurgroepen veroordeeld zijn tot een bestaan in de marge, en ze hun budget nuttig besteed doen lijken net door zo'n dingen waar smeerlapperij voor nodig is zoals contact met de burger. Dat de resultaten kant en klaar 'gekaderd' zijn om je argumentatie te staven neem je er schoorvoetend dan maar bij.

Misschien hebben ze daarom het dragen van een das verplicht, als die iedereen een basis betrouwbaarheid geeft, is er aan het begin een gelijk spelersveld. Ik beeld me er dan bij in dat ze zich afvragen hoe ze het doen aan de andere kant van het glazen plafond, maar dat zal aan mij liggen.

Statistiek is saai. Dus de journalistiek is die ook liever kwijt dan rijk, je krijgt er geen extra lezers door. Of confronteert net te veel hoe het zit met die lezers. Of het gebrek daaraan. Dus moet je zelf op zoek. Soms is het een publiek geheim dat bepaalde cijfers waardeloos zijn, soms slagen ze er net heel slecht in om te verbloemen dat de cijfers zomaar uit een donker gat zijn ontsproten.

Soit, we moeten vooruit. Beste politicus, je krijgt mijn stem als je alle cijfers kan kaderen in uw uitgestippelde beleid, en onderwijl armoede, werkloosheid, milieu-problemen en begrotingstekorten kan wegwerken. Wacht, dat komt me bekend voor. Ah, natuurlijk. Mijn fout, dat moet zijn: je krijgt mijn stem als onafhankelijk statistisch onderzoek aantoont dat jouw uitgestippelde beleid armoede, werkloosheid, milieu-problemen en het begrotingstekort zal wegwerken. Succes.

Wat als Limburg onafhankelijk zou zijn?

2017-10-05 09:48  limburg  actueel politiek  [permalink]

→ VRT NWS: Wat als Limburg onafhankelijk zou zijn?

O jee, zo braaf! Wil het toeval nu dat ik ook ooit al eens een denkoefening als deze had gemaakt, en die zag er behoorlijk anders uit. Ten eerste dacht ik meer aan Baskenland in plaats van Catalonië, en dus aan Noord- en Zuid-Limburg samen, een echte grens-kwestie. En twee nationale afscheuringen dus. Maar ook een echte politieke verschuiving. Er ligt namelijk een stukje goed uitgewerkte maar veel te weinig gebruikte spoorweg ten noorden van Maastricht, waar nieuw Limburg plots de volledige controle over krijgt. Als een poort tussen wereld-havens Antwerpen en Gent-Zeebrugge-Terneuzen-Sas-Van-Gent-En-De-Rest-Allemaal en het Ruhrgebied, kunnen ze de prijs zetten die ze willen per goederentrein. Oh, en de Limburgse luchtmacht kan gewoon wel lekker Raffale's kopen, waarschijnlijk.

Momoa

2017-09-26 10:39  momoa  coding  [permalink]

We've had XML. We've had JSON. There's a thing called YAML. And then there's Protocol Buffers and Thrift and a number of others.

And still, with each there's something is not quite right. So here is yet another proposition, humbly offered for adoption:

Binary. Why binary? Parsing speed matters. There's a belief that binary is not human readable, but:

ASCII control codes. Why ASCII control codes? They're out of use. Except 0x0A (and 0x0D) for new lines and 0x09 for tabs. I've come across a 0x0C and 0x1B when talking to printers, but that's it. And all modern editors know what to do with them. Best case may even be they show them as something foreign, but still they're visibliy right there with the other text.

A list of keys and values. It's tempting to provide structure and clearly indicate which is what, but it's unneccessary. A parser is smart enough to know these come two by two, and to pair them up when handing over to something for processing.

Types of values. A value has a preceding byte denoting what it is, and what rule to follow for the succeeding bytes.

0x02 string: read the string up to the next type byte. If a type byte needs to be actually part of the string, escape it with 0x07

0x03 number:  read a string up to the next type byte and convert it from text notation to something numeric. Depending on the context it may be something specific or variadic. By using the text notation we retain some human readability, and also get an acceptable storage to information ratio (smaller numbers take less bytes)

0x05 boolean true: with nothing more

0x06 boolean false: same as above but with opposite value

0x01 embedded key-value list: treat the following sequence of key-value pairs, delimited by a 0x04 closing type byte, as an embedded list

0x08 array: treat the following as a sequence of values only, delimited by a 0x04 closing type byte

There's no specific type byte assigned to null or undefined, but can be encoded as a single 0x03 without data following it.

Keys are themselves values, typically of type string (0x02). A possible permissible exception in specific contexts may be to encode sparse arrays as an embedded list (0x01) where all keys are of type number (0x03).

And now for a name for it... I know, let's type Jason into IMDB... Sounds nice, and serves as a tribute to the artist. So let the file extension be ".momo" and the MIME type be "application/momoa"

About vehicles of the (near!) future: electric or autonomous (not and).

2017-09-18 13:48  autoelec  actueel politiek  [permalink]

Little old humble me will try to give a naunced depiction of their complex and layered opinion about something that's recently been getting some news.

I regret that most news-items on these subjects tend to handle both the new models that have a fully electric drive-train, and the fact that onboard systems of sensors and advanced signals processing may be used to autonomously let these new models operate on the streets.

Not too long ago it was made painfully clear that the seat belt should be mandatory in every automobile, and also the fact of strapping yourself in with them. In a similar light, the design of systems that could handle the performance of said automobiles has indeed proceeded by so much as to have a far better safety record with operating vehicles than us humans. So there's no doubt that the distance between a future where self-driving cars are mentioned in the text of law to some extent, is measured in years, not decades. Perhaps even months since the time is now to begin thinking about authorization and certification.

The matter of a novel power train, on the other side, is a different thing. Electrical vehicles are not new. What is new, is that battery-technology has steadily improved, and that a certain captain of industry has thrown their weight behind an undertaking to launch mass-production of purely electric vehicles(*1), trailblazing into a new domain the settled automobile-constructors weren't committed to explore (yet).  Even more important is that he is succeeding at it. And building a giant battery-producing plant just for it.

What is also painfully clear is that we may just be ahead of the required battery-technology-improvement we actually need. Getting us to drive electric vehicles is hard, not only because we cling to what we know, but also because there's no way to create all the required batteries with the methods for creating them we master now. Also recharging a battery has a vastly different dynamic than refilling a gas tank; this doesn't mean that I think it should. Quite to the contrary, but it should in itself offer an improvement over how we did things before.

Where the automobile-constructors of old are set out to explore, is at the cutting edge if these combustion engines most of us are using. There's an apparent room for improvement, but apparently it only very slowly gets filled. It may have been a very good move to switch 'back' the Formula 1 specifications to a 6-cylinder design with a fuel content more in line with most mainstream vehicles. Any advancements engineered there should find their way in construction of engines a few years down the road. But that apparently takes years.

So that's why the coverage of autonomous electric vehicles kind of rubs me the wrong way. It would be the best thing for us that autonomous cars are here soon, and find mainstream acceptance quick; and that electric vehicles take over the majority when they're ready. With advances made in bio-fuel and high-milage-engines, to be expected over one or more decades, I dare even predict that autonomous control will get even more kilometers out of what you put in, be it liters or Ampère-hours.

(*1): and space-rockets, and solar panels with an in-house battery, and an attempt to improve tunnel-boring.

This one day at work

2017-09-07 11:00  fromthetrenches  computers weblog werk  [permalink]

Here's another nice story 'from the trenches'. Packaging stations use a barcode scanner to scan the barcode on the items that need packaging. We were able to buy a batch of really good barcode scanners, second hand, but newer and better than those that we had. A notice came in from an operator: "with this new scanner, we get the wrong packaging material proposal." The software we wrote for the packaging stations, would check the database for the item which is the best suitable packaging material to package it in. It's a fairly complicated bit of logic that used the order and product details, linked to the warehouse stockkeeping and knows about the several exceptions required by postal services of the different destination countries.

So I checked the configuration of this station first. Always try to reproduce first: the problem could go away by itself, or exist 'between the user and the keyboard', or worse only happen intermittent depending on something yet unknown... Sure enough, product '30cm wide' would get a packaging proposal of the '40cm box' which is incorrect since it fits the '30cm box'. Strange. The station had the 'require operator packaging material choice confirmation' flag set to 1, so I checked with 0 and sure enough, it proposed the '30cm box' (with on-screen display, without operator confirm, just as the flag says)...

So into the code. Hauling the order-data and product-data from the live DB into the dev DB (I still thank the day I thought of this tool to reliably transport a single order between DB's). Opening the source-code for the packaging software, starting the debugger while processing the order, and... nothing. Nicely proposing the '30cm box' every time, with any permutation of the different flags (and there are a few, so a lot of combinations...)

Strange. Very strange. Going over things again and again, checking with other orders and other products, nothing. I declared the issue 'non-reproducable' an flagged it 'need more feedback', not really knowing of any would come from anywhere.

A short while later, a new notice from the same station: "since your last intervention, scanned codes concatenate". What, huh? I probably forgot to switch the 'require operator packaging material choice confirmation' back to 1, but how could that cause codes to concatenate? I went to have a look, and indeed, when a barcode is scanned (the device emulates keyboard signals for the digits and a press of 'Enter') the input-box would select-all, so the number is displayed, and would get overwritten by the next input. This station didn't. The caret was behind the numbers, and the next scan would indeed concatenate the next code into the input field.

Strange. Very strange. Into to the code first: there's a SelectAll call, but what could be wrong with that? And how to reproduce? What I did was write a small tool that displayed the exact incoming data from the keyboard, since it's apparently all about this scanner. Sure enough, the input was: a series of digits (those from the barcode), an 'Enter', and 'Arrow Down'. A-ha! These were second hand scanners, remember? God knows what these scanners were used for before, but if having the scanner send an extra 'arrow down' after each code, is the kludge it takes to solve some mystery problem in software out of your control, than that is what a fellow support engineer has to do... Got to have some sympathy for that. And the '40cm box' was indeed just below the '30cm box' in the list, so the arrow down would land in the packaging material selection dialog, causing the initial issue.

Download the manual for the scanners, scan the 'reset all suffixes to "CR"' configuration code, done.

(Update: got some nice comments on reddit)

Why I choose Delphi

2017-08-15 22:49  whydelphi  coding dagboek delphi  [permalink]

Strange, all these Why I choose Delphi articles lately:

Keep them coming! It's good to see it stressed that it's really a myth that there's not enough Delphi talent out there. Rember, Delphi's debugger by itself is so strong, a decent developer should be able to learn both Delphi and an existing code-base that works just by stepping through the code with the debugger and see what it does. Yes, the language is a little verbose; yes, it's perhaps even older than C/C++; but remember, so is COBOL, and I would almost say that's not cross-platform or a systems language, but those just had other meanings back in the days. (Did you know there's Delphi for AS400?)

So, why do I stick with Delphi? The answer is pretty straight-forward (and perhaps a little sad): give me any kind of computing problem, and I'll find a way to tackle it with Delphi. I've done so much different things, and still found a way to get a great system I enjoy working on, and still have a Delphi project that its compiler happily churns into a binary executable that performs really well. Yes, you could do that also in C/C++/Rust/D/Java/(etc.) but I can't, and don't really want to. There are always up-sides and down-sides,  but it feels like with Delphi you don't meet much of any down-sides, and if you do some-one else knows something to do about it.

Odo v0.4.1.511

2017-06-21 23:15  odo511  freeware  [permalink]

Odo

v0.4.1.511
Fixed a bug that caused mouse clicks not getting counted and nobody told me :,(


delen in de winst? waarom niet sparen

2017-06-12 10:59  liqres2  actueel politiek  [permalink]

Open VLD wil werknemers laten delen in de winst van bedrijven

Ah, zijn de liberalen daar mee bezig? Ik heb een ander idee. Wat als middelgrote bedrijven en grote bedrijven zouden worden verplicht een 'liquidatiereserve' aan te leggen? Een bedrag dat pas vrij komt als een bedrijf er mee wil stoppen of een fractie van zijn personeel aan de deur wenst te zetten.

Ik loop blijkbaar al een tijdje met het idee (2011!) maar het speelt toch maar in je hoofd. Als je weet wat bedrijven kunnen/moeten doen met sommen geld die om verschillende redenen in het bedrijf aanwezig zijn, kan je misschien zelfs verplichten om zo'n fonds lokaal te investeren. Hawel kijk, dat zou zowel de linker- als de rechter-flank dienen. En de lokale economie. (En de schatkist.) En uiteindelijk ook de mensen die jaren de onderneming dienen maar dan moeten afvloeien...

Idea: assembly that flags when to release virtual registers

2017-05-31 23:52  asmvrr  coding computers  [permalink]

I just had a fragment of an idea. I want to write it down, just to let it go for now as I've got other things to do, and to be sure I can pick it up later exactly where I left off.

First situating what it's about: I have been reading up on WebAssembly, and to my surprise the intermediate representation is stack based (just like Java's JVM and .Net's CIL). I'm not sure why because it feels to me this makes registry assigning when constructing the effective platform-dependent instructions harder, but I may be wrong. Finding out objectively is a project on it's own, but sits on the pile 'lots of work, little gain'.

I also went through the great set of MIT 6.004 lectures by Chris Terman which really gives you a good view of 'the other side' of real assembly since it's actually born out of designing these processing units built out of silicon circuits. It prompted me to make this play thing, but again pushing that through with a real binary encoding of the instructions made it a 'lots of work, little gain' project, and I really don't have access to any kind of community that routinely handles circuit design, so it stalled there.

Before that, I read something about hyper-threading, and what it's really about. It turns out modern CPU cores actually handle two streams of incoming instructions, have a set of instruction decoding logic for each stream (and perhaps branch prediction), but share a lot of the other stuff, like the L1 cache,  and especially a set of virtual registers that the logical registers the instruction stream thinks it's using is mapped on to. Mapping used registers freely over physical slots makes sense when you're making two (or more?) streams of instructions work, but it's important to know when the value in the register is no longer needed. Also if the register is only needed for just a few instructions, pipelining comes in to play and could speed up processing a great deal. But for now the CPU has to guess about all this.

When playing around with a virtual machine of my own, I instinctively made the stack grow up, since you request just another block of memory, plenty of those, and start filling it from index 0. It shows I haven't really done much effective assembler myself, as most systems have the stack grow down. What's everybody seems to have forgotten is that this is an ugly trick from old days, where you would have (very!) limited memory and use (end of) the same block for the stack, and with more work going on the stack could potentially grow into your data, or even worse your code, producing garbled output or even crashing the system. (Pac-man kill screen comes to mind, although that's technically a range overflow.) Modern systems still have stack growing down, but virtually allocate a bit of the address-space at the start of that stack-data-block to invalid memory, so stack-overflows cause a hardware exception and have the system intervene. It's a great trick for operating system (and compilers alike) to have checks and balances happen at zero cost to performance.

The consensus nowadays is that nobody writes assembler any more. It's important to know about it, it's important to have access to it, but there is so much of it, it's best left to compilers to write it for you. In the best case it may find optimizations for you you didn't even think about yourself. But this works both ways. Someone writes the compiler(s), and need to teach it about all the possible optimizations. I can imagine the CPU's instruction set manual comes in handy, but that's written by someone also, right? I hope these people talk to eachother. Somewhere. Someday. But I guess they do as with x86-64 they've kind of agreed on a single ABI... and they've also added some registers. Knowing about the virtual registers allocation going on behind the scenes, it could be that that was just raising an arbitrarily imposed limit.

So this is where I noticed a gap. When performing all kinds of optimizations and static analysis on the code when compiling, and especially with register allocation, it's already known when a register's value is no longer relevant to future instructions. What if the compiler could encode this into the instruction bits? If I were ever to pick up where I left, and have a try at a binary encoding for a hypothetical processing core, the instruction set would have bits flagging when the data in registers becomes obsolete. Since this would be a new instruction set, and I guess it's more common to need the value in a register only once, I might make it the default that a value in a register becomes obsolete by default, and you'd use a suffix in assembler to denote you want to use the value for something extra later as well.

MurMurHash3

2017-05-19 20:09  murmur3  delphi freeware  [permalink]

@stijnsanders do you have MurMurHash3 code in pascal aswell ?
i truly liked your optimized code for md5 and all those

— _pusher_ (@_pusher_0x90) 12 mei 2017

Why, thank you. Eeuh, is it at all optimized? I took some decisions that may perform a little better than the reference implementation, but I haven't taken any time to compare to see if it actually performs any better or worse...

So MurMurHash3... Let's have a look, it's on wikipedia, so it's a thing. And the reference C implementation is in the public domain, great! Looks straight-forward enough, could boil down to a translation-job...

Rougly two hours later, got triple zero (0 errors, 0 warnings, 0 hints). Now for checking if I got it all right. Hmm, not much there, but those x32_64 match, so barring any typo's, assuming this pretty straight translate job will result in the expected behaviour for the other two functions, this should be it:

md5.zip (25KB)

Checking xxm for PHP's vulnerabilities

2017-05-12 07:56  xxmphp1  delphi internet freeware  [permalink]

If I read about a newly discovered vulnerability related to PHP, for example this one here, I try to find out if it would apply to xxm as well. 

In this case I guess there's nothing more than sending out the message, again and again, to sanitize your inputs, and poperly encode your output. Strings are never just strings. They are always an internal representation of a bit of textual data. So always think about that taking string values in, and preparing strings for output. A few weeks back I had to speak up to someone who wrote OutJSON:='{"field1":"'+value1+'"}';Little Bobby Tables comes to mind, though I'm not sure 'JSON injection' could be so devastating as SQL injection. (And OutJSON:=JSON(['field1',value1]); is shorter!)

The other time I found out it's a really good idea to strip nastiness like EOL's (CRLF) from headers added to a response, just in case a malicious script is up to no good. Come to think of it, that's also just another case of properly sanitizing your inputs...

Delphi, the shrinking island.

2017-05-09 21:48  delphitrend  coding delphi  [permalink]

Is there a language that has a single word for 'the feeling of being on a shrinking island'? Anyway, this is somewhat sad to see, especially that the few most recent Delphi versions gave the impression there was a new uptake with more people getting persuaded, but it doesn't show in the curve.

(via)

'Relax' scripting vs xxm

2017-04-22 13:12  relaxxxm  coding delphi internet  [permalink]

Delphi Relax Web Scripting (Marco Tech Blog)

I'm sorry but I feel I must react. In general I keep silent, in the hope people by themselves will know better, but as I'm getting no input what-so-ever that that is the case, I feel tempted to write something about this.

First about what's at hand. I see this bit of code:

<h2>Employees</h2>
<ul>
@foreach (var emp in employee) {
  <li>@emp.FirstName @emp.LastName (@emp.PhoneExt)</li>
}
</ul>

and it looks kind-of OK. To the untrained eye it looks good and may even look tempting to write more in this syntax. This is a straight-forward example of a template that works with a templating engine that no doubt has many more capabilities and features. And then I thought, learned from practice, what I typically would get asked is to not show " ()" when the PhoneExt field is empty. I would not know how to make that happen in that template syntax. That's mainly because I know nothing about the template syntax. If I look into the documentation, I might find an @if predicate to make it happen, but let's move on:

This is what it could look like in xxm:

[[!var emp:TEmployee;
<<h2>Employees</h2>
<ul>>
foreach emp in FDMemTable1 do
begin
<<li>>=[emp.FirstName,' ',emp.LastName,' (',emp.PhoneExt,')']<</li>>
end;
<</ul>

Looks roughly simlar. A little more like Delphi syntax. And in fact it is. If you know [[, ]], << and >> get translated into Context.SendHTML() and Context.Send() calls behind the scenes (full details are here),  you know this code will result in the same output. Without templating engine! Streamed to the user's client! Perhaps even while the data is streaming in from the database server, in case it's a longer list, and in case there is a database server, Marco uses a memory-table for his example.

What I find important is that there's less going on between the native compiled logic and getting the data to the user launching a request. Not only a templating engine looks superfluous, this entire ORM thing is something I don't get. If it's a gigantic database model with so much tables that you clearly benefit from code-completion, then I agree, but I haven't come across something remotely close to that in web projects.

Also the HTTP-server itself is something I think that values extra attention. I've seen platforms and frameworks that offer you a wealth of capabilities and features, but hastily slapped on something that listens on TCP port for basic HTTP requests, in some cases on port 80, but more often 8080 or something else in the thousands. In real web environments, the server(s) has/have a lot more going on: load-balancing, reverse proxies, firewalling, authentication. Since we're in a Post-Snowden-era nowadays, we're all responsible to think about protecting privacy and get that HTTPS in order with the proper certification and encryption... Not to mention HTTP version 2 that's heading full steam towards being generally accepted/expected.

I can image the web-admin responsible for all that, isn't happy with your request to add this newfangled separate thing that's doing its own handling of HTTP requests. ISAPI DLL's or Apache modules play much nicer with existing IIS or Apache installations. (FastCGI is on the table, but for now xxm has SCGI available for other servers.) Even if your 'Delphi HTTP framework' of choice is specifically designed to tap your ORM of choice and offer a REST-API for your data-layer needs, it will still be one more stop along the way between the user's browser, and the delivery-setup, and the front-end, and the page-template, and the data-layer, and the database, and what the user actually needs or wants. I think of this in the postal office when there's twelve people in the queue in front of me.

I don't expect to convince much people of this way of working, but it works great for me. I remember the days with early PHP and ASP and how simple and straight-forward everything was. Knowing these work on scripting engines, I kept worrying about lost performance. This was the core reason to start xxm: employ the speed and power of the Delphi compiler to have a native library serve my websites. And it turns out that Delphi code looks quite nice between HTML to handle server-side logic, if I may say so. It took me a few years to make this happen, but I couldn't do without it any more. And people kind-of appreciate that for using this new application, all they need is their trusted browser and a URL.

HTML: label, no more "for" for me!

2017-04-13 22:44  htmllabelfor  coding internet werk  [permalink]

If only I had known sooner! I forgot where I picked this up, but apparently if you put <label> around an <input>, typically of type checkbox or radio, browsers automatically know the label is for that control. Before, I would write my <input id="x"> first, then a <label for="x"> after. To keep code neat, I would put it on a separate line, but the EOL inbetween would not be clickable to actuate the control. This is a really minor issue, but still. Now that I know you can just write this:

<label><input type="checkbox" name="Toggle1" value="1" checked="1" /> Toggle1: clicking text after a checkbox should toggle the checkbox!</label>

Because, there are two kinds of people: those that click the box to switch a checkbox, and those that click the text right of the checbox. You might not even know that you do, but you do don't you. If you're of the latter type, it's just one of those minor frustrations, that a click on the text-label sometimes doesn't do what you expect, and you have to:

  1. first pick up that's this that's going on, possible because you've selected a bit of the text
  2. align your eyes to the checkbox
  3. align the mouse-cursor over the checkbox
  4. click the checkbox, confirming the previous one or more click are actually wasted

But there you have it. Heaven has great UX. Here we need to make do with what we get. (And need to make sure it's the way we like it for those bits that we have control over.)

TMongoWire v1.1, now on jsonDoc!

2017-04-04 19:46  mw_1_1  delphi freeware  [permalink]

→ TMongoWire

This took more effort than I anticipated, but I'm glad I saw it through. A tiny bit of history: when I started creating a Delphi connector to access a MongoDB instance, I had to create the tools to manipulate BSON, and since I really (really!) hate long lists of overloaded methods, I created something based on Variant values. It works great for ADO, so why not. Some time later I had to manipulate JSON, unrelated to MongoDB, so I took what I got, stripped BSON-specifics, into jsonDoc. There it evolved on its own and gained some useful features.

So it was time to re-work TMongoWire, making it use jsonDoc just like any other project. There's still a bit of BSON-specific code, but it deserves a unit of its own.  The downside is there's an extra unit to include in the project, but there were multiple already (jsonDoc, bsonTools, mongoWire and if needed mongoID, mongoAuth3 and mongoStream); the upside is the improved performance and features of jsonDoc, both of the current version and those the future could bring. Enough change to bump that version number:

https://github.com/stijnsanders/TMongoWire v1.1.0

Please let me know if the migration effort this generates is surmountable, and if I can do anything to help. In theory any references to bsonDoc, the BSON function and the IBSONDocument interface should keep working once replaced with references to respectively jsonDoc, JSON and IJSONDocument. The document object no longer implements IPersistStream, but this may have been stretching abstraction just a bit too far. We're on Delphi so plain old TStream should do, and apparently IPersistStream's Seek signature changed a tiny bit over Delphi versions, making it harder to make the code cross-version-ready.

Boxer

2017-03-24 21:57  boxer  delphi werk freeware  [permalink]

Drats. I thought I'll try something like Clover does, start with SetParent on any top-level window you could find with GetAncestor(GetForegroundWindow,GA_ROOT) and see what it gives. There's this old default MDI child mechanic that starts working, so I thought this might just work. But it looks like over at Microsoft the Windows 10 team decided to cut some corners. The theming doesn't do it's modern stuff and reverts to Vista-style borders, and the newfangled calulator, for example, won't even take the SetParent nicely any more. Oh well. For the time I'm still on Windows 7 at work, I guess it'll come in handy there for the time being. Probably in about a week I'll know if this could work where other desktop-management tools failed or were too cumbersome or too invasive...

How does it work? Boxer starts with an empty window, and will show an icon over the top-right corner of other windows. Click that to 'box' the window. The top bar shows a tab for each boxed window. Right-click to open a menu with options to unbox or close, and drag to reorder. Multiple instances play nice with each-other and show 'boxing handles'  next to eachother, the second instance labeled "A", the third "B", etc. To disable the boxing handles, right-click on the top bar to the right of all tabs.

Anyway, if you feel like having a try if you can do better, have a look at the code here. Download a binary here: Boxer.zip (209KB)

A story about two task-keeping-applications.

2017-03-18 17:22  s2tka  coding delphi werk freeware  [permalink]

Let me tell you a story of two task-keeping-applications. Once there was a team that was struggling to keep track of the work it was doing, had done, and still had to do. It was frustrating to work on the team, hard to schedule things, almost impossible to estimate when things where going to get done. And since clients are what they are, changing requirements and additional requests would cause much more disruption than expected of a team that calmly and firmly is determined to deliver the best of market solution.

An internal brainstorming-session about what to do about it, ended in two opposing visions about what decent issue-tracking should be about, and how a system that (co-!)operates with the team members should be structured internally, should behave, and which duties it should perform either by itself, or by effect of using its rules and restrictions correctly as designed.

In an attempt to get to the best solution, two teams were formed to develop each a project based on one of the two views. An evaluation would follow determining a winner, or if would it be possible to synergize the best parts of both into a single system.

A side note: from a managerial point of view this is a very tough decision. Allocating a lot of resources to work on internal structure, takes resources away of the work that brings in revenue, and such undertakings typically risk getting frivolous or spinning out of control. But I guess it's normal that all stop rowing to help keep the boat from sinking. So, apart from being intrinsically aware of the exceptionality of this opportunity, coordinators were given instructions to keep to a strict schedule in these projects and a determined focus on delivering a workable proof-of-concept quick. Sounds like a good work-ethic to apply generally, if you ask me.

A few weeks later progress was made, and the prototypes were already being used to keep track of the issues of these new task-keeping-applications and other projects. The main difference between design visions became apparent soon enough.

One application centered around the list of work items. Care was taken the entry form was extensive enough to have fields for all of the details about a work item, its categorization, its relation to the project, an outline of the projected outcome. An overview would show the current list, possibly filtered for those items assigned to you.

The other application was centered around getting information out of the system, especially structure and relation between items. Users would enter small specific reports, and add them to the best suitable node in a tree-structure, optionally marking relations with other items over branches. The overview showed an expandable structure starting at the root items. It also could have a filter applied, but would potentially show you an entirely different structure of the same data, when using a different relation type.

Having two working prototypes, attention gradually reverted back to the serious work and some of the frustrations of before were abated. After a few months an evaluation was undertaken.

One application had rendered itself useless. The first weeks of usage, a lot of entry happened, but without consensus about categorization, the list was enormous without a clear way of grouping relevant items. Duplicate entries and ambiguous task-descriptions were unresolved, causing confusion.

The other application was doing better. It needed work, but offered a good view of what had to get done.


Enough about the story. Reality, of course, is much more bleak. As no sane manager would make such a shift in resources of a troubled organization, the 'two teams' actually stand for the existing team using an off-the-shelf something badly administered on one side, and on the other side, well, just me, toiling on something potentially better, in my off-time.

I started — like many — with a plain text-file, then a spreadsheet. Then I took the step to design a database for it, but wanted something to do entry and retrieval with roughly the same ease-of-use that a spreadsheet would offer. Working with tree-structures for some other projects, I wanted a single structure to serve as the basis to store data in. Specifically with projects and tasks — as projects tend to have sub-projects, and tasks split into sub-tasks — using branches of a tree would enable to keep this distinction conveniently vague. If you add representation for entities like users and clients into this tree-structure, and relation between nodes over branches, you've got a richness to model much more of the world, and keep track of its changes, past and future.

From there it grew slowly, over years, into what it is now: tx. First versions suffered a notoriously bad interface, but I hope that has improved. For long I was its only user, but some cooperation features have been added since. What's left for me is to keep improving tx where possible, and demonstrating it to people what it's about.

Though entry and structure is important, where a task-keeping-system can really shine is helping to keep an overview. A cleverly designed filter can limit your view to exactly these items that are relevant to you, but in tx you get the additional option of having these items display with exactly those sections of the tree-structure they have in common. Also, I personally feel the most important items on any list, as long as it may be, should be on top. So when tx displays a list of items, they get ordered using their weight, determined by a combination of factors such as task-type and current status. As a task progresses from an active state to a final state, it may move down the list or even fade from view into an archival state.

And there's much, much more I could talk about, but it's all created out of necessity and designed adhering closely to a central vision of what a task-keeping-system should be and what it should be doing for you in order to be able to depend on it.

In conclusion, and for those people that — like me — skip long stories to the last paragraph, it's so very important that information systems succeed at keeping an up-to-date model of reality, and offer you the freedom and easy to update it's view of the world. Especially so with task-keeping software you depend on to keep track of the progress you make with projects, and to help stay on top of what's important. All of that served as the basis for developing tx.

How to import MSXML2_TLB

2017-03-13 15:07  msxml2  delphi  [permalink]

O my god I can't believe this isn't somewhere on the net already! I come across this question and ofcourse there's the default discussion about Indy and OpenSSL/LibreSSL, and Arnaud is very (very!) right about proposing to use WinHTTP. I personally would see if I could do it with MSXML2's XMLHTTP object. Contrary to what it looks like, it doesn't really have to do much about XML, and you can do really almost all of what you need out of a HTTP request with open, setRequestHeader, send and responseText or responseStream, with a much more straight-forward syntax. (If you can live with COM.)

Plus there's another pretty sound reason: back in the days, when using WinHTTP and/or VBScript (for the RegExp component...) you would make it very clear it would only work if you got Internet Explorer version 5.5 or newer installed. "How much back was this?" I hear you ask? It depends, but it's so far back that pretty much all of XML things came after, and XML being to closely related to data-processing, Microsoft needed to put MSXML*.dll deeper into the system than its web-browser. If it's tied to the MDAC or the actual core system I'm, not sure, but years of use and the success of AJAX caused it to get very many security updates. I suspect a far bit more than the DLL that handles your WinHTTP calls...

So, without further ado, do as I do and import the "Microsoft XML" type library in the most recent version you can find on your system:

On old Delphi versions (e.g. the venerable version 7) open 'Projects' on the main menu, then 'Import Type Library...', then select "Microsoft XML, v?.0 (Version ?.0)" from the list. Your system may have multiple versions installed, pick the highest version number (in my case 6.0). Uncheck "Generate Component Wrapper" as usually you don't need this, and actually have the added benefit of automatic reference counting when you use interface references to keep track of COM object instances.

On newer Delphi versions, I've noticed the import functionality has centralised, and is now under the 'Components' menu, the 'Import Component...' option and you need to select "Import a Type Library" from the first list, and then search for "Microsoft XML".

This will result in a automatically generated MSXML2_TLB.pas that you otherwise don't need to worry about. Except perhaps include it in all of your projects you'd launch HTTP requests from.
Use the CoXMLHTTP.Create class function to get a new XMLHTTP instance, and it's open and send methods to make magic happen.

uses MSXML2_TLB;

procedure TForm1.Button1Click(Sender: TObject);
var
r:XMLHTTP;
begin
r:=CoXMLHTTP.Create;
r.open('GET','http://www.google.com/search?q=hello+world',false,EmptyParam,EmptyParam);
r.send(EmptyParam);
Memo1.Text:=r.responseText;
end;

There's more ofcourse. This is just the basics. Depending on what you need to do there's HTTP POST and ways to correctly encode values into the request body you pass to send, using setRequestHeader. And if you need to handle larger chuncks of data, you should check out responseBody and perhaps TOleStream declared in AxCtrls.pas.

jsonDoc, jsonV 1.1.0

2017-03-09 01:22  jsonDoc110  delphi freeware  [permalink]

jsonDoc, jsonV v1.1.0

While working on TRethinkDB, I noticed something was wrong with document re-use. My original idea was to re-use a single IJSONDocument instance to process a list of similar documents, but keep the set of keys allocated, only overwriting the values from the new document. (If you're interested about the code, search jsonDoc.pas for FLoadIndex.) Nothing an extra internal-use interface can't fix. Then I noticed that IJSONDocument.ToString could do with a revision because it wasn't using the new IJSONEnumerator, though it should.

Then I noticed the feature I once added to function JSON, where you could declare embedded documents by listing a value of '[', and closing the document with a key of ']'.  The problem is that '[' could be a perfectly valid value! If it were to come via a variable, that would change the behaviour of the JSON call, and that's a big no-no. Also square brackets usually mean arrays in JSON-land,  so it's perhaps confusing that I chose square brackets because you already need them in the JSON([...]) call. So I changed it into a key suffix of '{', and a closing key of '}', counting on braces being really abnormal in key names. If you really need a key name that ends with '{', don't use the JSON function, but just d['x{']:='y';

A minor downside may be that JSON calls with braces in the string constants, break the comment block if you want to comment out a section of code with braces, but there's always (* *) or //. It by far doesn't outweigh how elegant this new solution is, but it's a breaking change (existing code using '[' values won't work correctly any more), so instead of version 1.0.6 I think it deserves a jump in minor version number to 1.1.0.

While I was at it I fixed some minor issues with jsonV, so remember to update that one as well. Hope you enjoy the changes. (Next up may be replacing TMongoWire's bsonDoc with jsonDoc...)

Aan de oevers van de lijn.

2017-03-07 18:53  lijn  dagboek  [permalink]

Hoe het bij mij zit? Awel kijk. Het is moeilijk om te weten wat er gaat komen. Niemand kan de toekomst voorspellen. Soms is dat jammer, soms lastig. Heel misschien brengt het je angst, maar eigenlijk is het een uitdaging. We moeten ons behelpen met wat we weten van voorgane opvolgingen van oorzaak en gevolg. Dingen die je zelf hebt waargenomen, dingen die andere hebben waargenomen (en al dan niet willen delen). En daar moet je voor een stuk zelf naar op zoek. Je kan wachten tot je het nodige vanzelf oppikt, maar als je weet waar je naar moet zoeken vind je al snel heel veel meer. (Soms zelfs te veel en soms verkeerde dingen, maar da's een ander verhaal.)

Het moeilijkste in het leven is andere mensen dingen doen doen. Dat is zo de laatste paar jaar een motto van me aan het worden. Als het genoegen je te beurt zou vallen dat je van die kleine mensen fatsoen moet bij brengen zal je (nog beter) begrijpen wat ik bedoel. Maar het geldt in het algemeen. Zoals bij katten hoeden is de basis-regel dat je moet proberen maken dat ze willen doen wat het is dat jij wil dat ze doen, maar gelukkig is er nog voor wat hoort wat en misschien zelfs handel in goederen en diensten. Daarbij komt dan een sloot theorie over ethiek en afspraken en gemeenschapsgevoel enzovoort enzovoort...

Misschien lijken die twee niet verwant, maar op een vreemde manier is er wel een fijne samenwerken tussen die twee. Zo is het me gaan opvallen dat als mensen begrijpen dat je iets meer dan de doorsnee bezig bent met wat er komen zal, zowel op korte als lange termijn, en goed over de argumentatie hebt afgewogen, dan krijg je wel eens een doordachte vraag ten gronde over het een of het ander. En dan doet het deugd dat je kan antwoorden en al dat onderzoek van pas komt. Dat er misschien zelfs ook voor nog mensen naast jezelf iets duidelijk wordt over wat er komen gaat. Wat er nog moet gebeuren en wat niet. Dat schept een band. Je wisselt een beetje krediet en/of vertrouwen, en krijg je misschien al eens iets gedaan van mekaar.

Maar dat is een heel gevoelig evenwicht. Het doet goed als dat goed zit, maak ik me zorgen over als dat niet goed zit. Kortom, daar vul ik mijn 10 seconden mee tussen WM_ENDSESSION en Frequency Kenneth

And for the people that do the speaking in English, a while ago I've written here around about the same things.

TRethinkDB

2017-03-06 23:03  TRethinkDB  delphi freeware  [permalink]

Delphi RethinkDB driver

I've given it another try and, in part thanks to a Windows executable that performs well,  and thanks to the gentle people over at the rethinkdb-dev group, I've got something working. It appears the basic functions you would expect from a driver work, but more advanced queries need some more extensive testing. (I've read about a driver testing harnass, but to replicate that around my driver, sounds like a separate project in its own.)

There are some strange sections in the design of ReSQL that show it was written for a weakly-typed language, but using variants and interfaces, I hope I've struck a nice balance between versatility and still having the best suitable methods showing up on auto-completion. Something that should be there may be hidden from view this way, but will probably be because of inaccuracy or error of my part.

Which leaves my in roughly the exact same position as I was closely after completing TMongoWire: having success learning about a new(ish) NoSQL DB the hard way by trying to connect to it directly with Delphi, but nothing in the way of an effective application that would use it for something vaguely useful. I've learned some people have effectively created things with TMongoWire (yey!) but I myself don't really have a good idea (or the motivation) to build something on its own that would use the features of these new database services to their best intent.

If you've got a good idea, please let me know. If you want to know more about TRethinkDB, let me know.

MetaClick v1.3.0.500

2017-02-03 22:54  MetaClick500  freeware  [permalink]

MetaClick v1.3.0.500


 

Archive... Search...