Ir ao conteúdo

Posts recomendados

Postado

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?

Postado

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

Postado

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 ;)

Postado

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

 

Postado

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.

Postado

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?

Postado

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?

Postado

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

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades 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

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!