Visualizador de Imagens BMP e PCX Fontes do Projeto: pcx_bmp1.h - Declara‡Æo de classes do projeto pcx_bmp2.h - Declara‡Æo de #defines do Projeto pcx_bmp.rc - Declara‡Æo de Resources (Menus e di logos) TApp.cpp - Implementa‡Æo da chamada inicial de TFrame (Window) TFrame.cpp - Implementa‡Æo das fun‡äes de controle da Window principal TCanvas.cpp - Implementa‡Æo do controle das janela de imagem TImage.h & TImage.cpp - Manipula‡Æo da Imagem em mem¢ria TFImage.h & TFImage.cpp - Carga do arquivo em mem¢ria TPalette.h & TPalette.cpp - Controle da palette ativa TToolBar.h & TToolBar.cpp - Implementa‡Æo da janela com a Barra de Botäes TMessage.h & TMessage.cpp - Implementa‡Æo da janela de mensagem da Window TAbout.h & TAboutdg.cpp - Implementa‡Æo da Dialog de "About" TGenFunc.h & TGenFunc.cpp - Fun‡äes de uso geral pcx_bmp1.h - Declara‡Æo de classes do projeto #include #include #include #include #include #include /**************************************************************************/ // Class definitions _CLASSDEF(TApp) // Main application _CLASSDEF(TFrame) // Global Frame _CLASSDEF(TCanvas) // Window de trabalho #include "ttoolbar.h" #include "tmessage.h" #include "tgenfunc.h" #include "tpalette.h" #include "timage.h" #include "tabout.h" #include "pcx_bmp2.h" /**************************************************************************/ // TAPP.CPP Class class _CLASSTYPE TApp : public TApplication { public: TApp(LPSTR Name,HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmd,int nCmdShow) :TApplication(Name,hInstance,hPrevInstance,lpCmd,nCmdShow){}; virtual void InitMainWindow(void); }; /**************************************************************************/ // TFRAME.CPP Class class _CLASSTYPE TFrame : public TWindow { public: PTToolBar ToolBar; PTCanvas Canvas; PTMsg Message; virtual LPSTR GetClassName (void){return "STARTUP_FRAME";}; virtual void GetWindowClass (WNDCLASS& wc); virtual void SetupWindow (void); virtual void WMSize (RTMessage Msg) = [WM_FIRST + WM_SIZE]; virtual void WMMenuSelect (RTMessage Msg) = [WM_FIRST + WM_MENUSELECT]; virtual void WMPaint (RTMessage Msg) = [WM_FIRST + WM_PAINT]; virtual void WMClose (RTMessage Msg) = [WM_FIRST + WM_CLOSE]; virtual void LoadImage (void) = [CM_FIRST + CMU_LOADIMAGE]; virtual void CleanImage (void) = [CM_FIRST + CMU_CLEANIMAGE]; virtual void HelpAbout (void) = [CM_FIRST + CMU_ABOUT]; virtual BOOL CanClose (void); virtual void CMToolBarAction (RTMessage Msg) = [WM_USER + CM_TOOLBARACTION]; TFrame(LPSTR Caption); ~TFrame(void); }; /**************************************************************************/ // TCANVAS.CPP Class class _CLASSTYPE TCanvas : public TWindow { public: PTFrame Main; PTImage Image; PTPalette Palette; OPENFILENAME Ofn; char ImageFile [128]; char ImageTitle [16]; char ImageFilter [256]; HDC Globalhdc; virtual LPSTR GetClassName (void){return "STARTUP_CANVAS";}; virtual void SetupWindow (void); virtual void LoadImage (void); virtual void CleanImage (void); virtual void WMPaint (RTMessage Msg) = [WM_FIRST + WM_PAINT]; virtual void WMSetCursor (RTMessage Msg) = [WM_FIRST + WM_SETCURSOR]; TCanvas(PTWindowsObject Main); ~TCanvas(void); virtual void WMLButtonDown (RTMessage Msg) = [WM_FIRST + WM_LBUTTONDOWN]; virtual void WMMouseMove (RTMessage Msg) = [WM_FIRST + WM_MOUSEMOVE]; virtual void WMLButtonUp (RTMessage Msg) = [WM_FIRST + WM_LBUTTONUP]; }; pcx_bmp2.h - Declara‡Æo de #defines do Projeto //************************************// /////////// STRINGS ////////////// //************************************// #define APPCAPTION 101 //************************************// /////////// ACTIONS ////////////// //************************************// #define CMU_LOADIMAGE 1 #define CMU_CLEANIMAGE 2 #define CMU_ABOUT 3 #define BMPPLACE 1001 pcx_bmp.rc - Declara‡Æo de Resources (Menus e di logos) #include #include #include "ttoolbar.h" #include "tabout.h" #include "pcx_bmp2.h" // Main Menu - Used at MAIN.CPP MAIN_MENU MENU BEGIN POPUP "&File" BEGIN MENUITEM "Load Image..." , CMU_LOADIMAGE MENUITEM SEPARATOR MENUITEM "&Exit", CM_EXIT END POPUP "\a&Help" BEGIN MENUITEM "&About..." , CMU_ABOUT END END // ToolBar Buttons Comments STRINGTABLE BEGIN // Geral APPCAPTION , "PCX and BMP load and display Demo by Luis F. Macedo" // Botäes END // ToolBar Buttons Bitmaps CMU_CLEANIMAGE BITMAP "f_new.bmp" CMU_LOADIMAGE BITMAP "f_open.bmp" MACEDO BITMAP "mac256.bmp" // Dialogs ABOUT DIALOG 61, 75, 236, 95 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CLASS "BorDlg" CAPTION "Hello !" BEGIN CONTROL "", 101, "BorShade", 32769 | WS_CHILD | WS_VISIBLE, 3, 3, 46, 54 CONTROL "", 102, "BorShade", 32769 | WS_CHILD | WS_VISIBLE, 3, 60, 46, 32 CONTROL "Button", IDOK, "BorBtn", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 10, 66, 32, 20 CONTROL "", 103, "BorShade", 32769 | WS_CHILD | WS_VISIBLE, 52, 3, 181, 89 CTEXT "PCX and BMP Image Load Demo", BMPPLACE, 58, 6, 167, 8, WS_CHILD | WS_VISIBLE | WS_GROUP CONTROL "You can reach me at:", 105, "BorStatic", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 55, 69, 76, 8 CONTROL "macedo@comsivam.org", 106, "BorStatic", SS_CENTER | WS_CHILD | WS_VISIBLE | WS_GROUP, 55, 79, 175, 8 LTEXT "This program was developed during my Master Degree between 1995 and 1998. If you find this application useful, fell free to use the source code, but don't forget to mention my name. This will entitle you a good karma.", -1, 55, 26, 175, 41, WS_CHILD | WS_VISIBLE | WS_GROUP CTEXT "by Lu¡s Francisco de Macedo", BMPPLACE, 58, 16, 167, 8, WS_CHILD | WS_VISIBLE | WS_GROUP END TApp.cpp - Implementa‡Æo da chamada inicial de TFrame (Window) #include "pcx_bmp1.h" /*************************************************************************/ /**************************** TAeroApp **********************************/ /*************************************************************************/ /*************************************************************************/ // InitMainWindow() void TApp::InitMainWindow() { char Caption[128]; LoadString(hInstance,APPCAPTION,Caption,sizeof(Caption)); MainWindow = new TFrame(Caption); } /*************************************************************************/ /**************************** WinMain ************************************/ /*************************************************************************/ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmd, int nCmdShow) { TApp App("STARTUP_APP",hInstance,hPrevInstance,lpCmd,nCmdShow); App.Run(); return App.Status; } TFrame.cpp - Implementa‡Æo das fun‡äes de controle da Window principal #include "pcx_bmp1.h" /*************************************************************************/ // TFrame Constructor TFrame::TFrame(LPSTR Caption) :TWindow(NULL,Caption,NULL) { RECT R; GetWindowRect(GetDesktopWindow(),&R); Attr.X = Attr.Y = 0; Attr.W = R.right - R.left; Attr.H = R.bottom - R.top; } /*************************************************************************/ // TFrame Destructor TFrame::~TFrame() { if(Message) delete Message; if(ToolBar) delete ToolBar; if(Canvas) delete Canvas; } /*************************************************************************/ //SetUpWindow() void TFrame::SetupWindow() { int x; char Aux[33]; ToolBar = (PTToolBar) GetApplication()->MakeWindow(new TToolBar(this)); Canvas = (PTCanvas) GetApplication()->MakeWindow(new TCanvas(this)); Message = (PTMsg) GetApplication()->MakeWindow(new TMsg(this)); AssignMenu("MAIN_MENU"); // TOOL BAR BUTTONS DEFINITION x=0; ToolBar->InsertSeparator(x++); LoadString(GetApplication()->hInstance,CMU_CLEANIMAGE,Aux,sizeof(Aux)); ToolBar->InsertButton(BMPBUTTON,x++,NULL,CMU_CLEANIMAGE,Aux); LoadString(GetApplication()->hInstance,CMU_LOADIMAGE,Aux,sizeof(Aux)); ToolBar->InsertButton(BMPBUTTON,x++,NULL,CMU_LOADIMAGE,Aux); } /*************************************************************************/ //GetWindowClass() void TFrame::GetWindowClass(WNDCLASS& wc) { TWindow::GetWindowClass(wc); } /*************************************************************************/ // WMSize void TFrame::WMSize(RTMessage Msg) { RECT R; if((Msg.WParam != SIZE_MINIMIZED)) { GetWindowRect(HWindow,&R); if((R.right-R.left)<300) R.right = R.left+300; if((R.bottom-R.top)<225) R.bottom = R.top+225; MoveWindow(HWindow,R.left,R.top,R.right-R.left,R.bottom-R.top,TRUE); GetClientRect(HWindow,&R); if(ToolBar) ToolBar->SetToolBarSize(0,0,R.right,ToolBar->GetToolBarHeight()); if(Canvas) MoveWindow(Canvas->HWindow,0,R.top+ToolBar->GetToolBarHeight(), R.right,R.bottom-(ToolBar->GetToolBarHeight()+Message- >GetMessageHeight()),TRUE); if(Message) MoveWindow(Message->HWindow,0,R.bottom-Message- >GetMessageHeight(),R.right,20,TRUE); } } /*************************************************************************/ // WMMenuSelect void TFrame::WMMenuSelect(RTMessage Msg) { if(Message) SendMessage(Message->HWindow,Msg.Message,Msg.WParam,Msg.LParam); } /*************************************************************************/ // HelpAbout() void TFrame::HelpAbout() { GetApplication()->ExecDialog(new TAboutDlg(this,"ABOUT")); } /*************************************************************************/ // CMToolBarAction() void TFrame::CMToolBarAction(RTMessage Msg) { // Images if(Msg.WParam == ToolBar->GetButtonPos(CMU_LOADIMAGE) && Msg.LParam == BUTTONCLICKED) { LoadImage(); } if(Msg.WParam == ToolBar->GetButtonPos(CMU_CLEANIMAGE) && Msg.LParam == BUTTONCLICKED) { CleanImage(); } // Importante para levantar botäes de acionamento de Dialogs if(Msg.LParam == BUTTONCLICKED) ToolBar->ReleaseButton(Msg.WParam); } /*************************************************************************/ // void TFrame::LoadImage(void) { Canvas->LoadImage(); } /*************************************************************************/ // void TFrame::CleanImage(void) { Canvas->CleanImage(); } /*************************************************************************/ // WMPaint() void TFrame::WMPaint(RTMessage Msg) { TWindow::WMPaint(Msg); } /*************************************************************************/ // BOOL TFrame::CanClose(void) { GetApplication()->ExecDialog(new TAboutDlg(this,"ABOUT")); return TWindowsObject::CanClose(); } /*************************************************************************/ // WMClose void TFrame::WMClose(RTMessage Msg) { CMExit(Msg); } TCanvas.cpp - Implementa‡Æo do controle das janela de imagem #include "pcx_bmp1.h" /*************************************************************************/ // Canvas Constructor TCanvas::TCanvas(PTWindowsObject AParent) :TWindow(AParent,NULL,NULL) { Main = (PTFrame)AParent; Image = NULL; _fmemset(&Ofn, 0, sizeof(OPENFILENAME)); Ofn.lStructSize = sizeof(OPENFILENAME); Ofn.hwndOwner = Main->HWindow; Ofn.lpstrFilter = ImageFilter; Ofn.nFilterIndex = 1; Ofn.lpstrFile = ImageFile; Ofn.nMaxFile = 128; Ofn.lpstrFileTitle = ImageTitle; Ofn.nMaxFileTitle = 128; Ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; Attr.Style = WS_CHILD | WS_VISIBLE; SetFlags(WB_MDICHILD, FALSE); } /*************************************************************************/ // Canvas Destructor TCanvas::~TCanvas() { if(Image) delete Image; if(Palette) delete Palette; } /*************************************************************************/ //SetUpWindow() void TCanvas::SetupWindow() { Palette = (PTPalette)new TPalette(); } /*************************************************************************/ // WMPaint() void TCanvas::WMPaint(RTMessage) { HDC hdc; PAINTSTRUCT ps; RECT Wnd; hdc = BeginPaint(HWindow, &ps); // Pinta tela vis¡vel de branco GetClientRect(HWindow,&Wnd); if(Image) Image->ShowImage(hdc,0,0,Wnd.right,Wnd.bottom,0,0,SRCCOPY); else BitBlt(hdc,0,0,Wnd.right,Wnd.bottom,hdc,0,0,WHITENESS); EndPaint(HWindow,&ps); } /********************************************************************************** ************/ // SetCursor() void TCanvas::WMSetCursor(RTMessage) { } /*************************************************************************/ // WMLButtonDown() void TCanvas::WMLButtonDown(RTMessage) { } /*************************************************************************/ // WMMouseMove() void TCanvas::WMMouseMove(RTMessage Msg) { int X,Y; RECT R; char Txt[100],AuxTxt[33]; X = MOUSEX(Msg); Y = MOUSEY(Msg); GetClientRect(HWindow,&R); strcpy(Txt,"Cursor ("); strcat(Txt,itoa(X,AuxTxt,10)); strcat(Txt,","); strcat(Txt,itoa(R.bottom-Y,AuxTxt,10)); strcat(Txt,")"); Main->Message->DisplayMessage(Txt); } /*************************************************************************/ // WMLButtonUp() void TCanvas::WMLButtonUp(RTMessage) { } /*************************************************************************/ // void TCanvas::LoadImage(void) { PTImage AuxImage; int i; BYTE Separator; ImageFile [0] = '\0'; strcpy(ImageFilter,"Zsoft (*.PCX)|*.pcx|" "Microsoft (*.BMP)|*.bmp|" "All Files (*.*)|*.*|"); i = strlen(ImageFilter); Separator = ImageFilter[i-1]; for(i=0; ImageFilter[i] != '\0'; i++) { if(ImageFilter[i] == Separator) ImageFilter[i] = '\0'; } if(GetOpenFileName(&Ofn)) { AuxImage = (PTImage) new TImage(); if(AuxImage->ReadFile(ImageFile)) { delete Image; Image = AuxImage; } else delete AuxImage; } InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // void TCanvas::CleanImage(void) { if(Image) { delete Image; Image = NULL; InvalidateRect(HWindow,NULL,FALSE); } } TImage.h - Manipula‡Æo da Imagem em mem¢ria #define GlobalPtrHandle(lp) ((HGLOBAL)LOWORD(GlobalHandle(SELECTOROF(lp)))) #define GlobalUnlockPtr(lp) GlobalUnlock(GlobalPtrHandle(lp)) #define GlobalAllocPtr(flags, cb) (GlobalLock(GlobalAlloc((flags), (cb)))) #define GlobalFreePtr(lp) (GlobalUnlockPtr(lp), (BOOL)GlobalFree(GlobalPtrHandle(lp))) /*****************************************************************************/ const size_t MaxBlock = 30*1024; _CLASSDEF(TImage) class TImage { protected: LPVOID PointerToDIB; // Bitmap independente do dispositivo (DIB) HPALETTE hPalette; // Paleta de cores da imagem HBITMAP hDDBitmap; // Bitmap dependente do dispositivo (DDB) unsigned short ImgWidth, ImgHeight; // Altura e largura da imagem unsigned short BytePerLine; unsigned short Count; struct ImageInfo { unsigned short left; unsigned short top; unsigned short width; unsigned short height; unsigned char flags; }; /********************************/ // Palette unsigned int NumColors (); void MakePalette(); void DIBtoDDB (HDC hdc); void DDBtoDIB (void); /********************************/ // PCX struct PCXHeader { unsigned char Header; unsigned char Version; unsigned char Encode; unsigned char BitPerPixPlane; short X1; short Y1; short X2; short Y2; unsigned short Hres; unsigned short Vres; unsigned char EGAPalette[48]; unsigned char VideoMode; unsigned char ColorPlanes; unsigned short BytePerLine; unsigned char Unused[60]; // Header de 128 bytes }; PCXHeader PCXHdr; /********************************/ // BMP BITMAPFILEHEADER BMPHdr; /********************************/ public: TImage(); ~TImage(); virtual int ReadFile (char *File); int ReadPCX (char *File); int ReadBMP (char *File); LPVOID GetDIB () {return PointerToDIB;} HBITMAP GetDDB () {return hDDBitmap;} HPALETTE GetPalette () {return hPalette;} DWORD GetWidth () {if(PointerToDIB != 0) return((LPBITMAPINFOHEADER)PointerToDIB)->biWidth; return ImgWidth;} DWORD GetHeight () {if(PointerToDIB != 0) return ((LPBITMAPINFOHEADER)PointerToDIB)->biHeight; return ImgHeight;} void ShowImage(HDC hdc, short OrgX = 0, short OrgY = 0, short width = 0, short height = 0, short XFrom = 0, short YFrom = 0, DWORD ROPCode = SRCCOPY); }; TImage.cpp - Manipula‡Æo da Imagem em mem¢ria #include "pcx_bmp1.h" /******************************************************************************/ // Construtor // Instancia os servi‡os para carga de imagem TImage::TImage() { PointerToDIB = 0; Count = 0; hPalette = 0; hDDBitmap = 0; BytePerLine = 0; ImgWidth = 0; ImgHeight = 0; } //******************************************************************************/ // Destrutor TImage::~TImage() { if(PointerToDIB) GlobalFreePtr(PointerToDIB); if(hPalette) DeleteObject (hPalette); if(hDDBitmap) DeleteObject (hDDBitmap); } /******************************************************************************/ // Retorna n£mero de cores da imagem unsigned int TImage::NumColors() { if(PointerToDIB == 0) return 0; LPBITMAPINFOHEADER BMPInfo=(LPBITMAPINFOHEADER)(PointerToDIB); // Se o campo biClrUsed nÆo ‚ zero, usa este o valor deste campo como n£mero // de cores da imagem if(BMPInfo->biClrUsed != 0) return (unsigned int)BMPInfo->biClrUsed; // Se o n£mero ‚ dado em fun‡Æo do n£mero de bits por pixel switch(BMPInfo->biBitCount) { case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; // Imagem de 24-bits/pixel ou cor verdadeira } } /******************************************************************************/ // Cria uma paleta de cores usando informa‡äes do DIB void TImage::MakePalette() { // Seta um ponteiro para o DIB LPBITMAPINFOHEADER BMPInfo = (LPBITMAPINFOHEADER)(PointerToDIB); if(BMPInfo == 0) return; // Apaga o ponteiro da paleta existente if(hPalette != 0) DeleteObject(hPalette); // Seta a paleta, se necess rio if(NumColors() > 0) { LPLOGPALETTE pPalette = (LPLOGPALETTE)GlobalAllocPtr(GHND,sizeof(LOGPALETTE)+NumColors()*sizeof(PALETTEE NTRY)); if(pPalette) { pPalette->palVersion = 0x0300; pPalette->palNumEntries = NumColors(); // Seta a paleta com valores provenientes do DIB LPBITMAPINFO pBMPInfo = (LPBITMAPINFO)BMPInfo; int i; for(i = 0; i < NumColors(); i++) { pPalette->palPalEntry[i].peRed = pBMPInfo->bmiColors[i].rgbRed; pPalette->palPalEntry[i].peGreen = pBMPInfo->bmiColors[i].rgbGreen; pPalette->palPalEntry[i].peBlue = pBMPInfo->bmiColors[i].rgbBlue; pPalette->palPalEntry[i].peFlags = 0; } hPalette = CreatePalette(pPalette); GlobalFreePtr(pPalette); } } } /******************************************************************************/ // Cria um DDB a partir de um DIB para poder apresentar no dispositivo alvo void TImage::DIBtoDDB(HDC hdc) { // Seta um ponteiro para o DIB LPBITMAPINFOHEADER BMPInfo = (LPBITMAPINFOHEADER)(PointerToDIB); if(BMPInfo == 0) return; // Apaga o DDB se ele j  existe if(hDDBitmap != 0) DeleteObject(hDDBitmap); // Seta um ponteiro para os dados da imagem pulando BITMAPINFOHEADER e a paleta LPSTR ImageData = (LPSTR)BMPInfo+sizeof(BITMAPINFOHEADER)+NumColors()*sizeof(RGBQUAD); HPALETTE hOldPalette = NULL; if(hPalette) { hOldPalette = SelectPalette(hdc, hPalette, FALSE); RealizePalette(hdc); } // Converte o DIB em um DDB e transfere para o contexto de dispositivo hDDBitmap = CreateDIBitmap(hdc,BMPInfo,CBM_INIT,ImageData,(LPBITMAPINFO)BMPInfo,DIB_RGB_COL ORS); if(hOldPalette) SelectPalette(hdc, hOldPalette, FALSE); } /******************************************************************************/ // Cria um DIB atrav‚s de um DDB associado a hDDBitmap void TImage::DDBtoDIB() { if(hDDBitmap == 0) return; if(PointerToDIB != NULL) return; BITMAP BitmapData; GetObject(hDDBitmap, sizeof(BitmapData), (LPSTR)&BitmapData); BITMAPINFOHEADER BitmapInfoHeader; BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER); BitmapInfoHeader.biWidth = BitmapData.bmWidth; BitmapInfoHeader.biHeight = BitmapData.bmHeight; BitmapInfoHeader.biPlanes = 1; BitmapInfoHeader.biBitCount = (WORD)(BitmapData.bmPlanes * BitmapData.bmBitsPixel); BitmapInfoHeader.biCompression = BI_RGB; ImgWidth = BitmapData.bmWidth; ImgHeight = BitmapData.bmHeight; // Computa bytes por linha e arrendonda para multiplo de 4 BytePerLine = ((long)BitmapInfoHeader.biWidth * (long)BitmapInfoHeader.biBitCount + 31L) / 32 * 4; BitmapInfoHeader.biSizeImage = (long)BitmapInfoHeader.biHeight * (long)BytePerLine; BitmapInfoHeader.biXPelsPerMeter = 0; BitmapInfoHeader.biYPelsPerMeter = 0; // Determina o n£mero de cores da paleta short NumColors = 0; switch(BitmapInfoHeader.biBitCount) { case 1: NumColors = 2; break; case 4: NumColors = 16; break; case 8: NumColors = 256; break; default: NumColors = 0; } BitmapInfoHeader.biClrUsed = NumColors; BitmapInfoHeader.biClrImportant = 0; // Computa tamanho DIB unsigned long DIBTotalSize = sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+BitmapInfoHeader.biSizeImage; // Aloca mem¢ria para o DIB PointerToDIB = GlobalAllocPtr(GHND, DIBTotalSize); if(PointerToDIB == NULL) return; HDC hdc = GetDC(NULL); // Copia estrutura BITMAPINFO (BitmapInfoHeader) para o ¡nicio do DIB. _fmemcpy(PointerToDIB, &BitmapInfoHeader, (size_t)BitmapInfoHeader.biSize); LPSTR ImageData = (LPSTR)PointerToDIB + (WORD)BitmapInfoHeader.biSize + NumColors * sizeof(RGBQUAD); // Chama GetDIBits para pegar a imagem e preencher os ¡ndices da paleta // da estrutura BITMAPINFO GetDIBits(hdc,hDDBitmap,0,(WORD)BitmapInfoHeader.biHeight,ImageData,(LPBITMAPINFO)Poi nterToDIB,DIB_RGB_COLORS); ReleaseDC(NULL, hdc); } /******************************************************************************/ // Mostra o DIB na device contexto especificado void TImage::ShowImage(HDC hdc, short OrgX, short OrgY, short HSize, short VSize, short XFrom, short YFrom, DWORD ROPCode) { LPBITMAPINFOHEADER BMPInfo = (LPBITMAPINFOHEADER)(PointerToDIB); if(BMPInfo != NULL) { if(hPalette == 0 && NumColors() > 0) MakePalette(); // Converte para DDB, se necess rio if(hDDBitmap == 0) DIBtoDDB(hdc); } if(hDDBitmap != 0) { HDC MemDC = CreateCompatibleDC(hdc); if(MemDC != 0) { HBITMAP OldBMP = (HBITMAP)SelectObject(MemDC, hDDBitmap); // Se largura e altura ‚ zero, usa a largura e altura da imagem if(HSize == 0) HSize = GetWidth(); if(VSize == 0) VSize = GetHeight(); BitBlt(hdc, OrgX, OrgY, HSize, VSize, MemDC, XFrom, YFrom, ROPCode); SelectObject(MemDC, OldBMP); DeleteDC(MemDC); } } } /******************************************************************************/ // Pega o File e dependendo da extensÆo direciona a leitura para o // servi‡o apropriado int TImage::ReadFile(char *File) { LPSTR Ext; Ext = _fstrchr(File, '.'); if(!Ext) return NULL; if(strcmp(Ext,".PCX")==0) return ReadPCX(File); if(strcmp(Ext,".BMP")==0) return ReadBMP(File); return NULL; } /******************************************************************************/ // Lˆ uma imagem tipo PCX int TImage::ReadPCX(char* FileName) { ifstream InputStream(FileName, ios::in | ios::binary); if(!InputStream) { return NULL; } // Lˆ o header PCX InputStream.read((unsigned char*)&PCXHdr,sizeof(PCXHeader)); // Verifica se o formato do arquivo de imagem ‚ aceit vel (tag=10) if(PCXHdr.Header != 0x0a) return NULL; // Verifica se a imagem ‚ de 1,4,8 ou 24 bits int BitPerPix = PCXHdr.ColorPlanes * PCXHdr.BitPerPixPlane; // Rejeita imagens diferentes de 1,4,8 e 24 if(BitPerPix != 1 && BitPerPix != 4 && BitPerPix != 8 && BitPerPix != 24) return NULL; // Calcula tamanho da imagem unsigned short HSize = PCXHdr.X2 - PCXHdr.X1 + 1; unsigned short VSize = PCXHdr.Y2 - PCXHdr.Y1 + 1; // Calcula tamanho descompactado da imagem em bytes long PCXDataSize = (long) PCXHdr.ColorPlanes*(long) VSize*(long)PCXHdr.BytePerLine; // Aloca espa‡o de mem¢ria para descompactar a imagem PCX unsigned char huge *Image = new unsigned char huge[PCXDataSize]; // Rejeita leitura se houve falha de aloca‡Æo de mem¢ria if(Image == NULL) return NULL; // Inicia leitura int i, Value, Count; unsigned long Position = 0L; // Lopping de leitura da  rea de dados de imagem // e efetua descompacta‡Æo RLL while((Value = InputStream.get()) != EOF) { // Se for tag RLL if((Value & 0xc0) == 0xc0) { // Calcula o n£mero de repeti‡äes Count = Value & 0x3f; // Lˆ o Value a ser repetido if((Value = InputStream.get()) != EOF) { // Carrega o Value no buffer for(i=0; i= PCXDataSize) break; Image[Position] = Value; Position++; } } } else // Se nÆo tem RLL entÆo somente copia o Value para o Buffer { if(Position >= PCXDataSize) break; Image[Position] = Value; Position++; } } // Inverte ordem BGR de PCX de 3 planos para RGB de BMP 24 bits if(PCXHdr.ColorPlanes==3) { for(long y=0; y 8) PalSize = 0; // Aloca mem¢ria para o DIB PointerToDIB = GlobalAllocPtr(GHND, sizeof(BITMAPINFOHEADER)+PalSize * sizeof(RGBQUAD)+(long)BytePerLine*(long)VSize); // Se a mem¢ria falha retorna NULL if(PointerToDIB == 0) return NULL; // Inicializa o header do DIB com os valores da imagem LPBITMAPINFOHEADER BMPInfo = (LPBITMAPINFOHEADER)PointerToDIB; BMPInfo->biSize = sizeof(BITMAPINFOHEADER); BMPInfo->biWidth = HSize; BMPInfo->biHeight = VSize; BMPInfo->biPlanes = 1; BMPInfo->biBitCount = PCXHdr.BitPerPixPlane * PCXHdr.ColorPlanes; BMPInfo->biCompression = BI_RGB; BMPInfo->biSizeImage = (long)VSize * (long)BytePerLine; BMPInfo->biXPelsPerMeter = 0; BMPInfo->biYPelsPerMeter = 0; BMPInfo->biClrUsed = 0; BMPInfo->biClrImportant = 0; if(PalSize > 0) { RGBQUAD *Palette = (RGBQUAD*) ((LPSTR)PointerToDIB + sizeof(BITMAPINFOHEADER)); int Index; for(Index = 0; Index < PalSize; Index++) { if(PalSize == 256) { // lˆ a paleta do arquivo Palette[Index].rgbRed = InputStream.get(); Palette[Index].rgbGreen = InputStream.get(); Palette[Index].rgbBlue = InputStream.get(); Palette[Index].rgbReserved = 0; } if(PalSize == 16) { // inicializa a paleta com os valores do header Palette[Index].rgbRed = PCXHdr.EGAPalette[3*Index]; Palette[Index].rgbGreen = PCXHdr.EGAPalette[3*Index+1]; Palette[Index].rgbBlue = PCXHdr.EGAPalette[3*Index+2]; Palette[Index].rgbReserved = 0; } if(PalSize == 2) { // inicializa a paleta com branco e preto Palette[Index].rgbRed = Index * 255; Palette[Index].rgbGreen = Index * 255; Palette[Index].rgbBlue = Index * 255; Palette[Index].rgbReserved = 0; } } } // Carrega ponteiro da imagem no DIB unsigned char huge *DIBData = (unsigned char huge*)PointerToDIB + sizeof(BITMAPINFOHEADER) + PalSize * sizeof(RGBQUAD) + (unsigned long)(VSize - 1) * (unsigned long)(BytePerLine); int LineCount, ByteCount, PlaneCount; long Index; unsigned short Val, BitCount, Pos, Bits, k, PixPerByte = 8/PCXHdr.BitPerPixPlane; unsigned short HiMask = 0x80, Mask; if(PCXHdr.BitPerPixPlane > 1) for(i = 0; i < PCXHdr.BitPerPixPlane - 1; i++) HiMask = 0x80 | (HiMask >> 1); for(LineCount = 0; LineCount < VSize; LineCount++, DIBData -= BytePerLine) { if(PCXBytesPerLine < BytePerLine) for(Pos = PCXBytesPerLine; Pos < BytePerLine; Pos++) DIBData[Pos] = 0; Pos = 0; Val = 0; BitCount = 0; for(ByteCount = 0; ByteCount < BMPBytesPerLine; ByteCount++) { for(k = 0, Mask = HiMask; k < PixPerByte; k++, Mask >>= PCXHdr.BitPerPixPlane) { for(PlaneCount = 0; PlaneCount < PCXHdr.ColorPlanes; PlaneCount++) { Index = ((long)(LineCount)*(long)PCXHdr.BytePerLine* (long)PCXHdr.ColorPlanes + (long)(PlaneCount)*(long)PCXHdr.BytePerLine + (long)(ByteCount)); Bits = Image[Index] & Mask; if(k > 0) Bits <<= (k*PCXHdr.BitPerPixPlane); if(BitCount > 0) Bits >>= BitCount; Val |= Bits; BitCount += PCXHdr.BitPerPixPlane; if(BitCount >= 8) { DIBData[Pos] = Val; Pos++; BitCount = 0; Val = 0; } } } } } delete Image; return TRUE; } /******************************************************************************/ // Lˆ uma imagem tipo BMP int TImage::ReadBMP(char *FileName) { ifstream InputStream(FileName, ios::in | ios::binary); if(!InputStream) { return 0; } // Lˆ o header do arquivo imagem InputStream.read((unsigned char*)&BMPHdr, sizeof(BITMAPFILEHEADER)); // Verifica se o formato da imagem ‚ aceit vel (deve ser 'BM') if(BMPHdr.bfType != (('M' << 8) | 'B')) return NULL; // Determina o tamanho do DIB para leitura atrav‚s do campo bfSize do BITMAPFILEHEADER // menos o tamanho do BITMAPFILEHEADER long bmpsize = BMPHdr.bfSize - sizeof(BITMAPFILEHEADER); // Aloca espa‡o para o bitmap PointerToDIB = GlobalAllocPtr(GHND, bmpsize); // Se a mem¢ria falha retorna NULL if(PointerToDIB == 0) return NULL; // Aloca espa‡o para descompactar a imagem PCX unsigned char *rbuf = new unsigned char[MaxBlock]; if(rbuf == NULL) return NULL; unsigned char huge *DIBData = (unsigned char huge*)PointerToDIB; unsigned int chunksize; unsigned int i; while(bmpsize > 0) { if(bmpsize > MaxBlock) chunksize = MaxBlock; else chunksize = (WORD)bmpsize; InputStream.read(rbuf, chunksize); // Copia para o DIB for(i = 0; i < chunksize; i++) DIBData[i] = rbuf[i]; bmpsize -= chunksize; DIBData += chunksize; } delete rbuf; // Computa o n£mero de bytes por linha, arredondando para m£ltiplo de 4 LPBITMAPINFOHEADER pBMPInfo = (LPBITMAPINFOHEADER)PointerToDIB; BytePerLine = ((long)pBMPInfo->biWidth * (long)pBMPInfo->biBitCount + 31L) / 32 * 4; // Ignora OS/2 1.x bitmap files if(pBMPInfo->biSize == 12) return NULL; return TRUE; } TFImage.h - Carga do arquivo em mem¢ria #include _CLASSDEF(TFileImage) #define TO_OPEN 1 #define TO_SAVE 2 #define PCXHDRTAG 10 // Flag para PCX v lido #define MAXRLLREPCOUNT 63 // Maximo de repeat para RLL encoding #define PCX256COLORTAG 12 // Flag para pallete extendida // PCX Structs & Data struct PCXCOLOR { BYTE Red; BYTE Green; BYTE Blue; }; struct PCXFILE // Header completa de PCX=128 bytes { BYTE Header; // Flag para PCX (10) BYTE Version; // 0 = Ver 2.5 BYTE Encode; // Flag para RLL (1=TRUE) BYTE BitPerPix; // Bits por pixel WORD X1; // Posicao da Picture WORD Y1; WORD X2; // Tamanho da Picture WORD Y2; WORD Hres; // H Res de origem WORD Vres; // V Res de origem PCXCOLOR EGAPalette[16]; // EGA Palette BYTE VideoMode; // Video Mode (obsoleto) BYTE ColorPlanes; // Color Planes (8 bits = 1) WORD BytesPerLine; // BytesPerLine (for RLL expand) BYTE Unused[60]; // Free space }; struct PCXEXTPALETTE { BYTE ExtendedPalette; PCXCOLOR Palette[256]; }; /**************************************************************************/ // class _CLASSTYPE TFileImage { private: PTCanvas Main; OPENFILENAME Ofn; char ImageFile [256]; char ImageTitle [256]; char ImageFilter [256]; int GetName (int Mode); HBITMAP OpenPCX (LPSTR FileName); void SavePCX (HBITMAP Image); HBITMAP OpenBMP (LPSTR FileName); void SaveBMP (HBITMAP Image); public: TFileImage(PTWindowsObject); ~TFileImage(); HBITMAP LoadImage (void); void SaveImage (HBITMAP Image); }; TFImage.cpp - Carga do arquivo em mem¢ria #include "rugo1.h" /*************************************************************************/ // TFileImage Constructor TFileImage::TFileImage(PTWindowsObject AParent) { Main = (PTCanvas)AParent; // Parent Window int i; char Separator; ImageTitle[0] = '\0'; ImageFile [0] = '\0'; strcpy(ImageFilter,"Zsoft (*.PCX)|*.pcx|Microsoft (*.BMP)|*.bmp|All Files (*.*)|*.*|"); i = strlen(ImageFilter); Separator = ImageFilter[i-1]; for(i=0; ImageFilter[i] != '\0'; i++) { if(ImageFilter[i] == Separator) ImageFilter[i] = '\0'; } memset(&Ofn, 0, sizeof(OPENFILENAME)); Ofn.lStructSize = sizeof(OPENFILENAME); Ofn.hwndOwner = Main->HWindow; Ofn.lpstrFilter = ImageFilter; Ofn.nFilterIndex = 1; Ofn.lpstrFile = ImageFile; Ofn.nMaxFile = 256; Ofn.lpstrFileTitle = ImageTitle; Ofn.nMaxFileTitle = 256; Ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; } /*************************************************************************/ // TFileImage Destructor TFileImage::~TFileImage() { } /*************************************************************************/ // HBITMAP TFileImage::LoadImage() { if(GetName(TO_OPEN)) { InvalidateRect(Main->HWindow,NULL,FALSE); UpdateWindow(Main->HWindow); InvalidateRect(Main->Main->HWindow,NULL,FALSE); UpdateWindow(Main->Main->HWindow); return OpenPCX(ImageFile); } return NULL; } /*************************************************************************/ // void TFileImage::SaveImage(HBITMAP) { if(GetName(TO_SAVE)) { } } /*************************************************************************/ // OpenDialog() int TFileImage::GetName(int Oper) { if(Oper==TO_OPEN) return GetOpenFileName(&Ofn); else return GetSaveFileName(&Ofn); } /*************************************************************************/ // HBITMAP TFileImage::OpenPCX(LPSTR FileName) { TPalette * Palette = NULL; FILE * TheFile = NULL; BITMAPINFO * BmI = NULL; BYTE ** Buf = NULL; HDC hdc = NULL,hdcBmp = NULL; BYTE CharReaded; int RepCount,TotX,TotY,InCount,i,y; HBITMAP hBmp,OldBmp; PCXFILE PCXData; PCXEXTPALETTE Color256Palette; if((TheFile = fopen(FileName,"rb")) == NULL) { MessageBox(Main->HWindow,"File access denied !","Error",MB_OK & MB_ICONEXCLAMATION); return NULL; } if(fread(&PCXData,sizeof(PCXData),1,TheFile) != 1) { MessageBox(Main->HWindow,"PCX header is too short !","Error",MB_OK & MB_ICONEXCLAMATION); fclose(TheFile); return NULL; } if(PCXData.BytesPerLine!=PCXData.X2+1) { MessageBox(Main->HWindow,"PCX header incorrect !","Error",MB_OK & MB_ICONEXCLAMATION); fclose(TheFile); return NULL; } if(PCXData.Header != PCXHDRTAG) { MessageBox(Main->HWindow,"PCX tag incorrect !","Error",MB_OK & MB_ICONEXCLAMATION); fclose(TheFile); return NULL; } if(PCXData.BitPerPix != 8 || (PCXData.X1 != 0) || (PCXData.Y1 != 0)) { MessageBox(Main->HWindow,"Only 8 bit PCX are supported !","Error",MB_OK & MB_ICONEXCLAMATION); fclose(TheFile); return NULL; } SetCursor(LoadCursor(NULL,IDC_WAIT)); TotX = PCXData.X2 + 1; TotY = PCXData.Y2 + 1; Buf = (BYTE **)new BYTE *[TotX]; for(y=0; yHWindow,"Unespected end of file !","Error",MB_OK & MB_ICONEXCLAMATION); goto READPCXEND; } if((CharReaded & 0xC0) == 0xC0) { RepCount = CharReaded & ~0xC0; if(fread(&CharReaded,1,1,TheFile)!=1) { MessageBox(Main->HWindow,"Unespected end of file !","Error",MB_OK & MB_ICONEXCLAMATION); goto READPCXEND; } while(RepCount--) Buf[y][InCount++] = CharReaded; } else Buf[y][InCount++] = CharReaded; }while(InCount < PCXData.BytesPerLine); } // Fim da carga dos bits fread(&Color256Palette,sizeof(Color256Palette),1,TheFile); if(Color256Palette.ExtendedPalette!=PCX256COLORTAG) MessageBox(Main->HWindow,"256 colors palette tag incorrect !","Error",MB_OK & MB_ICONEXCLAMATION); BmI = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)+(256 * sizeof(RGBQUAD))]; BmI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); BmI->bmiHeader.biWidth = TotX; BmI->bmiHeader.biHeight = TotY; BmI->bmiHeader.biPlanes = 1; BmI->bmiHeader.biBitCount = 8; BmI->bmiHeader.biCompression = BI_RGB; BmI->bmiHeader.biSizeImage = NULL; BmI->bmiHeader.biXPelsPerMeter = NULL; BmI->bmiHeader.biYPelsPerMeter = NULL; BmI->bmiHeader.biClrImportant = NULL; Palette = (PTPalette)new TPalette(); for(i=0; i<256; i++) { BmI->bmiColors[i].rgbRed = Color256Palette.Palette[i].Red; BmI->bmiColors[i].rgbGreen = Color256Palette.Palette[i].Green; BmI->bmiColors[i].rgbBlue = Color256Palette.Palette[i].Blue; BmI->bmiColors[i].rgbReserved = 0; Palette->SetPalIndex(i++,RGB(Color256Palette.Palette[i].Red, Color256Palette.Palette[i].Green, Color256Palette.Palette[i].Blue)); } hdc = GetDC(NULL); hBmp = CreateCompatibleBitmap(hdc,TotX,TotY); if(hBmp == NULL) { MessageBox(Main->HWindow,"Unable to create image buffer !","Error",MB_OK & MB_ICONEXCLAMATION); goto READPCXEND; } hdcBmp = CreateCompatibleDC(hdc); OldBmp = (HBITMAP) SelectObject(hdcBmp,hBmp); Palette->InstallPalette(hdcBmp); ReleaseDC(NULL,hdc); for(y=0; ypalVersion = 0x300; // Tem de ser 0x300 LPal->palNumEntries = 256; for(i=0; i<10; i++) { LPal->palPalEntry[i].peRed = (BYTE)i; LPal->palPalEntry[i].peGreen = 0; LPal->palPalEntry[i].peBlue = 0; LPal->palPalEntry[i].peFlags = PC_EXPLICIT; } for(i=246; i<256; i++) { LPal->palPalEntry[i].peRed = (BYTE)i; LPal->palPalEntry[i].peGreen = 0; LPal->palPalEntry[i].peBlue = 0; LPal->palPalEntry[i].peFlags = PC_EXPLICIT; } // Faz degradee de cinza Ri = 0.; Gi = 0.; Bi = 0.; Rf = 255.; Gf = 255.; Bf = 255.; stepR=(Rf-Ri)/236.; stepG=(Gf-Gi)/236.; stepB=(Bf-Bi)/236.; for(i=10; i<246; i++) { LPal->palPalEntry[i].peRed = (BYTE)Ri; Ri+=stepR; LPal->palPalEntry[i].peGreen = (BYTE)Gi; Gi+=stepG; LPal->palPalEntry[i].peBlue = (BYTE)Bi; Bi+=stepB; } // Palette Creation HPal = CreatePalette(LPal); } /********************************************************************************** ************/ // Destructor() TPalette::~TPalette() { if(HPal) DeleteObject(HPal); } /********************************************************************************** ************/ // RampPalette() void TPalette::RampPalette(int Start,int End,COLORREF RGB1,COLORREF RGB2) { int i; float stepR,stepG,stepB; float Ri,Gi,Bi; Ri = GetRValue(RGB1); Gi = GetGValue(RGB1); Bi = GetBValue(RGB1); stepR=(GetRValue(RGB2)-GetRValue(RGB1))/((float)(End-Start)+1); stepG=(GetGValue(RGB2)-GetGValue(RGB1))/((float)(End-Start)+1); stepB=(GetBValue(RGB2)-GetBValue(RGB1))/((float)(End-Start)+1); for(i=Start; i=0 && Index<=9) || (Index>=246 && Index<=255)) { Color = GetPalIndex(Index); Pe[0].peRed = (BYTE)Index; Pe[0].peGreen = 0; Pe[0].peBlue = 0; Pe[0].peFlags = PC_EXPLICIT; } else { SysPe[Index].peRed = Pe[0].peRed = GetRValue(Color); SysPe[Index].peGreen = Pe[0].peGreen = GetGValue(Color); SysPe[Index].peBlue = Pe[0].peBlue = GetBValue(Color); SysPe[Index].peFlags = Pe[0].peFlags = PC_RESERVED; } SetPaletteEntries(HPal,Index,1,Pe); } /********************************************************************************** ************/ // GetIndex() COLORREF TPalette::GetPalIndex(int Index) { PALETTEENTRY Pe[1]; if((Index>=0 && Index<=9) || (Index>=246 && Index<=255)) { Pe[0].peRed = SysPe[Index].peRed; Pe[0].peGreen = SysPe[Index].peGreen; Pe[0].peBlue = SysPe[Index].peBlue; Pe[0].peFlags = PC_EXPLICIT; } else { GetPaletteEntries(HPal,Index,1,Pe); } return(RGB(Pe[0].peRed,Pe[0].peGreen,Pe[0].peBlue)); } /********************************************************************************** ************/ // InstallPalette() int TPalette::InstallPalette(HDC Desthdc) { SelectPalette(Desthdc,HPal,FALSE); RealizePalette(Desthdc); return(256); } TToolBar.h - Implementa‡Æo da janela com a Barra de Botäes _CLASSDEF(TToolBar) // Window de botäes tipo tool bar _CLASSDEF(TButtonAbout) // Window de explica‡Æo sobre fun‡Æo do botÆo da tool bar //************************************// /////////// TTOOLBAR ////////////// //************************************// #define CM_TOOLBARACTION 3000 // TOOLBAR MAIN MESSAGE #define MAXBUTTONS 40 // Max number of buttons at ToolBar #define ABOUTMSGSIZE 40 // Max Size of About Button Message #define SAME -1 // Flag to don't change value #define NONE -1 // Mouse is not over a Button or Separator #define SPACE -2 // Mouse is over a Separator #define BMPBUTTON -3 // Button is normal type #define TWOSTATEBMPBUTTON -4 // Button is two state button or radio button type #define HORIZONTALTYPE -5 // Horizontal toolbar #define VERTICALTYPE -6 // Vertical toolbar #define TABLETTYPE -7 // Tablet toolbar // Buttons messages -> Msg.LParam is one of the folowing messages // -> Msg.WParam is the button number #define BUTTONPRESSED 0// Two State Button just pressed #define BUTTONRELEASED 1// Two State Button just released #define BUTTONCLICKED 2// Normal Button was just pressed & released #define BUTTONENABLED 3// Button is just enabled #define BUTTONDISABLED 4// Button is just disabled #define BUTTONINSERTED 5// Button is just inserted into ToolBar #define BUTTONREMOVED 6// Button is just removed from ToolBar #define MOUSEHIT 7// Cursor just hit the button #define MOUSESTAYOVER 8// Cursor stayed over button at least 3 seconds /**************************************************************************/ // TTOOLBAR.CPP Class class _CLASSTYPE TToolBar : public TWindow { protected: int TopBorder,BottomBorder,LeftBorder,RightBorder; int SeparatorSize; int ButtonWidth,ButtonHeight; int ToolBarOrgX,ToolBarOrgY,ToolBarWidth,ToolBarHeight; int ToolBarType,ToolBarRowCol; int MoveableToolBar,VisibleToolBar; public: typedef struct { int Type; int Name; int Group; int IsPressed; int IsEnable; HBITMAP hBmp; char About[ABOUTMSGSIZE]; } BUTTON; PTWindowsObject Main; HFONT AboutFont; BUTTON Button[MAXBUTTONS]; int BarPosX,BarPosY,TotButtons; int LastOver,LastX,LastY,LastStay,ToolBarMsg; PTButtonAbout Abouting; BOOL EnableAbout; virtual LPSTR GetClassName (void){return "STARTUP_TOOLBAR";}; virtual void SetupWindow (void); virtual void WMTimer (RTMessage Msg) = [WM_FIRST + WM_TIMER]; virtual void WMLButtonDown (RTMessage Msg) = [WM_FIRST + WM_LBUTTONDOWN]; virtual void WMMouseMove (RTMessage Msg) = [WM_FIRST + WM_MOUSEMOVE]; virtual void WMLButtonUp (RTMessage Msg) = [WM_FIRST + WM_LBUTTONUP]; virtual void WMPaint (RTMessage Msg) = [WM_FIRST + WM_PAINT]; virtual void PaintBMPButton (int ToolBarPos); virtual void PaintBMPButton (int ToolBarPos,int BaseX,int BaseY,HDC hdc,HDC hdcBmp); virtual void RepaintButtons (int ToolBarPos); virtual void PressButton (int ToolBarPos); virtual void ReleaseButton (int ToolBarPos); virtual int MouseIsOver (int X,int Y); TToolBar(PTWindowsObject Main); ~TToolBar(void); virtual void SelectGroupButton(int ToolBarPos,int Group); virtual void InsertButton (int Type,int ToolBarPos,int Group,int BitmapRCID,LPSTR About); virtual void RemoveButton (int ToolBarPos); virtual void InsertSeparator (int ToolBarPos); virtual void RemoveSeparator (int ToolBarPos); virtual int GetTotButtons (void); virtual void EnableButton (int ToolBarPos); virtual void DisableButton (int ToolBarPos); virtual int GetButtonBmpName (int ToolBarPos); virtual int GetButtonPos (int BmpNumber); virtual void SetToolBarBorders(int TopBorder,int LeftBorder,int BottomBorder,int RightBorder,int SeparatorSize); virtual void SetToolBarButtons(int ButtonWidth,int ButtonHeight); virtual void SetToolBarSize (int ToolBarOrgX,int ToolBarOrgY,int ToolBarWidth,int ToolBarHeight); virtual void SetToolBarType (int ToolBarType); virtual void SetToolBarRowCol (int ToolBarRowCol); virtual void SetToolBarMoveable(int MoveableToolBar); virtual void SetToolBarVisible (int VisibleToolBar); virtual int GetToolBarHeight(); }; /**************************************************************************/ // TTOOLBAR.CPP Class class _CLASSTYPE TButtonAbout : public TWindow { protected: PTWindowsObject Main; HFONT MsgFont; char AboutMsg[ABOUTMSGSIZE]; virtual LPSTR GetClassName (void){return "STARTUP_BUTTONABOUT";}; virtual void WMSize (RTMessage Msg) = [WM_FIRST + WM_SIZE]; virtual void WMPaint (RTMessage Msg) = [WM_FIRST + WM_PAINT]; public: TButtonAbout(PTWindowsObject Main,int PosX,int PosY,LPSTR About); ~TButtonAbout(void); }; TToolBar.cpp - Implementa‡Æo da janela com a Barra de Botäes #include "pcx_bmp1.h" /*************************************************************************/ // Constructor TToolBar::TToolBar(PTWindowsObject AParent) :TWindow(AParent,NULL,NULL) { LOGFONT FRec; RECT R; Main = AParent; // Parent Window ToolBarMsg = WM_USER+CM_TOOLBARACTION; // Message # to Post to Parent Window TopBorder = 4; BottomBorder = 4; LeftBorder = 4; RightBorder = 4; SeparatorSize = 6; ButtonWidth = 24; ButtonHeight = 22; ToolBarOrgX = 0; ToolBarOrgY = 0; GetClientRect(Main->HWindow,&R); ToolBarWidth = R.right; ToolBarHeight = TopBorder+BottomBorder+ButtonHeight; ToolBarType = HORIZONTALTYPE; ToolBarRowCol = 1; MoveableToolBar = TRUE; VisibleToolBar = TRUE; Abouting = NULL; // TButtonAbout Window is not instacieted EnableAbout = TRUE; // Control TButtonAbout presentation TotButtons = NULL; // Total # of buttons loaded LastOver = NONE; // Last Button the cursor is over LastStay = NONE; // Last Button the Stay message was Post LastX = NULL; // Last cursor position, to control About LastY = NULL; // presentation after 2 seconds stoped // Cria fonte para escrver o About memset(&FRec,0,sizeof(LOGFONT)); FRec.lfHeight = 8; FRec.lfWidth = 3; strcpy(&FRec.lfFaceName[0],"Helv"); AboutFont = CreateFontIndirect(&FRec); Attr.Style = WS_CHILD | WS_VISIBLE; SetFlags(WB_MDICHILD, FALSE); } /*************************************************************************/ // TToolBar Destructor TToolBar::~TToolBar() { int i; if(AboutFont) DeleteObject(AboutFont); if(Abouting) delete Abouting; for(i=0;i Apresenta if((LastX == P.x) && (LastY == P.y) && (NowOver!= NONE) && (!Abouting)) { LastStay = NowOver; // Guarda o botÆo a que se refere o About GetCursorPos(&P); ScreenToClient(Main->HWindow,&P); Abouting = (PTButtonAbout)GetApplication()->MakeWindow(new TButtonAbout(Main,P.x+1,P.y+GetSystemMetrics(SM_CYCURSOR)-14,Button[NowOver].About)); PostMessage(Main->HWindow,ToolBarMsg,NowOver,MOUSESTAYOVER); } if(Abouting && (NowOver != LastStay)) { delete Abouting; Abouting = NULL; LastStay = NONE; } GetCursorPos(&P); ScreenToClient(HWindow,&P); LastX = P.x; LastY = P.y; } /*************************************************************************/ // WMLButtonDown() void TToolBar::WMLButtonDown(RTMessage Msg) { int i,X,Y,ToolBarPos; X = MOUSEX(Msg); Y = MOUSEY(Msg); EnableAbout = FALSE; LastX = NULL; // Last cursor position, to control About LastY = NULL; // presentation after 2 seconds stoped if(Abouting) { delete Abouting; Abouting = NULL; } ToolBarPos = MouseIsOver(X,Y); if(ToolBarPos!=NONE) { /* if(!Button[ToolBarPos].IsEnable) { sndPlaySound("SystemExclamation",SND_SYNC); } else { sndPlaySound("MouseClick",SND_SYNC); } */ if(Button[ToolBarPos].IsEnable) { if(Button[ToolBarPos].Group != NULL) { if(!Button[ToolBarPos].IsPressed) { PressButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONPRESSED); for(i=0;iHWindow,ToolBarMsg,i,BUTTONRELEASED); } } } } else if(Button[ToolBarPos].Type == BMPBUTTON) { PressButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONCLICKED); } else if(Button[ToolBarPos].Type == TWOSTATEBMPBUTTON) { if(Button[ToolBarPos].IsPressed) { ReleaseButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONRELEASED); } else { PressButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONPRESSED); } } } } } /*************************************************************************/ // WMMouseMove() void TToolBar::WMMouseMove(RTMessage Msg) { int NowOver,X,Y; X = MOUSEX(Msg); Y = MOUSEY(Msg); if(Abouting) { NowOver = MouseIsOver(X,Y); if(NowOver != LastStay) { delete Abouting; Abouting = NULL; LastStay = NONE; } } } /*************************************************************************/ // WMLButtonUp() void TToolBar::WMLButtonUp(RTMessage) { EnableAbout = TRUE; } /*************************************************************************/ // WMPaint() void TToolBar::WMPaint(RTMessage) { int i; RECT R; HDC hdc; HPEN hPen,OldPen; PAINTSTRUCT ps; hdc = BeginPaint(HWindow, &ps); GetClientRect(HWindow,&R); // Cinza M‚dio (Fundo) hPen = CreatePen(PS_SOLID,1,RGB(192,192,192)); OldPen=(HPEN)SelectObject(hdc, hPen); for(i=0;i=MAXBUTTONS) return; // Posiciona botÆo no fim da ToolBar caso esteja al‚m if(ToolBarPos>TotButtons) ToolBarPos = TotButtons; // Corrige tipo de botÆo para botÆo de grupo if(Button[ToolBarPos].Group != NULL) Button[ToolBarPos].Type = TWOSTATEBMPBUTTON; // Abre espa‡o para novo botÆo caso esteja inserindo no meio if(ToolBarPos=ToolBarPos;i--) { Button[i+1].Type = Button[i].Type; Button[i+1].Name = Button[i].Name; Button[i+1].Group = Button[i].Group; Button[i+1].IsPressed = FALSE; Button[i+1].IsEnable = TRUE; Button[i+1].hBmp = Button[i].hBmp; strcpy(Button[i+1].About,Button[i].About); } } // Cadastra o botÆo na ToolBar Button[ToolBarPos].Type = Type; if(Type != SPACE) { Button[ToolBarPos].Name = BitmapRCID; Button[ToolBarPos].Group = Group; Button[ToolBarPos].IsPressed = FALSE; Button[ToolBarPos].IsEnable = TRUE; Button[ToolBarPos].hBmp = LoadBitmap(GetApplication()- >hInstance,MAKEINTRESOURCE(BitmapRCID)); if(!Button[ToolBarPos].hBmp) return; strcpy(Button[ToolBarPos].About,About); } TotButtons++; // Repinta a ToolBar RepaintButtons(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONINSERTED); } /*************************************************************************/ // RemoveButton() void TToolBar::RemoveButton(int ToolBarPos) { int i; // Se botÆo nÆo existe entÆo ignora if((ToolBarPos<0) || (ToolBarPos>TotButtons-1)) return; PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONREMOVED); // Remove botÆo da ToolBar if(Button[ToolBarPos].Type != SPACE) DeleteObject(Button[ToolBarPos].hBmp); // Puxa os demais botäes para cobrir espa‡o for(i=ToolBarPos;iTotButtons-1)) return; if(Button[ToolBarPos].Type != SPACE) return; else RemoveButton(ToolBarPos); } /*************************************************************************/ // RpaintButtons() void TToolBar::RepaintButtons(int ToolBarPos) { RECT R; HDC hdc,hdcBmp; int i,t,BaseX,BaseY; HPEN hPen,OldPen; BaseX = LeftBorder; BaseY = TopBorder; hdc = GetDC(HWindow); hdcBmp = CreateCompatibleDC(hdc); hPen = CreatePen(PS_SOLID,1,RGB(192,192,192)); OldPen =(HPEN)SelectObject(hdc, hPen); for(i=0;i=ToolBarPos) { // Cinza M‚dio (Fundo) for(t=BaseY;t=ToolBarPos) PaintBMPButton(i,BaseX,BaseY,hdc,hdcBmp); BaseX+=ButtonWidth; } } // Limpa o resto da janela para o caso de ter havido RemoveButton() GetClientRect(HWindow,&R); for(i=TopBorder; iTotButtons-1)) return NULL; if(Button[ToolBarPos].Type != SPACE) return Button[ToolBarPos].Name; else return SPACE; } /*************************************************************************/ // GetButtonPosition() int TToolBar::GetButtonPos(int Name) { int i; for(i=0;iTotButtons-1) return; if(Button[ToolBarPos].Type == SPACE) return; Button[ToolBarPos].IsEnable = TRUE; PaintBMPButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONENABLED); } /*************************************************************************/ // DisableButton() void TToolBar::DisableButton(int ToolBarPos) { if(ToolBarPos<0 || ToolBarPos>TotButtons-1) return; if(Button[ToolBarPos].Type == SPACE) return; Button[ToolBarPos].IsEnable = FALSE; PaintBMPButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONDISABLED); } /*************************************************************************/ // MouseIsOver() int TToolBar::MouseIsOver(int X,int Y) { int i,BaseX; LastOver = NONE; if(XTopBorder+ButtonHeight) return NONE; BaseX = LeftBorder; for(i=0;iBaseX && XBaseX && XHWindow,ToolBarMsg,i,MOUSEHIT); LastOver = i; return i; } BaseX+=ButtonWidth; } } return NONE; } /*************************************************************************/ // SelectGroupButton() void TToolBar::SelectGroupButton(int ToolBarPos,int Group) { int i; if(ToolBarPos<0 || ToolBarPos>TotButtons-1) return; if(Button[ToolBarPos].Group == Group) { PressButton(ToolBarPos); PostMessage(Main->HWindow,ToolBarMsg,ToolBarPos,BUTTONPRESSED); for(i=0;iHWindow,ToolBarMsg,i,BUTTONRELEASED); } } } } /*************************************************************************/ // void TToolBar::SetToolBarBorders(int Top,int Left,int Bottom,int Right,int Separator) { if(Top != SAME) TopBorder =Top; if(Left != SAME) LeftBorder =Left; if(Bottom != SAME) BottomBorder =Bottom; if(Right != SAME) RightBorder =Right; if(Separator != SAME) SeparatorSize=Separator; InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // void TToolBar::SetToolBarButtons(int Width,int Height) { if(Width != SAME) ButtonWidth = Width; if(Height != SAME) ButtonHeight = Height; InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // void TToolBar::SetToolBarSize(int OrgX,int OrgY,int Width,int Height) { if(OrgX != SAME) ToolBarOrgX = OrgX; if(OrgY != SAME) ToolBarOrgY = OrgY; if(Width != SAME) ToolBarWidth = Width; if(Height != SAME) ToolBarHeight = Height; MoveWindow(HWindow,ToolBarOrgX,ToolBarOrgY, ToolBarOrgX+ToolBarWidth,ToolBarOrgY+ToolBarHeight,TRUE); } /*************************************************************************/ // void TToolBar::SetToolBarType(int Type) { ToolBarType = Type; InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // void TToolBar::SetToolBarRowCol (int RowCol) { ToolBarRowCol = RowCol; InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // void TToolBar::SetToolBarMoveable(int Moveable) { MoveableToolBar = Moveable; InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // void TToolBar::SetToolBarVisible (int Visible) { VisibleToolBar = Visible; InvalidateRect(HWindow,NULL,FALSE); } /*************************************************************************/ // int TToolBar::GetToolBarHeight() { return ToolBarHeight; } /********************************* End ***********************************/ /*************************************************************************/ /******************************** TButtonAbout ***************************/ /*************************************************************************/ /*************************************************************************/ // TButtonAbout Constructor TButtonAbout::TButtonAbout(PTWindowsObject AParent,int PosX,int PosY,LPSTR About) :TWindow(AParent,NULL,NULL) { LOGFONT FRec; Main = AParent; strcpy(AboutMsg,About); // Cria fonte de mensagens memset(&FRec,0,sizeof(LOGFONT)); FRec.lfHeight = 8; FRec.lfWidth = 3; strcpy(&FRec.lfFaceName[0],"Helv"); MsgFont = CreateFontIndirect(&FRec); Attr.X = PosX; Attr.Y = PosY; Attr.Style = WS_CHILD | WS_VISIBLE; } /*************************************************************************/ // TButtonAbout Destructor TButtonAbout::~TButtonAbout() { if(MsgFont) DeleteObject(MsgFont); } /*************************************************************************/ // WMSize() void TButtonAbout::WMSize(RTMessage) { HFONT OldFont; HDC hdc; DWORD Aux; RECT R; POINT P; hdc = GetDC(HWindow); OldFont = (HFONT)SelectObject(hdc,MsgFont); Aux = GetTextExtent(hdc,AboutMsg,lstrlen(AboutMsg)); SelectObject(hdc,OldFont); ReleaseDC(HWindow,hdc); GetWindowRect(HWindow,&R); P.x = R.left; P.y = R.top; ScreenToClient(Main->HWindow,&P); MoveWindow(HWindow,P.x,P.y,LOWORD(Aux)+6,HIWORD(Aux)+5,TRUE); } /*************************************************************************/ // WMPaint() void TButtonAbout::WMPaint(RTMessage Msg) { RECT R; HFONT OldFont; HDC hdc; int i; HPEN hPen,OldPen; TWindow::WMPaint(Msg); hdc = GetDC(HWindow); GetClientRect(HWindow,&R); R.bottom--; R.right--; // Amarelo Claro (Fundo) hPen = CreatePen(PS_SOLID,1,RGB(255,255,0)); OldPen=(HPEN)SelectObject(hdc, hPen); for(i=0;i(YF-YI)){for(i=YI;ihInstance,FindResource(GetApplication()- >hInstance,MAKEINTRESOURCE(MACEDO),RT_BITMAP)); if(hResource==NULL) MessageBox(HWindow,"Unable to find my boss !","Error",MB_OK | MB_ICONEXCLAMATION); BmI = (BITMAPINFO *)GlobalLock(hResource); if(BmI==NULL) MessageBox(HWindow,"Unable to lock memory !","Error",MB_OK | MB_ICONEXCLAMATION); Size = sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD)); Pixels = (LPSTR)BmI+Size; for(i=0; i<256; i++) Pal->SetPalIndex(i,RGB(BmI->bmiColors[i].rgbRed,BmI->bmiColors[i].rgbGreen,BmI- >bmiColors[i].rgbBlue)); hdc = GetDC(HWindow); if(hdc==NULL) MessageBox(HWindow,"Unable to get screen context !","Error",MB_OK | MB_ICONEXCLAMATION); Pal->InstallPalette(hdc); hdcBmp = CreateCompatibleDC(hdc); if(hdcBmp==NULL) MessageBox(HWindow,"Unable to get bitmap context !","Error",MB_OK | MB_ICONEXCLAMATION); Pal->InstallPalette(hdcBmp); AboutBmp = CreateDIBitmap(hdc, &BmI->bmiHeader, CBM_INIT, Pixels, BmI, DIB_RGB_COLORS); if(AboutBmp==NULL) MessageBox(HWindow,"Error creating bitmap !","Error",MB_OK | MB_ICONEXCLAMATION); SelectObject(hdcBmp,AboutBmp); GlobalUnlock(hResource); FreeResource(hResource); if(NULL==BitBlt(hdc,10,10,84,99,hdcBmp,0,0,SRCCOPY)) MessageBox(HWindow,"Error copying bitmap !","Error",MB_OK | MB_ICONEXCLAMATION); DeleteDC(hdcBmp); DeleteObject(AboutBmp); ReleaseDC(HWindow,hdc); delete Pal; } /**************************************************************************/ // CanClose() void TAboutDlg::Ok(RTMessage Msg) { TDialog::Ok(Msg); } TGenFunc.h - Fun‡äes de uso geral _CLASSDEF(TGenFunc) #define MOUSEX(arg) (arg.LP.Lo) #define MOUSEY(arg) (arg.LP.Hi) /**************************************************************************/ // Large Blocks Memory Manager Functions typedef WORD (FAR PASCAL *PTDEVMODEFUNC)(HWND, HANDLE, LPSTR, LPSTR); extern "C" {void FAR PASCAL __ahIncr();} /**************************************************************************/ // TGENFUNC.CPP Classes class _CLASSTYPE TGenFunc { public: PTWindowsObject Main; TGenFunc(PTWindowsObject Main); ~TGenFunc(void); LPSTR GetFileName (LPSTR FilePath); LPSTR GetExtension(LPSTR FilePath); BOOL HasWildCards(LPSTR FilePath); void ChangeExt (LPSTR String,LPSTR NewExt); double G2R (double Graus); double R2G (double Radianos); BOOL Equal (Pchar S1, Pchar S2); int LoadString2 (UINT idResource, LPSTR lpszBuffer); }; TGenFunc.cpp - Fun‡äes de uso geral #include "pcx_bmp1.h" /*************************************************************************/ // TGenFunc Constructor TGenFunc::TGenFunc(PTWindowsObject AParent) { Main = AParent; } /*************************************************************************/ // TGenFunc Destructor TGenFunc::~TGenFunc() { } /**************************************************************************/ LPSTR TGenFunc::GetFileName(LPSTR FilePath) { LPSTR P; P = _fstrrchr(FilePath, '\\'); if ( !P ) P = _fstrrchr(FilePath, ':'); if ( !P ) return FilePath; else return P + 1; } /**************************************************************************/ LPSTR TGenFunc::GetExtension(LPSTR FilePath) { LPSTR P; P = _fstrchr(GetFileName(FilePath), '.'); if ( !P ) return _fstrchr(FilePath, '\0'); else return P; } /**************************************************************************/ BOOL TGenFunc::HasWildCards(LPSTR FilePath) { return _fstrchr(FilePath, '\*') || _fstrchr(FilePath, '\?'); } /**************************************************************************/ void TGenFunc::ChangeExt(LPSTR String,LPSTR NewExt) { LPSTR Ptr; Ptr = _fstrchr(String,'.'); if(!Ptr ) _fstrcat(String,NewExt); else _fstrcpy(Ptr,NewExt); }