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,835 other subscribers

Archive for the ‘Development’ Category

Toegankelijkheid is een recht, geen optie. Voor zowel overheid, als private bedrijven en instellingen dus een plicht in redelijkheid daarvoor te zorgen.

Posted by jpluimers on 2021/06/08

Uit een thread die een stuk onbenul aan de kaak stelde, kwam iets moois:

[WayBack] Max Verslakken 🌈 on Twitter: “‘Ik, een lopende persoon, bepaal wel effe voor mensen met een handicap wat er toegankelijk moet worden.’ Nieuwsflits: toegankelijkheid is een recht..…”:

Om precies te zijn: met de ratificatie van het #VNverdrag Handicap heeft Nederland als staat/overheid de plicht om toegankelijkheid te vergroten (zie vooral artikelen 4 en 9 van dit verdrag, wetten.overheid.nl/BWBV0004045/20…). Daarbij speelt ‘redelijk’ wel een rol, zie o.a. artikel 2. 1/2
2/2 Zo’n plicht was er nog niet voor private organisaties (zoals pretparken), maar die is er nu wel met Besluit Toegankelijkheid (zoek.officielebekendmakingen.nl/stb-2017-256.h…). Het is de plicht om ‘iets’ te doen voor algemene toegankelijkheid, waarbij ‘redelijk’ en ‘geleidelijk’ wel een rol spelen.
Tot slot: in het Besluit Toegankelijkheid staan enkele voorbeelden, zie de toelichting bij artikel 6. Wat ‘redelijk’ is, hangt af van o.a. de omvang van de organisatie, zie artikel 7. Zo mag je van bijv. een grote supermarkt veel meer verwachten/eisen dan van een kleine bakkerij.
Nog 1 P.S. 😉. Geert schrijft “alle attracties in een pretpark voor iedereen toegankelijk lukt niet”. Op korte termijn lukt dat idd niet, maar op langere tijd is veel mogelijk. Dat houdt die ‘geleidelijkheid’ in: niet alles hoeft meteen, maar er moet wel steeds vooruitgang zijn.

–jeroen Read the rest of this entry »

Posted in accessibility (a11y), Development, Software Development | Leave a Comment »

Delphi: some notes on HModule while tracking down an access violation in TRegGroups.UnregisterModuleClasses

Posted by jpluimers on 2021/06/08

Too bad the whole mechanism involving TRegGroups.UnregisterModuleClasses is not documented anywhere

It is the underlying storage to support TClassFinder, which was introduced in Delphi 6, documented on-line in Delphi 2007, documented slightly in Delphi 2009, and since Delphi 2010 only one line of documentation was added (including the unchanged “instatiated”):

  • Delphi 2007: [WayBack] TClassFinder Class

    This is class Classes.TClassFinder.

  • Delphi 2009:[WayBack] TClassFinder Class

    The TClassFinder allows the list of registered persistent classes to be retrieved. Objects instatiated from persistent classes are those that can be stored (serialised) beyond the operation of the current application.

  • Delphi 2010:[WayBack] Classes.TClassFinder – RAD Studio VCL Reference

    TClassFinder allows registered persistent classes to be retrieved.

    The TClassFinder allows the list of registered persistent classes to be retrieved. Objects instatiated from persistent classes are those that can be stored (serialised) beyond the operation of the current application.

Back to TRegGroups.UnregisterModuleClasses: it takes a HMODULE parameter and ultimately gets called through the (since Delphi 2007) on-line documented [WayBack] Classes.UnRegisterModuleClasses Function

procedure UnRegisterModuleClasses(Module: HMODULE);

Call UnRegisterModuleClasses to unregister all object classes that were registered by the module with the handle specified by the Module parameter. When a class is unregistered, it can’t be loaded or saved by the component streaming system.

After unregistering a class, its name can be reused to register another object class.

To get more context about the access violation, I used both the stack trace and a debugging watch for GetModuleName(Module) (using the [WayBack] SysUtils.GetModuleName Function).

In order to see which classes were registered by what module, I set a breakpoint at in TRegGroup.AddClass (which can be called through various code paths):

procedure TRegGroup.AddClass(AClass: TPersistentClass);
begin
  FGroupClasses.Add(AClass);
end;

HModule

That gave me the class, but I also needed the HModule for a class, so I did a windows get module of currently executing code – Google Search, giving me these links, all C/C++ related:

Here you already see some confusion: there is HINSTANCE and HMODULE. That’s a historic thing, as described by Raymond Chen in [WayBack] What is the difference between HINSTANCE and HMODULE? | The Old New Thing:

They mean the same thing today, but at one time they were quite different.
It all comes from 16-bit Windows.
In those days, a “module” represented a file on disk that had been loaded into memory, and the module “handle” was a handle to a data structure that described the parts of the file, where they come from, and where they had been loaded into memory (if at all). On the other hand an “instance” represented a “set of variables”.
One analogy that might (or might not) make sense is that a “module” is like the code for a C++ class – it describes how to construct an object, it implements the methods, it describes how the objects of the class behave. On the other hand, an “instance” is like a C++ object that belongs to that class – it describes the state of a particular instance of that object.
In C# terms, a “module” is like a “type” and an instance is like an “object”. (Except that modules don’t have things like “static members”, but it was a weak analogy anyway.)

GetModuleName

Searching for delphi “__ImageBase” – Google Search then got me [WayBack] c++ – Get DLL path at runtime – Stack Overflow with a nice Delphi related answer by [WayBack] Ian Boyd:

For Delphi users:

SysUtils.GetModuleName(hInstance);              //Works; hInstance is a special global variable
SysUtils.GetModuleName(0);                      //Fails; returns the name of the host exe process
SysUtils.GetModuleName(GetModuleFilename(nil)); //Fails; returns the name of the host exe process

In case your Delphi doesn’t have SysUtils.GetModuleName, it is declared as:

...

This reassured my use of [WayBack] SysUtils.GetModuleName code was OK:

function GetModuleName(Module: HMODULE): string; 
var
  ModName: array[0..MAX_PATH] of Char; 
begin
  SetString(Result, ModName, GetModuleFileName(Module, ModName, Length(ModName))); 
end;

HInstance in Delphi

The example from Ian Boyd also brought back memories from long ago about the [WayBack] HInstance Variable – Delphi in a Nutshell [Book]:

Read the rest of this entry »

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

List views in Oracle database – Oracle Query Toolbox

Posted by jpluimers on 2021/06/03

[WayBack] List views in Oracle database – Oracle Query Toolbox

A. All views accessible to the current user

select owner as schema_name, 
       view_name
from sys.all_views
order by owner, 
         view_name;

B. If you have privilege on dba_views

select owner as schema_name, 
       view_name
from sys.dba_views
order by owner, 
         view_name;

(more details in the above post)

–jeroen

Posted in Database Development, Development, OracleDB | Leave a Comment »

Thread by BiancaPrins: 8 simple steps to improve your site accessibility

Posted by jpluimers on 2021/06/03

[WayBack] Thread by @BiancaPrins: “@jpluimers @rulesbyrosita in begint met simpele dingen: 1) plaats alternatieve tekst bij foto’s (of duidelijke omschri […]” #toegankelijkheid #IT #a11y.

I need to translate it:

#toegankelijkheid in #IT begint met simpele dingen:

1) plaats alternatieve tekst bij foto’s (of duidelijke omschrijving eronder)
2) Voorzie filmpjes van ondertiteling en audiodiscriptie
3) gebruik standaard headers altijd in de juiste volgorde

#a11y 1/2

4) bij laag contrast ‘merk kleuren’ groter lettertype en bold font
5) bij voorkeur geen Italic font gebruiken
6) zorg dat alleen links underlined zijn en hyperlink met ‘weer te geven tekst’
7) duidelijke structuur
8) ‘knoppen’ voorzien van label

Via: [WayBack] Jeroen Pluimers on Twitter: “Wat kan ik beter doen op https://wiert.me ? Hoewel eigenlijk bedoeld voor mezelf als offline geheugen, trekt het dagelijks een berg bezoekers, dus het kan vast beter toegankelijk worden…”

Related:

–jeroen

Posted in accessibility (a11y), Development, Software Development, Usability, User Experience (ux) | Leave a Comment »

Who maintains GExperts · GitHub?

Posted by jpluimers on 2021/06/03

I wnder who maintains [WayBack] GExperts · GitHub:

GExperts has 4 repositories available. Follow their code on GitHub.

It has not been updated for about 5 years, but contains some important bits.

–jeroen

 

Posted in Delphi, Development, GExperts, Software Development | 1 Comment »

Microsoft subdomains

Posted by jpluimers on 2021/06/02

Almost every company I know has more than one subdomain, but while researching why support.microsoft.com could not be archived in the WayBack machine, I realised how many they have and bumped into a few sites listing most of them:

All via microsoft.com subdomains – Google Search.

–jeroen

Posted in Development, DNS, Internet, Power User, Software Development, Web Development | Leave a Comment »

Every site should have a script like web.archive.org/__cleancookies__.html

Posted by jpluimers on 2021/06/02

I run in too many sites that keep creating new cookies, but never delete the old ones, ultimately leading to 5xx errors.

Every site should have a page like [WayBack] web.archive.org/cleancookies.html that cleans non-current cookies.

So I copied toe source to [WayBack] Copy of https://web.archive.org/cleancookies.html · GitHub for inspiration to look at.

–jeroen

Read the rest of this entry »

Posted in Development, Power User, Software Development, Web Development | Leave a Comment »

Delphi: Passing build variables to batch files; I think the easiest is to use environment variables

Posted by jpluimers on 2021/06/02

A long time ago, I wrote about Delphi prebuild/prelink/postbuild events.

In practice, especially that you cannot inherit build events, then add new ones (), it is convenient to put all you need in a script, for instance a batch file.

Passing parameters to that script, then in my experience, is easiest to do as environment variables.

That way you can do this in a script:

> %temp%\build.txt echo ~dp0=%~dp0
>> %temp%\build.txt echo $(BDS)=%BDS%
>> %temp%\build.txt echo $(INPUTDIR)=%INPUTDIR%
>> %temp%\build.txt echo $(PROJECTDIR)=%PROJECTDIR%
>> %temp%\build.txt echo $(OUTPUTDIR)=%OUTPUTDIR%
>> %temp%\build.txt echo $(Platform)=%Platform%

if "%OUTPUTDIR:~0,2%"==".." set OUTPUTDIR=%INPUTDIR%%OUTPUTDIR%
>> %temp%\build.txt echo $(OUTPUTDIR)=%OUTPUTDIR%

Passing the parameters and calling the script results in this build event contents:

set Platform=$(Platform)
set INPUTDIR=$(INPUTDIR)
set PROJECTDIR=$(PROJECTDIR)
set OUTPUTDIR=$(OUTPUTDIR)
call ..\post-build-event.bat

The IDE then shows this fragment in the project output:

Target PostBuildEvent:
    set Platform=Win32&&set INPUTDIR=D:\Versioned\TestRepostitory\Test Project With Spaces\&&set PROJECTDIR=D:\Versioned\TestRepostitory\Test Project With Spaces&&set OUTPUTDIR=..\EXE Output Directory With Spaces\&&call ..\post-build-event.bat

The above batch file also shows things:

  1. how to handle relative directories in the OUTPUTDIR build parameter: check if the first two characters are .. (trick via [WayBack] Check if Batch variable starts with “…” – Stack Overflow).
  2. spaces are handled fine without any need to double quote the set assignments
  3. build-event lines are concatenated using the && success operator
  4. Parameters INPUTDIR and OUTPUTDIR end with a backslash, but PROJECTDIR does not (Delphi prebuild/prelink/postbuild events explains more about the parameters).

Note:

  • environment variable BDS does not end in a backslash
  • expansion %~dp0 does end in a backslash

With this trick now you can copy BPL files for the right platform:

xcopy /y "%BDS%\Redist\%Platform%\rtl250.bpl" "%OUTPUTDIR%"

Note that the LibSuffix (with value 250 for Delphi 10.2 Tokyo) is not available as environment variable, nor build parameter. The environment variable ProductVersion however (with value 19.0 for Delphi 10.2 Tokyo) is. So technically, you could make a mapping.

–jeroen

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

The two states of a programmer, a superposition

Posted by jpluimers on 2021/06/01

I have no idea how old it is, but it is still so true:

The two states of a programmer:

  • I am God.
  • I have no idea what I am doing.

Every programmer exists in a superposition of these two states. The exit code will determine which.

I saved the reddit thread of the image, and would love to know who to attribute the quote and image to.

[WayBack] Every programmer exists in a superposition of these two states. The exit code will determine which. : ProgrammerHumor.

[WayBack] Reddit image lno93dc8d5c21.jpg (600×450):

–jeroen

Read the rest of this entry »

Posted in Development, Fun, Software Development | Leave a Comment »

c++ – DLL Load Library – Error Code 126 – Stack Overflow: use Process Monitor, search for the first NAME NOT FOUND

Posted by jpluimers on 2021/06/01

In addition to [WayBack] c++ – DLL Load Library – Error Code 126 – Stack Overflow while debugging LoadLibrary error 126

Windows dll error 126 can have many root causes. The most useful methods I have found to debug this are:

  1. Use dependency walker to look for any obvious problems (which you have already done)
  2. Use the sysinternals utility [WayBack] Process Monitor – Windows Sysinternals | Microsoft Docs from Microsoft to trace all file access while your dll is trying to load. With this utility, you will see everything that that dll is trying to pull in and usually the problem can be determined from there.

Search for the first entry NAME NOT FOUND after your library is being loaded.

It indicates the module that cannot be found which indirectly causes error number 126 (ERROR_MOD_NOT_FOUND in [WayBack] System Error Codes (0-499) – Windows applications | Microsoft Docs ) in [WayBack] LoadLibrary:

 

ERROR_MOD_NOT_FOUND

126 (0x7E)

The specified module could not be found.

 

This is why I upvoted the very relevant comment:

… when I looked at the rows surrounding my dll being loaded I saw MSVCP140D.dll was giving a result of NAME NOT FOUND. Turns out the machine that couldn’t load my dll doesn’t have the ‘D’ version of MSVCP140.dll. Everything worked when I built my dll for release! – [WayBack] Pakman.

–jeroen

Posted in Delphi, Development, Software Development, Windows Development | Leave a Comment »