devxlogo

Creating a roll-up form

Creating a roll-up form

Question:
How can I create a form that will roll up; that is, a form that whenclicked will reduce its height to nothing but the title bar?

Answer:
I have seen a demo of a commercially availablecomponent in DCU form that does this and it’s pretty slick. Because it’sa component, the implementation is really nice. Just drop it inand you’re off.

What I’m showing here does the pretty much the samething, but is coded directly into the form. I did this because building a component would have required more event-handlingcode than I cared to perform. However, with Delphi 2.0’s Object Repository, it’s avery simple to add a form with this functionality into it anduse it over and over again.

Let’s look at the code, then discussit:

{================================================================================ Program        : Roll-up Form Created By     : Brendan V. Delumpa Description    : Unit code that will simulate the “rolling-up” of a form. ================================================================================}unit testmain;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  ExtCtrls, enhimage, StdCtrls, Printers, rollup, Buttons, ShellAPI;type  TForm1 = class(TForm)    procedure FormCreate(Sender: TObject);  private    { Private declarations }    FOldHeight : Integer;    procedure WMNCRButtonDown(var Msg : TWMNCRButtonDown); message WM_NCRBUTTONDOWN;  public    { Public declarations }  end;var  Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);begin  FOldHeight := ClientHeight;end;procedure TForm1.WMNCRButtonDown(var Msg : TWMNCRButtonDown);var  I : Integer;begin  if (Msg.HitTest = HTCAPTION) then    if (ClientHeight = 0) then      begin        I := 0;        while (I < FOldHeight) do begin          I := I + 40;          if (I > FOldHeight) then            I := FOldHeight;          ClientHeight := I;          Application.ProcessMessages;        end;      end    else      begin        FOldHeight := ClientHeight;        I := ClientHeight;        while (I > 0) do begin          I := I – 40;          if (I < 0) then            I := 0;          ClientHeight := I;          Application.ProcessMessages;        end;    end;end;end.

First, by way of synopsis, theroll-up/down occurs in response to a WM_NCRBUTTONDOWN messagefiring off and the WMNCRButtonDown procedurehandling the message,telling the window to roll up/down depending upon the height of theclient area. WM_NCRBUTTONDOWN fires whenever the right mouse buttonis clicked in a “non-client” area, such as a border, menu or, for ourpurposes, the caption bar of a form. (The client area of a windowis the area within the border where most of the interestingactivity usually occurs. In general, the Windows API restrictsapplication code to drawing only within the client area.)

See also  Why ChatGPT Is So Important Today

Delphi encapsulates the WM_NCRBUTTONDOWN in aTWMNCRButtonDown type, which is actually an assignment from aTWMNCHitMessage type that has the following structure:

type    TWMNCHitMessage = record      Msg     : Cardinal;    HitTest : Integer;    XCursor : SmallInt;    YCursor : SmallInt;    Result  : Longint;  end;

Table 1 below discusses the parameters of the TWMCHitMessagestructure in more detail:

Table 1 – TWMNCHitMessage record fields
ParameterTypeDescription
MsgCardinalEach Windows message has an integer value which is its assigned ID
HitTestIntegerThis is a constant value that is returned by an internal Windows callback function that specifies the area on window when the message fired. Look in the Win32 Developer’s Reference under WM_NCRBUTTONDOWN for values of nHitTest. For our purposes, we’ll use HTCAPTION as the test value.
XCursorSmallIntThis is the X value of the cursor position relative to the top left corner of the window
YCursorSmallIntThis is the Y value of the cursor position relative to the top left corner of the window
ResultLongIntThe result value of WM_NCRBUTTONDOWN. Should be 0 if the application handled the message.

Now that you know about the message, let’s look more closelyat the code.

It’s easy to create message wrappers in Delphi to deal withmessages that aren’t handled by an object by default. Since aright-click on the title bar of a form isn’t handled by default, Ihad to create a wrapper. The procedure procedureWMNCRButtonDown(var Msg : TWMNCRButtonDown); messageWM_NCRBUTTONDOWN; is the wrapper I created. All that goes onin the procedure is the following:

  1. If the value of the message’s HitTest field is equal to HTCAPTION (which means a right-click on the caption bar) then,
  2. If height of the form’s client area is equal to 0 then
    1. Roll the form down
  3. else if the height of the form’s client area is not equal to 0 then
    1. Roll the form up

In order to make this work, I had to create a variable calledFOldHeight and set its value at FormCreate whenever theform was to be rolled up. FOldHeight is used as a place for the form toremember what size it was before it was re-sized to 0. When aform is to be rolled up, FOldHeight is immediately set to the currentClientHeight, which means you can interactively set the form’ssize, and the function will always return the form’s ClientHeight towhat it was before you rolled it up.

So what use is this? Well, sometimes I don’t want toiconize a window; I just want to get it out of the way so I can seewhat’s underneath. Having the capability to roll a form up to itstitle bar makes it a lot easier to see underneath a window withouticonizing it, then having to Alt-tab back to it. (If you arefamiliar with the Macintosh platform, the System 7.5 environmentoffers a very similar facility called a “window shade,” and makes a roll-up sound when the shadegoes up.)

On an ending note, my good friend and colleague, Peter Jagielski,gave me a challenge: to create the effect of imploding and explodingwindows. About eight years ago, he wrote an article in the DB Advisorfor doing exploding and imploding windows in Paradox for DOS. When hesaw the code for this, he smugly said, “That’s pretty slick, butcan you do exploding and imploding windows like I did?” Howcould I pass up that challenge? So be on the lookout for anexample of exploding and imploding windows in a future tip.

By the way, a big thanks goes to KeithBartholomess of TeamBorland for turning me on to the WM_NCRBUTTONDOWNmessage. I wouldn’t have been able to write the event code withoutKeith pointing this message out to me.

See also  How to Create and Deploy QR Codes Online: A Comprehensive Guide
devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist