На этом шаге мы приведем текст небольшого графического редактора.
Студент 4 курса (2010-11 уч.год) Курочкин Дмитрий создал небольшой графический редактор средствами бибилиотеки OWL.
Данный графический редактор позволяет открывать, изменять и сохранять рисунки в формате BMP.
Внешний вид этого редактора приведен на рисунке 1:
Рис.1. Внешний вид приложения
Ниже приведен текст приложения с подробными коментариями:
#include <owl\owlpch.h> #include <owl\applicat.h> #include <owl\decframe.h> #include <owl\toolbox.h> #include <owl\buttonga.h> #include <owl\dc.h> #include <stdio.h> #include <owl\gdiobjec.h> #include <owl\opensave.h> #include <owl\dialog.h> #include <owl\clipboar.h> #include <string.h> #include <fcntl.h> #include <io.h> #include "paint.rc" //Буфер для диалогового окна, содержащий размеры изображения struct TrBuf { char width[6]; char height[6]; }Buf1; //Буфер для хранения имени файла, палитры, ширины линии и стиля //заливки struct { char* file; TColor* pal; int line; int style; }Buf; //Класс приложения class TApp: public TApplication { public: TApp():TApplication() {} void InitMainWindow(); }; //Класс панели палитры. Создадим его производным от класса //TToolBox class TCBar:public TToolBox { public: TCBar(TWindow*parent,int nc,int nr) :TToolBox(parent,nc,nr){}; protected: void Paint(TDC&,BOOL,TRect&); void EvLButtonDown(UINT,TPoint&p); void EvRButtonDown(UINT,TPoint&p); void EvLButtonDblClk(UINT,TPoint&p); DECLARE_RESPONSE_TABLE(TCBar); }; //Таблица откликов для панели палитры DEFINE_RESPONSE_TABLE1(TCBar,TToolBox) EV_WM_LBUTTONDOWN, EV_WM_RBUTTONDOWN, EV_WM_LBUTTONDBLCLK, END_RESPONSE_TABLE; //Клик левой кнопкой мыши по панель палитры void TCBar::EvLButtonDown(UINT,TPoint&p) { int c=-1; //Определим цвет, по которому мы щёлкнули. Так как каждая //"кнопка" у нас занимает 24 пикселя плюс 2 пикселя границы с //каждой из сторон, абсолютный размер кнопки 28X28. Кроме того, //для вычисления цвета нам нужно знать, что кнопки расположены с //отступом от левого края размером в две кнопки - 56 пикселей. //Сначала проверим первый ряд for(int i=0;i<16;i++) { if ((p.x>56+2+28*i)&&(p.x<56+24+28*i)&&(p.y>2)&&(p.y<24)) c=i;); } //Теперь проверим второй ряд for(i=0;i<16;i++) { if ((p.x>56+2+28*i)&&(p.x<56+24+28*i)&&(p.y>2+28)&&(p.y<24+28)) c=i+16;); } //После этих двух циклов в переменной c у нас должен содержаться //индекс цвета, по которому мы щёлкнули или -1 если мы щёлкнули //мимо цветов. 32-й элемент массива палитры в буфере Buf //содержит основной цвет. Заменим на тот, по которому мы //щёлкнули. Перерисуем панель палитры. if(c>=0) Buf.pal[32]=Buf.pal[c]; Invalidate(); } //Аналогично для правого клика void TCBar::EvRButtonDown(UINT,TPoint&p) { int c=-1; for(int i=0;i<16;i++) { if ((p.x>56+2+28*i)&&(p.x<56+24+28*i)&&(p.y>2)&&(p.y<24)) c=i;); } for(i=0;i<16;i++) { if ((p.x>56+2+28*i)&&(p.x<56+24+28*i)&&(p.y>2+28)&&(p.y<24+28)) c=i+16;); } //Здесь мы меняем побочный цвет, он хранится в 33-м элементе //массива палитры буфера Buf. if(c>=0) Buf.pal[33]=Buf.pal[c]; Invalidate(); } //Двойной клик по панели палитры должен вызывать диалоговое окно //выбора цвета, если кликнули мы по "кнопке". После выполнения //диалогового окна цвет "кнопки", по которой мы щёлкали, должен //измениться. void TCBar::EvLButtonDblClk(UINT,TPoint&p) { int c=-1; for(int i=0;i<16;i++) { if ((p.x>56+2+28*i)&&(p.x<56+24+28*i)&&(p.y>2)&&(p.y<24)) c=i;); } for(i=0;i<16;i++) { if ((p.x>56+2+28*i)&&(p.x<56+24+28*i)&&(p.y>2+28)&&(p.y<24+28)) c=i+16;); } if(c>=0) { TChooseColorDialog::TData colorData; static TColor customColors[16] = { 0x010101L, 0x101010L, 0x202020L, 0x303030L, 0x404040L, 0x505050L, 0x606060L, 0x707070L, 0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L, 0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L }; colorData.Flags = CC_FULLOPEN | CC_RGBINIT; if (c>=0) colorData.Color = Buf.pal[c]; colorData.CustColors = customColors; TChooseColorDialog *dialog =new TChooseColorDialog (this, colorData); if (dialog->Execute()== IDOK) { Buf.pal[c]=colorData.Color; Invalidate(); } } } //Перерисовка панели палитры. void TCBar::Paint(TDC&dc,BOOL b,TRect&r) { //Вызываем функцию Paint класса TToolBox. TToolBox::Paint(dc,b,r); //Рисуем цвета палитры dc.SelectObject(TPen(TColor::Black,1,PS_SOLID)); for(int i=0;i<16;i++) { dc.SelectObject(TBrush(Buf.pal[i])); dc.Rectangle(56+2+28*i,2,56+24+28*i,24); } for(i=0;i<16;i++) { dc.SelectObject(TBrush(Buf.pal[i+16])); dc.Rectangle(56+2+28*i,2+28,56+24+28*i,24+28); } //Рисуем состояние основного и побочного цветов dc.SelectObject(TBrush(Buf.pal[33])); dc.Rectangle(20,20,20+24,20+24); dc.SelectObject(TBrush(Buf.pal[32])); dc.Rectangle(12,12,12+24,12+24); }; //Класс клиентского окна class TCWndw:public TWindow { public: TCWndw(TWindow*parent,const char far*title); protected: void EvLButtonDown(UINT,TPoint&point); void EvLButtonUp(UINT,TPoint&point); void EvMouseMove(UINT,TPoint&point); void EvRButtonDown(UINT,TPoint&point); void EvRButtonUp(UINT,TPoint&point); LRESULT WmChangeP(WPARAM Id,LPARAM); LRESULT WmNew(WPARAM,LPARAM); LRESULT WmOpen(WPARAM,LPARAM); LRESULT WmSave(WPARAM,LPARAM); LRESULT WmAtr(WPARAM,LPARAM); void SetupWindow(); void Paint(TDC&DC,BOOL,TRect&); //В idp будем хранить индекс инструмента int idp; //В pp будет храниться точка нажатия TPoint pp; //В pressed будет храниться 0, если кнопка мыши не зажата, 1, //если зажата левая кнопка мыши, 2, если зажата правая. int pressed; //Указатель на изображение. TBitmap *pic; DECLARE_RESPONSE_TABLE(TCWndw); }; //Таблица откликов для клиентского окна DEFINE_RESPONSE_TABLE1(TCWndw,TWindow) EV_WM_LBUTTONDOWN, EV_WM_LBUTTONUP, EV_WM_MOUSEMOVE, EV_WM_RBUTTONDOWN, EV_WM_RBUTTONUP, EV_MESSAGE(WM_CHANGEP,WmChangeP), EV_MESSAGE(WM_NEW,WmNew), EV_MESSAGE(WM_OPEN,WmOpen), EV_MESSAGE(WM_SAVE,WmSave), EV_MESSAGE(WM_ATR,WmAtr), END_RESPONSE_TABLE; //Функция, вызываемая последней перед показом окна. void TCWndw::SetupWindow() { idp=1; pressed=false; //Создаём рисунок (объект класса TBitmap) TClientDC DC(HWindow); TRect rrr(0,0,256,256); TBrush b(TColor::White); TPen p(TColor::White,1,PS_SOLID); TMemoryDC mdc(DC); pic=new TBitmap(DC,rrr.Width(),rrr.Height(),FALSE); mdc.SelectObject(*pic); mdc.SelectObject(p); mdc.SelectObject(b); mdc.Rectangle(rrr); itoa(pic->Width(),Buf1.width,10); itoa(pic->Height(),Buf1.height,10); DC.BitBlt(0,0,rrr.Width(),rrr.Height(),mdc,0,0); } //Класс основного окна class TWndw : public TDecoratedFrame { public: TWndw (TWindow *parent, const char far *title,TWindow *client); ~TWndw (); protected: TToolBox *tbox,*cbar; DECLARE_RESPONSE_TABLE(TWndw); void CmP(WPARAM Id); void CmNew(); void CmOpen(); void CmSave(); void CmSaveAs(); void CmAtr(); void CmLine(WPARAM Id); void CmRc(WPARAM Id); void Paint(TDC&dc,BOOL,TRect&rect); TOpenSaveDialog::TData* FileData; }; //Конструктор главного окна TWndw::TWndw (TWindow *parent, const char far *title,TWindow *client) :TDecoratedFrame(parent,title,client) { //Заполним буфер Buf Buf.file=new char[80]; strcpy(Buf.file,""); //Создаём палитру Buf.pal=new TColor[34]; Buf.pal[0]=TColor::Black; Buf.pal[1]=TColor(32,32,32); Buf.pal[2]=TColor(64,64,64); Buf.pal[3]=TColor(96,96,96); Buf.pal[4]=TColor::LtBlue; Buf.pal[5]=TColor::LtRed; Buf.pal[6]=TColor::LtGreen; Buf.pal[7]=TColor::LtMagenta; Buf.pal[8]=TColor::LtCyan; Buf.pal[9]=TColor::LtYellow; Buf.pal[10]=TColor(0,0,128); Buf.pal[11]=TColor(128,0,0); Buf.pal[12]=TColor(0,128,0); Buf.pal[13]=TColor(128,0,128); Buf.pal[14]=TColor(0,128,128); Buf.pal[15]=TColor(128,128,0); Buf.pal[16]=TColor::White; Buf.pal[17]=TColor(255-32,255-32,255-32); Buf.pal[18]=TColor(255-64,255-64,255-64); Buf.pal[19]=TColor(255-96,255-96,255-96); Buf.pal[20]=TColor(0,128,255); Buf.pal[21]=TColor(255,128,128); Buf.pal[22]=TColor(128,255,128); Buf.pal[23]=TColor(255,128,255); Buf.pal[24]=TColor(128,255,255); Buf.pal[25]=TColor(255,255,128); Buf.pal[26]=TColor(0,0,128+64); Buf.pal[27]=TColor(128+64,0,0); Buf.pal[28]=TColor(0,128+64,0); Buf.pal[29]=TColor(128+64,0,128+64); Buf.pal[30]=TColor(0,128+64,128+64); Buf.pal[31]=TColor(128+64,128+64,0); //32-й и 33-й элементы хранят соответственно основной и побочный //цвета Buf.pal[32]=TColor::Black; Buf.pal[33]=TColor::White; Buf.line=1; Buf.style=0; AssignMenu(MENU_1); //Создаем панель палитры высотой в две кнопки. cbar=new TCBar(this,AS_MANY_AS_NEEDED,2); TButtonGadget *b; TSeparatorGadget *s; //Так как по сути наша панель палитры кнопок содержать не будет, //необходимо добавить в неё разделитель с размером нашей кнопки, //чтоб OWL смог определить размер панели. s=new TSeparatorGadget(28); cbar->Insert(*s); //Создаем панель инструментов и добавляем кнопки инструментов. tbox=new TToolBox(this); b=new TButtonGadget(BMP_LINE,CM_LINE,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Down); tbox->Insert(*b); b=new TButtonGadget(BMP_RECT,CM_RECT,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_ERA,CM_ERA,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_BID,CM_BID,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_PEN,CM_PEN,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_GET,CM_GET,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_ELL,CM_ELL,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_BR,CM_BR,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); //Разделитель не просто создает пустое пространство между //кнопками, он еще и разделяет группы эксклюзивных кнопок. //Таким образом в нашей панели инструментов будет три //одновременно нажатых кнопки - кнопка инструмента, кнопка //ширины линии и кнопка стиля заливки, несмотря на то, что все //они имеют стиль TButtonGadget::Exclusive. s=new TSeparatorGadget(24); tbox->Insert(*s); s=new TSeparatorGadget(24); tbox->Insert(*s); b=new TButtonGadget(BMP_L,CM_L,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Down); tbox->Insert(*b); b=new TButtonGadget(BMP_L+1,CM_L+1,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_L+2,CM_L+2,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); b=new TButtonGadget(BMP_L+3,CM_L+3,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); s=new TSeparatorGadget(24); tbox->Insert(*s); s=new TSeparatorGadget(24); tbox->Insert(*s); b=new TButtonGadget(BMP_RC,CM_RC,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Down); tbox->Insert(*b); b=new TButtonGadget(BMP_RC+1,CM_RC+1,TButtonGadget:: Exclusive,TRUE,TButtonGadget::Up); tbox->Insert(*b); //Вставляем панель инструментов и панель палитры. Insert(*cbar,TDecoratedFrame::Bottom); Insert(*tbox,TDecoratedFrame::Left); FileData=new TOpenSaveDialog::TData(OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, "Bitmap (*.bmp)|*.bmp|", 0, "", "bmp"); } //Деструктор главного окна TWndw::~TWndw() { delete tbox; delete cbar; } //Таблица откликов главного окна DEFINE_RESPONSE_TABLE1(TWndw,TDecoratedFrame) EV_COMMAND_AND_ID(CM_LINE,CmP), EV_COMMAND_AND_ID(CM_RECT,CmP), EV_COMMAND_AND_ID(CM_ERA,CmP), EV_COMMAND_AND_ID(CM_BID,CmP), EV_COMMAND_AND_ID(CM_PEN,CmP), EV_COMMAND_AND_ID(CM_GET,CmP), EV_COMMAND_AND_ID(CM_ELL,CmP), EV_COMMAND_AND_ID(CM_BR,CmP), EV_COMMAND_AND_ID(CM_L,CmLine), EV_COMMAND_AND_ID(CM_L+1,CmLine), EV_COMMAND_AND_ID(CM_L+2,CmLine), EV_COMMAND_AND_ID(CM_L+3,CmLine), EV_COMMAND_AND_ID(CM_RC,CmRc), EV_COMMAND_AND_ID(CM_RC+1,CmRc), EV_COMMAND(CM_NEW,CmNew), EV_COMMAND(CM_OPEN,CmOpen), EV_COMMAND(CM_SAVE,CmSave), EV_COMMAND(CM_SAVEAS,CmSaveAs), EV_COMMAND(CM_ATR,CmAtr), END_RESPONSE_TABLE; //Класс диалогового окна атрибутов. class TDlg:public TDialog { protected: TrBuf oldBuf; public: TDlg(TWindow *parent, TResId resld); protected: void SetupWindow(); BOOL CanClose(); void CmCancel(); DECLARE_RESPONSE_TABLE(TDlg); }; //Таблица откликов диалогового окна. DEFINE_RESPONSE_TABLE1(TDlg, TDialog) EV_COMMAND(IDCANCEL, CmCancel), END_RESPONSE_TABLE; //Конструктор диалогового окна. TDlg::TDlg(TWindow *parent,TResId resId):TDialog(parent,resId) { TEdit *edit; TValidator *valid; edit=new TEdit(this,IDC_WIDTH,sizeof(&Buf1.width)); valid = new TFilterValidator("0-9"); edit->SetValidator(valid); edit=new TEdit(this,IDC_HEIGHT,sizeof(&Buf1.height)); valid = new TFilterValidator("0-9"); edit->SetValidator(valid); TransferBuffer=&Buf1; TransferData(tdSetData); } //Инициализация диалогового окна. void TDlg::SetupWindow() { TDialog::SetupWindow(); memcpy(&oldBuf, &Buf1, sizeof(TrBuf)); } //Функция CanClose диалогового окна. BOOL TDlg::CanClose() { TDialog::CanClose(); TransferData(tdGetData); if ((strlen(Buf1.width)==0)||(strlen(Buf1.height)==0)) { MessageBox("Введите данные","Введите данные",MB_OK); return false; } else { return TRUE; } } //Функция, вызываемая при нажатии пользователем кнопки Cancel в //диалоговом окне. void TDlg::CmCancel() { memcpy(&Buf1, &oldBuf, sizeof(oldBuf)); TDialog::CmCancel(); } //Перерисовка главного окна. В общем-то не нужна. void TWndw::Paint(TDC&,BOOL,TRect&) { cbar->Invalidate(); } //Смена инструмента в главном окне void TWndw::CmP(WPARAM Id) { //Посылаем пользовательское сообщение окну-клиенту с индексом //нового инструмента в первом параметре ClientWnd->PostMessage(WM_CHANGEP,Id-200,0); } //Функция, вызываемая при смене толщины линии в панели //инструментов. void TWndw::CmLine(WPARAM Id) { Buf.line=Id-208; } //Функция смены стиля заливки в панели инструментов. void TWndw::CmRc(WPARAM Id) { Buf.style=Id-213; } //Функция, вызываемая при выборе пункта меню "Atributes". void TWndw::CmAtr() { //Посылаем пользовательское сообщение окну-клиенту. ClientWnd->PostMessage(WM_ATR,0,0); } //Функция клиентского окна, вызываемая при получении //пользовательского сообщения WM_ATR, то есть при выборе пункта //меню "Atributes". LRESULT TCWndw::WmAtr(WPARAM,LPARAM) { //Вызываем диалоговое окно атрибутов. int w,h; TClientDC dc(HWindow); TDialog *dialog = new TDlg(this, DIALOG_1); int result = dialog->Execute(); w=atoi(Buf1.width); h=atoi(Buf1.height); //Меняем размер рисунка в соответствии с новыми данными. TBitmap *pic1=new TBitmap(dc,w,h,0); TMemoryDC mdc(dc); mdc.SelectObject(*pic1); TRect r=mdc.GetClipBox(); TBrush b(TColor::White); TPen p(TColor::White,1,PS_SOLID); mdc.SelectObject(p); mdc.SelectObject(b); mdc.Rectangle(r); mdc.BitBlt(0,0,pic->Width(),pic->Height(),dc,0,0); delete pic; pic=pic1; dc.BitBlt(0,0,w,h,mdc,0,0); Invalidate(); return 1; } //Функция, вызываемая при выборе пункта меню "New" в главном //окне. void TWndw::CmNew() { strcpy(Buf.file,""); ClientWnd->PostMessage(WM_NEW,0,0); } //Функция, вызываемая при выборе пункта меню "Save" в главном //окне. void TWndw::CmSave() { if (strlen(Buf.file)!=0) ClientWnd->PostMessage(WM_SAVE,0,0); else if (TFileSaveDialog(this,*FileData,0,"Saving bitmap file").DoExecute()==IDOK) { Buf.file=new char[80]; strcpy(Buf.file,FileData->FileName); ClientWnd->PostMessage(WM_SAVE,0,0); } } //Функция, вызываемая при выборе пункта меню "Save as" в главном //окне. void TWndw::CmSaveAs() { if (TFileSaveDialog(this,*FileData,0,"Saving bitmap file as...").DoExecute()==IDOK) { Buf.file=new char[80]; strcpy(Buf.file,FileData->FileName); ClientWnd->PostMessage(WM_SAVE,0,0); } } //Функция, вызываемая при выборе пункта меню "Open" в главном //окне. void TWndw::CmOpen() { if (TFileOpenDialog(this,*FileData,0,"Opening bitmap file").Execute()==IDOK) { Buf.file=new char[80]; strcpy(Buf.file,FileData->FileName); ClientWnd->PostMessage(WM_OPEN,0,0); } } //Функция смены инструмента в окне-клиенте. Индекс инструмента //передаётся в параметре Id. LRESULT TCWndw::WmChangeP(WPARAM Id,LPARAM) { idp=Id; return 1; } //Функция, вызываема при выборе пункта меню "New" в окне- //клиенте LRESULT TCWndw::WmNew(WPARAM,LPARAM) { //Очищаем pic и перерисовываем клиентское окно. TClientDC dc(HWindow); TBrush b(TColor::White); TPen p(TColor::White,1,PS_SOLID); TRect rrr=dc.GetClipBox(); TMemoryDC mdc(dc); mdc.SelectObject(*pic); mdc.SelectObject(p); mdc.SelectObject(b); mdc.Rectangle(rrr); dc.BitBlt(0,0,rrr.Width(),rrr.Height(),mdc,0,0); Invalidate(); } //Функция, вызываемая при выборе пункта меню "Save" в окне- //клиенте LRESULT TCWndw::WmSave(WPARAM,LPARAM) { //Вычисляем количество байт, необходимое для хранения одной //строки рисунка. BMP-рисунки различаются количеством бит, //необходимых для сохранения одного пикселя. Это может быть 1-х //битный (2-хцветный), 4-х битный (16-тицветный), 8-ми битный //(256-тицветный), 16-ти битный, 24-х битный или 32-х битный //рисунок. Наша программа будет сохранять рисунки только в одном //из типов BMP-рисунков - в 24-х битном. Но так как длина строки //рисунка должна быть кратна длине параграфа, получим следующую //формулу: int bytePerLine = ((pic->Width() *24 + 31) / 32) * 4; //Вычисляем количество байт, необходимых для хранения всего //рисунка. int bytePerImage = bytePerLine*pic->Height(); FILE *f=fopen(Buf.file,"wb"); TClientDC dc(HWindow); TMemoryDC mdc(dc); mdc.SelectObject(*pic); //BMP-файл состоит из четырёх частей: заголовок файла, //информация о рисунке, палитра и собственно сам массив //пикселей. Чтобы сохранить рисунок в BMP-файл нам придётся //заполнить все эти части, кроме палитры, так как в 24-х //битных BMP-рисунках палитра не используется. Для хранения //заголовка BMP-файла в OWL существует структура //BITMAPFILEHEADER. BITMAPFILEHEADER* fheader=new BITMAPFILEHEADER; //Поле bfType структуры BITMAPFILEHEADER содержит тип файла, и в //BMP-файле должно содержать "BM". В шестнадцатеричном виде это //424D, в десятичном - 19778. fheader->bfType=19778; //Поле bfSize содержит размер файла в байтах. fheader->bfSize=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER)+bytePerImage; //Поля bfReserved1 и bfReserved2 должны быть пустыми. fheader->bfReserved1=0; fheader->bfReserved2=0; //Поле bfOffBits содержит отступ от начала файла до начала //массива пикселей в байтах. fheader->bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER); fwrite(fheader,sizeof(BITMAPFILEHEADER),1,f); //Для хранения информации о изображении в OWL существует //структура BITMAPINFOHEADER. BITMAPINFOHEADER* iheader=new BITMAPINFOHEADER; //Поле biSize структуры BITMAPINFOHEADER должно содержать размер //самой структуры. iheader->biSize=sizeof(BITMAPINFOHEADER); //Поля biWidth и biHeight должны содержать соответственно ширину //и высоту изображения. iheader->biWidth=pic->Width(); iheader->biHeight=pic->Height(); //Поле biPlanes хранит количество плоскостей изображения. Всегда //должно содержать единицу. iheader->biPlanes=1; //Количество бит на один пиксель. В нашем случае - 24. iheader->biBitCount=24; //Сжатие. В нашем случае не используется, поэтому приравнивается //BI_RGB. iheader->biCompression=BI_RGB; //Размер массива пикселей в байтах. iheader->biSizeImage=bytePerImage; //Указывает горизонтальное и вертикальное соответственно //разрешение в пикселях на метр для целевого устройства. //Стандарт - 2834 пикселя на метр. iheader->biXPelsPerMeter=2834; iheader->biYPelsPerMeter=2834; //Количество используемых цветов и количество важных цветов. У //нас изображение не содержит палитру, поэтому оба значения //равны нулю. iheader->biClrUsed=0; iheader->biClrImportant=0; fwrite(iheader,sizeof(BITMAPINFOHEADER),1,f); //Выделяем память для изображения. unsigned char *imageData; imageData=(unsigned char*)malloc(bytePerImage); TColor col; //Структура BITMAPINFO содержит два поля: bmiHeader - структура //типа BITMAPINFOHEADER и bmiColors - структура типа RGBQUAD, //палитра. Палитра пуста, а информацию о изображении мы уже //заполнили. BITMAPINFO BI; BI.bmiHeader=*iheader; //Функция GetDIBits извлекает биты заданного совместимого точечного рисунка //и копирует их в буфер как DIB(аппаратно-независимый растр), //используя заданный формат. mdc.GetDIBits( *pic,//рисунок 0,// первая устанавливаемая строка развертки pic->Height(),//количество строк развертки imageData, //массив для битов рисунка BI, //структура данных рисунка DIB_RGB_COLORS//индексы RGB или палитры ); fwrite(imageData,bytePerImage,1,f); fclose(f); delete fheader,iheader; free(imageData); delete imageData; return 1; } //Функция, вызываемая при выборе пункта меню "Save" в окне- //клиенте LRESULT TCWndw::WmOpen(WPARAM,LPARAM) { FILE* f=fopen(Buf.file,"r"); //Считываем из файла заголовок файла и информацию о изображении. BITMAPFILEHEADER* fheader=new BITMAPFILEHEADER; fread(fheader, sizeof(BITMAPFILEHEADER), 1, f); BITMAPINFOHEADER* iheader=new BITMAPINFOHEADER; fread(iheader, sizeof(BITMAPINFOHEADER), 1, f); //Наш графический редактор будет открывать BMP-изображения 4-х //разных типов: 1-но, 4-х, 8-ми и 24-х битные. Первые три типа - //палитровые, то есть их палитра не пуста, а пиксельный массив //содержит индексы цветов в палитре. Палитра располагается в //файле между информацией о изображении и пиксельным массивом, //но здесь это не имеет значения. Важно то, что //палитровые изображения мы будем открывать одним способом, а //беспалитровые - другим. if (iheader->biBitCount==8||iheader->biBitCount==4||iheader->biBitCount==1) { fclose(f); //Создаём аппаратно-независимый растр из файла. После имени //файла в конструкторе должен следовать указатель на палитру //TPalette, но у нас он не указан, значит равен нулю, а в этом //случае используется палитра по умолчанию. TDib DIB(Buf.file); TClientDC dc(HWindow); TMemoryDC mdc(dc); //Удаляем старое изображение. delete pic; //Создаём новое изображение из нашего аппаратно-независимого //растра с палитрой по умолчанию. pic=new TBitmap(DIB,0); mdc.SelectObject(*pic); dc.BitBlt(1,1,pic->Width(),pic->Height(),mdc,0,0); } if (iheader->biBitCount==24) { //Переходим к началу пиксельного массива. fseek(f,fheader->bfOffBits,SEEK_SET); TClientDC dc(HWindow); //Удаляем старое изображение. delete pic; //Создаём новое по размерам, взятым из структуры информации о //изображении файла. pic=new TBitmap(dc,iheader->biWidth,iheader->biHeight,true); TMemoryDC mdc(dc); mdc.SelectObject(*pic); //Вычисляем количество байт, которые необходимо прибавить к //длине строки изображения, чтобы она была кратна параграфу. int g=iheader->biWidth%4; //Выделяем память для изображения. unsigned char *imageData; imageData=(unsigned char *) malloc((iheader->biWidth+g)*iheader->biHeight*24); //Считываем изображение из файла. fread(imageData,1,(iheader->biWidth+g)*iheader->biHeight*24,f); BITMAPINFO BI; BI.bmiHeader=*iheader; //Функция SetDIBits устанавливает пиксели в совместимом точечном //рисунке (DDB), используя данные о цвете, найденные в заданном //аппаратно-независимом растровом формате (DIB). mdc.SetDIBits( *pic, //рисунок. 0, //начальная строка развертки. iheader->biHeight, //число строк развертки. imageData, //битовый массив рисунка. BI, //данные рисунка. DIB_RGB_COLORS//тип используемых индексов цвета. ); dc.BitBlt(0,0,pic->Width(),pic->Height(),mdc,0,0); fclose(f); free(imageData); delete imageData; } //Сохраняем размеры нового изображения в буфер Buf1. itoa(pic->Width(),Buf1.width,10); itoa(pic->Height(),Buf1.height,10); Invalidate(); delete iheader,fheader; return 1; } //Перерисовка клиентского окна. void TCWndw::Paint(TDC&DC,BOOL,TRect&) { //Сначала заливаем всё серым. TBrush *b=new TBrush(TColor::LtGray); TPen *p=new TPen(TColor::LtGray,1,PS_SOLID); DC.SelectObject(*b); DC.SelectObject(*p); TRect r=DC.GetClipBox(); DC.Rectangle(r); //Затем выводим наше изображение. TMemoryDC mdc(DC); mdc.SelectObject(*pic); DC.BitBlt(0,0,pic->Width(),pic->Height(),mdc,0,0); //Теперь нарисуем три красных квадратика, которые будут //показывать границу изображения. delete b,p; b=new TBrush(TColor::LtRed); p=new TPen(TColor::LtRed,1,PS_SOLID); DC.SelectObject(*b); DC.SelectObject(*p); int x,y; x=pic->Width(); y=pic->Height()/2; DC.Rectangle(x,y,x+2,y+2); x=pic->Width()/2; y=pic->Height(); DC.Rectangle(x,y,x+2,y+2); x=pic->Width(); y=pic->Height(); DC.Rectangle(x,y,x+2,y+2); delete b,p; } //Нажатие левой кнопки мыши в окне-клиенте. void TCWndw::EvLButtonDown(UINT,TPoint&point) { //Если инструмент - заливка if (idp==4) { TClientDC dc(HWindow); TMemoryDC mdc(dc); mdc.SelectObject(*pic); mdc.SelectObject(TBrush(Buf.pal[32])); mdc.ExtFloodFill(point,dc.GetPixel(point),FLOODFILLSURFACE); dc.BitBlt(0,0,pic->Width(),pic->Height(),mdc,0,0); } else //Если инструмент - пипетка if (idp==6) { TClientDC dc(HWindow); Buf.pal[32]=dc.GetPixel(point); //Вызываем перерисовку главного окна, которая в свою очередь //перерисовывает панель палитры. Parent->Invalidate(); } else //Любой другой инструмент. { //Запоминаем точку нажатия. pp=point; //Указываем в pressed, что нажата левая кнопка мыши. pressed=1; //Захватываем все события от мыши в клиентское окно. SetCapture(); } } //Левая кнопка мыши в окне-клиенте отпущена void TCWndw::EvLButtonUp(UINT,TPoint&point) { //Сохраним изменения в изображение pic. TClientDC dc(HWindow); TMemoryDC mdc(dc); TRect r; r=dc.GetClipBox(); mdc.SelectObject(*pic); int w,h; //Если вдруг окажется, что наше изображение больше контекстного //устройства клиентского окна, то ту часть изображения, которая //осталась "за кадром", мы перерисовывать не будем. if (pic->Width()<=r.Width()) w=pic->Width(); else w=r.Width(); if (pic->Height()<=r.Height()) h=pic->Height(); else h=r.Height(); mdc.BitBlt(0,0,w,h,dc,0,0); //Кнопки мыши не нажаты. pressed=0; //Отпускаем захват событий мыши. ReleaseCapture(); } //Нажатие правой кнопки мыши в окне-клиенте. Аналогично левой. void TCWndw::EvRButtonDown(UINT,TPoint&point) { // TClientDC dc(HWindow); // TMemoryDC mdc(dc); // mdc.SelectObject(*pic); if (idp==4) { TClientDC dc(HWindow); TMemoryDC mdc(dc); mdc.SelectObject(*pic); mdc.SelectObject(TBrush(Buf.pal[33])); mdc.ExtFloodFill(point,dc.GetPixel(point),FLOODFILLSURFACE); dc.BitBlt(0,0,pic->Width(),pic->Height(),mdc,0,0); } else if (idp==6) { TClientDC dc(HWindow); Buf.pal[33]=dc.GetPixel(point); Parent->Invalidate(); } else { pp=point; pressed=2; SetCapture(); } } //Правая кнопка мыши в окне-клиенте отпущена. Аналогично левой. void TCWndw::EvRButtonUp(UINT,TPoint&point) { TClientDC dc(HWindow); TMemoryDC mdc(dc); TRect r; r=dc.GetClipBox(); mdc.SelectObject(*pic); int w,h; if (pic->Width()<=r.Width()) w=pic->Width(); else w=r.Width(); if (pic->Height()<=r.Height()) h=pic->Height(); else h=r.Height(); mdc.BitBlt(0,0,w,h,dc,0,0); pressed=0; ReleaseCapture(); } //Мышь движется в клиентском окне. void TCWndw::EvMouseMove(UINT,TPoint&point) { //Если правая или левая кнопка мыши нажата. if (pressed>0) { TClientDC dc(HWindow); TMemoryDC mdc(dc); TBitmap *pic1=new TBitmap(dc,pic->Width(),pic->Height(),false); mdc.SelectObject(*pic1); mdc.BitBlt(0,0,pic->Width(),pic->Height(),dc,0,0); Paint(mdc,0,mdc.GetClipBox()); //Выберем перо в зависимости от нажатой кнопки мыши и заданной //ширины линии. mdc.SelectObject(TPen(Buf.pal[32+pressed-1],Buf.line,PS_SOLID)); //Если инструмент - прямая. if (idp==1) { mdc.MoveTo(pp); mdc.LineTo(point); } //Если инструмент - прямоугольник. if (idp==2) { //Если стиль заливки - прозрачный. if (Buf.style==0) { mdc.MoveTo(pp); mdc.LineTo(pp.x,point.y); mdc.LineTo(point); mdc.LineTo(point.x,pp.y); mdc.LineTo(pp); } else { mdc.SelectObject(TBrush(Buf.pal[33-pressed+1])); mdc.SelectObject(TPen(Buf.pal[32+pressed-1], Buf.line,PS_SOLID)); mdc.Rectangle(pp,point); } } //Если инструмент - ластик. if (idp==3) { mdc.SelectObject(*pic); mdc.SelectObject(TBrush(Buf.pal[33])); mdc.SelectObject(TPen(Buf.pal[33],1,PS_SOLID)); mdc.Rectangle(point.x,point.y,point.x+10,point.y+10); } //Если инструмент - карандаш. if (idp==5) { mdc.SelectObject(*pic); mdc.MoveTo(pp); pp=point; mdc.LineTo(point); } //Если инструмент - эллипс. if (idp==7) { mdc.SelectObject(TBrush(Buf.pal[33-pressed+1])); mdc.SelectObject(TPen(Buf.pal[32+pressed-1],Buf.line,PS_SOLID)); //Если стиль заливки - прозрачный, выбираем пустую кисть. if (Buf.style==0) mdc.SelectObject(TBrush((HBRUSH) GetStockObject(NULL_BRUSH))); mdc.Ellipse(pp,point); } //Если инструмент - кисть. if (idp==8) { mdc.SelectObject(TPen(Buf.pal[32+pressed-1],5,PS_SOLID)); mdc.SelectObject(*pic); mdc.MoveTo(pp); pp=point; mdc.LineTo(point); } dc.BitBlt(0,0,pic->Width(),pic->Height(),mdc,0,0); delete pic1; } } //Установка главного окна приложения. void TApp::InitMainWindow() { TWindow *client = new TCWndw (0, 0); TDecoratedFrame *frame = new TWndw (0,"Графический редактор", client); SetMainWindow(frame); } //Запуск приложения. int OwlMain(int,char *[]) { return TApp().Run(); }
Файл ресурсов:
#ifndef WORKSHOP_INVOKED #include "windows.h" #endif #define DIALOG_1 1 #define MENU_1 2 #define CM_OPEN 100 #define CM_ATR 101 #define CM_SAVE 102 #define CM_SAVEAS 103 #define CM_NEW 104 #define BMP_LINE 105 #define BMP_RECT 106 #define BMP_ERA 107 #define BMP_BID 108 #define BMP_PEN 109 #define BMP_GET 110 #define BMP_ELL 111 #define BMP_BR 112 #define BMP_L 113 #define BMP_L2 114 #define BMP_L3 115 #define BMP_L4 116 #define BMP_RC 117 #define BMP_RC2 118 #define BMP_CLR 125 #define CM_LINE 201 #define CM_RECT 202 #define CM_ERA 203 #define CM_BID 204 #define CM_PEN 205 #define CM_GET 206 #define CM_ELL 207 #define CM_BR 208 #define CM_L 209//212 #define CM_RC 213//214 #define CM_CHCOLOR 250//282 #define IDC_WIDTH 301 #define IDC_HEIGHT 302 #define CM_EXIT 24310 #define WM_CHANGEP WM_USER #define WM_OPEN WM_USER+1 #define WM_SAVE WM_USER+2 #define WM_ATR WM_USER+3 #define WM_NEW WM_USER+4 #ifdef RC_INVOKED BMP_LINE BITMAP { '42 4D 76 06 00 00 00 00 00 00 36 04 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 08 00 00 00' '00 00 40 02 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 00 20' '40 00 00 20 60 00 00 20 80 00 00 20 A0 00 00 20' 'C0 00 00 20 E0 00 00 40 00 00 00 40 20 00 00 40' '40 00 00 40 60 00 00 40 80 00 00 40 A0 00 00 40' 'C0 00 00 40 E0 00 00 60 00 00 00 60 20 00 00 60' '40 00 00 60 60 00 00 60 80 00 00 60 A0 00 00 60' 'C0 00 00 60 E0 00 00 80 00 00 00 80 20 00 00 80' '40 00 00 80 60 00 00 80 80 00 00 80 A0 00 00 80' 'C0 00 00 80 E0 00 00 A0 00 00 00 A0 20 00 00 A0' '40 00 00 A0 60 00 00 A0 80 00 00 A0 A0 00 00 A0' 'C0 00 00 A0 E0 00 00 C0 00 00 00 C0 20 00 00 C0' '40 00 00 C0 60 00 00 C0 80 00 00 C0 A0 00 00 C0' 'C0 00 00 C0 E0 00 00 E0 00 00 00 E0 20 00 00 E0' '40 00 00 E0 60 00 00 E0 80 00 00 E0 A0 00 00 E0' 'C0 00 00 E0 E0 00 40 00 00 00 40 00 20 00 40 00' '40 00 40 00 60 00 40 00 80 00 40 00 A0 00 40 00' 'C0 00 40 00 E0 00 40 20 00 00 40 20 20 00 40 20' '40 00 40 20 60 00 40 20 80 00 40 20 A0 00 40 20' 'C0 00 40 20 E0 00 40 40 00 00 40 40 20 00 40 40' '40 00 40 40 60 00 40 40 80 00 40 40 A0 00 40 40' 'C0 00 40 40 E0 00 40 60 00 00 40 60 20 00 40 60' '40 00 40 60 60 00 40 60 80 00 40 60 A0 00 40 60' 'C0 00 40 60 E0 00 40 80 00 00 40 80 20 00 40 80' '40 00 40 80 60 00 40 80 80 00 40 80 A0 00 40 80' 'C0 00 40 80 E0 00 40 A0 00 00 40 A0 20 00 40 A0' '40 00 40 A0 60 00 40 A0 80 00 40 A0 A0 00 40 A0' 'C0 00 40 A0 E0 00 40 C0 00 00 40 C0 20 00 40 C0' '40 00 40 C0 60 00 40 C0 80 00 40 C0 A0 00 40 C0' 'C0 00 40 C0 E0 00 40 E0 00 00 40 E0 20 00 40 E0' '40 00 40 E0 60 00 40 E0 80 00 40 E0 A0 00 40 E0' 'C0 00 40 E0 E0 00 80 00 00 00 80 00 20 00 80 00' '40 00 80 00 60 00 80 00 80 00 80 00 A0 00 80 00' 'C0 00 80 00 E0 00 80 20 00 00 80 20 20 00 80 20' '40 00 80 20 60 00 80 20 80 00 80 20 A0 00 80 20' 'C0 00 80 20 E0 00 80 40 00 00 80 40 20 00 80 40' '40 00 80 40 60 00 80 40 80 00 80 40 A0 00 80 40' 'C0 00 80 40 E0 00 80 60 00 00 80 60 20 00 80 60' '40 00 80 60 60 00 80 60 80 00 80 60 A0 00 80 60' 'C0 00 80 60 E0 00 80 80 00 00 80 80 20 00 80 80' '40 00 80 80 60 00 80 80 80 00 80 80 A0 00 80 80' 'C0 00 80 80 E0 00 80 A0 00 00 80 A0 20 00 80 A0' '40 00 80 A0 60 00 80 A0 80 00 80 A0 A0 00 80 A0' 'C0 00 80 A0 E0 00 80 C0 00 00 80 C0 20 00 80 C0' '40 00 80 C0 60 00 80 C0 80 00 80 C0 A0 00 80 C0' 'C0 00 80 C0 E0 00 80 E0 00 00 80 E0 20 00 80 E0' '40 00 80 E0 60 00 80 E0 80 00 80 E0 A0 00 80 E0' 'C0 00 80 E0 E0 00 C0 00 00 00 C0 00 20 00 C0 00' '40 00 C0 00 60 00 C0 00 80 00 C0 00 A0 00 C0 00' 'C0 00 C0 00 E0 00 C0 20 00 00 C0 20 20 00 C0 20' '40 00 C0 20 60 00 C0 20 80 00 C0 20 A0 00 C0 20' 'C0 00 C0 20 E0 00 C0 40 00 00 C0 40 20 00 C0 40' '40 00 C0 40 60 00 C0 40 80 00 C0 40 A0 00 C0 40' 'C0 00 C0 40 E0 00 C0 60 00 00 C0 60 20 00 C0 60' '40 00 C0 60 60 00 C0 60 80 00 C0 60 A0 00 C0 60' 'C0 00 C0 60 E0 00 C0 80 00 00 C0 80 20 00 C0 80' '40 00 C0 80 60 00 C0 80 80 00 C0 80 A0 00 C0 80' 'C0 00 C0 80 E0 00 C0 A0 00 00 C0 A0 20 00 C0 A0' '40 00 C0 A0 60 00 C0 A0 80 00 C0 A0 A0 00 C0 A0' 'C0 00 C0 A0 E0 00 C0 C0 00 00 C0 C0 20 00 C0 C0' '40 00 C0 C0 60 00 C0 C0 80 00 C0 C0 A0 00 F0 FB' 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 00 FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00' '00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF 00 00 FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF 00 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF 00 00 FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' '00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF 00 00 FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF 00 00 FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF 00 00 FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF 00 00 FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF 00 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } MENU_1 MENU { POPUP "File" { MENUITEM "New", CM_NEW MENUITEM "Open", CM_OPEN MENUITEM "Save", CM_SAVE MENUITEM "Save as...", CM_SAVEAS MENUITEM SEPARATOR MENUITEM "Exit", CM_EXIT } POPUP "Picture" { MENUITEM "Atributes", CM_ATR } } DIALOG_1 DIALOG 6, 15, 143, 86 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION CAPTION "Atributes" FONT 8, "MS Sans Serif" { DEFPUSHBUTTON "OK", IDOK, 12, 64, 52, 14 PUSHBUTTON "Cancel", IDCANCEL, 80, 64, 52, 14 LTEXT "Width", -1, 16, 16, 24, 12 LTEXT "Height", -1, 16, 40, 24, 12 EDITTEXT IDC_WIDTH, 48, 12, 84, 12, WS_BORDER | WS_TABSTOP EDITTEXT IDC_HEIGHT, 48, 36, 84, 12, WS_BORDER | WS_TABSTOP } BMP_RECT BITMAP { '42 4D 76 06 00 00 00 00 00 00 36 04 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 08 00 00 00' '00 00 40 02 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 00 20' '40 00 00 20 60 00 00 20 80 00 00 20 A0 00 00 20' 'C0 00 00 20 E0 00 00 40 00 00 00 40 20 00 00 40' '40 00 00 40 60 00 00 40 80 00 00 40 A0 00 00 40' 'C0 00 00 40 E0 00 00 60 00 00 00 60 20 00 00 60' '40 00 00 60 60 00 00 60 80 00 00 60 A0 00 00 60' 'C0 00 00 60 E0 00 00 80 00 00 00 80 20 00 00 80' '40 00 00 80 60 00 00 80 80 00 00 80 A0 00 00 80' 'C0 00 00 80 E0 00 00 A0 00 00 00 A0 20 00 00 A0' '40 00 00 A0 60 00 00 A0 80 00 00 A0 A0 00 00 A0' 'C0 00 00 A0 E0 00 00 C0 00 00 00 C0 20 00 00 C0' '40 00 00 C0 60 00 00 C0 80 00 00 C0 A0 00 00 C0' 'C0 00 00 C0 E0 00 00 E0 00 00 00 E0 20 00 00 E0' '40 00 00 E0 60 00 00 E0 80 00 00 E0 A0 00 00 E0' 'C0 00 00 E0 E0 00 40 00 00 00 40 00 20 00 40 00' '40 00 40 00 60 00 40 00 80 00 40 00 A0 00 40 00' 'C0 00 40 00 E0 00 40 20 00 00 40 20 20 00 40 20' '40 00 40 20 60 00 40 20 80 00 40 20 A0 00 40 20' 'C0 00 40 20 E0 00 40 40 00 00 40 40 20 00 40 40' '40 00 40 40 60 00 40 40 80 00 40 40 A0 00 40 40' 'C0 00 40 40 E0 00 40 60 00 00 40 60 20 00 40 60' '40 00 40 60 60 00 40 60 80 00 40 60 A0 00 40 60' 'C0 00 40 60 E0 00 40 80 00 00 40 80 20 00 40 80' '40 00 40 80 60 00 40 80 80 00 40 80 A0 00 40 80' 'C0 00 40 80 E0 00 40 A0 00 00 40 A0 20 00 40 A0' '40 00 40 A0 60 00 40 A0 80 00 40 A0 A0 00 40 A0' 'C0 00 40 A0 E0 00 40 C0 00 00 40 C0 20 00 40 C0' '40 00 40 C0 60 00 40 C0 80 00 40 C0 A0 00 40 C0' 'C0 00 40 C0 E0 00 40 E0 00 00 40 E0 20 00 40 E0' '40 00 40 E0 60 00 40 E0 80 00 40 E0 A0 00 40 E0' 'C0 00 40 E0 E0 00 80 00 00 00 80 00 20 00 80 00' '40 00 80 00 60 00 80 00 80 00 80 00 A0 00 80 00' 'C0 00 80 00 E0 00 80 20 00 00 80 20 20 00 80 20' '40 00 80 20 60 00 80 20 80 00 80 20 A0 00 80 20' 'C0 00 80 20 E0 00 80 40 00 00 80 40 20 00 80 40' '40 00 80 40 60 00 80 40 80 00 80 40 A0 00 80 40' 'C0 00 80 40 E0 00 80 60 00 00 80 60 20 00 80 60' '40 00 80 60 60 00 80 60 80 00 80 60 A0 00 80 60' 'C0 00 80 60 E0 00 80 80 00 00 80 80 20 00 80 80' '40 00 80 80 60 00 80 80 80 00 80 80 A0 00 80 80' 'C0 00 80 80 E0 00 80 A0 00 00 80 A0 20 00 80 A0' '40 00 80 A0 60 00 80 A0 80 00 80 A0 A0 00 80 A0' 'C0 00 80 A0 E0 00 80 C0 00 00 80 C0 20 00 80 C0' '40 00 80 C0 60 00 80 C0 80 00 80 C0 A0 00 80 C0' 'C0 00 80 C0 E0 00 80 E0 00 00 80 E0 20 00 80 E0' '40 00 80 E0 60 00 80 E0 80 00 80 E0 A0 00 80 E0' 'C0 00 80 E0 E0 00 C0 00 00 00 C0 00 20 00 C0 00' '40 00 C0 00 60 00 C0 00 80 00 C0 00 A0 00 C0 00' 'C0 00 C0 00 E0 00 C0 20 00 00 C0 20 20 00 C0 20' '40 00 C0 20 60 00 C0 20 80 00 C0 20 A0 00 C0 20' 'C0 00 C0 20 E0 00 C0 40 00 00 C0 40 20 00 C0 40' '40 00 C0 40 60 00 C0 40 80 00 C0 40 A0 00 C0 40' 'C0 00 C0 40 E0 00 C0 60 00 00 C0 60 20 00 C0 60' '40 00 C0 60 60 00 C0 60 80 00 C0 60 A0 00 C0 60' 'C0 00 C0 60 E0 00 C0 80 00 00 C0 80 20 00 C0 80' '40 00 C0 80 60 00 C0 80 80 00 C0 80 A0 00 C0 80' 'C0 00 C0 80 E0 00 C0 A0 00 00 C0 A0 20 00 C0 A0' '40 00 C0 A0 60 00 C0 A0 80 00 C0 A0 A0 00 C0 A0' 'C0 00 C0 A0 E0 00 C0 C0 00 00 C0 C0 20 00 C0 C0' '40 00 C0 C0 60 00 C0 C0 80 00 C0 C0 A0 00 F0 FB' 'FF 00 A4 A0 A0 00 80 80 80 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF' 'FF FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF' 'FF FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF' 'FF FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF' 'FF FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF' 'FF FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF' 'FF FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF' 'FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF' 'FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } BMP_CLR BITMAP { '42 4D 9E 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 01 00 00 00' '00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00' } BMP_ERA BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF F0 FF FF FF FF FF FF FF FF' 'FF FF FF 00 0F FF FF FF FF FF FF FF FF FF 00 B0' '30 FF FF FF FF FF FF FF FF F0 BB B0 33 0F FF FF' 'FF FF FF FF FF F0 BB B0 33 30 FF FF FF FF FF FF' 'FF F0 B0 0B 03 33 0F FF FF FF FF FF FF F0 00 BB' 'B0 33 30 FF FF FF FF FF FF FF 0B BB BB 03 30 FF' 'FF FF FF FF FF FF F0 BB BB B0 30 FF FF FF FF FF' 'FF FF FF 0B BB BB 00 FF FF FF FF FF FF FF FF F0' 'BB BB B0 FF FF FF FF FF FF FF FF FF 0B B0 0F FF' 'FF FF FF FF FF FF FF FF F0 0F FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } BMP_BID BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF F0 00 0F FF FF FF FF FF' 'FF 9F FF FF 00 11 00 FF FF FF FF FF F9 9F FF FF' '01 11 11 00 FF FF FF FF F9 9F FF F0 11 11 11 10' 'FF FF FF FF F9 9F FF 00 11 11 11 10 FF FF FF FF' 'F9 9F FF 01 11 11 11 00 FF FF FF FF 99 9F F0 01' '11 11 10 0F FF FF FF FF 99 9F 00 11 11 11 10 FF' 'FF FF FF FF 99 99 01 11 11 11 00 FF FF FF FF FF' 'F9 99 90 01 11 10 0F FF FF FF FF FF F9 99 99 00' '11 10 FF FF FF FF FF FF F0 09 99 99 01 0F FF FF' 'FF FF FF FF F0 FF 09 99 00 0F FF FF FF FF FF FF' 'F0 FF F0 00 00 FF FF FF FF FF FF FF F0 0F FF F0' '0F FF FF FF FF FF FF FF FF 00 FF 00 FF FF FF FF' 'FF FF FF FF FF FF 00 FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } BMP_PEN BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF 77 77 FF FF FF FF FF FF FF FF FF FF 77 00 FF' 'FF FF FF FF FF FF FF FF FF 70 BB 0F FF FF FF FF' 'FF FF FF FF FF F0 BB 0F FF FF FF FF FF FF FF FF' 'FF F0 BB B0 FF FF FF FF FF FF FF FF FF FF 0B B0' 'FF FF FF FF FF FF FF FF FF FF 0B BB 0F FF FF FF' 'FF FF FF FF FF FF F0 BB 0F FF FF FF FF FF FF FF' 'FF FF F0 BB B0 FF FF FF FF FF FF FF FF FF FF 0B' 'B0 FF FF FF FF FF FF FF FF FF FF 0B BB 0F FF FF' 'FF FF FF FF FF FF FF F0 BB 0F FF FF FF FF FF FF' 'FF FF FF F0 BB 00 FF FF FF FF FF FF FF FF FF FF' '00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } BMP_GET BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 99 99 99 99 FF FF FF FF FF FF' 'FF FF 99 99 99 99 99 99 99 FF FF FF FF FF 99 99' 'EE E9 99 99 99 9F FF FF FF FF 99 9E E9 9E 99 99' '99 9F FF FF FF FF F9 9E 99 99 E9 99 99 FF FF FF' 'FF FF F9 9E 99 99 9E FF FF FF FF FF FF FF FF FF' 'E9 99 99 EF FF FF FF FF FF FF FF FF FE 99 99 9E' 'FF FF FF FF FF FF FF FF FF E9 99 FF EF FF FF FF' 'FF FF FF FF FF FE 9F FF FE FF FF FF FF FF FF FF' 'FF FF EF FF FF EF FF F0 FF FF FF FF FF FF FE FF' 'FF FE FF 00 0F FF FF FF FF FF FF EF FF FF E0 00' '0F FF FF FF FF FF FF FE FF FF 00 0F FF FF FF FF' 'FF FF FF FF EF F0 00 00 FF FF FF FF FF FF FF FF' 'FE 00 00 00 0F FF FF FF FF FF FF FF F0 00 00 00' '00 FF FF FF FF FF FF FF 00 00 00 00 00 0F FF FF' 'FF FF FF F0 00 00 00 00 00 00 FF FF FF FF FF FF' '00 F0 00 00 00 00 FF FF FF FF FF FF FF FF 00 00' '00 00 FF FF FF FF FF FF FF FF F0 0F F0 00 FF FF' 'FF FF FF FF FF FF FF 00 00 0F FF FF FF FF FF FF' 'FF FF FF F0 00 FF' } BMP_ELL BITMAP { '42 4D 9E 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 01 00 00 00' '00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF C3 FF 00 FE 3C' '7F 00 FD FF BF 00 FB FF DF 00 F7 FF EF 00 F7 FF' 'EF 00 F7 FF EF 00 EF FF F7 00 EF FF F7 00 EF FF' 'F7 00 EF FF F7 00 F7 FF EF 00 F7 FF EF 00 F7 FF' 'EF 00 FB FF DF 00 FD FF BF 00 FE 3C 7F 00 FF C3' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00' } BMP_BR BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF F0 00 00 FF FF FF FF' 'FF F0 00 00 00 09 99 90 FF FF 00 00 00 09 99 99' '99 99 99 99 0F FF F0 00 00 09 99 99 99 90 00 00' '0F FF FF 00 99 00 00 00 00 09 99 99 90 FF FF F0' '99 99 09 99 99 99 00 00 00 FF FF F0 99 99 00 00' '00 00 FF FF FF FF FF F0 99 99 90 FF FF FF FF FF' 'FF FF FF F0 09 99 00 FF FF FF FF FF FF FF FF FF' '00 00 00 00 0F FF FF FF FF FF FF FF FF FF 03 33' '30 0F FF FF FF FF FF FF FF FF 03 33 33 30 0F FF' 'FF FF FF FF FF FF F0 33 33 33 30 FF FF FF FF FF' 'FF FF F0 33 33 33 33 0F FF FF FF FF FF FF FF 03' '33 33 33 30 FF FF FF FF FF FF FF F0 33 33 33 33' '0F FF FF FF FF FF FF FF 03 33 33 33 30 FF FF FF' 'FF FF FF FF F0 33 33 33 30 FF FF FF FF FF FF FF' 'FF 00 33 33 33 0F FF FF FF FF FF FF FF FF 00 33' '33 0F FF FF FF FF FF FF FF FF FF 00 03 0F FF FF' 'FF FF FF FF FF FF FF FF F0 FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } BMP_L BITMAP { '42 4D 9E 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 01 00 00 00' '00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 80 00' '01 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00' } BMP_L2 BITMAP { '42 4D 9E 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 01 00 00 00' '00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 80 00 01 00 80 00' '01 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00' } BMP_L3 BITMAP { '42 4D 9E 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 01 00 00 00' '00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 80 00 01 00 80 00 01 00 80 00' '01 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00' } BMP_L4 BITMAP { '42 4D 9E 00 00 00 00 00 00 00 3E 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 01 00 00 00' '00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 80 00 01 00 80 00 01 00 80 00' '01 00 80 00 01 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF' 'FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00' } BMP_RC BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00' '00 00 00 00 00 00 00 00 00 FF FF 0F FF FF FF FF' 'FF FF FF FF F0 FF FF 0F FF FF FF FF FF FF FF FF' 'F0 FF FF 0F FF FF FF FF FF FF FF FF F0 FF FF 0F' 'FF FF FF FF FF FF FF FF F0 FF FF 0F FF FF FF FF' 'FF FF FF FF F0 FF FF 0F FF FF FF FF FF FF FF FF' 'F0 FF FF 0F FF FF FF FF FF FF FF FF F0 FF FF 0F' 'FF FF FF FF FF FF FF FF F0 FF FF 0F FF FF FF FF' 'FF FF FF FF F0 FF FF 0F FF FF FF FF FF FF FF FF' 'F0 FF FF 00 00 00 00 00 00 00 00 00 00 FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } BMP_RC2 BITMAP { '42 4D 96 01 00 00 00 00 00 00 76 00 00 00 28 00' '00 00 18 00 00 00 18 00 00 00 01 00 04 00 00 00' '00 00 20 01 00 00 00 00 00 00 00 00 00 00 00 00' '00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80' '00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80' '00 00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF' '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF' '00 00 FF FF FF 00 FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00' '00 00 00 00 00 00 00 00 00 FF FF 07 77 77 77 77' '77 77 77 77 70 FF FF 07 77 77 77 77 77 77 77 77' '70 FF FF 07 77 77 77 77 77 77 77 77 70 FF FF 07' '77 77 77 77 77 77 77 77 70 FF FF 07 77 77 77 77' '77 77 77 77 70 FF FF 07 77 77 77 77 77 77 77 77' '70 FF FF 07 77 77 77 77 77 77 77 77 70 FF FF 07' '77 77 77 77 77 77 77 77 70 FF FF 07 77 77 77 77' '77 77 77 77 70 FF FF 07 77 77 77 77 77 77 77 77' '70 FF FF 00 00 00 00 00 00 00 00 00 00 FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 'FF FF FF FF FF FF' } #endif
На следующем шаге мы рассмотрим создание хранителя экрана.