Quick Tip: Implement Zoom In Virtual TreeView Using CTRL + / CTRL –

Virtual TreeView Zoom Most Windows applications I use in my daily work (email clients, browsers, text editors) have a handy feature allowing to make the text larger by increasing (or smaller by decreasing) the font size. Increasing the text size in a web browser is something I got accustomed to doing frequently – to make the web page easier to read if the default text size was set too small for my eyes.

Even though all applications have some visual way (track bars mainly) to zoom in/out their display – all also support zooming by using (standard?) keyboard shortcuts. CTRL+Plus to increase the font size, CTRL+Minus to decrease. Am not sure if you know, but Delphi IDE unit editor also has this feature.

One of my Delphi applications is extensively using the Virtual TreeView control. I’ve noticed how sometimes I automatically hit CTRL+ to make the nodes and text bigger – yet (of course) no zooming happens. Therefore a need for a quick and dirty implementation of Virtual TreeView text/node size zooming arose.

I’m implementing the magic in the OnKeyDown event for my tree. If CTRL and PLUS keys are pressed I want to increase the font size. Decrease in case of CTRL+MINUS. That’s the easy part – simply increase the Size property value for the Font. I also need to “fix” the node height for every node – if not, the text would get larger but the horizontal space between nodes would not follow font size. For this purpose the NodeHeight property is used – and set inside the IterateSubtree method (anonymous method used for Callback parameter).

//handles OnKeyDown for the “tree” Virtual TreeView control.
procedure TZoomTreeForm.treeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Shift = [ssCtrl]) then //CTRL key down
  begin
    if (Key = vkAdd) then //"+" (plus) key down
    begin
      Key := 0; //so no FHeader.AutoFitColumns from TBaseVirtualTree.WMKeyDown
      if (tree.Font.Size < 16) then
      begin
        tree.Font.Size := 1 + tree.Font.Size;
        tree.IterateSubtree(
          nil,
          procedure (Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean)
          begin
            Sender.NodeHeight[Node] := 1 + Sender.NodeHeight[Node];
          end,
          nil);
      end;
    end;
    if (Key = vkSubtract) then //"-" (minus) key down
    begin
      Key := 0; //so no FHeader.RestoreColumns from TBaseVirtualTree.WMKeyDown
      if (tree.Font.Size > 8) then
      begin
        tree.Font.Size := -1 + tree.Font.Size;
        tree.IterateSubtree(
          nil,
          procedure (Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean)
          begin
            Sender.NodeHeight[Node] := -1 + Sender.NodeHeight[Node];
          end,
          nil);
      end;
    end;
  end; //CTRL
end; (*OnKeyDown*)

A few notices:

  • The default font size, set at design time, is 8. I’m allowing the text size to go from 8 to 16 – anything bigger (for my case) makes no sense. This kind of hard coding plays when my application is run in 100% DPI and Screen.PixelsPerInch is 96. For a more DPI aware approach you would need to use the MulDiv function – but that’s another story.
  • I have to set Key:=0 as I do not want the default Virtual TreeView handling of the OnKeyDown to happen. By default Virtual TreeView calls AutoFitColumns if CTRL+ is pressed and RestoreColumns in case of CTRL-. Since I do not need this behavior – I’m using this quick and dirty approach.
  • Also, I’m not considering the size of the font in tree’s header – as simply I do not need it to be bigger/smaller.
  • If you are looking for a more visual approach, using TUpDown, check this post by Didier Cabale: Zoom in TVirtualStringTree. Didier also ensures tree header text size is increased / decreased.

Any cleaner / fresher ideas?

One thought on “Quick Tip: Implement Zoom In Virtual TreeView Using CTRL + / CTRL –

Leave a Reply to Agustin Ortu Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.