Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лекции / Shchupak_Yu._Win32_API_Razrabotka_prilozheniy_dlya_Windows

.pdf
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
13.15 Mб
Скачать

Элементы управления главного окна

401

 

 

 

Теперь панель инструментов увеличила размеры кнопок с учетом размещения самого длинного текста. По умолчанию текстовые метки выводятся ниже рисун ков. Но можно расположить их справа, если при вызове функции CreateToolbarEx указать дополнительный стиль TBSTYLE_LIST. Вид панели инструментов для этого стиля показан на рис. 8.7.

Кнопки вытянулись в ширину, поэтому при заданных размерах окна пользова тель видит только первые шесть кнопок. Чтобы увидеть панель инструментов полностью, он вынужден раздвигать окно приложения с помощью мыши.

Но если при вызове функции CreateToolbarExуказать не только стиль TBSTYLE_LIST, но еще и стиль TBSTYLE_WRAPABLE, то панель инструментов будет автоматически пе реходить на новую строку, когда ширина окна оказывается недостаточной для нор мального отображения панели. Этот вариант реализации панели инструментов по казан на рис. 8.8.

Рис. 8.8. Панель инструментов со стилями TBSTYLE_LIST | TBSTYLE_WRAPABLE

Размещение на панели инструментов других элементов управления

Панель инструментов поддерживает только кнопки, поэтому для расположения на ее поверхности какого либо другого элемента управления следует создать до чернее окно. Наиболее часто на панель инструментов добавляются комбиниро ванные списки (combo box).

Добавление дочернего окна элемента управления на панель инструментов связано с решением трех проблем: а) резервирование места для дочернего окна; б) обработка сообщений от дочернего окна; в) поддержка подсказки для дочер него окна.

Резервирование места под встроенный элемент управления несложно обеспе чить, поместив кнопку разделитель требуемой ширины. Напомним, что факти ческая ширина кнопки разделителя задается присваиванием нужного значения полю tbb[i].iBitmap. Обычно это значение подбирается экспериментально, исходя из желательной ширины встраиваемого элемента управления.

Уведомительные сообщения от встроенного элемента управления поступают в виде сообщений WM_COMMAND в родительское окно панели инструментов. Так как оконная процедура панели инструментов (спрятанная в недрах Windows) эти

402

Глава 8. Элементы управления общего пользования

 

 

сообщения не обрабатывает, она передает их родительскому окну панели инстру ментов, то есть главному окну приложения. Поэтому в блоке обработки сообще ния WM_COMMAND оконной процедуры WndProc необходимо предусмотреть обра ботку этих уведомительных сообщений.

Мы уже знаем, что панель инструментов поддерживает окна подсказок для всех своих кнопок. Но на встроенные элементы управления эта поддержка не распро страняется. В следующем разделе будет показано, как решить эту проблему с по мощью автономных элементов управления Tooltip.

Рассмотрим технику добавления комбинированного списка на панель инст рументов на примере разработки приложения ComboInToolbar, которое является модификацией приложения ToolBar. Цель модификации — добавить возможность выбора толщины пера, которым обводится контур рисуемой фигуры (до сих пор использовалось перо по умолчанию толщиной в 1 пиксел).

Создайте новый проект с именем ComboInToolbar. Затем скопируйте из папки про екта ToolBar(см. листинг 8.1) в папку проекта ComboInToolbarфайлы с расширениями

.cpp, .h и .rc, скорректировав их имена заменой подстроки ToolBar на ComboInToolbar. Скопируйте также файл toolbar1.bmp. Добавьте эти файлы в состав проекта. Добавьте к настройкам проекта на вкладке Link библиотеку comctl32.lib.

Откройте вкладку ResourceView в окне Workspace и вызовите редактор панелей инструментов двойным щелчком мыши на элементе IDR_TOOLBAR1. Добавьте в на чале панели инструментов две кнопки без изображений с идентификаторами

ID_SEP.

Откройте текст файла ComboInToolbar.cpp и отредактируйте его так, чтобы он соответствовал листингу 8.3.

Листинг 8.3. Проект ComboInToolbar

//////////////////////////////////////////////////////////////////////

// ComboInToolBar.cpp

/* Директивы #include и #define, объявление типов ShapeSize и ShapeData

– из листинга 8.1 */

#define ID_TOOLBAR

201

#define IDC_TB_COMBOBOX

202

#define NUM_BUTTONS

13

#define SEPARATOR_WIDTH

10

#define COMBO_SPACE_WIDTH

50

#define COMBO_SPACE_HEIGHT 100

HWND

hwndToolBar;

 

HWND

hwndCombo;

 

HWND

InitToolBar(HWND hWnd);

void

UpdateToolBar(ShapeData& sd);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //==================================================================== int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow)

{

MSG msg;

Элементы управления главного окна

403

 

 

 

KWnd mainWnd("ComboInToolBar", hInstance, nCmdShow, WndProc,

MAKEINTRESOURCE(IDR_MENU1), 100, 100, 400, 300);

/* Здесь такой же текст, как и в листинге 8.1 */

return msg.wParam;

}

//==================================================================== HWND InitToolBar(HWND hWnd) {

HWND hToolBar;

int btnID[NUM_BUTTONS] = { ID_SEP, ID_SEP, ID_RECTANGLE, ID_RHOMB, ID_ELLIPSE, ID_SEP, ID_RED, ID_GREEN, ID_BLUE, ID_SEP,

ID_DARK, ID_MEDIUM, ID_LIGHT };

int btnStyle[NUM_BUTTONS] = { TBSTYLE_SEP, TBSTYLE_SEP, TBSTYLE_BUTTON, TBSTYLE_BUTTON, TBSTYLE_BUTTON, TBSTYLE_SEP, TBSTYLE_CHECK, TBSTYLE_CHECK, TBSTYLE_CHECK, TBSTYLE_SEP, TBSTYLE_CHECKGROUP, TBSTYLE_CHECKGROUP, TBSTYLE_CHECKGROUP };

TBBUTTON tbb[NUM_BUTTONS]; memset(tbb, 0, sizeof(tbb));

for (int i = 0; i < NUM_BUTTONS; ++i) {

if (!i) tbb[i].iBitmap = COMBO_SPACE_WIDTH; else if (btnID[i] == ID_SEP)

tbb[i].iBitmap = SEPARATOR_WIDTH; else tbb[i].iBitmap = i;

tbb[i].idCommand = btnID[i]; tbb[i].fsState = TBSTATE_ENABLED; tbb[i].fsStyle = btnStyle[i];

}

hToolBar = CreateToolbarEx(hWnd,

WS_CHILD | WS_VISIBLE | WS_BORDER | TBSTYLE_TOOLTIPS, ID_TOOLBAR, NUM_BUTTONS, GetModuleHandle(NULL), IDR_TOOLBAR1, tbb, NUM_BUTTONS, 0, 0, 0, 0, sizeof(TBBUTTON));

// Определение позиции и размеров для элемента управления Combo box int x, y, cx, cy;

RECT rcItem;

SendMessage(hToolBar, TB_GETITEMRECT, 0, (LPARAM)&rcItem);

x = rcItem.left + 2;

y = rcItem.top;

cx = COMBO_SPACE_WIDTH;

cy = COMBO_SPACE_HEIGHT;

// Создание элемента управления Combo box

hwndCombo = CreateWindow("combobox", NULL, WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, x, y, cx, cy, hToolBar, (HMENU)IDC_TB_COMBOBOX, GetModuleHandle(NULL), 0);

// Инициализация списка для hwndCombo SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)" 1 "); SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)" 2 ");

продолжение

404

Глава 8. Элементы управления общего пользования

 

 

Листинг 8.3 (продолжение)

SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)" 5 ");

SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)" 10 ");

SendMessage(hwndCombo, CB_SETCURSEL, 0, 0);

return hToolBar;

}

//==================================================================== void UpdateToolBar(ShapeData& sd) {

/* Здесь такой же текст, как и в листинге 8.1 */

}

//==================================================================== LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

/* Объявления локальных переменных из листинга 8.1 */

static HPEN hPen, hOldPen; static int indPen;

int penWidth[] = { 1, 2, 5, 10 };

switch (uMsg)

{

case WM_CREATE:

/* Здесь такой же текст, как и в листинге 8.1 */

break;

case WM_SIZE:

SendMessage(hwndToolBar, TB_AUTOSIZE, 0, 0); break;

case WM_NOTIFY:

/* Здесь такой же текст, как и в листинге 8.1 */ break;

case WM_COMMAND:

switch (LOWORD(wParam))

{

/* Обработка для кодов сообщений IDM_OPEN, IDM_CLOSE, … , IDM_RESIZE – как в листинге 8.1 */

case IDM_ABOUT: MessageBox(hWnd,

"ComboInToolBar\nVersion 1.0\nCopyright: " "Finesoft Corporation, 2005.",

"About ComboInToolBar", MB_OK); break;

// Обработка уведомительного сообщения от комбинированного списка case IDC_TB_COMBOBOX:

switch (HIWORD(wParam)) { case CBN_SELCHANGE:

// Выбираем текущий индекс пера

indPen = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);

}

Элементы управления главного окна

405

 

 

 

break;

default:

break;

}

UpdateToolBar(shapeData); InvalidateRect(hWnd, NULL, TRUE); break;

case WM_PAINT:

hDC = BeginPaint(hWnd, &ps);

brightness = intensity[shapeData.id_bright - ID_DARK];

if (bShow) {

hPen = CreatePen(PS_SOLID, penWidth[indPen], RGB(0,0,0)); hOldPen = (HPEN)SelectObject(hDC, hPen);

/* Здесь такой же текст, как и в листинге 8.1 */

DeleteObject(SelectObject(hDC, hOldBrush)); DeleteObject(SelectObject(hDC, hOldPen));

}

EndPaint(hWnd, &ps); break;

case WM_DESTROY: PostQuitMessage(0); break;

default:

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

return 0;

}

//////////////////////////////////////////////////////////////////////

В этой программе количество кнопок на панели инструментов увеличено до тринадцати, так как добавлены две кнопки разделителя в начале панели. Первая из этих кнопок разделителей, имеющая ширину COMBO_SPACE_WIDTH, использует ся для резервирования места под комбинированный список. Вторая кнопка раз делитель создает промежуток между комбинированным списком и первой стан дартной кнопкой панели инструментов.

Обратите внимание на то, что в массивах btnID и btnStyle учтено появление новых кнопок. Первые два элемента в btnID инициализированы значением ID_SEP, а первые два элемента в btnStyle инициализированы значением TBSTYLE_SEP.

Панель инструментов создается, как и раньше, вызовом функции CreateToolbarEx. Затем определяются позиция и размеры для встраиваемого комбинированного списка. Поскольку он размещается на месте первой кнопки разделителя, мы уз наем координаты изображения этой кнопки, имеющей нулевой индекс, отправив сообщение TB_GETITEMRECT. В результате структура rcItem получает искомые ко ординаты кнопки разделителя. Эти координаты используются затем для вычис ления позиции (x, y) встраиваемого элемента управления.

406

Глава 8. Элементы управления общего пользования

 

 

Дочернее окно комбинированного списка hwndCombo создается вызовом функ ции CreateWindow. Инициализация списка осуществляется отправкой серии сооб щений CB_ADDSTRING.

В тексте оконной процедуры WndProc произошли определенные изменения. Прежде всего были добавлены определения переменных:

static HPEN hPen, hOldPen; static int indPen;

int penWidth[] = { 1, 2, 5, 10 };

Также добавлена обработка уведомительного сообщения CBN_SELCHANGE от ком бинированного списка:

case IDC_TB_COMBOBOX:

switch (HIWORD(wParam)) { case CBN_SELCHANGE:

// Выбираем текущий индекс пера

indPen = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);

}

break;

В блоке обработки сообщения WM_PAINT выбранный индекс пера используется при создании пера hPen:

hPen = CreatePen(PS_SOLID, penWidth[indPen], RGB(0,0,0)); hOldPen = (HPEN)SelectObject(hDC, hPen);

На рис. 8.9 показано окно работающего приложения ComboInToolbar после вы бора в окне комбинированного списка значения 10.

Рис. 8.9. Приложение ComboInToolbar. Выбрана толщина пера 10 логических единиц

К сожалению, в нашей новой программе комбинированный список, встроен ный на панель инструментов, отличается от кнопок панели тем, что не имеет окна подсказки. В следующем разделе мы сможем устранить этот недостаток, приме нив автономный элемент управления Tooltip.

Окно подсказки

Вотличие от встроенного на панель инструментов элемента управления Tooltip, автономный элемент управления Tooltip создается в явном виде как окно предоп ределенного оконного класса TOOLTIPS_CLASS при помощи функции CreateWindowEx.

Вдальнейшем изложении, употребляя термин «окно подсказки», мы будем гово рить именно об автономном элементе управления Tooltip.

Элементы управления главного окна

407

 

 

 

Следующий фрагмент кода показывает, как обычно создается окно подсказки:

hwndTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, hInst, NULL);

Элемент управления Tooltip всегда имеет стили WS_EX_TOPMOST и WS_POPUP, неза висимо от того, указаны ли они при вызове функции CreateWindowEx. Дополнительно можно использовать стиль TTS_NOPREFIX, означающий, что символ амперсанда (&) не является префиксом для обозначения «горячей» клавиши в меню и выводится в строке подсказки наравне с другими символами. Также можно использовать стиль TTS_ALWAYSTIP, означающий, что окно подсказки появляется при наведении кур сора мыши на инструмент даже тогда, когда окно владелец подсказки неактивно.

Напомним, что элемент управления Tooltip может хранить список «горячих» областей или инструментов (tool). Каждый инструмент — это некоторая прямоу гольная область в обслуживаемом окне (в пределе — все окно).

Элемент управления Tooltip начинает поддерживать некий инструмент только после его регистрации. Регистрация инструмента осуществляется отправкой со общения TTM_ADDTOOL, например, при помощи следующей инструкции:

SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO) &ti);

Последнему параметру функции SendMessage передается адрес структурной пе ременной ti типа TOOLINFO. Структура TOOLINFO имеет следующее определение:

typedef struct tagTOOLINFO {

UINT

cbSize;

// размер структуры в байтах

UINT

uFlags;

// флаги

HWND

hwnd;

// дескриптор окна, содержащего инструмент

WPARAM

uId;

// идентификатор инструмента

RECT

rect;

// ограничивающий прямоугольник для инструмента

HINSTANCE hinst;

// дескриптор экземпляра приложения, содержащего

 

 

// строковый ресурс с текстом подсказки

LPTSTR

lpszText; // указатель на буфер с C-строкой или идентификатор

 

 

// строкового ресурса

#if (_WIN32_IE >= 0x0300)

PARAM lParam;

// необязательное 32-битное значение,

 

 

// связанное с инструментом

#endif

 

 

} TOOLINFO,

FAR* LPTOOLINFO;

Поле uFlags может содержать один или несколько флагов из тех, что приведе ны в табл. 8.11.

Таблица 8.11. Флаги для поля uFlags

Ôëàã

Описание

 

 

TTF_CENTERTIP

Окно подсказки выводится в центре по горизонтали под инструментом,

 

а не как по умолчанию — ниже и справа относительно курсора мыши

TTF_IDISHWND

Означает, что в поле uId задается дескриптор дочернего окна. Если этот

 

флаг не задан, то поле uId является идентификатором инструмента

TTF_SUBCLASS

Означает, что окно подсказки будет иметь свою оконную процедуру для

 

перехвата и обработки сообщений, таких как WM_MOUSEMOVE

 

 

Если флаг TTF_IDISHWND не указан, то поле uId содержит произвольный иден тификатор для инструмента. В принципе, этот идентификатор может и не исполь зоваться в дальнейшей работе.

408

Глава 8. Элементы управления общего пользования

 

 

Комментарий к полю lpszText показывает, что текст подсказки может хранить ся либо в виде С строки, либо в виде строкового ресурса в таблице строк прило жения.

Таким образом, создав элемент управления Tooltip и зарегистрировав в нем «го рячую» область какого либо окна, можно обеспечить вывод требуемой подсказки. Перечисленные действия имеет смысл инкапсулировать в теле какой нибудь функ ции. Такой подход будет продемонстрирован в рассмотренном ниже примере.

Замена класса KWnd на класс KWndEx

Вернемся к нашей последней программе, в которой комбинированный список, встроенный в панель инструментов, не имел всплывающей подсказки. Попробу ем устранить этот недостаток.

Одновременно заменим хорошо послуживший нам класс KWnd на его модифи кацию — класс KWndEx. Цель замены — обеспечить регистрацию оконных классов для элементов управления общего пользования в конструкторе класса, чтобы осво бодить программиста от этой рутинной операции. Кроме того, в файлах KWndEx.h, KWndEx.cpp будут размещены также интерфейс и реализация функций общего при менения.

В состав функций общего применения войдут следующие функции:

перегруженная функция ShiftWindow, предназначенная для сдвига и модифи кации размеров окон (эта функция использовалась ранее в листинге 7.5);

функция AddTooltip, добавляющая окно подсказки к указанному окну;

функция TRACE, которую можно использовать для отладочного вывода в окно Output (аналогично макросу TRACE в библиотеке MFC).

Все во имя программиста, все для блага программиста!

Создайте новый проект с именем ToolTip. Скопируйте из папки проекта

ComboInToolbar (см. листинг 8.3) в папку проекта ToolTip файлы с расширениями

.cpp, .h и .rc, скорректировав их имена заменой подстроки ComboInToolbar на ToolTip. Скопируйте также файл toolbar1.bmp. Измените имена файлов Kwnd.h, Kwnd.cpp на KwndEx.h и KwndEx.cpp соответственно. Добавьте все перечисленные файлы в со став проекта. Также к настройкам проекта на вкладке Link надо добавить библио теку comctl32.lib.

Откройте вкладку ResourceView в окне Workspace. В списке ресурсов откройте папку String table и вызовите редактор таблицы строк двойным щелчком мыши на элементе String table. Добавьте в таблицу строк следующие две строки:

Идентификатор

Строка

 

 

IDS_TB_COMBOBOX

Доступ к списку для выбора толщины пера

IDS_EDIT_IN_COMBO

Толщина пера для контура фигуры

 

 

Обратите внимание на то, что потребовалось указать две строки, чтобы эле мент управления Combo box получил все необходимые подсказки. Первый текст подсказки будет отображаться при наведении курсора мыши на стрелку, исполь зуемую для открывания списка, второй текст подсказки — при наведении курсо ра мыши на окно редактирования.

Отредактируйте тексты файлов KwndEx.h, KwndEx.cpp, ToolTip.cpp так, чтобы они соответствовали листингу 8.4.

Элементы управления главного окна

409

 

 

 

Листинг 8.4. Проект ToolTip

//////////////////////////////////////////////////////////////////////

// KWndEx.h

#include <windows.h>

class KWndEx { public:

KWndEx(LPCTSTR windowName, HINSTANCE hInst, int cmdShow, LRESULT (WINAPI *pWndProc)(HWND,UINT,WPARAM,LPARAM), LPCTSTR menuName = NULL,

int x = CW_USEDEFAULT, int y = 0,

int width = CW_USEDEFAULT, int height = 0, UINT classStyle = CS_HREDRAW | CS_VREDRAW, DWORD windowStyle = WS_OVERLAPPEDWINDOW, HWND hParent = NULL);

HWND GetHWnd() { return hWnd; }

protected: HWND hWnd;

WNDCLASSEX wc;

};

//==================================================================== // Ô ó í ê ö è è î á ù å ã î ï ð è ì å í å í è ÿ //--------------------------------------------------------------------

// Ñ ä â è ã è î ê î í

//Сдвиг окна верхнего уровня с модификацией размеров void ShiftWindow(HWND hwnd, int dX = 0, int dY = 0,

int dW = 0, int dH = 0);

//Сдвиг дочернего окна с модификацией размеров

void ShiftWindow(HWND hChild, HWND hParent, int dX = 0, int dY = 0, int dW = 0, int dH = 0);

//Сдвиг окна элемента управления с модификацией размеров void ShiftWindow(int ctrlID, HWND hParent, int dX = 0,

int dY = 0, int dW = 0, int dH = 0); //--------------------------------------------------------------------

//Добавление окна подсказки

void AddTooltip (HWND hwndOwner, LPTSTR lpMsg);

//--------------------------------------------------------------------

//Функция отладочной печати (вывод в окно "Output")

//- работает аналогично макросу TRACE в библиотеке MFC void TRACE(LPCTSTR lpszFormat, ...);

//////////////////////////////////////////////////////////////////////

// KWndEx.cpp #include "KWndEx.h" #include <commctrl.h>

KWndEx::KWndEx(LPCTSTR windowName, HINSTANCE hInst, int cmdShow, LRESULT (WINAPI *pWndProc)(HWND,UINT,WPARAM,LPARAM), LPCTSTR menuName, int x, int y, int width, int height, UINT classStyle, DWORD windowStyle, HWND hParent)

{

/* Такой же текст, как и в конструкторе KWnd (листинг 1.2)

*/

// Инициализация библиотеки "Common Control Library"

продолжение

410 Глава 8. Элементы управления общего пользования

Листинг 8.4 (продолжение)

INITCOMMONCONTROLSEX icc;

icc.dwSize = sizeof(INITCOMMONCONTROLSEX); icc.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&icc);

}

//====================================================================

// Ô ó í ê ö è è

î á ù å ã î

ï ð è ì å í å í è ÿ

//

--------------------------------------------------------------------

 

 

//

Сдвиг окна верхнего уровня с

модификацией размеров

void ShiftWindow(HWND hwnd, int dX, int dY, int dW, int dH) { /* Текст функции из листинга 7.5 (файл KWndPlut.cpp) */

}

// Сдвиг дочернего окна с модификацией размеров

void ShiftWindow(HWND hChild, HWND hParent, int dX, int dY, int dW, int dH) {

/* Текст функции из листинга 7.5

*/

}

 

// Сдвиг окна элемента управления с модификацией размеров

void ShiftWindow(int ctrlID, HWND hParent, int dX, int dY, int dW, int dH) { /* Текст функции из листинга 7.5 */

}

//--------------------------------------------------------------------

// Добавление окна подсказки

void AddTooltip (HWND hwndOwner, LPTSTR lpMsg) {

HWND hwndTip;

// дескриптор элемента управления Tooltip

static TOOLINFO ti;

// информация об

инструменте (о «горячей» области),

 

// обслуживаемом

элементом hwndTip

HINSTANCE hInst = (HINSTANCE)GetWindowLong(hwndOwner, GWL_HINSTANCE);

hwndTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, hInst, NULL);

//Инициализация структуры ti ti.cbSize = sizeof(TOOLINFO); ti.uFlags = TTF_SUBCLASS; ti.hwnd = hwndOwner;

ti.hinst = hInst; ti.uId = 0; ti.lpszText = lpMsg;

//Местоположение инструмента в окне hwndOwner

//(инструмент покрывает всю клиентскую область) GetClientRect (hwndOwner, &ti.rect);

//Регистрация инструмента с информацией ti SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)(LPTOOLINFO) &ti);

}

//--------------------------------------------------------------------