[ Next ] [ Previous ] Chapter 33
[ Contents ] [ Using Dialog Window as Main Application's Window ] [ Appendix A - Window Messages ]

Color Wheel control / Использование ColorSelectClass

2001-08-25
Dmitry Zaharov

Однажды  мне непременно захотелось поменять цвета кнопок в WPS. Увы, сделать мне это удалось лишь частично, поскольку Палитра Схем упорно не хотела менять тень кнопки :( Так зародилась программа SysColors. Я думаю, детальное изучение данной программы поможет некоторым индивидуумам более эффективно использовать возможности Presentation Manager, некоторые из которых до сих пор остаются под темной завесой секретности. ;-)

ColorSelect control

Так вот. Я думаю, многие из читающих сей текст (а их я думаю не меньше 99%) видели этот замечательный контрол при выборе цвета чего либо, например при изменении цвета в Палитре Цветов или Схем. Представляет он собой некую окружность заполненную всеми возможными оттенками цветов (на самом деле, не всеми, а только лишь различными комбинациями rgb). Кроме того, эта окружность пересечена двумя перпендикулярными линиями, на их пересечении находится выбранный оттенок цвета. Справа же мы видим прямоугольник с градациями этого цвета. По понятным причинам, мне очень захотелось использовать этот контрол в программе SysColors. SysColors window


После некоторого шаманства с XRay я выяснил что зовут его, как и следовало догататься, ColorSelectClass. Дальнейшие попытки выяснить, что это за класс такой и где он обитает, привели меня в Undocumented features of OS/2 (os2undoc.inf|63661|15/06/98). Оттуда я узнал что: The color wheel control used by the Solid and Mixed Color Palette object is a publicly registered window class within OS/2, but is undocumented, что подразумевает примерно следующее:

Выбор цвета является публично (?) зарегистрированным классом, используется в Палитре Смешанных и Чистых цветов, но недокументирован.

Далее, я узнал что этот класс фактически содержится в WPCONFIG.DLL (что вобщем, неудивительно). Т.е., для того чтобы его использовать, нам нужно загрузить WPCONFIG.DLL через функцию DosLoadModule.
Ну что ж, подумал я, совсем неплохо. Из тех-же Undocumented features of OS/2 я узнал что выбором цвета можно управлять через сообщение 0x0602 (0x1384 для версий OS/2 младше 4.0), а узнать цвет выбранный пользователем можно отловив сообщение 0x0601(0x130C для версий OS/2 младше 4.0).
Теперь определим это по человечески:
#define CLM_SETCOLOR    0x0602 // 0x1384
#define CLN_USERCOLOR 0x0601 // 0x130C

Параметром mp1 функции WinSendMsg в сообщении CLM_SETCOLOR будет 24битовое значение цвета в формате 0x00RRGGBB. При приходе сообщения CLN_USERCOLOR в mp1 значение цвета выбранного пользователем. Понятно, что сразу после посылки CLM_SETCOLOR к нам придет CLN_USERCOLOR.

Использование ColorSelect

Теперь, когда все точки над i расставлены, мы можем использовать Выбор Цвета в наших программах. Как наиболее логичный путь, мы определим этот контрол в качестве элемента диалога и предоставим ему (диалогу) самому разбиратся с ним (Выбором Цвета).
А определим мы его так:

CONTROL "Text?", IDD_COLORSELECT, 1, 1, 200, 120,
"ColorSelectClass", WS_VISIBLE

Да, для того чтобы ваш диалог выглядил пристойно, стоит позаботится о том, чтобы высота Выбора Цвета была примерно 60% от его ширины.

А теперь представим себе, как мы будем управлять Выбором цвета:

MRESULT EXPENTRY MainDialogProc( HWND hwnd,
ULONG msg,
MPARAM mp1,
MPARAM mp2)
{
switch (msg)
{
case WM_INITDLG:
/* ... */
WinSendDlgItemMsg( hwnd, IDD_COLORSELECT,
CLM_SETCOLOR, (MPARAM)aSysClr[0], (MPARAM)0L );
/* ... */
break;
case CLN_USERCOLOR:
if( iClrNumber < 0 ) break;
aSysClr[iClrNumber] = (LONG)mp1;
/* ... */
break;
/* ... */
}
return ( WinDefDlgProc( hwnd, msg, mp1, mp2 ) );
}


А в main() мы напишем (без купюр)...
HAB      hab; /* ОН нам нужен здесь. */

int main()
{
HMQ hmq;
QMSG qmsg;
HMODULE hmWpConfig;
CHAR szError[256];
HWND hwndFrame;

hab = WinInitialize( 0 );
if( !hab ) return ( -1 );
hmq = WinCreateMsgQueue( hab, 0 );
if( !hmq ) return ( -1 );

/* Загружаем... */
DosLoadModule( szError, 256, "WPCONFIG", &hmWpConfig );

/* Запускаем... */
hwndFrame = WinLoadDlg( HWND_DESKTOP,
HWND_DESKTOP,
( PFNWP )MainDialogProc,
NULLHANDLE,
IDR_MAINDIALOG,
NULL );

if( !hwndFrame ) return ( -1 );

while ( WinGetMsg( hab, &qmsg, NULL, 0, 0 ) )
WinDispatchMsg( hab, &qmsg );

/* Выгружаем... */
DosFreeModule ( hmWpConfig );

WinDestroyWindow( hwndFrame );
WinDestroyMsgQueue( hmq );
WinTerminate( hab );
return ( 0 );
}

SYSCLR.C
SYSCLR.RC
SYSCLR.H
SYSCLR.DEF
SYSCLR.MAK


[ Next ] [ Previous ] Chapter 33
[ Contents ] [ Using Dialog Window as Main Application's Window ] [ Appendix A - Window Messages ]