Ir ao conteúdo
  • Cadastre-se
Cambalinho

Como salvar 1 estrutura num ficheiro?

Recommended Posts

eu fiz 2 funcçoes para salvar e ler 1 estrutura num ficheiro:

//save a structure object to a file
template<typename structure>
void SaveDataBase(string filename,structure *StructureVariable )
{
    remove(filename.c_str());
    ofstream WriteOnFile(filename.c_str());
    WriteOnFile.write(reinterpret_cast<char*>(StructureVariable), sizeof(structure));
    WriteOnFile.close();
}
  
//read a structure object from a file
template<typename structure>
void ReadDataBase(string filename,structure *StructureVariable )
{
    ifstream ReadFromFile(filename.c_str());
    ReadFromFile.read(reinterpret_cast<char*>(StructureVariable), sizeof(structure)-1);
    ReadFromFile.close();
}

ambas funçoes dao-me resultados.

mas se salvar esta estrutura:

struct user
{
    string name;//C++ type
    int age;
    image foto;//my own class
};

ao encerrar o programa, ele fica alguns segundos activo e depois encerra, mas com 1 erro no exit.

ja ouvi falar da serializaçao, mas nao queria usar librarias externas. eu quero fazer o meu codigo.

alguem me pode dar umas dicas?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu compilei seu exemplo da seguinte forma e não me deu erro algum, porém recomendo tomar algo de cuidado com o alinhamento dos Bytes na hora de fazer leituras para não obter erros inesperados.

#include <iostream>
#include <fstream>
using namespace std;

class image {
public:
    image(): altura(0), largura(0), ppp(0) {}
    ~image() {}
    

    int altura;
    int largura;
    int ppp;
};


struct user {
    user(): name(std::move(name)), age(0), foto(){}
    std::string name;//C++ type
    int age;
    image foto;//my own class
};

//save a structure object to a file
template<typename structure>
void SaveDataBase(string filename,structure *StructureVariable ){
    remove(filename.c_str());
    ofstream WriteOnFile(filename.c_str());
    WriteOnFile.write(reinterpret_cast<char*>(StructureVariable), sizeof(structure));
    WriteOnFile.close();
}

//read a structure object from a file
template<typename structure>
void ReadDataBase(string filename,structure *StructureVariable )
{
    ifstream ReadFromFile(filename.c_str());
    ReadFromFile.read(reinterpret_cast<char*>(StructureVariable), sizeof(structure)-1);
    ReadFromFile.close();
}

int main () {

    user dados; //{0} para não mostrar lixo.
    
    dados.name = "marcos";
    dados.age  = 22;
    dados.foto.altura  = 800;
    dados.foto.largura = 600;
    dados.foto.ppp     = 300;
    
    string path = "lol.dat"; 
    SaveDataBase( path, &dados);
    
    user dados2;
    ReadDataBase( path, &dados2);

    cout << dados2.name << dados2.foto.ppp;
    return 0;
}

Como não tinha a classe image inventei uma. Como pode ver tudo vai corretamente, ou isso acho.

Nesses casos eu gosto de enviar os dados serializados ao arquivo.

 

sorte

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

então tenho 1 erro na image sem dar conta:

//Creates a HDC object
//returns a HDC object

class MemoryDC
{
private:
    HDC memoryDC;

public:
    //creates a HDC object from desktop
    MemoryDC ()
    {
        HDC hdc=GetDC(GetDesktopWindow());
        memoryDC=CreateCompatibleDC(hdc);
        ReleaseDC(GetDesktopWindow(),hdc);
    }

    //returns the HDC object
    operator HDC() const
    {
        return memoryDC;
    }

    //deletes the HDC
    ~MemoryDC ()
    {
       DeleteDC(memoryDC);
    }
};

//creates a hbtimap object with a HDC object
//these class returns a HDC object
//these class retrun
class BitmapDC
{
private:
    MemoryDC hdcbitmap;
    HGDIOBJ bitmapold;
    HBITMAP bitmapcurrent;
    HBITMAP bitmapcurrent2;
    COLORREF clrBackColor=RGB(0,0,0);

    int intwidth;
    int intheight;

    void init(int width, int height,COLORREF backcolor=RGB(0,0,0))
    {
        bitmapcurrent = CreateBitmap(width, height, 1, 32, NULL);
        bitmapold = SelectObject(hdcbitmap, bitmapcurrent);
        RECT rect={0,0,width, height};
        HBRUSH hbrBackColor=CreateSolidBrush(backcolor);
        FillRect(hdcbitmap,&rect,hbrBackColor);
        DeleteBrush(hbrBackColor);
        intwidth=width;
        intheight=height;
    }

    void destroy()
    {
        SelectObject(hdcbitmap, bitmapold);
        DeleteObject(bitmapcurrent);
    }

public:

    BitmapDC(int width, int height, COLORREF backcolor=RGB(0,0,0))
    {
        clrBackColor=backcolor;
        destroy();
        init(width, height,backcolor);
        DeleteBitmap(bitmapcurrent2);
        bitmapcurrent2 = HBITMAPfromHDC(hdcbitmap);
    }

    BitmapDC()
    {
        destroy();
        init(1, 1);
        DeleteBitmap(bitmapcurrent2);
        bitmapcurrent2 = HBITMAPfromHDC(hdcbitmap);
    }

    void resize(int width, int height, COLORREF backcolor=RGB(0,0,0))
    {
        destroy();
        init(width, height, backcolor);
        clrBackColor=backcolor;
        DeleteBitmap(bitmapcurrent2);
        bitmapcurrent2 = HBITMAPfromHDC(hdcbitmap);
    }

    COLORREF GetBackColor()
    {
        return clrBackColor;
    }

    void SetBackColor(COLORREF backcolor)
    {
        clrBackColor=backcolor;
        MemoryDC mdc;
        HBITMAP bitmapcurrent3 = CreateBitmap(intwidth, intheight, 1, 32, NULL);
        HBITMAP bitmapold2 = (HBITMAP)SelectObject(mdc, bitmapcurrent3);
        RECT rect={0,0,intwidth, intheight};
        HBRUSH hbrBackColor=CreateSolidBrush(backcolor);
        FillRect(mdc,&rect,hbrBackColor);
        TransparentBlt(mdc,0,0,intwidth, intheight,hdcbitmap,0,0,intwidth, intheight, GetPixel(hdcbitmap,intwidth-1, intheight-1));
        FillRect(hdcbitmap,&rect,hbrBackColor);
        DeleteBrush(hbrBackColor);
        TransparentBlt(hdcbitmap,0,0,intwidth, intheight,mdc,0,0,intwidth, intheight, GetPixel(mdc,intwidth-1, intheight-1));
        SelectObject(mdc, bitmapold2);
        DeleteObject(bitmapcurrent3);
    }

    int Width()
    {
        return intwidth;
    }

    int Height()
    {
        return intheight;
    }

    BitmapDC& operator= (const BitmapDC &bitmapsource)
    {
        if (this == &bitmapsource)      // Same object?
            return *this;
        destroy();
        DeleteBitmap(bitmapcurrent2);
        init(bitmapsource.intwidth, bitmapsource.intheight);
        BitBlt(hdcbitmap, 0, 0, intwidth, intheight, bitmapsource.hdcbitmap, 0, 0, SRCCOPY);
        bitmapcurrent2 = HBITMAPfromHDC(hdcbitmap);
        return *this;
    }

    BitmapDC& operator= (const HBITMAP bitmapsource)
    {
        DeleteBitmap(bitmapcurrent2);
        destroy();
        BITMAP bm;
        GetObject(bitmapsource,sizeof(bm),&bm);
        init(bm.bmWidth, bm.bmHeight);
        DrawHBITMAPtoHDC(bitmapsource,hdcbitmap);
        bitmapcurrent2 = HBITMAPfromHDC(hdcbitmap);
        return *this;
    }

    //testing the bitmao value if is nullptr
    bool operator != ( nullptr_t ) const
    {
        return bitmapcurrent != nullptr;
    }

    bool operator==(const BitmapDC &other) const
    {
        return (other.bitmapcurrent == this->bitmapcurrent);
    }

    bool operator!=(const BitmapDC &other) const
    {
        return !(*this == other);
    }

    operator HBITMAP()
    {
        return bitmapcurrent2;
    }

    operator HDC() const
    {
        return hdcbitmap;
    }

    ~BitmapDC()
    {
       destroy();
       DeleteBitmap(bitmapcurrent2);
    }
};
class image
{
private:
    ULONG_PTR m_gdiplusToken;
    Gdiplus::GdiplusStartupInput gdiplusStartupInput=NULL;
    BitmapDC HBitmap;
    Image *img=NULL;
    int imageheight=0;
    int imageweight=0;
    int framecount=0;
    int intSelectFrame=0;
    int framedelay=0;
    string strfilename="";
    COLORREF clrBackColor=RGB(0,0,0);
    bool blnTransparent=true;
    HPEN imgPen;
    HBRUSH imgBrush;
    CHOOSEFONT chFont;
    HICON hIcon;
    HBITMAP hbmMask;
    int intRotate=0;
    Timer tmrAnimation;
    BitmapDC OriginalBitmap;

    void UpdateReturnBitmap()
    {
        HDC dstdc = CreateCompatibleDC(HBitmap); // Note: compatible to the dc in question
        HGDIOBJ hold = SelectObject(dstdc,hbmMask);
        BitBlt(dstdc,0,0,imageweight, imageheight, HBitmap,0,0, SRCCOPY);
        SelectObject(dstdc,hold); // Note: you cannot select a bitmap twice into different dc, hence unselect it here
        DeleteDC(dstdc);
    }

    void readimagefile(string filename)
    {
        if (img!=NULL)
            delete img;
        strfilename=filename;
        BeforeDrawImage(intSelectFrame);
        if(toupper(filename[filename.size()-3])=='C' && toupper(filename[filename.size()-2])=='U' && toupper(filename[filename.size()-1])=='R')
        {
            //create the transparent icon handle
            HCURSOR hicon = (HCURSOR)LoadImage(NULL, filename.c_str(), IMAGE_CURSOR, imageweight, imageheight, LR_LOADFROMFILE|LR_SHARED|LR_DEFAULTSIZE|LR_LOADTRANSPARENT);
            ICONINFO ii;
            BOOL fResult = GetIconInfo(hicon, &ii);
            if (fResult)
            {
                BITMAP bm;
                fResult = GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm);
                if (fResult)
                {
                    imageweight= bm.bmWidth;
                    imageheight= ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
                }
                if (ii.hbmMask)
                    DeleteObject(ii.hbmMask);
                if (ii.hbmColor)
                    DeleteObject(ii.hbmColor);
            }
            HBitmap.resize(imageweight,imageheight);
            DrawIconEx(HBitmap,0,0,hicon,imageweight,imageheight,0,0,DI_NORMAL);
            framecount=1;
            DestroyCursor(hicon);
        }
        else
        {
            Gdiplus::Image img2(towstring(filename).c_str());
            imageweight=img2.GetWidth();
            imageheight=img2.GetHeight();
            HBitmap.resize(imageweight,imageheight);
            Gdiplus::Graphics graphics(HBitmap);
            Matrix rotatepoint;
            PointF rotatezeropoint={(REAL)imageweight/2,(REAL)imageheight/2};
            rotatepoint.RotateAt(intRotate,rotatezeropoint);

            graphics.SetTransform(&rotatepoint);
            graphics.DrawImage(&img2, 0,0,imageweight,imageheight);

            UINT count = 0;
            count = img2.GetFrameDimensionsCount();
            vector<GUID> pDimensionIDs;
            pDimensionIDs.resize(count);
            img2.GetFrameDimensionsList(pDimensionIDs.data(), pDimensionIDs.size());
            framecount=img2.GetFrameCount(pDimensionIDs.data());
            framedelay =img2.GetPropertyItemSize(PropertyTagFrameDelay);
            img=new Image(towstring(filename).c_str());
            if(framecount>1)
            {
                tmrAnimation.timerprocedure=[&]()
                {
                    static int intFrame=0;
                    intFrame=intFrame+1;
                    if(intFrame==framecount)
                        intFrame=0;
                    SelectFrame=intFrame;
                };
                tmrAnimation.Interval=framedelay;
                tmrAnimation.Start();
            }
        }
        DeleteBitmap(hbmMask);
        hbmMask = HBITMAPfromHDC(HBitmap);
        UpdateReturnBitmap();

        //these is for do the reset option:
        OriginalBitmap=HBitmap;
        DrawImage(intSelectFrame);
        AfterDrawImage(intSelectFrame);
    }

public:

    Event<int> BeforeDrawImage;
    Event<int> DrawImage;
    Event<int> AfterDrawImage;

    void Reset()
    {
        HBitmap=OriginalBitmap;
        UpdateReturnBitmap();
        DrawImage(intSelectFrame);
        AfterDrawImage(intSelectFrame);
    }

    void resize(const int width, const int height, bool blnEmpty=true)
    {

        BitmapDC bdc(height,height);
        if(blnEmpty==false)
            BitBlt(bdc,0,0,HBitmap.Width(), HBitmap.Height(),HBitmap,0,0,SRCCOPY);
        HBitmap.resize(width,height);
        if(blnEmpty==false)
            BitBlt(HBitmap ,0,0,HBitmap.Width(), HBitmap.Height(),bdc,0,0,SRCCOPY);
        imageheight=height;
        imageweight=width;
        DeleteBitmap(hbmMask);
        hbmMask = HBITMAPfromHDC(HBitmap);
    }

    image()
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        imageheight=1;
        imageweight=1;
        HBitmap.resize(imageweight,imageheight);
        DeleteBitmap(hbmMask);
        hbmMask = HBITMAPfromHDC(HBitmap);
    }

    image(const int width, const int height, COLORREF backcolor=RGB(0,0,0))
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        framecount=1;
        imageheight=height;
        imageweight=width;
        HBitmap.resize(imageweight,imageheight,backcolor);
        clrBackColor=backcolor;
        DeleteBitmap(hbmMask);
        hbmMask = HBITMAPfromHDC(HBitmap);
    }

    image( const string & filename)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        readimagefile(filename);
    }

    image ( const image &cSource)
    {
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        readimagefile(cSource.strfilename);
        BitBlt(HBitmap,0,0,imageweight,imageheight,cSource.HBitmap,0,0,SRCCOPY);
    }

    image& operator= (const image &cSource)
    {
        if (this == &cSource)      // Same object?
            return *this;
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
        DeleteObject(hIcon);
        DeleteBitmap(hbmMask);
        readimagefile(cSource.strfilename);
        BitBlt(HBitmap,0,0,imageweight,imageheight,cSource.HBitmap,0,0,SRCCOPY);
        return *this;
    }

    void Pen(int PenStyle, int PenSize, COLORREF PenColor)
    {
        imgPen=CreatePen(PenStyle,PenSize,PenColor);
    }

    void Pen(HPEN hPen)
    {
        imgPen=hPen;
    }

    void Brush(HBRUSH BrushColor)
    {
        imgBrush = BrushColor;
    }

    void Brush(COLORREF BrushColor)
    {
        imgBrush=CreateSolidBrush(BrushColor);
    }

    void Brush(HBITMAP BrushImage)
    {
        imgBrush=CreatePatternBrush(BrushImage);
    }

    void Brush(int HatchedStyle, COLORREF HatchedColor )
    {
        imgBrush=CreateHatchBrush(HatchedStyle, HatchedColor);
    }

    void DrawControlBackground(string classname, int part, int state, RECT rectdestination)
    {
        HDC destination=HBitmap;
        HTHEME htheme=OpenThemeData(GetFocus(),towstring(classname).c_str());
        DrawThemeBackground(htheme, destination, part, state, &rectdestination, NULL);
        CloseThemeData(htheme);
    }

    void DrawRectangle(int PosX, int PosY, int Width, int Height, int EllipseWidth=0, int EllipseHeight=0)
    {
        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        RoundRect(HBitmap, PosX, PosY, Width + PosX, Height + PosY, EllipseWidth, EllipseHeight);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);
        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

    void DrawEllipse(int PosX, int PosY, int Width, int Height)
    {
        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        Ellipse(HBitmap, PosX, PosY, Width + PosX, Height + PosY);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);
        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

    void DrawLine(int PosX, int PosY, int PosX2, int PosY2)
    {
        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        MoveToEx(HBitmap, PosX,PosY, NULL);
        LineTo(HBitmap, PosX2,PosY2);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);
        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

    void DrawTriangle(POINT vertice1, POINT vertice2, POINT vertice3)
    {

        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        //vertice 1 on left
        MoveToEx(HBitmap, vertice1.x,vertice1.y, NULL);
        LineTo(HBitmap, vertice2.x,vertice2.y);

        //vertice 2 on top
        MoveToEx(HBitmap, vertice2.x,vertice2.y, NULL);
        LineTo(HBitmap, vertice3.x,vertice3.y);

        //vertice 3 on bottom
        MoveToEx(HBitmap, vertice3.x,vertice3.y, NULL);
        LineTo(HBitmap, vertice1.x,vertice1.y);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);
        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

    void TextColor(COLORREF txtColor)
    {
        SetTextColor(HBitmap,txtColor);
    }

    void Font(CHOOSEFONT chft)
    {
        chFont=chft;
    }

    void DrawText(string strText,int PosX=0, int PosY=0)
    {
        // geting the text rectangle
        RECT r = { 0, 0, 0, 0 };
        char *text=(char*)strText.c_str();


        //draw the text

        HBRUSH hBackBrush=(HBRUSH)imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        HFONT hFont=CreateFontIndirect(chFont.lpLogFont);
        HFONT holdfont=(HFONT)SelectObject((HDC)HBitmap,hFont);
        SetTextColor(HBitmap,chFont.rgbColors);

        //change the position of the text

        ::DrawText(HBitmap, text, -1,&r,DT_LEFT | DT_EXPANDTABS | DT_CALCRECT);
        r.left+=PosX;
        r.top+=PosY;
        r.bottom+= PosX;
        r.right+= PosY;
        SetBkColor(HBitmap,GetPixel(HBitmap,0,0));
        SetBkMode(HBitmap,TRANSPARENT);
        ::DrawText(HBitmap, text, -1,&r,DT_LEFT | DT_EXPANDTABS | DT_END_ELLIPSIS | DT_NOCLIP );

        SelectObject(HBitmap,holdfont);
        DeleteBrush(hFont);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);

        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

    property <int> SelectFrame
    {
        Get(int)
        {
            return intSelectFrame;
        },
        Set(int selectframe)
        {
            if(intSelectFrame<0)
                intSelectFrame=0;
            else if (intSelectFrame>=framecount)
                intSelectFrame=framecount-1;
            else
                intSelectFrame=selectframe;
            BeforeDrawImage(intSelectFrame);
            UINT count = 0;
            count = img->GetFrameDimensionsCount();
            vector<GUID> pDimensionIDs;
            pDimensionIDs.resize(count);
            img->GetFrameDimensionsList(pDimensionIDs.data(), pDimensionIDs.size());
            img->SelectActiveFrame(&pDimensionIDs[0],intSelectFrame);
            Gdiplus::Graphics graphics(HBitmap);
            Gdiplus::Color clrbackcolor;
            clrbackcolor.SetFromCOLORREF(clrBackColor);
            graphics.Clear(clrbackcolor);
            Matrix rotatepoint;
            PointF rotatezeropoint={(REAL)imageweight/2,(REAL)imageheight/2};
            rotatepoint.RotateAt(intRotate,rotatezeropoint);
            graphics.SetTransform(&rotatepoint);
            graphics.DrawImage(img, 0, 0, imageweight, imageheight);
            DrawImage(intSelectFrame);
            AfterDrawImage(intSelectFrame);
        }
    };

    property <int> Rotate
    {
        Get(int)
        {
            return intRotate;
        },
        Set(int rotate)
        {

            UINT count = 0;
            count = img->GetFrameDimensionsCount();

            vector<GUID> pDimensionIDs;


            pDimensionIDs.resize(count);

            img->GetFrameDimensionsList(pDimensionIDs.data(), pDimensionIDs.size());
            img->SelectActiveFrame(&pDimensionIDs[0],intSelectFrame);
            Gdiplus::Graphics graphics(HBitmap);
            Gdiplus::Color clrbackcolor;
            clrbackcolor.SetFromCOLORREF(clrBackColor);
            graphics.Clear(clrbackcolor);
            Matrix rotatepoint;
            PointF rotatezeropoint={(REAL)imageweight/2,(REAL)imageheight/2};
            rotatepoint.RotateAt(intRotate,rotatezeropoint);
            graphics.SetTransform(&rotatepoint);
            graphics.DrawImage(img, 0, 0, imageweight, imageheight);
            DrawImage(intSelectFrame);
        }
    };

    void getImageFromResource(string strResourceName)
    {
        HGLOBAL hGlobal;
        LPSTREAM pStream;

        HRSRC hRsrc = FindResource(NULL, strResourceName.c_str(), RT_RCDATA);
        HGLOBAL hGlob1 = LoadResource(NULL, hRsrc);
        int size = SizeofResource(NULL, hRsrc);
        hGlobal = GlobalAlloc(GMEM_FIXED, size);
        LPVOID resPtr = LockResource(hGlob1);
        memcpy(hGlobal, resPtr, size);
        FreeResource(hGlobal);

        CreateStreamOnHGlobal(hGlobal, true,&pStream);
        //img = new Image(pStream, false);
    }

    int GetLastImageError()
    {
        return img->GetLastStatus();
    }

    property<int> FrameCount
    {
        Get(int)
        {
            return framecount;
        }
    };

    property<int> FrameDelay
    {
        Get(int)
        {
            return framedelay;
        }
    };

    property<string> FileName
    {
        Get(string)
        {
            return strfilename;
        },
        Set(string filename)
        {
            readimagefile(filename);
        }
    };

    property<COLORREF> Backcolor
    {
        Get(COLORREF)
        {
            return clrBackColor;
        },
        Set(COLORREF bkcolor)
        {
            if(bkcolor==-1)
            {
                blnTransparent=true;
            }
            else
            {
                blnTransparent=false;
                clrBackColor=bkcolor;
                HBitmap.SetBackColor(clrBackColor);
            }
        }
    };

    void draw(HDC control, long posX=0, long posY=0)
    {
        if (blnTransparent==true)
        {
            TransparentBlt(control, posX, posY,width(),height(),HBitmap, 0, 0,width(), height(), GetPixel(HBitmap,0,0));
        }
        else
        {
            BitBlt(control,posX,posY,width(),height(),HBitmap,0,0,SRCCOPY);
        }
    }

    operator string() const
    {
        return strfilename;
    }

    operator HICON()
    {
        DestroyIcon(hIcon);
        UpdateReturnBitmap();
        ICONINFO ii = {0};
        ii.fIcon    = TRUE;
        ii.hbmColor = hbmMask;
        ii.hbmMask  = hbmMask ;
        hIcon = CreateIconIndirect(&ii);
        return hIcon;
    }

    operator HBITMAP()
    {
        UpdateReturnBitmap();
        return hbmMask;
    }

    int height()
    {
        return imageheight;
    }

    int width()
    {
        return imageweight;
    }

    operator HDC()
    {
        return HBitmap;
    }

    bool operator != ( nullptr_t ) const
    {
        return HBitmap != nullptr;
    }

    bool operator==(const image &other) const
    {
        return (other.HBitmap == this->HBitmap);
    }

    bool operator!=(const image &other) const
    {
        return !(*this == other);
    }

    bool haveimage()
    {
        if((HBITMAP)HBitmap==nullptr)
            return false;
        else
            return true;
    }

    void save(string filename)
    {
        CLSID pngClsid;
        GetEncoderClsid(L"image/gif", &pngClsid);
        EncoderParameters encoderParameters;
        encoderParameters.Count = 1;
        encoderParameters.Parameter[0].Guid = EncoderQuality;
        encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
        encoderParameters.Parameter[0].NumberOfValues = 1;
        std::wstring widestr = std::wstring(filename.begin(), filename.end());
        const wchar_t* widecstr = widestr.c_str();
        img->Save(widecstr, &pngClsid, &encoderParameters);
    }

    friend std::ostream& operator << (std::ostream& lhs, const image& rhs)
    {

        //Create an empty IStream:
        IStream* pIStream;
        if(CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
            DebugText("error on creating an empty IStream");

        //choose image format for save it on IStream:
        // Get encoder class id for jpg compression
        // for other compressions use
        //    image/bmp
        //    image/jpeg
        //    image/gif
        //    image/tiff
        //    image/png
        CLSID pngClsid;
        GetEncoderClsid(L"image/gif", &pngClsid);

        // Setup encoder parameters
        EncoderParameters encoderParameters;
        encoderParameters.Count = 1;
        encoderParameters.Parameter[0].Guid = EncoderQuality;
        encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
        encoderParameters.Parameter[0].NumberOfValues = 1;

        // setup compression level
        ULONG quality = 50;
        encoderParameters.Parameter[0].Value = &quality;

        //  Save the image to the stream
        if(rhs.img->Save(pIStream, &pngClsid, &encoderParameters) != Ok)
        {
            pIStream->Release();
            DebugText("error on saving to IStream");
        }

        //getting the stream size:

        STATSTG sts;
        pIStream->Stat(&sts, STATFLAG_DEFAULT);
        ULARGE_INTEGER uli = sts.cbSize;
        LARGE_INTEGER zero;
        zero.QuadPart = 0;
        int size = (int)uli.QuadPart;
        ULONG written;
        char* bits = new char[size];
        pIStream->Seek(zero, STREAM_SEEK_SET, NULL);
        pIStream->Read(bits, size, &written);

        //write the stream size on file
        //lhs.write(reinterpret_cast<char*>(&size),sizeof(size));
        lhs<<size;
        //write pBuff data on file
        lhs.write(reinterpret_cast<char*>(bits),size);
        //clean resources
        delete[] bits;
        pIStream->Release();

        return lhs;
    }

    friend std::istream& operator >> (std::istream& lhs, image& rhs)
    {
        //getting IStream size:
        SIZE_T streamsize;
        //lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
        lhs>>streamsize;
        // getting IStream data:
        IStream* pIStream;
        HGLOBAL hg= ::GlobalAlloc(GMEM_MOVEABLE,streamsize);
        void* p =GlobalLock(hg);
        lhs.read(reinterpret_cast<char*>(p),streamsize);
        GlobalUnlock(hg);

        if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
            DebugText("error on creating an empty IStream");


        LARGE_INTEGER zero;
        zero.QuadPart = 0;
        pIStream->Seek(zero, STREAM_SEEK_SET, NULL);
        //reading IStream to Image class:
        rhs.img=Image::FromStream(pIStream);
        Status stat = rhs.img->GetLastStatus();
        if(stat!=S_OK)
            DebugText("error reading stream to Image: "  + to_string(stat));
        else
        {
            DebugText("reading stream to Image sucessfull");
        }


        //realease resources:
        pIStream->Release();
        GlobalFree(hg);
        free(p);
        MessageBox("reading stream to Image sucessfull");
        return lhs;
    }

    ~image()
    {
        delete img;
        Gdiplus::GdiplusShutdown(m_gdiplusToken);
        DeleteObject(hIcon);
        DeleteBitmap(hbmMask);
    }
};

podes testar esta class, mas falta alguma funçoes dependentes... desculpa.

desculpa se faltar algumas funçoes para testares, por isso avisa.

obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Posso lhe dizer o que acho? Por que você quer enviar a classe completamente para o arquivo? Por que você não envia cada dado por separado? Assim você evitaria problemas de alinhamento dos dados. Para ler é só fazer o processo inverso.

Pense que uma classe é um conjunto de dados. Nesse conjunto também inclui ponteiros e etc, os ponteiros sabemos que são variáveis locais que apontam a valores que estão em outra parte, em um desses casos pode acontecer que você envie a classe com o ponteiro ao arquivo, porém o valor realmente fique de fora, o que seria enviado ao arquivo é a direção de memória onde estaria o dado, porém nós sabemos que isso muda a cada execução. Chegou a pensar nisso?

Enviando cada dado por separado ou transformando tudo em uma bonita string você está garantindo que todos os dados vaiam a parar tal como você quer no arquivo, e não como sei lá fizer o programa com estes casts atrozes, prefiro ter o controle total eu mesmo.

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

tive mesmo que serializar a class:

//serializar a string:
std::ostream& operator << (std::ostream& lhs, string& rhs)
{
    int stringsize=rhs.length()+1;
    char *cstr = new char[stringsize];
    strcpy(cstr, rhs.c_str());
    lhs<<stringsize;
    lhs.write(cstr,stringsize);
    delete []cstr;
    return lhs;
}


std::istream& operator >> (std::istream& lhs, string& rhs)
{
    int stringsize;
    lhs>>stringsize;
    char *chrfilename;
    lhs.read(chrfilename, stringsize);
    rhs=chrfilename;
    return lhs;
}

//user class:
struct user
{
    string name;//C++ type
    int age;
    image foto;//my own class

    void write(std::ostream& stream)
    {
        stream << name << age << foto;
    }

    void read(std::istream& stream)
    {
        stream >> name >> age >> foto;
    }
};

//save a structure object to a file
template<typename structure>
void SaveDataBase(string filename,structure *StructureVariable )
{
    remove(filename.c_str());
    ofstream WriteOnFile(filename.c_str(), ios::out | ios::binary);
    StructureVariable->write(WriteOnFile);
    WriteOnFile.close();
}

//read a structure object from a file
template<typename structure>
void ReadDataBase(string filename,structure *StructureVariable )
{
    ifstream ReadFromFile(filename.c_str(), ios::in | ios::binary);
    StructureVariable->read(ReadFromFile);
    ReadFromFile.close();
}

agora obtenho a string correctamente.

vou ter de corrigir o operator<< e operator>> da minha classe image. mas agora parece estar a correr melhor.

sim. tens razao... se a class nao tiver read ou isso, dá erro. talvez eu consiga corrigir isso com o tempo. penso que é só subscrever o operator>> e operator<<, mas ainda estou a testar.

muito obrigado

testa essa subscriçao do string, está legal ;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

quando se trata de enviar dados a arquivos o pela net, sempre é boa pratica serializa-los antes. Já sei que serializa-los custa mais trabalho, sem duvida seria bem mais fácil faze-lo como você quer, mas como podemos ver,  podem dar erros muito difíceis de prever, já que para isso deveríamos saber o que está acontecendo exatamente em essas funções, casts, ter em mente a estrutura da classe, etc, a nível de maquina, ou pelo menos estar 100% seguros de como trabalham todas elas, e infelizmente não sei tanto =(, pense que as classes tem ponteiros ocultos 'this' etc, então acho que é mais "fácil" serializa-los, você evita montões de problemas. Acho que cada classe ja deveria ter esse método dentro de si mesma se vai ser enviada a um arquivo.

7 horas atrás, Cambalinho disse:

talvez eu consiga corrigir isso com o tempo.

Certamente sim... você é um cara inquieto. >_<

 

A noite eu tive brincando um pouco com a serialização. Acho que você não teria que modificar muito seu programa, somente as 2 funções anteriores(SaveDataBase e ReadDataBase). Deixo uma ideia.
 

#include <iostream>
#include <fstream>
using namespace std;

class image {
public:
    image(): altura(0), largura(0), ppp(0) {}
    ~image() {}
    

    int altura;
    int largura;
    int ppp;
};


struct user {
    user(): name(std::move(name)), age(0), foto(){}
    std::string name;//C++ type
    int age;
    image foto;//my own class
};

//save a structure object to a file
template<typename structure>
void SaveDataBase ( string filename, structure& StructureVariable ) {
    remove ( filename.c_str() );
    ofstream WriteOnFile ( filename.c_str());
    WriteOnFile.write ( reinterpret_cast<const char*> ( StructureVariable.name.c_str() ), StructureVariable.name.length() );
    WriteOnFile<<' ';
    WriteOnFile<<StructureVariable.age;
    WriteOnFile<<' ';    
    WriteOnFile<<StructureVariable.foto.altura;
    WriteOnFile<<' ';    
    WriteOnFile<<StructureVariable.foto.largura;
    WriteOnFile<<' ';    
    WriteOnFile<<StructureVariable.foto.ppp;
    WriteOnFile<<endl;    

    WriteOnFile.close();
}

int main () {

    user dados;

    dados.name = "marcos";
    dados.age  = 22;
    dados.foto.altura  = 800;
    dados.foto.largura = 600;
    dados.foto.ppp     = 300;
    
    
    SaveDataBase( (string)"lol.bin", dados);

    return 0;
}

As possibilidades são grandes, certamente você dará com varias formas de fazer isso, pois pelo que vejo você é um dos melhores programadores que vi, essa inquietude de saber como são as coisas te levará longe, muito mais que a grande maioria.

Sorte e muito obrigado por compartilhar a solução, se encontrar o por quê do problema anterior também compartilhe aqui conosco, se eu encontrar algo farei a mesma coisa. =)

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

desculpa mas nao sei se notastes 1 coisa: em alguns casos, com a string, nao se pode usar o '<<' ou '>>': erros de memoria ou isso. por isso fiz aquelas funçoes de 'overloading' para a string. da mesma forma vou fazer com as minhas classes e nao só.

 

sabes guardar HICON ou BITMAP em char* ou converter para data do ficheiro *.ICO ou *.BMP respectivamente?(istream)

porque? assim posso tratar das minhas funçoes image\HBitmap e outras dependentes para fazer a serializaçao ;)

eu quero manter aquelas 2 funçoes mais gerais possiveis

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para abri-lo você precisa obviamente conhecer a estrutura do arquivo BMP. Se' googleamos' um pouco com encontramos algo como isso usando o termo "estrutura de um bitmap": http://www2.ic.uff.br/~aconci/curso/bmp.pdf

 

Na pagina 3 mais ou menos começa a descrição da estrutura do arquivo... coisas como essa:

 

Captura.JPG

 

Dai você ve que tem 2 Bytes e que deveria conter "BM", isso é uma string, certamente deveria ser lido 2 chars do arquivo e ser guardado em algo como char assinatura[3]; dai você lê o primeiro char do arquivo e guarda ele em assinatura[0], lê o segundo byte e guarda ele em assinatura[1] e por ultimo você deveria por o '\0' na 3ª posição de assinatura[2] = '\0' já que se trata de uma string, logo após isso podemos fazer algo como if ( assinatura == "BM") quer dizer que o arquivo é um BMP, se não fosse não há sentido continuar tomando dados desse arquivo. >_< Acho que da para pegar a ideia não?

Se entrar na wikipedia em español encontramos uma lista com a estrutura do bitmap, algo assim traduzido:
 

bytes           Informação
0, 1            Tipo arquivo "BM"
2, 3, 4, 5      Tamanho em Bytes do arquivo
6, 7            Reservado
8, 9            Reservado
10, 11, 12, 13  Início dos dados de imagem
14, 15, 16, 17  Cabeçalho bitmap tamanho
18, 19, 20, 21  Largura (pixels)
22, 23, 24, 25  Altura (pixels)
26, 27          Número de planos
28, 29          Tamanho de cada ponto
30, 31, 32, 33  Compressão (0 = não comprimido)
34, 35, 36, 37  Tamanho Imagem
38, 39, 40, 41  Resolução Horizontal
42, 43, 44, 45  Resolução vertical
46, 47, 48, 49  Tabela de cores tamanho
50, 51, 52, 53  Contador de colores importantes

Sei algo de español =)
Dai você ve que do byte 0 ao 1 representa o dado "BM" que é uma string, dai você tem que ler esses 2 bytes como seja necessário, 2 fgetchar por exemplo, sei lá XD, deveria jogar eles no seu devido lugar, posso até estar falando algumas baboseiras devido a que não estou realizando provas, só quero mostrar o caminho e você deverá percorre-lo. A ideia é construir um struct com esses dados prevendo em base o tamanho em Bytes e o dado que contem. Por exemplo (2, 3, 4, 5 Tamanho em Bytes do arquivo) é óbvio que é um int, seria lido depois dos 2 primeiros chars né.


Bom... acho que ja ficou claro mais ou menos o tema da reserva, outra coisa a ter em conta é que não devemos pegar o arquivo comprimido, se não teríamos que conhecer também o algoritmo de descompressão, isso você pode saber na linha  (30, 31, 32, 33  Compressão (0 = não comprimido)), isso é um inteiro que depois de ser lido corretamente deveria conter um zero que indica que não está comprimido.

 

também saber que é bom usar um editor hexadecimal para poder "sondar" internamente a estrutura do arquivo. cada pixel do arquivo está representado por 3 tons de cor RGB em formato hexadecimal. Se abrir um BMP que não estiver comprimido você deveria ver algo como:
scaled_004.png.jpg

dai você vê uma repetição muito grande de "FF 00 00", saiba que isso esta baseado em uma imagem vermelha completamente. O sistema de cor de cada pixel é baseado como falei em 3 tons de cores de 0 a 255 em imagens de 24 bits RGB(vermelho, verde e azul), no qual FF em hexadecimal quer dizer 255, que é a tonalidade de vermelho que temos, verde = 0 e azul = 0, para entender melhor R=255, G=0 e B=0. Então devemos ter claro também a quantidade de bits por que disso depende a quantidade de tons da imagem.


Cada "FF 00 00" da para intuir que é referente a cada pixel da imagem. Para calcular os pixels acho que deveria multiplicar a altura pela largura da imagem, isso daria a quantidade de pixels que deveria ter a imagem, cada um com 3 inteiros RGB. Exemplo si tiver uma imagem de 600*800, teríamos algo como
struct RGB{
int r;
int g;
int b
}

dai uma matriz algo assim:

RGB pixel[800][600]

Isso acho que seria a imagem, para mudar um pixel seria fazer pixel[0][0].r = 255, isso colocaria o primeiro pixel em vermelho, acho que da pra pegar a ideia não?

Eu to no meio da noite aqui assim que amanhã se quiser podemos fazer algumas provas. O tema como mínimo é bem interessante, tenho mais material porém em español, mas podemos uma tarde dar uma olhada.

 

O pdf que eu deixei é bem completo, ou isso parece, não comprovei se tudo o que está realmente representa a estrutura do BMP, faça provas com algum arquivo pequeno de 100X100 a 24 bits de cor e assim poder ir decifrando todo o conteúdo dos BMP.

Comente o que te pareceu e deixe aí seu ponto de vista, se quiser compartilhar os códigos e ideias que tiver beleza.

Sorte!



 

 



 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

honestamente devo ter feito a pergunta errada desculpa.

imagina que tenho HICON ou HBITMAP. eu preciso de os converter em char* e assim os guardar correctamente num ficheiro(*.ICO ou *:BMP) ou fazer parte de 1 ficheiro de dados, se é que me entendes.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não estou acostumado a trabalhar com Handlers de Microsoft, porém eu provaria buscar algo como: "HBITMAP to char array in C++" em google, certamente algo sai.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

consegui este codigo:

//write HBITMAP:
std::ostream& operator << (std::ostream& lhs, HBITMAP& hBitmap)
{
    //get hbitmap size:
    BITMAP bm;
    GetObject(hBitmap, sizeof(BITMAP), &bm);
    HDC hdc = GetDC(GetDesktopWindow());
    HDC hdcMem = CreateCompatibleDC (hdc);
    SelectObject(hdcMem, hBitmap);
    BYTE* pBitmapBits;
    BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdc, 0, 0, SRCCOPY);
    LONG lWidth=bm.bmWidth;
    LONG lHeight=bm.bmHeight;
    WORD wBitsPerPixel=bm.bmBitsPixel;
    //const unsigned long& padding_size;

    // Some basic bitmap parameters
    unsigned long headers_size = sizeof( BITMAPFILEHEADER ) +
                                 sizeof( BITMAPINFOHEADER );

    //unsigned long pixel_data_size = lHeight * ( ( lWidth * ( wBitsPerPixel / 8 ) ) + padding_size );

    BITMAPINFOHEADER bmpInfoHeader = {0};

    // Set the size
    bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);

    // Bit count
    bmpInfoHeader.biBitCount = wBitsPerPixel;

    // Use all colors
    bmpInfoHeader.biClrImportant = 0;

    // Use as many colors according to bits per pixel
    bmpInfoHeader.biClrUsed = 0;

    // Store as un Compressed
    bmpInfoHeader.biCompression = BI_RGB;

    // Set the height in pixels
    bmpInfoHeader.biHeight = lHeight;

    // Width of the Image in pixels
    bmpInfoHeader.biWidth = lWidth;

    // Default number of planes
    bmpInfoHeader.biPlanes = 1;

    // Calculate the image size in bytes
    bmpInfoHeader.biSizeImage = lWidth*lHeight;

    //getting the HBitmap pixel data from HDC:
    GetDIBits(hdc, hBitmap, 0, bm.bmHeight, pBitmapBits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);

    //release hdc:
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);

    BITMAPFILEHEADER bfh = {0};

    // This value should be values of BM letters i.e 0x4D42
    // 0x4D = M 0×42 = B storing in reverse order to match with endian
    bfh.bfType = 0x4D42;
    //bfh.bfType = 'B'+('M' << 8);

    // <<8 used to shift ‘M’ to end  */

    // Offset to the RGBQUAD
    bfh.bfOffBits = headers_size;

    // Total size of image including size of headers
    bfh.bfSize =  headers_size +  bmpInfoHeader.biSizeImage ;

    // Write the File header:
    lhs.write((char*)&bfh, sizeof(bfh));

    //Write the bitmap info header:
    lhs.write((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));

    //write pixel data:
    lhs.write((char*) pBitmapBits, bmpInfoHeader.biSizeImage);

    return lhs;
}

and now, on BitmapDC:

void save(string FileName)
    {
        ofstream WriteOnFile(FileName.c_str(), ios::out | ios::binary);
        WriteOnFile << bitmapcurrent2;
        WriteOnFile.close();
    }

on file data:

Citação

0x890515e4

 

porquê eu só obtenho o endereço? porque nao tenho a imagem?

Compartilhar este post


Link para o post
Compartilhar em outros sites

finalmente consigo fazer a escrita num ficheiro. mas continuo com problemas no read:

//write HBITMAP:
    friend std::ostream& operator << (std::ostream& lhs, BitmapDC &hBitmap)
    {
        //get hbitmap size:
        BITMAP bm;
        GetObject(hBitmap.bitmapcurrent, sizeof(BITMAP), &bm);
        LONG lWidth=bm.bmWidth;
        LONG lHeight=bm.bmHeight;
        BYTE* pBitmapBits;
        BitBlt(GetWindowDC(ActivatedForm), 100, 100, bm.bmWidth, bm.bmHeight, hBitmap.hdcbitmap, 0, 0, SRCCOPY);


        WORD wBitsPerPixel=bm.bmBitsPixel;
        unsigned long pixel_data_size = lHeight * ( ( lWidth * ( wBitsPerPixel / 8 ) ) + 0 );
        // Some basic bitmap parameters
        unsigned long headers_size = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );

        BITMAPINFOHEADER bmpInfoHeader = {0};

        // Set the size
        bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);

        // Bit count
        bmpInfoHeader.biBitCount = wBitsPerPixel;

        // Use all colors
        bmpInfoHeader.biClrImportant = 0;

        // Use as many colors according to bits per pixel
        bmpInfoHeader.biClrUsed = 0;

        // Store as un Compressed
        bmpInfoHeader.biCompression = BI_RGB;

        // Set the height in pixels
        bmpInfoHeader.biHeight = lHeight;

        // Width of the Image in pixels
        bmpInfoHeader.biWidth = lWidth;

        // Default number of planes
        bmpInfoHeader.biPlanes = 1;

        // Calculate the image size in bytes
        bmpInfoHeader.biSizeImage = pixel_data_size;

        //getting the HBitmap pixel data from HDC:
        pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
        GetDIBits(hBitmap.hdcbitmap , hBitmap.bitmapcurrent, 0, bm.bmHeight, pBitmapBits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);

        BITMAPFILEHEADER bfh = {0};

        // This value should be values of BM letters i.e 0x4D42
        // 0x4D = M 0×42 = B storing in reverse order to match with endian
        bfh.bfType = 0x4D42;
        //bfh.bfType = 'B'+('M' << 8);

        // <<8 used to shift ‘M’ to end  */

        // Offset to the RGBQUAD
        bfh.bfOffBits = headers_size;

        // Total size of image including size of headers
        bfh.bfSize =  headers_size +  bmpInfoHeader.biSizeImage ;

        // Write the File header:
        lhs.write((char*)&bfh, sizeof(bfh));

        //Write the bitmap info header:
        lhs.write((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));

        //write pixel data:
        lhs.write((char*)pBitmapBits, bmpInfoHeader.biSizeImage);

        delete []pBitmapBits;

        return lhs;
    }

    //read HBITMAP:
    friend std::istream& operator >> (std::istream& lhs, BitmapDC &hBitmap)
    {
        MessageBox("read it");
        BITMAPFILEHEADER bfh = {0};
        lhs.read((char*)&bfh, sizeof(bfh));

        BITMAPINFOHEADER bmpInfoHeader = {0};
        bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
        lhs.read((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));
        BYTE* pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
        lhs.read((char*)pBitmapBits, bmpInfoHeader.biSizeImage);
        hBitmap.init(bmpInfoHeader.biWidth, bmpInfoHeader.biHeight);
        SetDIBitsToDevice(hBitmap.hdcbitmap, 0, 0, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, 0, 0, 0, bmpInfoHeader.biHeight, pBitmapBits,(BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
        BitBlt(GetWindowDC(ActivatedForm), 200, 100, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, hBitmap.hdcbitmap, 0, 0, SRCCOPY);
        delete []pBitmapBits;
        return lhs;
    }

    void save(string FileName)
    {
        ofstream WriteOnFile(FileName.c_str(), ios::out | ios::binary);
        WriteOnFile << bitmapcurrent;
        WriteOnFile.close();
        ifstream ReadOnFile(FileName.c_str(), ios::in | ios::binary);
        ReadOnFile >> (char*) bitmapcurrent;
        ReadOnFile.close();
    }

penso estar enganado no:

ifstream ReadOnFile(FileName.c_str(), ios::in | ios::binary);
ReadOnFile >> (char*) bitmapcurrent;

porque senao usar 'char*', eu irei ter erros de compilaçao. mas mesmo assim nao obtenho resultados :(

alem disso nao estou a conseguir entrar no 'operator >>'. porque nao recebo a mensagem.

alguem me pode explicar, por favor?

finalmente consigo fazer a escrita num ficheiro. mas continuo com problemas no read:

//write HBITMAP:
    friend std::ostream& operator << (std::ostream& lhs, BitmapDC &hBitmap)
    {
        //get hbitmap size:
        BITMAP bm;
        GetObject(hBitmap.bitmapcurrent, sizeof(BITMAP), &bm);
        LONG lWidth=bm.bmWidth;
        LONG lHeight=bm.bmHeight;
        BYTE* pBitmapBits;
        BitBlt(GetWindowDC(ActivatedForm), 100, 100, bm.bmWidth, bm.bmHeight, hBitmap.hdcbitmap, 0, 0, SRCCOPY);


        WORD wBitsPerPixel=bm.bmBitsPixel;
        unsigned long pixel_data_size = lHeight * ( ( lWidth * ( wBitsPerPixel / 8 ) ) + 0 );
        // Some basic bitmap parameters
        unsigned long headers_size = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );

        BITMAPINFOHEADER bmpInfoHeader = {0};

        // Set the size
        bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);

        // Bit count
        bmpInfoHeader.biBitCount = wBitsPerPixel;

        // Use all colors
        bmpInfoHeader.biClrImportant = 0;

        // Use as many colors according to bits per pixel
        bmpInfoHeader.biClrUsed = 0;

        // Store as un Compressed
        bmpInfoHeader.biCompression = BI_RGB;

        // Set the height in pixels
        bmpInfoHeader.biHeight = lHeight;

        // Width of the Image in pixels
        bmpInfoHeader.biWidth = lWidth;

        // Default number of planes
        bmpInfoHeader.biPlanes = 1;

        // Calculate the image size in bytes
        bmpInfoHeader.biSizeImage = pixel_data_size;

        //getting the HBitmap pixel data from HDC:
        pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
        GetDIBits(hBitmap.hdcbitmap , hBitmap.bitmapcurrent, 0, bm.bmHeight, pBitmapBits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);

        BITMAPFILEHEADER bfh = {0};

        // This value should be values of BM letters i.e 0x4D42
        // 0x4D = M 0×42 = B storing in reverse order to match with endian
        bfh.bfType = 0x4D42;
        //bfh.bfType = 'B'+('M' << 8);

        // <<8 used to shift ‘M’ to end  */

        // Offset to the RGBQUAD
        bfh.bfOffBits = headers_size;

        // Total size of image including size of headers
        bfh.bfSize =  headers_size +  bmpInfoHeader.biSizeImage ;

        // Write the File header:
        lhs.write((char*)&bfh, sizeof(bfh));

        //Write the bitmap info header:
        lhs.write((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));

        //write pixel data:
        lhs.write((char*)pBitmapBits, bmpInfoHeader.biSizeImage);

        delete []pBitmapBits;

        return lhs;
    }

    //read HBITMAP:
    friend std::istream& operator >> (std::istream& lhs, BitmapDC &hBitmap)
    {
        MessageBox("read it");
        BITMAPFILEHEADER bfh = {0};
        lhs.read((char*)&bfh, sizeof(bfh));

        BITMAPINFOHEADER bmpInfoHeader = {0};
        bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
        lhs.read((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));
        BYTE* pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
        lhs.read((char*)pBitmapBits, bmpInfoHeader.biSizeImage);
        hBitmap.init(bmpInfoHeader.biWidth, bmpInfoHeader.biHeight);
        SetDIBitsToDevice(hBitmap.hdcbitmap, 0, 0, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, 0, 0, 0, bmpInfoHeader.biHeight, pBitmapBits,(BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
        BitBlt(GetWindowDC(ActivatedForm), 200, 100, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, hBitmap.hdcbitmap, 0, 0, SRCCOPY);
        delete []pBitmapBits;
        return lhs;
    }

    void save(string FileName)
    {
        ofstream WriteOnFile(FileName.c_str(), ios::out | ios::binary);
        WriteOnFile << bitmapcurrent;
        WriteOnFile.close();
        ifstream ReadOnFile(FileName.c_str(), ios::in | ios::binary);
        ReadOnFile >> (char*) bitmapcurrent;
        ReadOnFile.close();
    }

penso estar enganado no:

ifstream ReadOnFile(FileName.c_str(), ios::in | ios::binary);
ReadOnFile >> (char*) bitmapcurrent;

porque senao usar 'char*', eu irei ter erros de compilaçao. mas mesmo assim nao obtenho resultados :(

alem disso nao estou a conseguir entrar no 'operator >>'. porque nao recebo a mensagem.

alguem me pode explicar, por favor?

Compartilhar este post


Link para o post
Compartilhar em outros sites

ja consegui ver qual era o meu erro.

agora consigo salvar HBITMAP em ficheiro BMP:

//write HBITMAP:
    friend std::ostream& operator << (std::ostream& lhs, BitmapDC &hBitmap)
    {
        //get hbitmap size:
        BITMAP bm;
        GetObject(hBitmap.bitmapcurrent, sizeof(BITMAP), &bm);
        LONG lWidth=bm.bmWidth;
        LONG lHeight=bm.bmHeight;
        BYTE* pBitmapBits;
        WORD wBitsPerPixel=bm.bmBitsPixel;
        unsigned long pixel_data_size = lHeight * ( ( lWidth * ( wBitsPerPixel / 8 ) ) + 0 );
        // Some basic bitmap parameters
        unsigned long headers_size = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );

        BITMAPINFOHEADER bmpInfoHeader = {0};

        // Set the size
        bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);

        // Bit count
        bmpInfoHeader.biBitCount = wBitsPerPixel;

        // Use all colors
        bmpInfoHeader.biClrImportant = 0;

        // Use as many colors according to bits per pixel
        bmpInfoHeader.biClrUsed = 0;

        // Store as un Compressed
        bmpInfoHeader.biCompression = BI_RGB;

        // Set the height in pixels
        bmpInfoHeader.biHeight = lHeight;

        // Width of the Image in pixels
        bmpInfoHeader.biWidth = lWidth;

        // Default number of planes
        bmpInfoHeader.biPlanes = 1;

        // Calculate the image size in bytes
        bmpInfoHeader.biSizeImage = pixel_data_size;

        //getting the HBitmap pixel data from HDC:
        pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
        GetDIBits(hBitmap.hdcbitmap , hBitmap.bitmapcurrent, 0, bm.bmHeight, pBitmapBits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);

        BITMAPFILEHEADER bfh = {0};

        // This value should be values of BM letters i.e 0x4D42
        // 0x4D = M 0×42 = B storing in reverse order to match with endian
        bfh.bfType = 0x4D42;
        //bfh.bfType = 'B'+('M' << 8);

        // <<8 used to shift ‘M’ to end  */

        // Offset to the RGBQUAD
        bfh.bfOffBits = headers_size;

        // Total size of image including size of headers
        bfh.bfSize =  headers_size +  bmpInfoHeader.biSizeImage ;

        // Write the File header:
        lhs.write((char*)&bfh, sizeof(bfh));

        //Write the bitmap info header:
        lhs.write((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));

        //write pixel data:
        lhs.write((char*)pBitmapBits, bmpInfoHeader.biSizeImage);

        delete []pBitmapBits;

        return lhs;
    }

    //read HBITMAP:
    friend std::istream& operator >> (std::istream& lhs, BitmapDC &hBitmap)
    {
        BITMAPFILEHEADER bfh = {0};
        lhs.read((char*)&bfh, sizeof(bfh));
        BITMAPINFOHEADER bmpInfoHeader = {0};
        bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
        lhs.read((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));
        BYTE* pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
        lhs.read((char*)pBitmapBits, bmpInfoHeader.biSizeImage);
        hBitmap.init(bmpInfoHeader.biWidth, bmpInfoHeader.biHeight);
        SetDIBitsToDevice(hBitmap.hdcbitmap, 0, 0, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, 0, 0, 0, bmpInfoHeader.biHeight, pBitmapBits,(BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
        delete []pBitmapBits;
        return lhs;
    }

    void save(string FileName)
    {
        ofstream WriteOnFile(FileName.c_str(), ios::out | ios::binary);
        WriteOnFile << *this;
        WriteOnFile.close();
    }

muito obrigado por tudo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×