mirror of
https://github.com/VincentWei/minigui-docs.git
synced 2025-10-19 20:13:25 +08:00
769 lines
27 KiB
Markdown
769 lines
27 KiB
Markdown
# List Box Control
|
||
|
||
- [Types and Styles of List Box](#types-and-styles-of-list-box)
|
||
- [Messages of List Box](#messages-of-list-box)
|
||
+ [Adding Item into List Box](#adding-item-into-list-box)
|
||
+ [Deleting Item from List Box](#deleting-item-from-list-box)
|
||
+ [Selecting and Getting Item](#selecting-and-getting-item)
|
||
+ [Searching Item Including a Text String](#searching-item-including-a-text-string)
|
||
+ [Setting/Getting the Status of Check Mark](#settinggetting-the-status-of-check-mark)
|
||
+ [Setting the Bold Status of Item](#setting-the-bold-status-of-item)
|
||
+ [Setting/Getting the Disable Status of Item](#settinggetting-the-disable-status-of-item)
|
||
+ [Adding Multiple Items into List Box](#adding-multiple-items-into-list-box)
|
||
+ [Other Messages](#other-messages)
|
||
- [Notification Codes of List Box](#notification-codes-of-list-box)
|
||
- [Sample Program](#sample-program)
|
||
|
||
|
||
A list box generally provides a series of options, which are shown in a scroll
|
||
window. The user can select one or more items with the keyboard or mouse
|
||
operation. The selected items are usually highlighted. The most typical use of
|
||
list box is the open file dialog box, as shown in Figure 1.
|
||
|
||

|
||
|
||
__Figure 1__ Typical use of list box: “Open File” dialog box
|
||
|
||
We can create a list box control by calling `CreateWindow` function with
|
||
`CTRL_LISTBOX` as the control class name.
|
||
|
||
## Types and Styles of List Box
|
||
|
||
List box controls of MiniGUI can be divided into three types: single-selection
|
||
list box, multiple-selection list box and bitmap list box. A list box is
|
||
single-selection style by default; namely, the user can only select one item.
|
||
To create a multiple-selection list box, you should use `LBS_MULTIPLESEL`
|
||
style. When using this style, the user can select an item by clicking this
|
||
item, and cancel the selection by clicking it again. When the list box has the
|
||
input focus, you can also use the space key to select or cancel selection of an
|
||
item. The effect of running a multiple-selection list box is as shown in Figure
|
||
2.
|
||
|
||
|
||

|
||
|
||
__Figure 2__ Multiple-selection list box
|
||
|
||
|
||
Besides the two list box types described above, MiniGUI also provides an
|
||
advanced list box type. In this type of list box, the list item can be not only
|
||
text string, but also attached by a bitmap or an icon. With such a list box, we
|
||
can also display a check box besides the list item to represent checked or
|
||
uncheck status. To create such an advanced list box, `LBS_USEICON` or
|
||
`LBS_CHECKBOX` style should be specified. Fig 21.3 shows the running effect of
|
||
the advanced list box. If you want the selection state auto-switched when the
|
||
user clicks the check box, you can use `LBS_AUTOCHECK` style. The advanced list
|
||
box can also have `LBS_MULTIPLESEL` style.
|
||
|
||

|
||
|
||
__Figure 3__ Advanced list box control
|
||
|
||
Except the styles described above to distinguish the type of list box, you can
|
||
also specify other general styles when creating a list box.
|
||
|
||
By default, the message handler of a list box only shows the list items, with
|
||
no border around them. You can add border by using the window style `WS_BORDE`.
|
||
In addition, you can also add a vertical scroll bar with window style
|
||
`WS_VSCROLL` to scroll the list items by the mouse and add a horizontal scroll
|
||
bar with window style `WS_HSCROLL`.
|
||
|
||
The default list box styles does not generate notification message when the
|
||
user select a list item, so the program must send a message to the list box to
|
||
get the selection state of item. Therefore, a list box control generally
|
||
includes `LBS_NOTIFY` style, which can feed back some state information in time
|
||
to the application during the user’s operation.
|
||
|
||
In addition, if you want the list box control sort the list items, you can use
|
||
another commonly used style `LBS_SORT`.
|
||
|
||
Generally, the most commonly used style combination for creating list box is as
|
||
follows:
|
||
|
||
|
||
```cpp
|
||
(LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
|
||
```
|
||
|
||
## Messages of List Box
|
||
### Adding Item into List Box
|
||
|
||
After a list box is created, the next step is to add text strings to it. You
|
||
can realize this by sending messages to the window message handler of the list
|
||
box by calling `SendMessage`. The items in a list box can be referred to by an
|
||
index value; the top-most item has index value of zero. In the following
|
||
example, `hwndList` is the handle of the list box control, and index is the
|
||
index value. When `SendMessage` is used to pass the text string, `lParam` is
|
||
the pointer to the `NULL-terminated` string.
|
||
|
||
When the stored content of the list box exceeds the available memory space,
|
||
`SendMessage` returns `LB_ERRSPACE`. If error is caused by other reasons,
|
||
`SendMessage` returns `LB_ERR`. If the operation is successful, `SendMessage`
|
||
returns `LB_OKAY`. We can determine above two errors by testing the non-zero
|
||
value of `SendMessage`.
|
||
|
||
If you adopt `LBS_SORT` style, or just want to append the new text string as
|
||
the last item of a list box, the simplest approach to append string into the
|
||
list box is using `LB_ADDSTRING` message:
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM)string) ;
|
||
```
|
||
|
||
We can also use `LB_INSERTSTRING` to specify an index, and insert a text string
|
||
to the specified position of the list box.
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_INSERTSTRING, index, (LPARAM)string) ;
|
||
```
|
||
|
||
For example, if index value is 4, string would be a text string with index 4:
|
||
the fifth string counting from the beginning (due to zero-based), and all the
|
||
text strings after this position will move backward. When the index is -1, the
|
||
string will append to the last position. We can also use `LB_INSERTSTRING` for
|
||
a list box with `LBS_SORT` style, but at this time the list box will ignore the
|
||
index, and insert the new item according to the sorted result.
|
||
|
||
It should be noted that, after specifying `LBS_CHECKBOX` or `LBS_USEICON`
|
||
style, when you add an item to a list box, you must use `LISTBOXITEMINFO`
|
||
structure, and cannot use the string address directly, for example:
|
||
|
||
|
||
```cpp
|
||
HICON hIcon1; /* Declare an icon handle */
|
||
LISTBOXITEMINFO lbii; /* Declare a structure variable of the list box item*/
|
||
|
||
hIcon1 = LoadIconFromFile (HDC_SCREEN, "res/audio.ico", 1); /* Load an icon */
|
||
|
||
/* Set the structure information, and add an item */
|
||
lbii.hIcon = hIcon1;
|
||
lbii.cmFlag = CMFLAG_CHECKED;
|
||
lbii.string = "abcdefg";
|
||
SendMessage (hChildWnd3, LB_ADDSTRING, 0, (LPARAM)&lbii);
|
||
```
|
||
|
||
Here, the value of `cmFlag` can be `CMFLAG_CHECKED`, `CMFLAG_BLANK`, or
|
||
`CMFLAG_PARTCHECKED`, indicating checked, unchecked, and partly checked,
|
||
respectively.
|
||
|
||
We can also display bitmaps in an advanced list box, rather than icons by
|
||
default. If you want a list box item display a bitmap instead of an icon, you
|
||
can include `IMGFLAG_BITMAP` in the flag, and specify the pointer to the bitmap
|
||
object:
|
||
|
||
|
||
```cpp
|
||
/* Set structure information, and add an item */
|
||
lbii.hIcon = (DWORD) GetSystemBitmap (SYSBMP_MAXIMIZE);
|
||
lbii.cmFlag = CMFLAG_CHECKED | IMGFLAG_BITMAP;
|
||
lbii.string = "abcdefg";
|
||
SendMessage (hChildWnd3, LB_ADDSTRING, 0, (LPARAM)&lbii);
|
||
```
|
||
|
||
### Deleting Item from List Box
|
||
|
||
Send `LB_DELETESTRING` message and specify the index value, and then you can
|
||
delete an item with the index from the list box:
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_DELETESTRING, index, 0) ;
|
||
```
|
||
|
||
We can even use `LB_RESETCONTENT` message to clear all contents in the list
|
||
box:
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_RESETCONTENT, 0, 0) ;
|
||
```
|
||
|
||
### Selecting and Getting Item
|
||
|
||
Send `LB_GETCOUNT` to get the number of items in the list box:
|
||
|
||
```cpp
|
||
count = SendMessage (hwndList, LB_GETCOUNT, 0, 0) ;
|
||
```
|
||
|
||
When you need to get the text string of a certain item, you can send
|
||
`LB_GETTEXTLEN` message to get the length of the string of the specified item
|
||
in a list box:
|
||
|
||
```cpp
|
||
length = SendMessage (hwndList, LB_GETTEXTLEN, index, 0) ;
|
||
```
|
||
|
||
And then, copy the item to a text buffer by sending the message `MSG_GETTEXT`:
|
||
|
||
```cpp
|
||
length = SendMessage (hwndList, LB_GETTEXT, index, (LPARAM)buffer) ;
|
||
```
|
||
|
||
In these two conditions, the length value returned by above messages is the
|
||
length of the text. For the length of a `NULL-terminate` string, the buffer
|
||
must be big enough. You can use the string length returned by `LB_GETTEXTLEN`
|
||
message to allocate some local memory for storing the string.
|
||
|
||
If we need to set the string of list item, you can send `LB_SETTEXT` message:
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_SETTEXT, index, buffer) ;
|
||
```
|
||
|
||
For an advanced list box, we must use `LB_GETITEMDATA` and `LB_SETITEMDATA` to
|
||
get other information of a list item, such as the bitmap object or the handle
|
||
to icon, state of check box, and these messages also can be used to get or set
|
||
the text string of item:
|
||
|
||
```cpp
|
||
HICON hIcon1; /* Declare an icon handle */
|
||
LISTBOXITEMINFO lbii; /* Declare a struct variable of the list box item info */
|
||
|
||
hIcon1 = LoadIconFromFile (HDC_SCREEN, "res/audio.ico", 1); /* Load an icon */
|
||
|
||
/* Set the structure information, and set an item */
|
||
lbii.hIcon = hIcon1;
|
||
lbii.cmFlag = CMFLAG_CHECKED;
|
||
lbii.string = "new item";
|
||
SendMessage (hChildWnd3, LB_SETITEMDATA, index, (LPARAM)&lbii);
|
||
```
|
||
|
||
The following messages are used to retrieve the selection state of list items;
|
||
these messages have different calling method for single-selection list box and
|
||
multiple-selection list box. Let us to look at the single-selection list box
|
||
first.
|
||
|
||
Generally, the user selects an item by mouse and keyboard. But we also can
|
||
control the current selected item by program, at this time, we need send
|
||
`LB_SETCURSEL` message:
|
||
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_SETCURSEL, index, 0) ;
|
||
```
|
||
|
||
In contrast, we can use `LB_GETCURSEL` to get the current selected item:
|
||
|
||
```cpp
|
||
index = SendMessage (hwndList, LB_GETCURSEL, 0, 0) ;
|
||
```
|
||
|
||
If no item is selected, then the message returns `LB_ERR`.
|
||
|
||
For multiple-selection list box, `LB_SETCURSEL` and `LB_GETCURSEL` can only be
|
||
used to set or get the current highlighted item, but cannot get all selected
|
||
items. But we can use `LB_SETSEL` to set the selection state of a certain item
|
||
without affecting other items:
|
||
|
||
```cpp
|
||
SendMessage (hwndList, LB_SETSEL, wParam, (LPARAM)index) ;
|
||
```
|
||
|
||
If `wParam` is not 0, this function selects and highlights an item; if `wParam`
|
||
is 0, this function cancels the selection. In contrast, we can use `LB_GETSEL`
|
||
to get the selection state of a certain item:
|
||
|
||
```cpp
|
||
select = SendMessage (hwndList, LB_GETSEL, index, 0) ;
|
||
```
|
||
|
||
Here, if the item specified by index is selected, select is a non-zero value,
|
||
else select is 0.
|
||
|
||
In addition, you can also use `LB_GETSELCOUNT` message to get the number of all
|
||
selected items in a multiple-selection list box. Then you can send
|
||
`LB_GETSELITEMS` message to get the index values of all the selected items. The
|
||
following is an example:
|
||
|
||
```cpp
|
||
int i, sel_count;
|
||
int* sel_items;
|
||
|
||
sel_count = SendMessage (hwndList, LB_GETSELCOUNT, 0, 0L) ;
|
||
if (sel_count == 0)
|
||
return;
|
||
|
||
sel_items = alloca (sizeof(int)*sel_count);
|
||
SendMessage (hwndList, LB_GETSELITEMS, sel_count, sel_items);
|
||
for (i = 0; i < sel_count; i++) {
|
||
/* sel_items [i] is the index of one selected item */
|
||
}
|
||
```
|
||
|
||
### Searching Item Including a Text String
|
||
|
||
```cpp
|
||
index = SendMessage (hwndList, LB_FINDSTRING, (LPARAM)string) ;
|
||
```
|
||
|
||
Here, string is the pointer to a string, which should be found; the message
|
||
returns the index of the fuzzy matched string, and `LB_ERR` means failure.
|
||
Using `LB_FINDSTRINGEXACT` message will search the matched item exactly.
|
||
|
||
### Setting/Getting the Status of Check Mark
|
||
|
||
```cpp
|
||
status = SendMessage (hwndList, LB_GETCHECKMARK, index, 0) ;
|
||
```
|
||
|
||
The message `LB_GETCHECKMARK` returns the check mark status of the check box
|
||
specified by index. If corresponding item is not found, `LB_ERR` returned.
|
||
`CMFLAG_CHECKED` indicates the check box of the item is checked.
|
||
`CMFLAG_PARTCHECKED` indicates the check box of the item is partly checked.
|
||
`CMFLAG_BLANK` indicates the check box of the item is not checked.
|
||
|
||
```cpp
|
||
ret = SendMessage (hwndList, LB_SETCHECKMARK, index, (LPARAM)status) ;
|
||
```
|
||
|
||
The message `LB_SETCHECKMARK` sets the check mark status of the check box
|
||
specified by index to be the value of status. If the item specified by the
|
||
index is not found, it returns `LB_ERR` for failure, else returns `LB_OKAY` for
|
||
success.
|
||
|
||
### Setting the Bold Status of Item
|
||
|
||
```cpp
|
||
ret = SendMessage (hwndList, LB_SETITEMBOLD, index, (LPARAM)status) ;
|
||
```
|
||
|
||
The message `LB_` `SETITEMBOLD` sets the bold status of the item specified by
|
||
index to be the value of status (TRUE or `FALSE`). If the item specified by the
|
||
index is not found, it returns `LB_ERR` for failure.
|
||
|
||
### Setting/Getting the Disable Status of Item
|
||
|
||
```cpp
|
||
status = SendMessage (hwndList, LB_GETITEMDISABLE, index, 0) ;
|
||
```
|
||
|
||
The message `LB_GETI` `TEMDISABLE` returns the disable status of the item
|
||
specified by index. If corresponding item is not found, `LB_ERR` returned. 1
|
||
indicates the item is disabled. 0 indicates the item is not disabled.
|
||
|
||
```cpp
|
||
ret = SendMessage (hwndList, LB_SETITEMDISABLE, index, (LPARAM)status) ;
|
||
```
|
||
|
||
The message `LB_SETITEMDISABLE` sets the disable status of the item specified
|
||
by index to be the value of status. If the item specified by the index is not
|
||
found, it returns `LB_ERR` for failure.
|
||
|
||
### Adding Multiple Items into List Box
|
||
|
||
The message `LB_MULTIADDITEM` is used to adding multiple items into List Box.
|
||
When the stored content of the list box exceeds the available memory space,
|
||
`SendMessage` returns `LB_ERRSPACE`. If error is caused by other reasons,
|
||
`SendMessage` returns `LB_ERR`. If the operation is successful, `SendMessage`
|
||
returns `LB_OKAY`. We can determine above two errors by testing the non-zero
|
||
value of `SendMessage`.
|
||
|
||
If you adopt `LBS_SORT` style, or just want to append the new text string array
|
||
as the last items of a list box, sample is as follows:
|
||
|
||
```cpp
|
||
int num = 2;
|
||
const char text[num][] = {“item1”, “item2”};
|
||
|
||
SendMessage (hwndList, LB_MULTIADDITEM, num, (LPARAM)text);
|
||
```
|
||
|
||
Parameter `hwndList` is the handle of the list box control; num is the number
|
||
of item added, and text is the string text array address.
|
||
|
||
It should be noted that, after specifying `LBS_CHECKBOX` or `LBS_USEICON`
|
||
style, when you add multiple items to a list box, you must use
|
||
`LISTBOXITEMINFO` structure, and cannot use the string array address directly,
|
||
for example:
|
||
|
||
```cpp
|
||
int num = 2;
|
||
HICON hIcon1; /* Declare an icon handle */
|
||
LISTBOXITEMINFO lbii[num]; /* Declare a struct variable of the list box item info */
|
||
|
||
hIcon1 = LoadIconFromFile (HDC_SCREEN, "res/audio.ico", 1); /* Load an icon */
|
||
|
||
/* Set the structure information, and add items */
|
||
lbii[0].hIcon = hIcon1;
|
||
lbii[0].cmFlag = CMFLAG_CHECKED;
|
||
lbii[0].string = "item1";
|
||
|
||
lbii[1].hIcon = hIcon1;
|
||
lbii[1].cmFlag = CMFLAG_CHECKED;
|
||
lbii[1].string = "item2";
|
||
|
||
SendMessage (hwndList, LB_MULTIADDITEM, num, (LPARAM)lbii);
|
||
```
|
||
|
||
### Other Messages
|
||
|
||
A list box with style of `LBS_SORT` uses the standard C function strncmp to
|
||
sort items. But we can overload the default sort method by using
|
||
`LB_SETSTRCMPFUNC` in order to sort items according to the expected method. For
|
||
example:
|
||
|
||
```cpp
|
||
static int my_strcmp (const char* s1, const char* s2, size_t n)
|
||
{
|
||
int i1 = atoi (s1);
|
||
int i2 = atoi (s2);
|
||
return (i1 – i2);
|
||
}
|
||
|
||
SendMessage (hwndList, LB_SETSTRCMPFUNC, 0, (LPARAM)my_strcmp);
|
||
```
|
||
|
||
Thus, the list box will use the user-defined function to sort items. Sort
|
||
function described above can be used to sort the items in form as 1, 2, 3, 4,
|
||
10, 20 etc. according to integer values, while the default sort rule would sort
|
||
the items above as 1, 10, 2, 20, 3, and 4. Generally speaking, application
|
||
should use the message to set a new string comparison function before adding
|
||
any item.
|
||
|
||
We also can associate an additional 32-bit data with each list item, and get
|
||
the value at appropriate time. For doing this, we can use `LB_SETITEMADDDATA`
|
||
and `LB_GETITEMADDDATA` messages. The values operated by the two messages have
|
||
no meaning for the list box control. The control only takes charge to store the
|
||
value and return the value when needed.
|
||
|
||
In addition, we can also use `LB_SETITEMHEIGHT` message to set the height of
|
||
items, and use `LB_GETITEMHEIGHT` to get the height. Generally, height of items
|
||
depends on the size of control font, and varies when the control font changes
|
||
(call `SetWindowFont` to change). The users can also set themselves height of
|
||
items. The actual height will be the maximum of the height set and control font
|
||
size.
|
||
|
||
|
||
## Notification Codes of List Box
|
||
|
||
Notification codes generated by a list box with `LBS_NOTIFY` style and their
|
||
meanings are shown in Table 1.
|
||
|
||
|
||
__Table 1__ Notification codes of list box
|
||
|
||
| *Notification code identifier* | *Meaning* |
|
||
|--------------------------------|-----------|
|
||
| `LBN_ERRSPACE` |Indicates that memory allocation failure.|
|
||
| `LBN_SELCHANGE` |Indicates the current selected item changes|
|
||
| `LBN_CLICKED` |Indicates click on an item|
|
||
| `LBN_DBLCLK` |Indicates double click on an item|
|
||
| `LBN_SELCANCEL` |Indicates cancel of the selection|
|
||
| `LBN_SETFOCUS` |Indicates gain of input focus|
|
||
| `LBN_KILLFOCUS` |Indicates loss of input focus|
|
||
| `LBN_CLICKCHECKMARK` |Indicates click on the check mark|
|
||
| `LBN_ENTER` |Indicates the user has pressed the `ENTER` key|
|
||
|
||
A list box control will not send notification messages described above unless
|
||
the window style of the list box have `LBS_NOTIFY` style. Certainly, if you
|
||
have called `SetNotificationCallback` function to set the notification callback
|
||
function, the control will not send `MSG_COMMAND` notification message to its
|
||
parent window, but call the specified notification callback function directly.
|
||
|
||
`LBN_ERRSPACE` indicates that the memory allocation fails. `LBN_SELCHANGE`
|
||
indicates the currently selected item has been changed, which occurs in the
|
||
following cases: the user changes the highlighted item with the keyboard or
|
||
mouse, or the user switches the selection status with the Space key or mouse.
|
||
`LBN_CLICKED` indicates the mouse, which occurs when the user uses the mouse to
|
||
click an item, clicks the list box. `LBN_DBLCLK` indicates an item is double
|
||
clicked by the user if `LBS_CHECKBOX` style is set, `LBN_CLICKCHECKMARK`
|
||
indicates the user clicked the check mark, and if `LBS_AUTOCHECK` style is set
|
||
at the same time, the check box will be auto-switched between the checked or
|
||
unchecked status.
|
||
|
||
Based on the requirements of applications, either `LBN_SELCHANGE` or
|
||
`LBN_DBLCLK` might be used, or both might be used. Program will receive many
|
||
messages of `LBN_SELCHANGE`, but the message of `LBN_DBLCLK` will be received
|
||
only when users double click.
|
||
|
||
## Sample Program
|
||
|
||
The program in List 1 provides an example for the use of list box controls. The
|
||
program imitates the “Open File” dialog box to realize the file deleting
|
||
function. Initially, the program lists all the files in the current directory,
|
||
and the user can also change to other directories through the directory list
|
||
box. The user can select multiple files to be deleted in the file list box by
|
||
select the check marks. When the user pushes the “Delete” button, the program
|
||
will prompt the user. Of course, to protect the user’s files, the program does
|
||
not delete the files really. The effect of the dialog box created by this
|
||
program is shown in Figure 4. Please refer to `listbox.c` file of the demo
|
||
program package of this guide for complete source code.
|
||
|
||
__List 1__ The use of list box controls
|
||
|
||
```cpp
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <stdarg.h>
|
||
#include <string.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/time.h>
|
||
#include <sys/types.h>
|
||
#include <unistd.h>
|
||
#include <pwd.h>
|
||
#include <errno.h>
|
||
|
||
#include <minigui/common.h>
|
||
#include <minigui/minigui.h>
|
||
#include <minigui/gdi.h>
|
||
#include <minigui/window.h>
|
||
#include <minigui/control.h>
|
||
|
||
#define IDL_DIR 100
|
||
#define IDL_FILE 110
|
||
#define IDC_PATH 120
|
||
|
||
/* Define dialog box template */
|
||
static DLGTEMPLATE DlgDelFiles =
|
||
{
|
||
WS_BORDER | WS_CAPTION,
|
||
WS_EX_NONE,
|
||
100, 100, 304, 225,
|
||
"删除文件",
|
||
0, 0,
|
||
7, NULL,
|
||
0
|
||
};
|
||
|
||
static CTRLDATA CtrlDelFiles[] =
|
||
{
|
||
{
|
||
CTRL_STATIC,
|
||
WS_VISIBLE | SS_SIMPLE,
|
||
10, 10, 130, 15,
|
||
IDC_STATIC,
|
||
"目录列表框",
|
||
0
|
||
},
|
||
/* This list box displays directories */
|
||
{
|
||
CTRL_LISTBOX,
|
||
WS_VISIBLE | WS_VSCROLL | WS_BORDER | LBS_SORT | LBS_NOTIFY,
|
||
10, 30, 130, 100,
|
||
IDL_DIR,
|
||
"",
|
||
0
|
||
},
|
||
{
|
||
CTRL_STATIC,
|
||
WS_VISIBLE | SS_SIMPLE,
|
||
150, 10, 130, 15,
|
||
IDC_STATIC,
|
||
"文件列表框",
|
||
0
|
||
},
|
||
/* This list box displays files with a check box in front for each file */
|
||
{
|
||
CTRL_LISTBOX,
|
||
WS_VISIBLE | WS_VSCROLL | WS_BORDER | LBS_SORT | LBS_AUTOCHECKBOX,
|
||
150, 30, 130, 100,
|
||
IDL_FILE,
|
||
"",
|
||
0
|
||
},
|
||
/* This static control is used to display the current path information */
|
||
{
|
||
CTRL_STATIC,
|
||
WS_VISIBLE | SS_SIMPLE,
|
||
10, 150, 290, 15,
|
||
IDC_PATH,
|
||
"路径:",
|
||
0
|
||
},
|
||
{
|
||
"button",
|
||
WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP,
|
||
10, 170, 130, 25,
|
||
IDOK,
|
||
"删除",
|
||
0
|
||
},
|
||
{
|
||
"button",
|
||
WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
|
||
150, 170, 130, 25,
|
||
IDCANCEL,
|
||
"取消",
|
||
0
|
||
},
|
||
};
|
||
|
||
/* This function gets all the directory items in the current directory,
|
||
* and adds them to the directory list box and file list box, respectively
|
||
*/
|
||
static void fill_boxes (HWND hDlg, const char* path)
|
||
{
|
||
struct dirent* dir_ent;
|
||
DIR* dir;
|
||
struct stat ftype;
|
||
char fullpath [PATH_MAX + 1];
|
||
|
||
SendDlgItemMessage (hDlg, IDL_DIR, LB_RESETCONTENT, 0, (LPARAM)0);
|
||
SendDlgItemMessage (hDlg, IDL_FILE, LB_RESETCONTENT, 0, (LPARAM)0);
|
||
SetWindowText (GetDlgItem (hDlg, IDC_PATH), path);
|
||
|
||
if ((dir = opendir (path)) == NULL)
|
||
return;
|
||
|
||
while ( (dir_ent = readdir ( dir )) = NULL ) {
|
||
|
||
/* Assemble full path name. */
|
||
strncpy (fullpath, path, PATH_MAX);
|
||
strcat (fullpath, "/");
|
||
strcat (fullpath, dir_ent->d_name);
|
||
|
||
if (stat (fullpath, &ftype) < 0 ) {
|
||
continue;
|
||
}
|
||
|
||
if (S_ISDIR (ftype.st_mode))
|
||
SendDlgItemMessage (hDlg, IDL_DIR, LB_ADDSTRING, 0, (LPARAM)dir_ent->d_name);
|
||
else if (S_ISREG (ftype.st_mode)) {
|
||
/* When using the list box of a checkbox,
|
||
* the following structure need to be used */
|
||
LISTBOXITEMINFO lbii;
|
||
|
||
lbii.string = dir_ent->d_name;
|
||
lbii.cmFlag = CMFLAG_BLANK;
|
||
lbii.hIcon = 0;
|
||
SendDlgItemMessage (hDlg, IDL_FILE, LB_ADDSTRING, 0, (LPARAM)&lbii);
|
||
}
|
||
}
|
||
|
||
closedir (dir);
|
||
}
|
||
|
||
static void dir_notif_proc (HWND hwnd, int id, int nc, DWORD add_data)
|
||
{
|
||
/* When the user double clicked the directory name or
|
||
* pressed the ENTER key, he will enter the corresponding directory */
|
||
if (nc == LBN_DBLCLK || nc == LBN_ENTER) {
|
||
int cur_sel = SendMessage (hwnd, LB_GETCURSEL, 0, 0L);
|
||
if (cur_sel >= 0) {
|
||
char cwd [MAX_PATH + 1];
|
||
char dir [MAX_NAME + 1];
|
||
GetWindowText (GetDlgItem (GetParent (hwnd), IDC_PATH), cwd, MAX_PATH);
|
||
SendMessage (hwnd, LB_GETTEXT, cur_sel, (LPARAM)dir);
|
||
|
||
if (strcmp (dir, ".") == 0)
|
||
return;
|
||
strcat (cwd, "/");
|
||
strcat (cwd, dir);
|
||
/* Fill the two list boxes again */
|
||
fill_boxes (GetParent (hwnd), cwd);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void file_notif_proc (HWND hwnd, int id, int nc, DWORD add_data)
|
||
{
|
||
/* Do nothing */
|
||
}
|
||
|
||
static void prompt (HWND hDlg)
|
||
{
|
||
int i;
|
||
char files [1024] = "你选择要删除的文件是:\n";
|
||
|
||
/* Get all the checked files */
|
||
for (i = 0; i < SendDlgItemMessage (hDlg, IDL_FILE, LB_GETCOUNT, 0, 0L); i++) {
|
||
char file [MAX_NAME + 1];
|
||
int status = SendDlgItemMessage (hDlg, IDL_FILE, LB_GETCHECKMARK, i, 0);
|
||
if (status == CMFLAG_CHECKED) {
|
||
SendDlgItemMessage (hDlg, IDL_FILE, LB_GETTEXT, i, (LPARAM)file);
|
||
strcat (files, file);
|
||
strcat (files, "\n");
|
||
}
|
||
}
|
||
|
||
/* Prompt the user */
|
||
MessageBox (hDlg, files, "确认删除", MB_OK | MB_ICONINFORMATION);
|
||
|
||
/* Here these files are actually deleted */
|
||
}
|
||
|
||
static int DelFilesBoxProc (HWND hDlg, int message, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
switch (message) {
|
||
case MSG_INITDIALOG:
|
||
{
|
||
char cwd [MAX_PATH + 1];
|
||
SetNotificationCallback (GetDlgItem (hDlg, IDL_DIR), dir_notif_proc);
|
||
SetNotificationCallback (GetDlgItem (hDlg, IDL_FILE), file_notif_proc);
|
||
fill_boxes (hDlg, getcwd (cwd, MAX_PATH));
|
||
return 1;
|
||
}
|
||
|
||
case MSG_COMMAND:
|
||
switch (wParam) {
|
||
case IDOK:
|
||
prompt (hDlg);
|
||
case IDCANCEL:
|
||
EndDialog (hDlg, wParam);
|
||
break;
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
return DefaultDialogProc (hDlg, message, wParam, lParam);
|
||
}
|
||
|
||
int MiniGUIMain (int argc, const char* argv[])
|
||
{
|
||
#ifdef _MGRM_PROCESSES
|
||
JoinLayer(NAME_DEF_LAYER , "listbox" , 0 , 0);
|
||
|
||
#endif
|
||
|
||
DlgDelFiles.controls = CtrlDelFiles;
|
||
|
||
DialogBoxIndirectParam (&DlgDelFiles, HWND_DESKTOP, DelFilesBoxProc, 0L);
|
||
|
||
return 0;
|
||
}
|
||
|
||
#ifndef _MGRM_PROCESSES
|
||
#include <minigui/dti.c>
|
||
#endif
|
||
```
|
||
|
||

|
||
|
||
__Figure 4__ “Delete File” dialog box
|
||
|
||
----
|
||
|
||
[<< Button Control](MiniGUIProgGuidePart6Chapter02.md) |
|
||
[Table of Contents](README.md) |
|
||
[Edit Box Control >>](MiniGUIProgGuidePart6Chapter04.md)
|
||
|
||
[Release Notes for MiniGUI 3.2]: /supplementary-docs/Release-Notes-for-MiniGUI-3.2.md
|
||
[Release Notes for MiniGUI 4.0]: /supplementary-docs/Release-Notes-for-MiniGUI-4.0.md
|
||
[Showing Text in Complex or Mixed Scripts]: /supplementary-docs/Showing-Text-in-Complex-or-Mixed-Scripts.md
|
||
[Supporting and Using Extra Input Messages]: /supplementary-docs/Supporting-and-Using-Extra-Input-Messages.md
|
||
[Using CommLCD NEWGAL Engine and Comm IAL Engine]: /supplementary-docs/Using-CommLCD-NEWGAL-Engine-and-Comm-IAL-Engine.md
|
||
[Using Enhanced Font Interfaces]: /supplementary-docs/Using-Enhanced-Font-Interfaces.md
|
||
[Using Images and Fonts on System without File System]: /supplementary-docs/Using-Images-and-Fonts-on-System-without-File-System.md
|
||
[Using SyncUpdateDC to Reduce Screen Flicker]: /supplementary-docs/Using-SyncUpdateDC-to-Reduce-Screen-Flicker.md
|
||
[Writing DRM Engine Driver for Your GPU]: /supplementary-docs/Writing-DRM-Engine-Driver-for-Your-GPU.md
|
||
[Writing MiniGUI Apps for 64-bit Platforms]: /supplementary-docs/Writing-MiniGUI-Apps-for-64-bit-Platforms.md
|
||
|
||
[Quick Start]: /user-manual/MiniGUIUserManualQuickStart.md
|
||
[Building MiniGUI]: /user-manual/MiniGUIUserManualBuildingMiniGUI.md
|
||
[Compile-time Configuration]: /user-manual/MiniGUIUserManualCompiletimeConfiguration.md
|
||
[Runtime Configuration]: /user-manual/MiniGUIUserManualRuntimeConfiguration.md
|
||
[Tools]: /user-manual/MiniGUIUserManualTools.md
|
||
[Feature List]: /user-manual/MiniGUIUserManualFeatureList.md
|
||
|
||
[MiniGUI Overview]: /MiniGUI-Overview.md
|
||
[MiniGUI User Manual]: /user-manual/README.md
|
||
[MiniGUI Programming Guide]: /programming-guide/README.md
|
||
[MiniGUI Porting Guide]: /porting-guide/README.md
|
||
[MiniGUI Supplementary Documents]: /supplementary-docs/README.md
|
||
[MiniGUI API Reference Manuals]: /api-reference/README.md
|
||
|
||
[MiniGUI Official Website]: http://www.minigui.com
|
||
[Beijing FMSoft Technologies Co., Ltd.]: https://www.fmsoft.cn
|
||
[FMSoft Technologies]: https://www.fmsoft.cn
|
||
[HarfBuzz]: https://www.freedesktop.org/wiki/Software/HarfBuzz/
|