|
(Un)Common Controls
Uncommon controls are Windows controls that are used in an uncommon way
to solve problems that are not those for which they were created. Did
you know, for example, that a ListView could be used as an Image control
that can display JPEG, PNG and GIF format too?
Here there are some of them that I’d like to share with you. But please,
do the same: if you have a cool Uncommon Control, send it to me, and if
it fits in this section, I’ll publish it with your name and your description.
A Short History
Many years ago, in the Windows 3.0 age, I remember a guy that, because
there was no direct support for images in Dialog Boxes but there was for
icons, proposed to divide images into 16*16 pixels icons and then align
them in order to reconstruct the original image. This is what I call an
Uncommon Control, and this was the first one that I encountered in my
programmer life.
I increased my interests in Uncommon Controls when I was developing the
Dfm2API utility. For those who
still does not know what this utility is for, this is a tool that converts
Borland Delphi and C++ Builder VCL Forms into a Resource Script file (.RC)
and a .CPP and .HPP file with a lot of code automatically generated
to replicate original VCL behavior, such as control initialization, etc….
The major difficulties in achieving a satisfactory result, were that there
are a lot of commonly used VCL controls that are not easily available
in plain API programming because they are not directly supported by the
OS. For example, the so widely used TGlyphButton (that is a button with
a text) has no direct Windows support. Or maybe it has?
There are many reasons to use Uncommon Controls:
1) Impossibility to use a control under certain
circumstances: as mentioned above, GlyphButtons are not directly supported
by OS, so it seems quite difficult to use them, unless you don’t write
all the required code.
2) Necessity to reduce code size: why should
I use a DLL if it is not *REALLY*
necessary? Why should I write some code if it is already available? In
the example mentioned above, why use an Image Control or link an Image
Library just to display a JPEG file?
3) To reduce the needs for external (and maybe
expensive) packages:< and this seems to be self-explanatory…
4) To reduce the effort of upgrading the software
and the risk of incompatibilities between different
libraries: if you use a standard component, you don’t need to upgrade
anything, at least until the OS will support that component. Moreover,
you have released a program that requires VCL 4.0 and a plug-in that requires
VCL 5.0. Are you sure that no problems will arise?
5) To demonstrate your skill and lateral thinking
capabilities... ;-)
It is also my desire to publish them on a Journal when there is enough
material, and with the consent (and acknowledgments) of those of you that
will contribute to this page.
Title
|
Description
|
Release
|
Language Independent Simple Data Transfer
Mechanism
|
Problem:
Sometimes, you need
to transfer simple data types from an Executable written in a language
to a DLL written in another one. For example you can have a list
of strings that need to be transferred from a Visual Basic EXE to
a Delphi DLL.
Solution:
You can use invisible
Windows controls to store data and then "send" the handle
of that control instead of the whole structure: in the example above
you can use an invisible ListBox, fill it from the VB side and call
the DLL by simply giving the ListBox handle. You can then do whatever
you want to that List of Strings (see also the "Language
Independent String List With Sorting Capabilities, and a Little
"bit" More" topic).
Benefits:
You can use this trick in whatever
language you want, and for every structure and datatype supported
by Windows. This includes strings, stringlists, numbers, datetimes,
currencies, etc... Did you think you needed OLE to do this?
|
28 October 2000,
Luigi Bianchi
|
Glyph
Button 2
|
Problem:
Windows does not seem
to have a standard control for displaying buttons with text and
glyph. It is easy to have a button with text or a button with images,
but not both.
Solution:
The common control
SysTabControl32 has the TCS_BUTTONS style, for which Tabs appear
as buttons. Moreover, each Tab has an Image and a Text property
that can be shown simultaneously.
Images must be handled
by an ImageList control that can be initialized at runtime using
bitmaps or icons.
What happens if I use
a TabControl with just a tab? Here there is an example:
During the WM_INITDIALOG
message, an ImageList is created to store the glyph, then it is
bind to the TabControl, and the TCITEM structure is initialized
and passed to the TabControl. That’s all. Now we have to catch the
WM_NOTIFY message to see when the Tab is pressed and then we have
to bring it up again, because by default Tab Buttons stay pressed.
case WM_INITDIALOG:
{
hCtlTabControl1 = GetDlgItem(hWnd, IDC_TABCONTROL1);
HIMAGELIST himlImages = ImageList_LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_BITMAP1), 64, 1, CLR_NONE, IMAGE_BITMAP,
LR_CREATEDIBSECTION);
TabCtrl_SetImageList(hCtlTabControl1, himlImages);
TabCtrl_SetItemSize(hCtlTabControl1, 160, 68);
TCITEM item;
ZeroMemory(&item, sizeof(item));
item.mask = TCIF_IMAGE | TCIF_TEXT;
item.pszText = "Look ma, it's me!";
TabCtrl_InsertItem(hCtlTabControl1, 0, &item);
TabCtrl_SetCurSel(hCtlTabControl1, -1); //to bring it up again
}
break; //WM_INITDIALOG
case WM_NOTIFY:
{ LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code)
{ case TCN_SELCHANGE:
if (pnmh->idFrom == IDC_TABCONTROL1)
{ //do something here
TabCtrl_SetCurSel(hCtlTabControl1, -1); //to bring
it up again
}
break;
}
}
break;
Benefits:
Possibility to have
nicer buttons using plain API programming, with no needs for additional
libraries.
OS support, requires
comctl32 4.71 and above, works with all the Win32 OS family.
|
22 June
2000, Luigi Bianchi
|
Glyph
Button 1
|
Problem:
Windows does not seem
to have a standard control for displaying buttons with text and
glyph. It is easy to have a button with text or a button with images,
but not both.
Solution:
The simplest and most
used method is to write the text directly into the bitmap. This
however has some limitations, because it is not guaranteed
that it has the standard fonts, color and appearance for that kind
of control.
Benefits:
Really simple solution,
but with some limitations
|
1 January
1990,
everyone!
|
Language
Independent String List With Sorting Capabilities, and a Little
"bit" More
|
Problem:
Sometimes, a list of
strings is necessary to perform various operations, including sorting.
If you program in C++, you can use STL list<string> with sort,
while if you're using C you can use qsort. C++ Builder and Delphi
programmers can use TStringList class, that is widely used by VCL.
Alternative:
You can also use an
invisible ListBox and use the classic StringList capabilities in
order to add items (LB_ADDSTRING), remove items(LB_DELETESTRING),
get the list size (LB_GETCOUNT), clear the list (LB_RESETCONTENT)
find an item (LB_FINDSTRING) and so on. You can also specify that
the list must be sorted (through the LBS_SORT style). You can also,
however, have more things, such as associate a bit
value to each item: this can be done selecting and unselecting each
item of a multiselect ListBox (there are many message for doing
that).
Benefits:
You can save some bytes of code, because
you just need a call to CreateWindow and some SendMessages, you
can associate a boolean value to each item, you can have search
for strings in the list.
|
28 October 2000,
Luigi Bianchi
|
GIF /
PNG / JPEG lightweight Image Control
|
Problem:
Windows does not seems
to have a standard control for displaying JPEG, PNG and GIF images
Solution:
ListView controls have
the capability to display JPEG, PNG, GIF, BMP, WMF and
EMF images.
To use them as simple
image controls, it is sufficient to send them a message as in the
following example (where hCtlListView1 is the handle of the
ListView control and where szFileName is the FULL
path of the image file to be displayed).
LVBKIMAGE lv;
ZeroMemory(&lv, sizeof(lv));
lv.ulFlags = LVBKIF_STYLE_NORMAL | LVBKIF_SOURCE_URL;
lv.pszImage = szFileName;//full path
required
lv.cchImageMax = lstrlen(szFileName); //unnecessary?
ListView_SetBkImage(hCtlListView1, &lv);
This requires comctl32.dll
4.71 and above. Note that animated GIF are displayed as normal GIF,
and only the first frame is displayed. Note also that they cannot
be stretched and that the images must be loaded from external files.
Benefits:
No need for extra DLL;
Code size minimal increase; OS support;
|
13 June
2000, Luigi Bianchi, but I must confess that Dino Esposito partially
published this before!!!
|
© Copyright (2000), Luigi Bianchi
Last Update:
June 25, 2002
|