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

Archive for the ‘Development’ Category

The “Just In Time” Theory of User Behavior

Posted by jpluimers on 2014/08/10

Abstract of The “Just In Time” Theory of User Behavior:

…the design of your software has a profound impact on how users behave within your software…

  • Encouraging the “right” things by making those things intentionally easy to do.
  • Discouraging the “wrong” things by making those things intentionally difficult, complex, and awkward to do.

–jeroen

via: The “Just In Time” Theory of User Behavior.

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

Windows key character that displays on non-Windows systems (like Mac)

Posted by jpluimers on 2014/08/08

Though there is a Unicode character for the Apple Command Key, there is none for the Windows Key.

The Windows font WinDings does have a character 255 for it, but that font usually is not installed on non-Windows systems. There it will look like Unicode Character ‘LATIN SMALL LETTER Y WITH DIAERESIS’ (U+00FF)

This Unicode code point comes closest to the Windows key: Unicode Character ‘SQUARED PLUS’ (U+229E) and is used by Windows Key page on WikiPedia.

  • The WinDings character looks like this: ÿ
    (non no Windows systems, it will look like an y with two dots on it: ÿ)
  • The Unicode Codepoint U+229E like this: ⊞
    Not a complete match, but pretty close.

The Unicode code points for Mac modifier keys are these:

–jeroen

Posted in Development, Encoding, Mac, Mac OS X / OS X / MacOS, Mac OS X 10.4 Tiger, Mac OS X 10.5 Leopard, Mac OS X 10.6 Snow Leopard, Mac OS X 10.7 Lion, MacBook Retina, MacBook-Air, MacBook-Pro, OS X 10.8 Mountain Lion, Power User, Software Development, Unicode, Windows, Windows 7, Windows 8, Windows Server 2003, Windows Server 2003 R2, Windows Vista, Windows XP, Windows-1252 | Leave a Comment »

Delphi: a memento that executes any code at end of method

Posted by jpluimers on 2014/08/07

Following up on yesterdays Delphi: using IInterface to restore cursor at end of mehod (prelude to a memento that executes any code at end of method) here is the memento I meant.

They are based on anonymous methods, which in Delphi are closures: they capture location.

The location is kept just as long as needed, based on a well known Delphi reference counting mechanism: interfaces. The same one I used for the TTemporaryCursor class (and one of the reasons the TTemporaryCursor will keep functioning).

My goal was to simplify code like this:

procedure TTemporaryCursorMainForm.TemporaryCursorClassicButtonClick(Sender: TObject);
var
  Button: TButton;
  SavedCursor: TCursor;
  SavedEnabled: Boolean;
begin
  Button := Sender as TButton;
  SavedEnabled := Button.Enabled;
  try
    Button.Enabled := False;
    SavedCursor := Screen.Cursor;
    try
      Screen.Cursor := crHourGlass;
      Sleep(3000);
    finally
      Screen.Cursor := SavedCursor;
    end;
  finally
    Button.Enabled := SavedEnabled;
  end;
end;

Into this:

procedure TTemporaryCursorMainForm.TemporaryCursorMementoButtonClick(Sender: TObject);
var
  Button: TButton;
  SavedEnabled: Boolean;
begin
  TTemporaryCursor.SetTemporaryCursor();
  Button := Sender as TButton;
  SavedEnabled := Button.Enabled;
  TAnonymousMethodMemento.CreateMemento(procedure begin Button.Enabled := SavedEnabled; end);
  Button.Enabled := False;
  Sleep(3000); // sleep 3 seconds with the button disabled crHourGlass cursor
  // Delphi will automatically restore the cursor
end;

We’ve already seen one of the try…finally…end blocks vanish by using TTemporaryCursor. Now lets look at TAnonymousMethodMemento:

unit AnonymousMethodMementoUnit;

interface

uses
  System.SysUtils;

type
  IAnonymousMethodMemento = interface(IInterface)
  ['{29690E1E-24C8-43A5-8FDF-5F21BB32CEC2}']
  end;

  TAnonymousMethodMemento = class(TInterfacedObject, IAnonymousMethodMemento)
  strict private
    FFinallyProc: TProc;
  public
    constructor Create(const AFinallyProc: TProc);
    destructor Destroy; override;
    procedure Restore(const AFinallyProc: TProc); virtual;
    class function CreateMemento(const AFinallyProc: TProc): IAnonymousMethodMemento;
  end;

implementation

{ TAnonymousMethodMemento }
constructor TAnonymousMethodMemento.Create(const AFinallyProc: TProc);
begin
  inherited Create();
  FFinallyProc := AFinallyProc;
end;

destructor TAnonymousMethodMemento.Destroy;
begin
  Restore(FFinallyProc);
  inherited Destroy();
end;

class function TAnonymousMethodMemento.CreateMemento(const AFinallyProc: TProc): IAnonymousMethodMemento;
begin
  Result := TAnonymousMethodMemento.Create(AFinallyProc);
end;

procedure TAnonymousMethodMemento.Restore(const AFinallyProc: TProc);
begin
  AFinallyProc();
end;

end.

Like TTemporaryCursor, I’ve kept it self-contained.

It uses a TProc parameter – a parameterless anonymous method – called AFinallyProc that needs to be executed right before the memento goes out of scope.

It can be called like any method, as to the compiler it is a method.

–jeroen

Posted in Delphi, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development | 11 Comments »

Delphi: using IInterface to restore cursor at end of mehod (prelude to a memento that executes any code at end of method).

Posted by jpluimers on 2014/08/06

A long while ago, I wrote about a (then overdue post) on .NET/C#: Using IDisposable to restore temporary settrings example: TemporaryCursor class.

I had been using a similar technique in Delphi since before I found out about the [WayBack] TRecall class and thought: I think my TTemporaryCursor is smarter, as it is based on interfaces.

TRecall (and the [WayBack] Vcl.Graphics descendants [WayBack] TBrushRecall, [WayBack] TFontRecall, and [WayBack] TPenRecall) store [WayBack] TPersistent properties using the Assign method. They were introduced in Delphi 6.

Too bad there are only [WayBackvery few people using TRecall as lots of TPersistent things warrant sasaving and restoring.

My [WayBack] TTemporaryCursor (now [WayBack] at bitbucket) class only stores an integer, so it cannot derive from TRecall. Besides it is based on IInterface which got introduced in Delphi 6, but was present as IUnknown since Delphi 3 (see [WayBack] Interface It! A quick guide to the ins and outs of interfaces in Delphi. By Jimmy Tharpe).

This means that TRecall could have been based on IInterface, so I wonder why it was not.

Note I’m not the first to publish about such a class (Malcolm Grooves wrote [WayBack] TCursorSnapshot, SwissDelphiCenter has [WayBack] TMyCursor, Nick Hodges published about [WayBack] TAutoCursor), it’s just that it has been in my tool box for so long, and written memento classes that you will see 2 articles on it this week.

In the mean time (this works with Delphi 2009 and up), I also wrote a small class that does similar things for any  [WayBackanonymous method. More on that tomorrow.

Back to TRecall: it is an example of [WayBack] the memento pattern in Delphi. The [WayBack] memento pattern allows you to restore state.

SourceMaking.com a.k.a. [WayBack] Design Patterns and Refactoring is a great site about [WayBack] Design Patterns, [WayBack] UML, [WayBack] AntiPatterns and [WayBack] Refactoring.

Most pattern example code is available in all of the C#, C++, Delphi, Java and PHP languages.

Great stuff!

One of the constructs for restoring state is a [WayBack] try … finally … end construct: it allows you to always execute something in the finally block, for instance restoring the state to right before the try block. Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Design Patterns, Development, Diagram, Event, Software Development, UML | 14 Comments »

Word API Documents collection documentation: moved and changes with the introduction of Word 2013

Posted by jpluimers on 2014/08/05

I’ve done a bit of WinWord automation and came across different locations for the API:

New Style:

Old Style:

Fun fact: there is no Old Style Word 2007 documentation any more. You might expect it at http://msdn.microsoft.com/en-us/library/ms263641(v=office.12) but it is not there.

Not so fun fact (and the reason I was looking for the Documents documentation), is because of this big bug ONLY in Office 2010 (it does not occur in Office 2000 .. 2007, and is fixed in 2013): The WordMeister » Bug Word 2010: Documents collection is not correctly maintained.

The only workaround is to run an Office Add-in, or VBA Macro. Both not feasible for external clients.

–jeroen

Posted in Delphi, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Office, Office 2007, Office 2010, Office 2013, Office Automation, Office VBA, Power User, Scripting, Software Development, VBScript | Leave a Comment »

Spring4D: How is the GlobalContainer intended to be used? Are there important don’ts? – Google Groups

Posted by jpluimers on 2014/08/04

Short answer: do not use the GlobalContainer.

Long answers are in this Spring4D thread: How is the GlobalContainer intended to be used? Are there important don’ts? – Google Groups.

Especially read this message by Stefan Glienke that shows you to setup your main program without using GlobalContainer at all.

Note that this doesn’t mean you should avoid a container at all.

Background information:

–jeroen

Posted in Delphi, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE5, Delphi XE6, Development, Software Development, Spring4D | 5 Comments »

TortoiseSvn – How do I move a file (or folder) from one folder to another (via: Stack Overflow)

Posted by jpluimers on 2014/07/31

It is the second – italic – paragraph what I always forget. Thanks Mark Embling!

To move a file or set of files using tortoise, right-click-and-drag the target files to their destination and release the right mouse button. The popup menu will have a ‘SVN move versioned files here’ option.

Note that the destination folder must have already been added to the repository for the ‘SVN move versioned files here’ option to appear.

Yes, it is also in the TortoiseSVN documentation under Deleting, Moving and Renaming and Copying/Moving/Renaming Files and Folders. But those are lacking emphasis on the the italic stuff.

–jeroen

via svn – How do I move a file (or folder) from one folder to another in TortoiseSVN? – Stack Overflow.

Posted in Development, Software Development, Source Code Management, Subversion/SVN | Leave a Comment »

Delphi: mapping of COM/Windows exceptions to Delphi Exceptions and run-time errors

Posted by jpluimers on 2014/07/30

Every time

---------------------------
Debugger Exception Notification
---------------------------
Project Some.exe raised exception class $C0000005 with message 'access violation at 0x00537b14: read of address 0x00000000'.
---------------------------
Break   Continue   Help
---------------------------

'Exception "EAccessViolation" with message "Access violation at address 00537B30 in module ''TestWordInterface.exe''. Read of address 00000000" at address 00537B30'

---------------------------
Testwordinterface
---------------------------
Access violation at address 00537B14 in module 'Some.exe'. Read of address 00000000.
---------------------------
OK
---------------------------

In system.pas:

{$IFDEF STACK_BASED_EXCEPTIONS}
procedure       MapToRunError(P: PExceptionRecord); stdcall;
const
  STATUS_ACCESS_VIOLATION         = $C0000005;
  STATUS_ARRAY_BOUNDS_EXCEEDED    = $C000008C;
  STATUS_FLOAT_DENORMAL_OPERAND   = $C000008D;
  STATUS_FLOAT_DIVIDE_BY_ZERO     = $C000008E;
  STATUS_FLOAT_INEXACT_RESULT     = $C000008F;
  STATUS_FLOAT_INVALID_OPERATION  = $C0000090;
  STATUS_FLOAT_OVERFLOW           = $C0000091;
  STATUS_FLOAT_STACK_CHECK        = $C0000092;
  STATUS_FLOAT_UNDERFLOW          = $C0000093;
  STATUS_INTEGER_DIVIDE_BY_ZERO   = $C0000094;
  STATUS_INTEGER_OVERFLOW         = $C0000095;
  STATUS_PRIVILEGED_INSTRUCTION   = $C0000096;
  STATUS_STACK_OVERFLOW           = $C00000FD;
  STATUS_CONTROL_C_EXIT           = $C000013A;
var
  ErrCode: Byte;
begin
  case P.ExceptionCode of
    STATUS_INTEGER_DIVIDE_BY_ZERO:  ErrCode := 200; { reDivByZero }
    STATUS_ARRAY_BOUNDS_EXCEEDED:   ErrCode := 201; { reRangeError }
    STATUS_FLOAT_OVERFLOW:          ErrCode := 205; { reOverflow }
    STATUS_FLOAT_INEXACT_RESULT,
    STATUS_FLOAT_INVALID_OPERATION,
    STATUS_FLOAT_STACK_CHECK:       ErrCode := 207; { reInvalidOp }
    STATUS_FLOAT_DIVIDE_BY_ZERO:    ErrCode := 200; { reZeroDivide }
    STATUS_INTEGER_OVERFLOW:        ErrCode := 215; { reIntOverflow}
    STATUS_FLOAT_UNDERFLOW,
    STATUS_FLOAT_DENORMAL_OPERAND:  ErrCode := 206; { reUnderflow }
    STATUS_ACCESS_VIOLATION:        ErrCode := 216; { reAccessViolation }
    STATUS_PRIVILEGED_INSTRUCTION:  ErrCode := 218; { rePrivInstruction }
    STATUS_CONTROL_C_EXIT:          ErrCode := 217; { reControlBreak }
    STATUS_STACK_OVERFLOW:          ErrCode := 202; { reStackOverflow }
  else                              ErrCode := 255;
  end;
  RunErrorAt(ErrCode, P.ExceptionAddress);
end;

Posted in Algorithms, Development, Floating point handling, Software Development, Uncategorized | Leave a Comment »

Delphi: workaround for when you loose many of the ModelMaker Code Explorer keyboard shortcuts

Posted by jpluimers on 2014/07/29

ModelMaker Code Explorer (MMX for short) stores the keyboard shortcuts in the registry.

I’ve had it occur once that somehow most (about 95%) of the shortcuts got lost.

Two thinks I learned from resurrecting the shortcuts:

  • MMX writes these settings when you exit Delphi
  • Only a few keys (with lots of values under them) store the keys.

To resurrect them,

Read the rest of this entry »

Posted in Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 5, Delphi 6, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Development, Software Development | Leave a Comment »

A few HTML to Markdown converters written in javascript, Python, Ruby, PHP and C#

Posted by jpluimers on 2014/07/24

It’s not perfect, but makes the conversion a heck of a lot easier:

to-markdown – an HTML to Markdown converter written in javascript (of which sources are on github).

[Edit 20150919: added more converters: now at least there is competition (:]

Read the rest of this entry »

Posted in Development, JavaScript/ECMAScript, MarkDown, Power User, Scripting, Software Development, Web Development | Leave a Comment »