ANN: Sheet Extender

Sheet Extender

Extends standard SHEET control.

Sheet Extender is a class that allows to add a small button to each TAB control. This button has no default action, the demo demonstrates
only 3 possible actions: dropdown menu, close button, help button.

Screenshot 2

The buttons are fully customizabe, you can set up: text, font, size, colors, hover colors, acftions.

Home page

mikeduglas/SheetExtender: Extends standard SHEET control. (

  • Here you’ll find source files and the demo.
  • Press green button “Code” then select “Download ZIP”.

Very nice Mike!

Is it also possible to mix those buttons? So first tab with cross button, second tab with dropdown button and third tab with help button?

Best regards

Yes it is very easy.

1 Like

If someone really wants mixed buttons:

Declare overridden OnDrawCustomButton event handler:

TSheetExtMixed                CLASS(TSheetExtBase), TYPE
OnDrawCustomButton              PROCEDURE(TDC pDc, SIGNED pTabFeq, TRect pTabRect), PROTECTED, DERIVED
OnCustomButtonPressed           PROCEDURE(SIGNED pTabFeq), BOOL, PROTECTED, DERIVED

In this handler choose which button will be drawn on which tab:

TSheetExtMixed.OnDrawCustomButton PROCEDURE(TDC pDc, SIGNED pTabFeq, TRect pTabRect)
  CASE pTabFeq
  OF ?TAB3_1
  OF ?TAB3_2
  OF ?TAB3_3
  PARENT.OnDrawCustomButton(pDc, pTabFeq, pTabRect)
1 Like

That’s great Mike!

Best regards

Unicode support added.

I downloaded the code in GitHub for the SheetExtender control by Mike Douglas ( GitHub - mikeduglas/SheetExtender: Extends standard SHEET control.) but when I try to compile the demo. it lacks 2 files: and

anyone have those files?
thanks, marcelo

Hi Marcelo

Look at “Dependences” on that link you provided.


Geoff R

You can remove the Include the 2 calls to PrintD() are commented. If you need that code it is simple enough to replace with a call to OutputDebugString and concatenation.

thanks for the anwers;
Geoff, where is “dependences” ??

Here’s a link with the Dependencies Highlighted

It’s funny :slight_smile: printf’s purpose is to avoid OutputDebugString calls and a lot of concatenations, among other goodies.

1 Like

many thanks, I don’t understand how I didn’t see it.

I agree the PrintF syntax can be elegant for many purposes. Obviously C programmers like it, but IIRC they can’t easily concat bunches of variables easily like in Clarion. The formatting of some values like Date, Time, Hex are “goodies” that save code and produce better results.

Most of my debug is Label=Value multiple times
DB('UpdateAPTransProcess - AddToCksFile Vndr: '& PeTran:VendorAutoNo &' Src: '&PeTran:JrnlSrc &' CKNO: '& PeTran:CkNo &' ACCT: '& CLIP(ACTMST:AcctNo) &' AMT: '& PeTran:Debit &' REF: '&PeTran:RefNo)

So your way the 6 Labels and Variables would separate:
PrintD('UpdateAPTransProcess - AddToCksFile Vndr: %i Src: %z CKNO: %i ACCT: %s AMT: %f REF: %z', PeTran:VendorAutoNo, PeTran:JrnlSrc, PeTran:CkNo, ACTMST:AcctNo, PeTran:Debit, PeTran:RefNo)

For me coding Debug often variables are inserted, removed, rearranged, copied. That’s easier cut/paste/delete with the Literal=Variable next to each other.

There is A LOT of Debug left in the old code I work on, much in batch processes so 100s or 1000s. I would be concerned the code that runs inside PrintD() slowing it. There are many ANYs and the concat 1 byte at a time using ANY is slow hence string libraries. In reality it probably does not matter as CPUs are so fast.

PrintF() does look nice to create a Message() so you can focus on the complete message text and not have the text cluttered with concatenated variables. There are usually not as many variables and much more text. There aren’t 100s of Messages showing during a process like Debug. I am trying PrintF and will send you some thoughts.