The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,860 other subscribers

Archive for December, 2020

Old New Thing IAccessible examples

Posted by jpluimers on 2020/12/17

The blog examples are only two:

The book has more: The Old New Thing: Practical Development Throughout the Evolution of Windows – Raymond Chen – Google Books

jeroen

Posted in COM/DCOM/COM+, Development, Software Development, The Old New Thing, Windows Development | Leave a Comment »

List Of Windows Messages – WineHQ Wiki

Posted by jpluimers on 2020/12/17

Easiest way to find which message # (decimal or hexadecimal) belongs to which message and vice versa:

None of the lists are completely accurate, but they get you going.

For comparison: an early Windows 10 SDK WinUser.h and [Archive.is] NativeMethods.cs

Translations:

–jeroen

Posted in C, C++, Delphi, Development, Software Development | Leave a Comment »

Indy10, TIdSMTP, how to get protocol log?

Posted by jpluimers on 2020/12/17

Indy is great, but not well documented so: [WayBack] Indy10, TIdSMTP, how to get protocol log? I try to get log from SMTP communication, like this (copy from wiki): {code} S: 220 smtp.example.com ESMTP P… – Jacek Laskowski – Google+

Q

Indy10, TIdSMTP, how to get protocol log?

I try to get log from SMTP communication, like this (copy from wiki):

{code}
S: 220 smtp.example.com ESMTP Postfix
C: HELO relay.example.com
S: 250 smtp.example.com, I am glad to meet you
C: MAIL FROM:<bob@example.com>
S: 250 Ok
C: RCPT TO:<alice@example.com>
S: 250 Ok
C: RCPT TO:<theboss@example.com>
S: 250 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "Bob Example" <bob@example.com>
C: To: Alice Example <alice@example.com>
C: Cc: theboss@example.com
C: Date: Tue, 15 January 2008 16:02:43 -0500
C: Subject: Test message
{code}

but without success :-(

I try use many events from TIdSMTP, TIdLogEvent, TIdSSLIOHandlerSocketOpenSSL but result is low level like bytes, status etc. not true SMTP log.

How to do it?

A

Sending stuff still might be tough, so you might want to consider alternatives too: [WayBack] I need to add to the REST server the ability to send emails with attachments of different types. Which library is best to use? Indy or maybe ICS? Of cou… – Jacek Laskowski – Google+

Q

I need to add to the REST server the ability to send emails with attachments of different types. Which library is best to use? Indy or maybe ICS? Of course with SSL/TLS support.

A

Dany Marmur's profile photo

+Balázs Szakály, YES! Synapse. Let’s get people using it more. You can give it some criticism surely, but consider the pro’s:

It is straight-forwardly-written so when you hit a wall you can read the code easily (compared to other solutions),

You can inherit, extend and extrapolate, re-use and tweak,

Very Delphi-ish (TMimeMessages = TStringList or some such, not at at devmachine atm)

Compact and free!

Quite stable too.

–jeroen

Posted in Communications Development, Delphi, Development, Indy, Internet protocol suite, SMTP, Software Development | Leave a Comment »

git the meaning of `–` is to treat the rest of the arguments as file names (Hard reset of a single file – Stack Overflow)

Posted by jpluimers on 2020/12/16

Learned TWO things at once Mark Longair and VonC at [WayBack] git – Hard reset of a single file – Stack Overflow :

You can use the following command:

git checkout HEAD -- my-file.txt

… which will update both the working copy of my-file.txt and its state in the index with that from HEAD.

-- basically means: treat every argument after this point as a file name. More details in this answer. Thanks to VonC for pointing this out.

Related:

Read the rest of this entry »

Posted in Development, DVCS - Distributed Version Control, git, Software Development, Source Code Management | Leave a Comment »

Spinettaro’s Blog: Delphi Flux application architecture

Posted by jpluimers on 2020/12/16

On my list of things to try: [WayBack] Spinettaro’s Blog: Delphi Flux application architecture.

It is about a Delphi implementation of the Facebook Flux application architecture.

Related:

Via: [WayBack] Delphi Flux application architecture A good application architecture Finding a good application architecture is not easy, but defining an architecture f… – Daniele Spinetti – Google+

Note that by using the [WayBack] CodeRage 2018 Replay | Embarcadero Academy, you are disallowed using any of what you learn in a commercial way.

Embarcadero evangelists told the public that for the Community Edition, similar terms would not be upheld, but then the sales department started sending out nasty emails to people registering Community Edition using their work email address.

[WayBackhttps://www.embarcaderoacademy.com/p/terms:

under this license you may not:

  1. modify or copy the materials;
  2. use the materials for any commercial purpose, or for any public display (commercial or non-commercial);
  3. attempt to decompile or reverse engineer any software contained on the School’s web site;
  4. remove any copyright or other proprietary notations from the materials; or
  5. transfer the materials to another person or ‘mirror’ the materials on any other server.

–jeroen

Read the rest of this entry »

Posted in Delphi, Development, JavaScript/ECMAScript, Scripting, Software Development, Systems Architecture, TypeScript | Leave a Comment »

System.SyncObjs.TLightweightSemaphore.Create: the AInitialCount parameter

Posted by jpluimers on 2020/12/16

Multi-threading is hard, knowing your primitives is important, but Embarcadero documentation is always far from complete, leading to [WayBack] System.SyncObjs.TLightweightSemaphore.Create: Please simply explain to me the parameters of this constructor, especially first, AInitialCount… – Jacek Laskowski – Google+

The concept of semaphores is universal (the free book [WayBack] The Little Book of Semaphores – Green Tea Press is great), but the implementation/wrapping can slightly differ, so on the [Archive.is] XE introduced TLightweightSemaphore.Create parameters:

  • Primož Gabrijelčič's profile photo

    Semaphore is used to allow ‘counted’ access. It allows access to as much owners as it has maximum count. If you wait on a semaphore (WaitFor) and wait succeeds, the semaphore’s count is decremented. When it drops to 0, no new Wait will succeed.

    When you call Release, the semaphore’s count is incremented which allows somebody else to own the semaphore.

    Parameters simply set the initial state for this count and maximum value of the counter. Usually you’ll both set to the same value.

  • Primož Gabrijelčič's profile photo

    If you intend to use semaphores, read this. Great book.

    The Little Book of Semaphores – Green Tea Press
    greenteapress.com
  • Jacek Laskowski's profile photo
    I know (theoretically) how a semaphore works. I even used this semaphore class in production code.
    I want to create as many threads as there are cores in the processor (+ 1 additional, little loaded).fCoreController := TLightweightSemaphore.Create(TThread.ProcessorCount, TThread.ProcessorCount + 1);But now it turned out that customers who have CPUs with one core (yes, there are those), this code blocks the remaining threads. And I am looking for a reason, maybe I misunderstand this semaphore. What does AInitialCount mean?

    ps. Delphi Seattle

  • Stefan Glienke's profile photo
    AInitialCount is the number of entires a semaphore has left when created. If that is one less than AMaxCount that means you already gave one entry away. I just do a wild guess and say that you might do a Wait on the created semaphore shortly after creating it and in some other thread as well but since for one CPU your AInitialCount is only 1, one of them will block – possibly you created a deadlock situation here.
  • Jacek Laskowski's profile photo
    +Stefan Glienke Ok, if I want threads to be given a semaphore so that they work when it’s open (thread execute -> Semaphor.WaitFor) and I want to have as many threads as there are cores (+1 additional) then how should I create TLightweightSemaphore object?
  • Stefan Glienke's profile photo
    What Primoz said at the end of the very first comment – put same value for both: TThread.ProcessorCount + 1
  • Jacek Laskowski's profile photo

 

–jeroen

 

Posted in Delphi, Development, Multi-Threading / Concurrency, Software Development | Leave a Comment »

Alternatives to UUID/GUID as database keys

Posted by jpluimers on 2020/12/15

For my link archive:

–jeroen

Posted in Database Development, Development, PostgreSQL, Software Development | Leave a Comment »

I really wish people reporting bugs provide more factual details, especially when asked for

Posted by jpluimers on 2020/12/15

Basically the below thread goes like this: [WayBack] GExperts / Bugs / #92 Grep cannot handle UTF-16 and UTF-32 pas files

  1. There is a bug in UTF-16 and UTF-32 handling in your tool when running under AAA, but  not when running your tool under BBB; these files fail: xxx.txt  and yyy.txt
  2. Which version of our tool did you run under AAA and which version of our tool did you run under BBB
  3. It fails with your tool when running under AAA , but succeeds under BBB
  4. Repeat at step 2 until you fall asleep.

Part of the [WayBack] Short, Self Contained, Correct Example are indeed in it, but without more details it is hard to reproduce.

So without the reporter providing those details, nobody, especially not on open source projects, is going to fix it just on that bug report.

Via: [WayBack] It’s time for a gift to all Delphi developers, a new Release of GExperts. Happy Holidays! (But do spend some time with your family rather than testing G… – Thomas Mueller (dummzeuch) – Google+

Which highlights another conceptual problem from the same bug reporter: expecting a new version to have a regression of all open bugs against the new version.

That’s not how the world works, if it has ever worked that way. If your issue is not mentioned in any release notes, then assume nothing happened. If you want to bump it up, then provide more details.

–jeroen

Posted in Conference Topics, Conferences, Development, Event, How to report bugs, Issue/Bug tracking, Software Development | Leave a Comment »

In Delphi, avoid having a TComponent descendant implement interfaces, unless you are prepared to handle your refcounting

Posted by jpluimers on 2020/12/15

Every now and then I see code, where a class descending from TComponent implements some interfaces, only interface references are used to the instances, and the expected behaviour is that the instances will free themselves when all the references went out of scope.

Bummer: TComponent by default is not reference counted.

It is when you assign VCLComObject an IVCLComObject which is hell to implement (Delphi provides two of them: TVCLAutoObject and TActiveFormControl. They sound heavey, and are).

Do not go that way. If you need some form of ownership in a class implementing an interface, then descend the class from TInterfacedObject, and add a field of TComponent that is the owner of things that need to be freed later on. In the destructor, free that field.

Something like this:

unit InterfacedObjectWithRootUnit;

interface

type
   TInterfacedObjectWithRoot = class(TInterfacedObject)
   strict private
      FRoot: TComponent;
      function GetRoot: TComponent;
   strict protected
      property Root: TComponent read GetRoot;
   public
      destructor Destroy; override;
   end;

implementation

destructor TInterfacedObjectWithRoot.Destroy;
begin
  if Assigned(FRoot) then
  begin
    FRoot.Free();
    FRoot := nil;
  end;
  inherited Destroy();
end;

function TInterfacedObjectWithRoot.GetRoot: TComponent;
begin
  if FRoot = nil then
    FRoot := TComponent.Create(nil);
  Result := FRoot;
end;

end.

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

RAMBOOT – booting Linux into a RAM disk…

Posted by jpluimers on 2020/12/14

Interesting as this should work for other Linux distributions as well: [WayBack] RAMBOOT – How to booting Debian into a RAM disc for speed and silence. How to RAMBOOT. It’s a poor man’s SSD, or a way to get SSD benefits on a laptop … – Isaac Kuo – Google+

Via: [WayBack] RAMBOOT – How to booting Debian into a RAM disc for speed and silence. How to RAMBOOT. It’s a poor man’s SSD, or a way to get SSD benefits on a laptop … – Jürgen Christoffel – Google+

Covers: [WayBack] RAMBOOT is an initrd hack that loads the entire OS partition in RAM, making it run like an extremely fast SSD, at the expense of perhaps 1.5+GB of RAM.

A quick search revealed these:

–jeroen

Posted in *nix, *nix-tools, Linux, Power User | Leave a Comment »