В этой главе рассматривается работа с растровыми изображениями. Изображения очень важны для “дизайна” вашего приложения, и могут использоваться с элементами управления, например с панелями инструментов, списками, вкладками, кнопками, HTML окнами, или при рисовании. Иногда их можно сделать невидимыми в приложении, например, когда нужно избежать мерцания во время прорисовки. В этой главе, мы рассмотрим разные классы изображений и методы перегрузки стандартных классов иконок и изображений, которые есть в wxWidgets.
Программирование с использованием wxBitmap
С помощью wxBitmap
Вы можете делать несколько вещей:
- Рисовать его в окне с помощью контекста устройства.
- Использовать его, как изображение для таких классов, как
wxBitmapButton
,wxStaticBitmap
, илиwxToolBar
. - Использовать его для рисования методом двойной буферизации (рисования в невидимом буфере
wxMemoryDC
, перед тем как рисовать в окне).
На некоторых платформах (в частности на Windows), растровые изображения имеют ограниченные ресурсы, и если у Вас много изображений, которые Вам нужно хранить в памяти, предпочтительней работать с wxImage
объектами и конвертировать их во временный wxBitmap
для рисования в контексте устройства.
Перед тем, как мы обсудим создание wxBitmap и рисование с его помощью, давайте рассмотрим функции класса (Таблица 10-2).
wxBitmap
– Растровое изображение может быть создано с заданными высотой и шириной, из другого растрового изображения, изwxImage
, XPM данных (char**
), битовых данных (char[]
), или из файла, с указанием имя файла и его типа.ConvertToImage
– Конвертирует вwxImage
, с сохранением прозрачности.CopyFromIcon
– Создает растровое изображение изwxIcon
.Create
– Создает растровое изображения из данных, или заданного размера.GetWidth
,GetHeight
– Возвращает размеры растрового изображения.GetDepth
– Возвращает глубину цвета изображения.GetMask
,SetMask
– ВозвращаетwxMask
объект илиNULL
.GetSubBitmap
– Возвращает область текущего изображения, как новое растровое изображение.LoadFile
,SaveFile
– Загружает файл и (для некоторых форматов) сохраняет его.- Ok – Возвращает
true
, если объект содержит данные растрового изображения.
Создание wxBitmap
Есть несколько способов создать объект wxBitmap
.
Вы можете создать неинициализированный объект (без данных изображения), используя конструктор по умолчанию. Вам нужно будет вызвать Create
, LoadFile
или назначить объекту существующее растровое изображение для того, что бы с ним работать.
Вы можете создать wxBitmap
, задав ему размер, и глубину. Созданное растровое изображение будет заполнено произвольными данными, поэтому Вам придется на нем что-нибудь нарисовать. Снизу показан пример, который создает изображение 200 x 100 пикселей, и задает ему белый цвет фона.
// Создает изображение размером 200x100 пикселей с текущей глубиной дисплея. wxBitmap bitmap(200, 100, -1); // Создаем контекст устройства памяти (memory device context, далее DC) wxMemoryDC dc; // Назначаем контексту устройства наше изображение dc.SelectObject(bitmap); // задаем белый фон dc.SetBackground(*wxWHITE_BRUSH); // Закрашиваем изображение белым (очищаем) dc.Clear(); // Отключаем изображение от контекста dc.SelectObject(wxNullBitmap);
Вы можете создать растровое изображение из любой картинки, сохранив при этом маску, или альфа канал исходного изображения:
// Загружаем картинку из файла wxImage image(wxT("image.png"), wxBITMAP_TYPE_PNG); // Конвертируем в растровое изображение wxBitmap bitmap(image);
Растровое изображение так же можно создать, используя иконку, функцией CopyFromIcon
:
// Загружаем иконку wxIcon icon(wxT("image.xpm"), wxBITMAP_TYPE_XPM); // Конвертируем иконку в растровое изображение wxBitmap bitmap; bitmap.CopyFromIcon(icon);
Или же можно загрузить изображение из файла:
// Load from a file wxBitmap bitmap(wxT("picture.png", wxBITMAP_TYPE_PNG); if (!bitmap.Ok()) { wxMessageBox(wxT("Sorry, could not load file.")); }
wxBitmap
может загружать все типы файлов, которые может загружать wxImage
(смотрите Таблицу 10-7), используя wxImage
или более эффективную реализацию некоторых типов файлов для конкретной платформы. wxWidgets поддерживает наиболее популярные форматы PNG, JPEG, TIFF, BMP, и XPM, загрузка и сохранение которых поддерживается на всех платформах.
Таблица 10-7. Доступные Обработчики Форматов Изображений
wxBMPHandler
– Для загрузки и сохранения Windows файлов растровых изображений.wxPNGHandler
– Для загрузки и сохранения файлов PNG. Поддерживаются изображения с прозрачностью и альфа каналом.wxJPEGHandler
– Для загрузки и сохранения файлов JPEG.wxGIFHandler
– GIF файлы: только для загрузки, из-за юридических вопросов.wxPCXHandler
– Для загрузки и сохранения PCX файлов.wxPCXHandler
подсчитывает количество цветов в изображении; если в изображении 256 или меньше, оно будет сохранено в 8-битном формате; в противном случае в 24-битном.wxPNMHandler
– Для загрузки и сохранения PNM файлов. Загрузка PNMs работает только для ASCII или строковых RGB изображений. При сохранении в PNM формате, wxPNMHasndler всегда сохраняет в строковом RGB.wxTIFFHandler
– Для загрузки и сохранения TIFF файлов.wxIFFHandler
– Для загрузки IFF файлов.wxXPMHandler
– Для загрузки и сохранения XPM файлов.wxICOHandler
– Для загрузки и сохранения Windows иконок.wxCURHandler
– Для загрузки и сохранения файлов курсора Windows.wxANIHandler
– Для загрузки и сохранения анимированных файлов курсора Windows.
Также можно загрузить PICT ресурсы для Mac OS X, указав wxBITMAP_TYPE_PICT_RESOURCE
.
Если Вы хотите загрузить специфические ресурсы для данной платформы, Вы можете использовать wxBITMAP
макрос. Например:
#if !defined(__WXMSW__) & !defined(__WXPM__) #include "picture.xpm" #endif wxBitmap bitmap(wxBITMAP(picture));
На Windows и OS/2 этот код будет загружать ресурс picture
из исполняемого файла, на всех других платформах, он будет загружать переменную picture_xpm
из XPM файла. В любом случае XPM поддерживается всеми платформами, поэтому необходимости в этом макросе нет.
Использование wxMask
Каждый объект wxBitmap
может иметь wxMask
, монохромное растровое изображение, которое указывает прозрачные области основного растрового изображения. Оно создается автоматически, когда Вы загружаете изображение с прозрачностью, например XPM, PNG, или GIF изображения, но Вы можете создать его программно, и назначить функцией SetMask
. Создать wxMask
можно из wxBitmap
, или из wxBitmap
, с заданием цвета, который будет указывать на прозрачную область.
Следующий пример создает монохромное прозрачное изображение mainBitmap
, шириной в 32 пикселя и 32 пикселя высотой, из данных растрового изображения (imageBits
) и маски (maskBits
), где 1 это черный а 0 белый для битов изображения, и 1 непрозрачность а 0 прозрачность для маски.
static char imageBits[] = { 255, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255, 25, 243, 255, 255, 19, 249, 255, 255, 7, 252, 255, 255, 15, 254, 255, 255, 31, 255, 255, 255, 191, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; static char maskBits[] = { 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 255, 31, 0, 0, 255, 31, 0, 0, 254, 15, 0, 0, 252, 7, 0, 0, 248, 3, 0, 0, 240, 1, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; wxBitmap mainBitmap(imageBits, 32, 32); wxBitmap maskBitmap(maskBits, 32, 32); mainBitmap.SetMask(new wxMask(maskBitmap));
Формат XPM
Если Вам нужны небольшие растровые изображения с прозрачностью, например для кнопок на панели инструментов или для изображений на вкладках и списках, в wxWidgets очень удобно использовать XPM формат. Преимущество этого формата в том, что он использует C/C++ синтаксис, таким образом он может подгружаться динамически, и компилироваться в вашу программу. Например:
// Также можно использовать #include "open.xpm" static char *open_xpm[] = { /* columns rows colors chars-per-pixel */ "16 15 5 1", " c None", ". c Black", "X c Yellow", "o c Gray100", "O c #bfbf00", /* pixels */ " ", " ... ", " . . .", " ..", " ... ...", " .XoX....... ", " .oXoXoXoXo. ", " .XoXoXoXoX. ", " .oXoX..........", " .XoX.OOOOOOOOO.", " .oo.OOOOOOOOO. ", " .X.OOOOOOOOO. ", " ..OOOOOOOOO. ", " ........... ", " " }; wxBitmap bitmap(open_xpm);
Как Вы видите, XPM файлы состоят из символьных данных. Перед данными собственно изображения, записана палитра, где к каждому символу привязан свой цвет, с использованием встроенного идентификатора цвета, или шести-цифровым числом в шестнадцатеричном формате, перед которым ставится шестнадцатеричный флаг “#”. Идентификатор None
указывает на прозрачную область изображения. Формат XPM непопулярен в графических редакторах под Windows, но Вы можете сохранить изображение как PNG и конвертировать его в XPM с помощью ImageBlocks (поставляется с DialogBlocks), или можно самому написать свой конвертер, используя wxWidgets.
Рисование растровых изображений (Bitmaps)
Растровое изображение непосредственно можно нарисовать двумя разными способами. Вы можете ассоциировать (назначить) его контексту устройства памяти (wxMemoryDC
) и потом использовать wxDC::Blit
для того, что бы перенести содержимое растрового изображения в другой контекст устройства. Или же можно просто использовать wxDC::DrawBitmap
. В обоих случаях, если изображение имеет прозрачность или альфа канал, Вы должны указать это, передав true
в функцию.
В этом примере показаны оба метода:
// Рисование растрового изображения с wxMemoryDC wxMemoryDC memDC; memDC.SelectObject(bitmap); // Рисуем в координатах 100, 100 на конечном DC destDC.Blit(100, 100, // Draw at (100, 100) bitmap.GetWidth(), bitmap.GetHeight(), // Draw full bitmap & memDC, // Draw from memDC 0, 0, // Draw from bitmap origin wxCOPY, // Logical operation true); // Take mask into account memDC.SelectObject(wxNullBitmap); // Альтернативный способ: используем DrawBitmap destDC.DrawBitmap(bitmap, 100, 100, true);
Более детально рисование растровых изображений описывается в Главе 5 “Рисование и Печать”.
Упаковка графических ресурсов
Если Вы программировали под Windows, Вы привыкли загружать растровые изображения из ресурсов исполняемых файлов. Вы можете не изменять своей привычке, и загружать их из ресурсов, используя wxBITMAP_TYPE_BMP_RESOURCE
в конструкторе, но скорее всего Вы предпочитаете менее платформозависимый метод.
Очень удобный способ паковать ресурсы, будь то растровые изображения, HTML файлы, или другие файлы, используемые в приложении, хранить их в одном zip архиве отдельно от исполняемого файла или в отдельной директории данных. Также Вы можете использовать функциональность виртуальных файловых систем в wxWidgets, что бы загружать изображение прямо из zip архива, как показано в следующем примере.
// Создадим новый объект файловой системы wxFileSystem*fileSystem = new wxFileSystem; wxString archiveURL(wxT("myapp.bin")); wxString filename(wxT("myimage.png")); wxBitmapType bitmapType = wxBITMAP_TYPE_PNG; // Создаем URL wxString combinedURL(archiveURL + wxString(wxT("#zip:")) + filename); wxImage image; wxBitmap bitmap; // Открываем архив wxFSFile* file = fileSystem->OpenFile(combinedURL); if (file) { wxInputStream* stream = file->GetStream(); // Load and convert to a bitmap if (image.LoadFile(* stream, bitmapType)) bitmap = wxBitmap(image); delete file; } delete fileSystem; if (bitmap.Ok()) { ... }
Более подробно о виртуальных файловых системах, Вы сможете узнать в Главе 14, “Файлы и Потоки”.
Программирование с wxIcon
wxIcon
это небольшое растровое изображение, у которого всегда есть маска. wxIcon
можно использовать:
- Как иконку для фрейма или диалога
- Как иконку для
wxTreeCtrl
,wxListCtrl
, илиwxNotebook
черезwxImageList
класс (смотрите дальше в этой главе) - Рисовать иконку в контексте устройства, используя
wxDC::DrawIcon
Таблица 10-3 основные функции класса.
wxIcon
– Иконка может быть создана с использованием другой иконки, XPM данных (char**), битовых данных (char[]), или из файла с заданным форматом.CopyFromBitmap
– Создает иконку из wxBitmap.GetWidth
,GetHeight
– Возвращает размер иконки.GetDepth
– Возвращает глубину иконки.LoadFile
– Загружает иконку из файла.Ok
– Возвращаетtrue
, если присутствуют данные иконки.
Создание wxIcon
Объект wxIcon
можно создать, используя XPM данные, подключенные к приложению, из объекта wxBitmap
, из битовых данных, или загрузить ее из файла, например из XPM файла с прозрачностью. В wxWidgets есть wxICON
макрос, аналогичный к wxBITMAP
макросу, который был рассмотрен выше, для загрузки из ресурса, характерного для данной платформы либо из XPM данных.
В Windows, LoadFile
и схожий конструктор будет работать для Windows растровых изображений (BMP) и иконок (ICO), ресурсов и файлов. Если Вы хотите работать с другим форматом, загрузите файл в wxBitmap
и сконвертируйте в иконку.
На Mac OS X и Unix/Linux с использованием GTK+, wxIcon
имеет те же возможности при загрузке из файла, что и wxBitmap
.
В ниже поданном примере показано создание wxIcon
объекта разными способами.
// Метод 1: загрузка из XPM данных #include "icon1.xpm" wxIcon icon1(icon1_xpm); // Метод 2: загрузка из ICO ресурса (только для Window и OS/2) wxIcon icon2(wxT("icon2")); // Метод 3: загрузка из ICO файла (только для Window и OS/2) // Вы можете указывать желаемый размер, так как файл // может содержать несколько иконок. wxIcon icon3(wxT("icon3.ico"), wxBITMAP_TYPE_ICO, 16, 16); // Метод 4: создание из растрового изображения wxIcon icon4; wxBitmap bitmap(wxT("icon4.png"), wxBITMAP_TYPE_PNG); icon4.CopyFromBitmap(bitmap);
Использование wxIcon
В этом коде показаны три разных способа использования иконки wxIcon
: установка как иконки фрейма, добавление иконки в список изображений и рисование иконки в контексте устройства.
#include "myicon.xpm" wxIcon icon(myicon_xpm); // 1: Установка иконкой фрейма frame->SetIcon(icon); // 2: Добавление в wxImageList wxImageList* imageList = new wxImageList(16, 16); imageList->Add(icon); // 3: Рисование иконки в точке (10, 10) wxClientDC dc(window); dc.DrawIcon(icon, 10, 10);
Назначение Иконки Приложению
Назначить иконку приложению (для того, что бы операционная система использовала ее как значок приложения), нельзя с помощью инструментов wxWidgets, это одно из немногих мест, где Вы должны использовать разные способы для разных платформ.
На Windows, нужно добавить скрипт ресурса (расширение .rc) в ваш makefile, или в файл проекта, и добавить выражение ICON
в файле .rc, например:
aardvarkpro ICON aardvarkpro.ico #include "wx/msw/wx.rc"
Здесь, aardvarkpro.ico это имя файла Windows иконки с разными разрешениями и глубиной (обычно разрешения 48×48, 32×32 и 16×16). Когда иконка показывается в Проводнике (Windows Explorer), Windows рассматривает иконки из ресурса в алфавитном порядке, таким образом, если в ресурсе у Вас несколько иконок, удостоверьтесь, что нужная иконка для приложения в алфавитном порядке первая в списке; иначе на рабочем столе или в директории будет не та иконка, которую Вы ожидали увидеть.
На Mac, Вам нужно подготовить пакет (bundle) для приложения, в которой есть ICNS файлы. Больше информации о пакетах Вы найдете в разделе об установке в Главе 20, “Сделаем Ваше приложение Идеальным”; нужная секция файла в пакете Info.plist например, может выглядеть вот так:
<key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <array> <string>pjd</string> </array> <key>CFBundleTypeIconFile</key> <string>dialogblocks-doc.icns</string> <key>CFBundleTypeName</key> <string>pjdfile</string> <key>CFBundleTypeRole</key> <string>Editor</string> </dict> </array> <key>CFBundleIconFile</key> <string>dialogblocks-app.icns</string> ...
Иконки для вашего приложения и документов вашего приложения описываются в CFBundleIconFile
и CFBundleTypeIconFile
свойствах. ICNS файлы Вы можете создать с помощью редактора иконок, которые поставляет Apple. Если Вы преимущественно работаете в другой операционной системе, Вам нужно создать несколько иконок с разрешением 16×16, 32×32, 48×48, и 128×128, сохранить их в PNG формате, скопировать их на Mac, потом скопировать их и вставить в нужном месте в редактор иконок. Удостоверьтесь, что каждый PNG файл содержит маску, которую редактор будет использовать при создании иконки.
В Linux’e, у GNOME и KDE свои способы для назначения иконок приложениям, эти способы коротко будут описаны в Главе 20.
Программирование с wxCursor
Курсор используется для указания позиция указателя мыши. Вы можете изменить курсор для отдельного окна, если хотите акцентировать пользователя на конкретной функции мыши в данном окне. Так же как и иконки, курсор это небольшое изображение с поддержкой прозрачности. Создать его можно с помощью как общих, так и с помощью специфических для данной платформы конструкторов. Некоторые из этих конструкторов берут актуальную позицию указателя как самую левую верхнюю точку изображения курсора, и именно эта точка по-умолчанию является “острием” вашего курсора.
Таблица 10-4 функции класса wxCursor.
wxCursor
– Курсор может быть создан изwxImage
, битовых данных (char[]
), используя стандартный идентификатор курсора, или из файла с указанием формата файла.Ok
– Возвращаетtrue
, если объект содержит данные курсора.
Создание wxCursor
Самый простой способ задать курсор – это передать стандартный идентификатор конструктору объекта, как показано в примере ниже.
// Создание курсора, используя стандартный идентификатор wxCursor cursor(wxCURSOR_WAIT);
Таблица 10-5 список доступных идентификаторов и их внешний вид (на разных платформах могут быть незначительные отличия).
Table 10-5. Идентификаторы Стандартных Курсоров
wxCURSOR_ARROW
– Стандартный курсор стрелка.wxCURSOR_RIGHT_ARROW
– Стандартный курсор, указывающий вправо.wxCURSOR_BLANK
– Прозрачный (пустой) курсор.wxCURSOR_BULLSEYE
– Курсор мишень.wxCURSOR_CROSS
– Курсор крест.wxCURSOR_HAND
– Курсор в форме руки.wxCURSOR_IBEAM
– I-образный курсор (вертикальная линия).wxCURSOR_LEFT_BUTTON
– Изображение мыши с нажатой левой кнопкой (только в GTK+).wxCURSOR_MAGNIFIER
– Курсор увеличения.wxCURSOR_MIDDLE_BUTTON
– Изображение мыши с нажатой средней кнопкой (только в GTK+).wxCURSOR_NO_ENTRY
– Курсор в форме знака “входа нет”.wxCURSOR_PAINT_BRUSH
– Курсор в форме кисти для рисования.wxCURSOR_PENCIL
– Курсор карандаш.wxCURSOR_POINT_LEFT
– Курсор указывающий налево.wxCURSOR_POINT_RIGHT
– Курсор указывающий направо.wxCURSOR_QUESTION_ARROW
– Стрелка и знак вопроса.wxCURSOR_RIGHT_BUTTON
– Изображение мыши с нажатой правой кнопкой (только в GTK+).wxCURSOR_SIZENESW
– Курсор изменения размера в направлении СВ-ЮЗ.wxCURSOR_SIZENS
– Курсор изменения размера в направлении С-Ю.wxCURSOR_SIZENWSE
– Курсор изменения размера в направлении СЗ-ЮВ.wxCURSOR_SIZEWE
– Курсор изменения размера в направлении З-В.wxCURSOR_SIZING
– Курсор изменения размера (часто перемещения)wxCURSOR_SPRAYCAN
– Курсор пульвелизатора.wxCURSOR_WAIT
– Курсор ожидания.wxCURSOR_WATCH
– Курсор в форме часов.wxCURSOR_ARROWWAIT
– Курсор со стрелкой и песочными часами.
Так же можно использовать предопределенные курсоры wxSTANDARD_CURSOR
, wxHOURGLASS_CURSOR
, и wxCROSS_CURSOR
.
wxCursor
можно загрузить из Windows ресурсов в Windows или из Mac OS X ресурса курсоров в Mac OS X:
// Курсор из Windows ресурса wxCursor cursor(wxT("cursor_resource"), wxBITMAP_TYPE_CUR_RESOURCE, hotSpotX, hotSpotY); // Курсор из Mac OS ресурса курсоров wxCursor cursor(wxT("cursor_resource"), wxBITMAP_TYPE_MACCUR_RESOURCE);
Вы можете создать свой курсор, используя wxImage
. Актуальную позицию указателя можно задать функцией wxImage::SetOptionInt
, так как “острие” курсора может не совпадать с левой верхней точкой изображения. Например, у курсора в виде прицела актуальная позиция находится ровно по центру изображения. Вот пример кода, который загружает PNG изображение и использует его в качестве курсора:
// Создаем курсор из wxImage wxImage image(wxT("cursor.png"), wxBITMAP_TYPE_PNG); image.SetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X, 5); image.SetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y, 5); wxCursor cursor(image);
Использование wxCursor
Каждое окно может иметь свой курсор, который будет использоваться для указателя, когда мышь будет в пределах данного окна. Если для окна не указан курсор, будет использоваться курсор, заданный родительскому окну; если же у окна нет родителя с заданным курсором, будет использован стандартный курсор.
Курсор для окна задается вот так:
window->SetCursor(wxCursor(wxCURSOR_WAIT));
Использование wxSetCursorEvent
В Windows и Mac OS X есть подводные камни, которых Вы должны остерегаться, в частности, когда Вы рисуете нестандартное окно. Скажем, Вы рисуете окно с разделителем так, что на самом деле видима очень маленькая часть самого окна; например так рисуются окна с плавающим разделителем, так называемым “переплетом”. Далее Вы устанавливаете курсор для переплета (скажем, wxCURSOR_WE
) таким образом, пользователь видит, что границу-разделитель можно тянуть. И если для окон-потомков не установлен собственный курсор, то будет применяться курсор, установленный нашему основному окну, в нашем случае курсор, предназначенный только переплету.
Для того, что бы указать, что нужно использовать заданный курсор только для разделителя, а в остальных случаях рисовать стандартный, Вы должны определить обработчик событий с помощью wxSetCursorEvent
. Это событие вызывается в Windows и Mac OS X, когда должен изменятся курсор (обычно, когда указатель мыши двигается над окном). Ваш обработчик события должен вызывать wxSetCursorEvent::SetCursor
, если Вы хотите изменять курсор в частности для данного окна:
BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow) EVT_SET_CURSOR(wxSplitterWindow::OnSetCursor) END_EVENT_TABLE() // Указываем, что курсор должен изменятся только для переплета void wxSplitterWindow::OnSetCursor(wxSetCursorEvent& event) { // Если мы этого не сделаем, курсор изменения размера будет использоваться // и в окнах-потомках. Здесь мы указываем, что наш курсор // не должен использоваться для дочерних окон. if ( SashHitTest(event.GetX(), event.GetY(), 0) ) { // Вызываем обработчик по-умолчанию event.Skip(); } //else: Ничего не делать, в частности не вызывать Skip() }
В этом примере, если курсор мыши двигается над переплетом, SashHitTest
возвращает true
и вызывается Skip
, который прерывает обработку события. Это равнозначно тому, что событие не обрабатывалось вообще, и wxWidgets отображает курсор (wxCURSOR_WE
) как он задан для окна. Если SashHitTest
возвращает false
, наш указатель двигается в пределах дочернего окна, значит мы не заменяем стандартный курсор. Если позволить завершится обработчику (не вызывая Skip
), не задавая курсор окну, это укажет wxWidgets обрабатывать наше окно-разделитель, как не имеющее заданного курсора. В итоге дочернее окно не унаследует родительский курсор, даже если дочернее окно не имеет собственного курсора (например, если дочернее окно wxTextCtrl
, реализация которого имеет свой курсор, но wxWidgets не знает этого).
3 Comments
Adamos
Формат XPM действительно непопулярен в графических редакторах под Windows,
НО с ним прекрасно работает GIMP, и это заведомо удобнее, чем изобретать велосипеды
T-Rex
XnView поддерживает XPM и еще кучу всего. Только им сейчас и пользуюсь. Довольно удобно конвертировать в XMP/PNG/JPEG. Для XPM еще и куча настроек есть