47 KiB
Icon, Cursor, and Caret
Icon
An icon is a small image, and is usually used to present an application, or used in the windows such as warning message box. It consists of a bitmap and a mask bitmap, and can produce transparent image region. An icon file may include more than one icon image, and the application can choose an appropriate one to use according to the size and color bit number of each icon image.
MiniGUI provides the support to load, display, create and destroy of mono-color, 16-color and 256-color Windows icons.
Loading and Displaying Icon
The application can use the LoadIconFromFile
function to load an icon file,
and
the prototype of the LoadIconFromFile
function is as follows:
HICON GUIAPI LoadIconFromFile (HDC hdc, const char* filename, int which);
The argument meanings are as follow:
- hdc: The device context.
- filename: The file name of the icon file
- which: The index value of the selected icon.
LoadIconFromFile
function loads an icon from a Windows icon file (*.ico
),
and
the icon can be mono-color, 16-color or 256-color icon. Some Windows icon files
contain two icons in different sizes. You can tell this function to load which
icon though the argument of which, 0 for the first icon, and 1 for the second
icon. LoadIconFromFile
function reads in the information of the icon size,
color bit number and bitmap image pixel data, etc., calls CreateIcon
function
to create an icon object, and then returns an icon handle which presents the
loaded icon object.
You can also load an icon from a memory area by LoadIconFromMem
function, the
prototype of which is as follows:
HICON GUIAPI LoadIconFromMem (HDC hdc, const void* area, int which);
The memory area pointed to by area must have the same layout as a Windows ICO
file.
After the application has loaded the icon object, you can call DrawIcon
function to draw an icon in the specified position. DrawIcon
function draws
an
icon object in a rectangle region. The prototype of DrawIcon
function is as
follows:
void GUIAPI DrawIcon (HDC hdc, int x, int y, int w, int h, HICON hicon);
The argument meanings are as follow:
- hdc The device context.
- x, y The x and y coordinates of the upper-left corner of the rectangle.
- w, h The width and height of the rectangle, respectively
- hicon The handle of the icon object.
The code in List 1 illustrates how to load an icon from an icon file, and then
draw an icon in the client area of the window. The complete code of this
program can be referred to program drawicon.c in sample program package
mg-samples
for this guide.
List 1 Loading and drawing an icon
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
static int DrawiconWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
static HICON myicon_small, myicon_large;
HDC hdc;
switch (message) {
case MSG_CREATE:
/* call LoadIconFromFile function to load two icons with different size
* from myicon.ico file.
*/
myicon_small = LoadIconFromFile(HDC_SCREEN, "myicon.ico", 0);
if (myicon_small == 0)
fprintf (stderr, "Load icon file failure!");
myicon_large = LoadIconFromFile(HDC_SCREEN, "myicon.ico", 1);
if (myicon_large == 0)
fprintf (stderr, "Load icon file failure!");
break;
case MSG_PAINT:
/* display two icons in diffent positions of the window */
hdc = BeginPaint(hWnd);
if (myicon_small = 0)
DrawIcon(hdc, 10, 10, 0, 0, myicon_small);
if (myicon_large = 0)
DrawIcon(hdc, 60, 60, 0, 0, myicon_large);
EndPaint(hWnd, hdc);
return 0;
case MSG_CLOSE:
/* destroys the icon and the main window itself */
DestroyIcon(myicon_small);
DestroyIcon(myicon_large);
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/* the code below for creating main window are omitted */
The output of the program is as shown in Figure 1.
Figure 1 Drawing icon
The program described above loads two 16-color icons of 32x32 pixels and 16x16
pixels, respectively. The icon with number 0 is the big icon with 32x32 pixels,
and is saved in the icon object myicon_large;
and the icon with number 1 is
the
small one with 16x16 pixels, and is saved in the icon object myicon_small.
The
program uses DrawIcon
function to draw these two icons in the client area of
the window when handling MSG_PAINT
message. Note that w and h arguments
passed
to DrawIcon
function are both zero when calling it, and in this case
DrawIcon
function will draw the icon according to its original size without scaling.
Destroying Icon
The application should destroy an icon when the application does not need it
any more. The program above destroys the two icons previously loaded using
LoadIconFromFile
function by calling DestroyIcon
function when it is going
to
quit (when handling MSG_CLOSE
message). DestroyIcon
function destroys the
icon
handle, and releases the memory it used. This function’s prototype is as
follows:
BOOL GUIAPI DestroyIcon(HICON hicon);
DestroyIcon
function has only one parameter hicon, which specify the icon
object to be destroyed. The icon loaded by LoadIconFromFile
function needs to
be destroyed by DestroyIcon
function. We will see that DestroyIcon
can also
destroy the icon created dynamically by the application using CreateIcon
function.
Creating Icon
Besides loading an icon from an icon file, the application can also use
CreateIcon
function to create an icon dynamically at run time. The icon
created
by this function also needs to be destroyed by calling DestroyIcon
function.
The prototype of CreateIcon
function is as follows:
MG_EXPORT HICON GUIAPI CreateIconEx (HDC hdc, int w, int h,
const BYTE* AndBits, const BYTE* XorBits, int colornum,
const RGB* pal);
#define CreateIcon(hdc, w, h, AndBits, XorBits, colornum) \
CreateIconEx(hdc, w, h, AndBits, XorBits, colornum, NULL)
The argument meanings are as follow:
hdc: The device context.
w, h: The width and height of the icon, respectively.
pAndBits: The pointer to the AND bits of the icon.
pXorBits: The pointer to the XOR bits of the icon.
colornum: The bit-per-pixel of XOR bits.
CreateIcon
creates an icon according to the specified data such as icon size,
color and the bit-mask bitmap image. The icon width and height specified by
arguments of w and h respectively must be sizes supported by the system, for
example 16x16 pixels or 32x32 pixels. PAndBits
points to a byte array, which
comprises the image data of the AND
bit-mask bitmap of the icon, and the
AND
bit-mask bitmap should be mono-color. PXorBits
points to a byte array, which
comprises the image data of the XOR
bit-mask bitmap of the icon, and the
XOR
bit-mask bitmap can be a mono-color or colorful. MiniGUI currently supports
mono-color icon, 16-color icon and 256-color icon. Colornum specifies the
number of color bits of the icon, i.e., the number of the color bits of the
XOR
bit-mask bitmap. For mono-color icon, it should be 1, for 16-color icon, it
should be 4, for 256-color icon, it should be 8.
The code in List 2 describes how to use CreateIcon
function to create a
user-defined icon during runtime. The complete code of this program is
available in program createicon.c in the example program package mg-samples.
List 2 Creating an icon
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
/* define the AND mask data and XOR mask data of the icon */
static BYTE ANDmaskIcon[] = {
0xff, 0x9f, 0x00, 0x00,
0xff, 0x1f, 0x00, 0x00,
0xfc, 0x1f, 0x00, 0x00,
0xf0, 0x1f, 0x00, 0x00,
0xe0, 0x0f, 0x00, 0x00,
0xc0, 0x07, 0x00, 0x00,
0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00,
0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x00, 0x00,
0xc0, 0x07, 0x00, 0x00,
0xf0, 0x1f, 0x00, 0x00
};
static BYTE XORmaskIcon[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x8f, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x8f, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x08, 0xff, 0xf8, 0xff, 0xf8, 0x00, 0x00,
0x00, 0xff, 0xff, 0x80, 0x8f, 0xff, 0xf0, 0x00,
0x00, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xf0, 0x00,
0x0f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0x00,
0x0f, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x00,
0x0f, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0x00,
0x0f, 0xff, 0xf0, 0x0f, 0x00, 0xff, 0xff, 0x00,
0x00, 0xff, 0xf8, 0x00, 0x08, 0xff, 0xf0, 0x00,
0x00, 0x8f, 0xff, 0x80, 0x8f, 0xff, 0xf0, 0x00,
0x00, 0x00, 0x8f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x9f, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00,
0xfc, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00,
0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00,
0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x80, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00,
0xc0, 0x07, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00,
0x26, 0x00, 0x00, 0x00, 0xf4, 0xd9, 0x04, 0x08,
0xa8, 0xf8, 0xff, 0xbf, 0xc0, 0xf7, 0xff, 0xbf,
0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x00, 0x00,
0x28, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0xf0, 0x10, 0x04, 0x00, 0x70, 0xe1, 0x04, 0x08,
0xd8, 0xf8, 0xff, 0xbf, 0x41, 0x90, 0x04, 0x08
};
static int CreateiconWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
static HICON new_icon;
HDC hdc;
switch (message) {
case MSG_CREATE:
/* create an icon using the user-difined data */
new_icon = CreateIcon(HDC_SCREEN, 16, 16, ANDmaskIcon, XORmaskIcon, 4);
break;
case MSG_PAINT:
hdc = BeginPaint(hWnd);
if (new_icon = 0) {
/* display the icon with its actual size */
DrawIcon(hdc, 0, 0, 0, 0, new_icon);
/* display the scaled icon */
DrawIcon(hdc, 50, 50, 64, 64, new_icon);
}
EndPaint(hWnd, hdc);
return 0;
case MSG_CLOSE:
/* destroy the icon and the main window */
DestroyIcon(new_icon);
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/* the code below for creating main window are omitted */
The output of the program is as shown in Figure 2.
Figure 2 Creating and drawing icon
The code in List 2 creates a user-defined icon new_icon
by calling
CreateIcon
according to the data in the ANDmaskIcon
and XORmaskIcon
bit-mask byte
array.
The size of the icon is 16x16 pixels, and the number of color bits is 4. And
then the program draws the created “interrogation” icon in the client area of
the window with its original size and scaled size. Finally, the program calls
DestroyIcon
function to destroy the user-defined icon created by CreateIcon
function when handling MSG_CLOSE
message.
Using System Icons
Each renderer section in MiniGUI.cfg
, the configuration file of MinGUI
,
defines
the icons which are used and provided by the system. The icons of Classic
renderer are shown as follow:
[classic]
# Note that max number defined in source code is 5.
- [Icon](#icon)
+ [Loading and Displaying Icon](#loading-and-displaying-icon)
+ [Destroying Icon](#destroying-icon)
+ [Creating Icon](#creating-icon)
+ [Using System Icons](#using-system-icons)
- [Cursor](#cursor)
+ [Loading and Creating Cursor](#loading-and-creating-cursor)
+ [Destroying Cursor](#destroying-cursor)
+ [Positioning and Displaying Cursor](#positioning-and-displaying-cursor)
+ [Clipping Cursor](#clipping-cursor)
+ [Using System Cursors](#using-system-cursors)
+ [Sample Program](#sample-program)
- [Caret](#caret)
+ [Creating and Destroying Caret](#creating-and-destroying-caret)
+ [Showing and Hiding Caret](#showing-and-hiding-caret)
+ [Positioning Caret](#positioning-caret)
+ [Changing Blink Time of Caret](#changing-blink-time-of-caret)
+ [Sample Program](#sample-program)
iconnumber=5
icon0=form.ico
icon1=failed.ico
icon2=help.ico
icon3=warning.ico
icon4=excalmatory.ico
NOTE The maximum number of the icon files the system uses is 5, which is defined in the source code of MiniGUI. Therefore, if you modify the iconnumber item in the configuration file, its value should be smaller than or equal to 5, and the icons with number larger than 5 will be ignored.
There are four renderers are defined in MiniGUI.cfg
, the configuration file
of
MiniGUI, classic, flat, skin and fashion (fashion renderer must be together
with mgplus component). Each renderer defines the specified system icons.
MiniGUI loads all the system icons from icon files to memory according to the
setting of the iconinfo section in the configuration file when initializing
renderer. The application can get the built-in system icons through
GetLargeSystemIcon
function and GetSmallSystemIcon
function. The prototypes
of
these two functions are as follow:
HICON GUIAPI GetLargeSystemIcon (int id);
HICON GUIAPI GetSmallSystemIcon (int id);
GetLargeSystemIcon
is used to get a large system icon with 32x32 pixels, and
GetSmallSystemIcon
is used to get a small system icon with 16x16 pixels.
These
two functions return the handle of the built-in system icon object. The
obtained icon is one of the seven system icons, which is specified by id. Id is
an integer value, and may be one of the following values:
IDI_APPLICATION Application icon
IDI_STOP / IDI_HAND Stoping icon
IDI_QUESTION Question icon
IDI_EXCLAMATION Exclamation icon
IDI_INFORMATION / IDI_ASTERISK Information icon
These identifiers are defined in minigui/window.h
as follow:
#define IDI_APPLICATION 0
#define IDI_HAND 1
#define IDI_STOP IDI_HAND
#define IDI_QUESTION 2
#define IDI_EXCLAMATION 3
#define IDI_ASTERISK 4
#define IDI_INFORMATION IDI_ASTERISK
It can be seen that they present the five icon files with sequence number from
0 to 4 in MiniGUI.cfg
. The icon files with index numbers 5 and 6 are used by
TREEVIEW
control.
The icons obtained by GetLargSystemIcon
and GetSamllSystemIcon
functions
are
system-predefined icons, which are system sharing resources and do not need to
be destroyed by the application.
In addition, the application may also use LoadSystemIcon
function to load the
required icon directly from the icon file defined in MiniGUI.cfg
configuration
file:
HICON GUIAPI LoadSystemIcon (const char* szItemName, int which);
Here szItemName
argument specifies the symbol name of the icon file defined
in
the iconinfo section of MiniGUI.cfg
, for example, icon0 presents form.ico
icon
file. The argument of which specifies which icon is to be loaded. This function
returns the handle to the obtained icon object.
Actually, LoadSystemIcon
loads an icon by calling LoadIconFromFile
.
Apparently,
the icon created by LoadSystemIcon
must be destroyed using DestroyIcon
function
when it is not be required any more.
Cursor
The pointing device such as mouse controls a cursor, which is a small bitmap and its position in the screen. It is used to indicate the position of the pointing device. When the user moves the mouse, the cursor will move on the screen accordingly. If the cursor moves into different region or different window, the system possibly changes the shape of the cursor. A pixel called hotspot in the cursor indicates the accurate position of the cursor on the screen. The system uses this point to trace and identify the cursor position. For example, the hotspot of a arrow cursor is commonly its arrowhead position. The cursor hotspot is commonly the cursor focus. If a mouse input event occurs, the system will send the mouse containing the hotspot coordinates to the window, which the hotspot is located in, or to the window, which captures the mouse.
MiniGUI provides functions for loading, creating, displaying, destroying, and moving mono- and 16-color cursors. Currently, MiniGUI does not support 256-color or animation cursor.
Loading and Creating Cursor
The application may use LoadCursorFromFile
function to load a cursor form a
Windows cursor file. The prototype of this function is as follows:
HCURSOR GUIAPI LoadCursorFromFile (const char* filename);
LoadCursorFromFile
function reads in information of the size of the cursor,
the
hotspot position, the number of color bits, and the bitmap image data, etc.,
creates an cursor object, and returns a cursor handle presenting this cursor
object.
LoadCursorFromMem
function loads a cursor from memory:
HCURSOR GUIAPI LoadCursorFromMem (const void* area);
This function loads a cursor from a specified memory area, the cursor memory area to which area points should be the same as the layout of the Windows cursor file.
The application may also create dynamically a cursor by calling CreateCursor
function during run time. The prototype of CreateCursor
function is as
follows:
HCURSOR GUIAPI CreateCursor (int xhotspot, int yhotspot, int w, int h,
const BYTE* pANDBits, const BYTE* pXORBits, int colornum);
The argument meanings are as follow:
xhotspot, yhotspot: the horizontal and vertical positions of the cursor hotspot
w, h: the width and height of the cursor
pAndBits: The pointer to the AND bits of the cursor.
pXorBits: The pointer to the XOR bits of the cursor.
colornum: The bit-per-pixel of XOR bits.
Similar to the method of creating an icon by CreateIcon
function,
CreateCursor
function creates an cursor according to the data of specified cursor size,
color and bit-mask bitmap image in memory. The difference is that the hotspot
position of the cursor to be created must be specified when using
CreateCursor
function. Xhotspot and yhotspot arguments specify the horizontal and vertical
positions of the hotspot of the created cursor, respectively. The cursor width
and height specified by w and h must be the size supported by the system, and
MiniGUI can only use cursor of 32x32 pixels. Therefore, the value of w and h
arguments can only be 32. PANDBits
points to a byte array of a AND
bit-mask
bitmap image data containing a cursor, and AND
bit-mask bitmap is a
mono-color
bitmap. PXorBits
points to a byte array of a XOR
bit-mask bitmap image data
containing a cursor, and XOR
bit-mask bitmap may be either a mono-color
bitmap
or a color bitmap. Colornum specifies the number of color bits of the cursor,
or the number of color number of the XOR
bit-mask bitmap. For a mono-color
cursor, it should be 1, and for 16-color cursor, it should be 4.
Destroying Cursor
The application should destroy the cursor when not requiring it any more.
DestroyCursor
function can destroy the cursor created by LoadCursorFromFile
and
CreateCursor
functions, and release the memory used by the cursor object. The
prototype of this function is as follows:
BOOL GUIAPI DestroyCursor (HCURSOR hcsr);
The argument hcursor of DestroyCursor
function specifies the cursor object to
be destroyed.
Positioning and Displaying Cursor
If the system includes a mouse, then the system will display it automatically,
and update its position on the screen according to the position of mouse and
repaint the cursor. The application can get the current screen position of the
cursor by calling GetCursorPos
function, and move the cursor to the specified
position on the screen by calling SetCursorPos
function.
void GUIAPI GetCursorPos (POINT* ppt);
void GUIAPI SetCursorPos (int x, int y);
The application can get the current cursor handle by calling GetCurrentCursor
function, and set the current cursor by calling SetCursorEx
function. The
prototypes of these two functions are as follow:
HCURSOR GUIAPI GetCurrentCursor (void);
HCURSOR GUIAPI SetCursorEx (HCURSOR hcsr, BOOL set_def);
SetCursorEx
function sets the cursor specified by hcsr as the current cursor.
If set_def
is TRUE
, SetCursorEx
will further set this cursor as the
default
cursor, which is the cursor displayed when moved the mouse to the desktop. This
function returns old cursor handle. SetCursorEx
has other two simplified
versions: SetCursor
and SetDefaultCursor
. SetCursor
sets the current
cursor and
does not change the default cursor; and SetDefaultCursor
sets the specified
cursor as the current cursor and the default cursor.
#define SetCursor(hcsr) SetCursorEx (hcsr, FALSE);
#define SetDefaultCursor(hcsr) SetCursorEx (hcsr, TRUE);
MiniGUI will send MSG_SETCURSOR
to the window under the cursor when the user
moves the mouse, and the application can change the current cursor when
handling MSG_SETCURSOR
message. If the window procedure function changes the
cursor when handling this message, it should be returned immediately.
The system displays the class cursor related to the control where the cursor
is. The application can assign a class cursor to the control class when
registering the control class. After registering this control class, each
control of this control class has the same class cursor, i.e., the cursor
displayed by the system is the same specified cursor when the mouse moves onto
these controls. The application can get the current cursor of the specified
window through GetWindowCursor
, and sets a new window cursor through
SetWindowCursor
.
HCURSOR GUIAPI GetWindowCursor (HWND hWnd);
HCURSOR GUIAPI SetWindowCursor (HWND hWnd, HCURSOR hNewCursor);
The code below is from listview.c in the MiniGUI source code, which illustrates
how to assign a cursor handle to hCursor
member of the WNDCLASS
structure
to
specify the class cursor for a control class.
WNDCLASS WndClass;
WndClass.spClassName = CTRL_LISTVIEW;
WndClass.dwStyle = WS_NONE;
WndClass.dwExStyle = WS_EX_NONE;
WndClass.hCursor = GetSystemCursor (0);
WndClass.iBkColor = PIXEL_lightwhite;
WndClass.WinProc = sListViewProc;
return RegisterWindowClass (&WndClass);
The class cursor in the code above is the system default cursor gotten by
GetSystemCursor
function, i.e., an arrow cursor. GetSystemCursor
(0) and
GetSystemCursor
(IDC_ARROW
) are the same.
The application can show or hide the cursor by calling ShowCursor
function.
int GUIAPI ShowCursor (BOOL fShow);
ShowCursor
function hides the cursor when parameter fShow
is FALSE
, and
shows
the cursor when fShow
is TRUE
. ShowCursor
does not change the shape of
the
current cursor. This function internally uses a cursor showing counter to
determine whether showing or hiding the cursor. Each calling of ShowCursor
function to show the cursor will increase this counter by one, and each calling
of ShowCursor
function to hide the cursor will decrease this counter by one.
The cursor is visible only when the counter is larger than or equal to 0.
Clipping Cursor
The application can use ClipCursor
function to clip the cursor within a
certain
rectangle area, which is usually used to correspond to an event in a certain
clipping rectangle. The prototype of this function is as follows:
void GUIAPI ClipCursor (const RECT* prc);
The specified clipping rectangle is pointed by parameter prc. If prc is NULL
,
ClipCursor
will disable cursor clipping. When ClipCursor
function clips the
cursor in a certain rectangular area on the screen, it moves the cursor to the
center of the rectangular area.
GetClipCursor
function gets the current cursor clipping rectangle, and can be
used to save the original clipping rectangle before setting a new clipping
rectangle and use it to restore the original area when required. The prototype
of this function is as follows:
void GUIAPI GetClipCursor (RECT* prc);
Using System Cursors
The cursorinfo section in the configuration file of MiniGUI, MiniGUI.cfg
,
defines all the cursors provide by the system, as shown below:
[cursorinfo]
# Edit following line to specify cursor files path
- [Icon](#icon)
+ [Loading and Displaying Icon](#loading-and-displaying-icon)
+ [Destroying Icon](#destroying-icon)
+ [Creating Icon](#creating-icon)
+ [Using System Icons](#using-system-icons)
- [Cursor](#cursor)
+ [Loading and Creating Cursor](#loading-and-creating-cursor)
+ [Destroying Cursor](#destroying-cursor)
+ [Positioning and Displaying Cursor](#positioning-and-displaying-cursor)
+ [Clipping Cursor](#clipping-cursor)
+ [Using System Cursors](#using-system-cursors)
+ [Sample Program](#sample-program)
- [Caret](#caret)
+ [Creating and Destroying Caret](#creating-and-destroying-caret)
+ [Showing and Hiding Caret](#showing-and-hiding-caret)
+ [Positioning Caret](#positioning-caret)
+ [Changing Blink Time of Caret](#changing-blink-time-of-caret)
+ [Sample Program](#sample-program)
cursorpath=/usr/local/lib/minigui/res/cursor/
cursornumber=23
cursor0=d_arrow.cur
cursor1=d_beam.cur
cursor2=d_pencil.cur
cursor3=d_cross.cur
cursor4=d_move.cur
cursor5=d_sizenesw.cur
cursor6=d_sizens.cur
cursor7=d_sizenwse.cur
cursor8=d_sizewe.cur
cursor9=d_uparrow.cur
cursor10=d_none.cur
cursor11=d_help.cur
cursor12=d_busy.cur
cursor13=d_wait.cur
cursor14=g_rarrow.cur
cursor15=g_col.cur
cursor16=g_row.cur
cursor17=g_drag.cur
cursor18=g_nodrop.cur
cursor19=h_point.cur
cursor20=h_select.cur
cursor21=ho_split.cur
cursor22=ve_split.cur
The maximum number of the cursors used by the system defined in MiniGUI is
(MAX_SYSCURSORINDEX + 1). MAX_SYSCURSORINDEX
is the maximum system cursor
index
value, defined as 22; therefore the maximum cursor number predefined by the
system is 23.
MiniGUI loads all the system cursors from the specified cursor files to memory
according to the setting of the cursorinfo section in the configuration file
when initializing the system. The application can get the built-in system
cursor through GetSystemCursor
function. The prototype of this function is as
follows:
HCURSOR GUIAPI GetSystemCursor (int csrid);
GetSystemCursor
function returns the handle to the cursor object in memory.
The
obtained cursor is one of the possible 23 system system-predefined cursors, and
is specified by identifier csrid. Parameter csrid is an integer value, and may
be one of the following values:
IDC_ARROW System default arrow cursor
IDC_IBEAM ‘I’ shaped cursor, indicating an input filed
IDC_PENCIL Pencil-shape cursor
IDC_CROSS Cross cursor
IDC_MOVE Moving cursor
IDC_SIZENWSE Sizing cursor, along north-west and south-east
IDC_SIZENESW Sizing cursor, along north-east and south-west
IDC_SIZEWE Sizing cursor, along west and east
IDC_SIZENS Sizing cursor, along north and south
IDC_UPARROW Up arrow cursor
IDC_NONE None cursor
IDC_HELP Arrow with question
IDC_BUSY Busy cursor
IDC_WAIT Wait cursor
IDC_RARROW Right arrow cursor
IDC_COLOMN Cursor indicates column
IDC_ROW Cursor indicates row
IDC_DRAG Draging cursor
IDC_NODROP No droping cursor, used in dragging operation
IDC_HAND_POINT Hand point cursor
IDC_HAND_SELECT Hand selection cursor
IDC_SPLIT_HORZ Horizontal splitting cursor
IDC_SPLIT_VERT Vertical splitting cursor
The definitions of these cursor index values are as follow:
/* System cursor index. */
#define IDC_ARROW 0
#define IDC_IBEAM 1
#define IDC_PENCIL 2
#define IDC_CROSS 3
#define IDC_MOVE 4
#define IDC_SIZENWSE 5
#define IDC_SIZENESW 6
#define IDC_SIZEWE 7
#define IDC_SIZENS 8
#define IDC_UPARROW 9
#define IDC_NONE 10
#define IDC_HELP 11
#define IDC_BUSY 12
#define IDC_WAIT 13
#define IDC_RARROW 14
#define IDC_COLOMN 15
#define IDC_ROW 16
#define IDC_DRAG 17
#define IDC_NODROP 18
#define IDC_HAND_POINT 19
#define IDC_HAND_SELECT 20
#define IDC_SPLIT_HORZ 21
#define IDC_SPLIT_VERT 22
They present the 23 system-predefined cursors with sequence number from 0 to 22 in MiniGUI, respectively.
The cursor gotten through GetSystemCursor
function is the system-predefined
cursor, and belongs to the system sharing resource; therefore it needs not to
be destroyed by the application.
Sample Program
The code in List 3 illustrates the use of the cursor in MiniGUI. The complete code of this program is available in program cursordemo.c in the sample program package mg-samples.
List 3 Using cursor
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#define IDC_TRAP 100
static HWND hTrapWin, hMainWnd;
static RECT rcMain, rc;
/* window procedure of “trap” control class */
static int TrapwindowProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
static BOOL bTrapped = FALSE;
switch (message) {
case MSG_MOUSEMOVE:
/* further clipping in the range of the control
* when the mouse enters the range of this control
*/
if (!bTrapped) {
GetWindowRect(hWnd, &rc);
ClientToScreen(hMainWnd, &rc.left, &rc.top);
ClientToScreen(hMainWnd, &rc.right, &rc.bottom);
ClipCursor(&rc);
bTrapped = TRUE;
}
break;
case MSG_DESTROY:
return 0;
}
return DefaultControlProc(hWnd, message, wParam, lParam);
}
/* register “trap” control class */
BOOL RegisterTrapwindow (void)
{
WNDCLASS WndClass;
WndClass.spClassName = "trap";
WndClass.dwStyle = 0;
WndClass.dwExStyle = 0;
WndClass.hCursor = GetSystemCursor(IDC_HAND_POINT);
WndClass.iBkColor = PIXEL_black;
WndClass.WinProc = TrapwindowProc;
return RegisterWindowClass (&WndClass);
}
static int CursordemoWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case MSG_CREATE:
/* register “trap” control class */
RegisterTrapwindow();
/* create an instance of “trap” control class */
hTrapWin = CreateWindow("trap", "", WS_VISIBLE | WS_CHILD, IDC_TRAP,
10, 10, 100, 100, hWnd, 0);
break;
case MSG_LBUTTONDOWN:
/* Clip the cursor to the main window when the user click the left mouse button. */
GetWindowRect(hWnd, &rcMain);
ClipCursor(&rcMain);
/* hide the mouse cursor */
ShowCursor(FALSE);
break;
case MSG_RBUTTONDOWN:
/* show the mouse cursor when the right mouse button clicked */
ShowCursor(TRUE);
break;
case MSG_SETCURSOR:
/* set the mouse cursor shape to be “I” shape */
SetCursor (GetSystemCursor (IDC_IBEAM));
return 0;
case MSG_CLOSE:
/* destroy the control and the main window itself */
DestroyAllControls (hWnd);
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/* the code below for creating main window are omitted */
Figure 3 Using cursor
The user interface of the sample program above is shown in Figure 3. The
procedure of the main window registers a window class “trap” by calling
RegisterTrapWindow
function, and then creates a child window of “trap” class
with size of 100x100 in the up-left corner (10, 10). RegisterTrapWindow
function sets the background color of the window to be black and sets the
window class cursor to be hand-point cursor when registering the “trap” window
class. The window procedure of trap window class clips the cursor within this
window by calling ClipCursor
function when handling MSG_MOUSEMOVE
message.
When handling MSG_LBUTTONDOWN
message, the main window procedure first gets
the
main window rectangle by calling GetWindwoRect
, clips the cursor within the
main window rectangle by calling ClipCursor
function, and then hides the
cursor
by calling ShowCursor
function. When handling MSG_RBUTTONDOWN
message, the
main
window procedure shows the cursor by calling ShowCursor
function. The main
window procedure resets the current cursor (arrow cursor) to I-shaped cursor.
During program running, the moving of the cursor is clipped within the main window and is hidden when the user clicks the mouse left button in the main window. The user can show the cursor again by clicking the right mouse button. When the cursor is moved onto the trap window, it will be “grasped” within this black window.
Caret
The caret is a blinking character in the window client area, and is normally used to indicate the position of keyboard input. Usual shapes of the caret are an underline, a vertical line, a block, and so on.
MiniGUI provides the application with functions of creating, destroying, showing, hiding, positioning the caret, and changing the caret blinking time.
Creating and Destroying Caret
CreateCaret
function creates a caret and assigns it to a specified window.
BOOL GUIAPI CreateCaret (HWND hWnd, PBITMAP pBitmap, int nWidth, int nHeight);
The argument meanings are as follow:
hWnd: The owner of the caret.
pBitmap: The bitmap shape of the caret.
nWidth: The width of the caret.
nHeight: The height of the caret.
If pBitmap
is not NULL
, CreateCaret
function will create a caret
according to
the bitmap object. If pBitmap
is NULL
, CreateCaret
function will create
the
caret by a rectangle with nWidth
wide and nHeight
high. The width nWidth
and
height nHeight
of the caret are in pixels.
The caret is hidden after being created. To show the caret, you must call
ShowCaret
function to show the caret on the screen after creating it by
calling
CreateCaret
function.
DestroyCaret
function destroys the caret created by CreateCaret
function,
and
its prototype is as follows:
BOOL GUIAPI DestroyCaret (HWND hWnd);
DestroyCaret
function destroys the caret of a window, and deletes it from the
screen.
We can create a caret by calling CreateCaret
in MSG_CREATE
message, and
then
destroy it by calling DestroyCaret
function when receiving MSG_DESTROY
message.
Showing and Hiding Caret
At a time, only one window has the keyboard input focus. Usually, the window, which receives the keyboard input, shows the caret when receiving the input focus, and hides the caret when losing the input focus.
The system sends MSG_SETFOCUS
message to the window that has received the
input
focus and the application should shows the caret by calling ShowCaret
function
when receiving this message. When the window loses the keyboard input focus,
the system sends a MSG_KILLFOCUS
message to this window, and the application
should hides the caret by calling HideCaret
function when handling this
message. The prototypes of these two functions are as follow:
BOOL GUIAPI ShowCaret (HWND hWnd);
BOOL GUIAPI HideCaret (HWND hWnd);
ShowCaret
function shows the caret of a given window, and the caret will
automatically blink after appearing. HideCaret
function deletes the caret
from
the screen. If the application must repaint the screen when handling
MSG_PAINT
message, and must retain the caret, you can use HideCaret
function to hide
the
caret before painting, and use ShowCaret
function to show the caret again
after
painting. If the message being handled by the application is MSG_PAINT
message,
you need not hide and show again the caret, because BeginPaint
and EndPaint
function will automatically finish these operations.
Positioning Caret
The application uses GetCaretPos
function to get the position of the caret,
and
uses SetCaretPos
function to move the caret within a window.
BOOL GUIAPI GetCaretPos (HWND hWnd, PPOINT pPt);
BOOL GUIAPI SetCaretPos (HWND hWnd, int x, int y);
The function GetCaretPos
copies the position of the window caret, in client
coordinates, to a POINT
structure pointed to by pPt
. SetCaretPos
function
moves
the caret of the window to the position in the client area specified by x and
y, regardless whether or not the caret is visible.
Changing Blink Time of Caret
The elapsed time for reversing the caret is called reversing time. Blinking
time is referred to the elapsed time for showing, reversing, and recovering.
The application uses GetCaretBlinkTime
to get the blink time of the caret, in
milliseconds. The blink time of the system default caret is 500 milliseconds.
You can use SetCaretBlinkTime
function to change the blink time of the caret.
The blink time of the caret cannot be less than 100 milliseconds. The
definitions of these two functions are as follow:
UINT GUIAPI GetCaretBlinkTime (HWND hWnd);
BOOL GUIAPI SetCaretBlinkTime (HWND hWnd, UINT uTime);
Sample Program
The code in List 4 uses the caret functions discussed in this section to create a simple text input window, which can be considered as a simple edit box control. In “myedit” control, you can input less than 10 characters, move the caret by left and right arrow key (caret moving key), and delete the character in the window with backspace key. The complete code of this program is available in program caretdemo.c in the sample program package mg-samples.
List 4 Using caret
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#define IDC_MYEDIT 100
/* the window procedure of a simple edit box control class */
static int MyeditWindowProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
/* use a static variable to save the information of the control.
* in a real control, you should not use static variables to save these informations,
* because a control class may have many control instances at the same time
*/
static char *pBuffer = NULL;
static int pos = 0, len = 0;
HDC hdc;
switch (message) {
case MSG_CREATE:
/* set the control font to be the system default font */
SetWindowFont(hWnd, GetSystemFont(SYSLOGFONT_WCHAR_DEF));
/* create the caret */
if (!CreateCaret (hWnd, NULL, 1, GetSysCharHeight())) {
return -1;
}
/* allocate the edit buffur */
pBuffer = (char *) malloc(10);
*pBuffer = 0;
break;
case MSG_SETFOCUS:
/* set the caret postion when getting the input focus */
SetCaretPos(hWnd, pos*GetSysCharWidth(), 0);
/* showing the caret */
ShowCaret(hWnd);
break;
case MSG_KILLFOCUS:
/* hiding the caret when losing the focus */
HideCaret(hWnd);
break;
case MSG_CHAR:
switch (wParam) {
case '\t':
case '\b':
case '\n':
{
/* change the blink time of the caret when inputting these characters */
SetCaretBlinkTime(hWnd, GetCaretBlinkTime(hWnd)-100);
}
break;
default:
{
/* insert characters in the buffer area */
char ch, buf[10];
char *tmp;
ch = wParam;
if (len == 10)
break;
tmp = pBuffer+pos;
if (*tmp = 0) {
strcpy(buf, tmp);
strcpy (tmp+1, buf);
}
*tmp = ch;
pos++;
len++;
break;
}
break;
}
break;
case MSG_KEYDOWN:
switch (wParam) {
case SCANCODE_CURSORBLOCKLEFT:
/* move the caret to the left */
pos = MAX(pos-1, 0);
break;
case SCANCODE_CURSORBLOCKRIGHT:
/* move the caret to the right */
pos = MIN(pos+1, len);
break;
case SCANCODE_BACKSPACE:
{
/* delete the character where the caret is */
char buf[10];
char *tmp;
if (len == 0 || pos == 0)
break;
tmp = pBuffer+pos;
strcpy(buf, tmp);
strcpy(tmp-1, buf);
pos--;
len--;
}
break;
}
/* update the caret positon and repaint the window */
SetCaretPos(hWnd, pos*GetSysCharWidth(), 0);
InvalidateRect(hWnd, NULL, TRUE);
break;
case MSG_PAINT:
hdc = BeginPaint(hWnd);
/* output text */
TextOut(hdc, 0, 0, pBuffer);
EndPaint(hWnd, hdc);
return 0;
case MSG_DESTROY:
/* destroy the caret and release the buffer */
DestroyCaret (hWnd);
if (pBuffer)
free(pBuffer);
return 0;
}
return DefaultControlProc(hWnd, message, wParam, lParam);
}
/* register a simple edit box control */
BOOL RegisterMyedit(void)
{
WNDCLASS WndClass;
WndClass.spClassName = "myedit";
WndClass.dwStyle = 0;
WndClass.dwExStyle = 0;
WndClass.hCursor = GetSystemCursor(IDC_IBEAM);
WndClass.iBkColor = PIXEL_lightwhite;
WndClass.WinProc = MyeditWindowProc;
return RegisterWindowClass (&WndClass);
}
/* main windoww proc */
static int CaretdemoWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
HWND hMyedit;
switch (message) {
case MSG_CREATE:
/* register simple edit box control class and create an instance */
RegisterMyedit();
hMyedit = CreateWindow("myedit", "", WS_VISIBLE | WS_CHILD, IDC_MYEDIT,
30, 50, 100, 20, hWnd, 0);
SetFocus(hMyedit);
break;
case MSG_CLOSE:
/* destroy the control and the main window itself */
DestroyAllControls (hWnd);
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/* the code below for creating main window are omitted */
Figure 4 A simple edit box
For simplification, we use fixed-width font in “myedit” because other fonts are
more difficult to handle. The window procedure function of myedit uses
GetSystemFont
(SYSLOGFONT_WCHAR_DEF
) to get the system default fixed-width
font, and then set the font of the text input window by calling
SetWindowFont
.
Myedit control calls CreatCaret
function in MSG_CREATE
message to create a
caret of width 1 and the same height as the font.
The buffer area pointed to by pBuffer
is used to save the characters input
into
the text window; len presents the number of characters, and pos presents the
current edit position of the current caret.
The window procedure of myedit calls ShowCaret
function to show the caret
when
receiving MSG_SETFOCUS
message, and calls HideCaret
to hide the caret when
receiving MSG_KILLFOCUS
message.
myedit handles the input of normal characters in MSG_CHAR
message, and
adjusts
the buffer and values of the pos and len correspondingly. Furthermore, each
time myedit receives special character such as newline, myedit calls
SetCaretBlinkTime
to reduce the reversing time of caret by 100 ms.
myedit handles the left and arrow keys and the backspace key in MSG_KEYDOWN
message, adjusts the caret position by calling SetCaretPos
function, paints
in
MSG_PAINT
, and destroys the caret when receiving MSG_DESTROY
message.
<< Input Messages | Table of Contents | Look-and-feel and UI Effects >>