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

Archive for August, 2014

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 »

7zip on a Mac: Keka, 7zip on Windows: their plain installer.

Posted by jpluimers on 2014/08/04

Though I’ve written only a few blog posts about 7zip – my compressor of choice ever since I discovered 7zip some 10 years ago around version 3.13 (their history goes much further back: 1999) – here is a fresh one:

7zip is a fast, free, multi-platform and has great compression. No wonder Toms Hardware gave them an award last year: And The Undisputed Winner Is… 7-Zip.

For Windows, I take the downloads from 7-Zip: there are both x64 and x86 versions (x64 supports more memory so can handle bigger archives).

For Mac, I’ve been using Keka – the free Mac OS X file archiver. Both compressing and decompressing involve dragging the uncompressed or compressed files to the Keka dock icon.

That is slightly more involved than the context menu in Windows, but it works great.

For Windows command line usage, I use either 7za.exe or 7z.exe (uses DLLs, supports more compression)

For Mac command line usage, I use p7zip.

–jeroen

Posted in 7zip, Apple, Compression, 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, MacBook Retina, MacBook-Air, MacBook-Pro, OS X 10.8 Mountain Lion, Power User, Windows, Windows 7, Windows 8, Windows Server 2000, Windows Server 2003, Windows Server 2003 R2, Windows Server 2008, Windows Server 2008 R2, Windows Vista, Windows XP | Leave a Comment »

Making Keystrokes with Macintosh Keyboards – Citrix eDocs

Posted by jpluimers on 2014/08/03

If an Alt-combination does not work, try the Command-Alt-combination or through the menu.

For instance:

  • Alt-Tab: works
  • Alt-F: fails
  • Command-Alt-F: works (starts the file menu
  • Alt-Space: fails
  • Command-Alt-Space: fails
  • Via the menu: works

–jeroen

via: Making Keystrokes with Macintosh Keyboards – Citrix eDocs.

Posted in Keyboards and Keyboard Shortcuts, Power User | Leave a Comment »

When combined with Ctrl or Alt: RDP Shift Key Gets Stuck (via: davidbond.net)

Posted by jpluimers on 2014/08/01

When using Windows RDP you have the risk of a Shift key getting stuck.

This happens when press Ctrl and Shift. Make sure you release Shift first, otherwise Shift gets stuck.

Same with Alt and Shift: you have to release the Shift key first.

This is not a problem when using the OS X Remote Desktop application 8.x from Microsoft: only the Windows MSTSC.exe applications included in Windows 7 and higher suffer from this when you connect to Windows 7 and higher (including connecting from Windows to Windows Server and from Windows Server to Windows).

It does not happen with the MSTSC.exe in Windows 2000/XP and Windows Server 2003/2003 R2.

Results

Here are the important results:

  • Press Shift and Control (either order) -> Release Shift -> Release Control: Normal state
  • Press Shift and Control (either order) -> Release Control -> Release Shift: Problem state 

Conclusion

RDP has a bug whereby the shift state incorrectly remains in the “pressed” state if, after pressing Shift+Control, the Control key is released first.

Bug reference

Bug is with Microsoft: https://connect.microsoft.com/WindowsServer/feedback/details/766863/rdp-shift-key-gets-stuck

And the comments there:

You have described the exact same problem that I am having, only in my case it’s with RDP between two Win7 machines. […]

I have been using RDP for years without problems, until about 2 or 3 weeks ago when it suddenly starting going wrong.

Too bad the connect issue requires logon: I have no idea if this is ever going to be fixed.

–jeroen

via: davidbond.net: RDP Shift Key Gets Stuck.

Edit: some comments on G+

made in Delphi :)
Happens to me sometimes when connecting from Win7 to XP+.
Seems closely relatedhttp://support.microsoft.com/kb/978829 in older OSs.
Frequently beaten by “Securing remote connection…” delay http://support.microsoft.com/kb/2915774

Posted in Power User, Windows, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2 | 2 Comments »

Multiple office versions on one computer: it is possible, but you should not do it

Posted by jpluimers on 2014/08/01

Wow, I didn’t even know this was possible, but I recently came across a few people that had actually done this: run multiple versions of Office on one computer.

Microsoft even has a couple of knowledge base articles on it and indicate it is not recommended (wow!), installation/update orders, and potential issues you will face.

I’ve added the respective office version ranges for each link:

–jeroen

Posted in Excel, Office, Office 2003, Office 2007, Office 2010, Office 2013, Outlook, Power Point, Power User, Word | Leave a Comment »