CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Edycja Cofnij
Strona 1 z 1

Edycja Cofnij

Nowy postNapisane: poniedziałek, 28 maja 2012, 12:50
przez Frytek18
KOD cpp:     UKRYJ  
void __fastcall TForm1::UndoClick(TObject *Sender)
{
  Graphics::TBitmap *Bitmap2;

   if (Clipboard()->HasFormat(CF_BITMAP)){
         Bitmap2 = new Graphics::TBitmap();
                try{
                   Bitmap2->Assign(Clipboard());
                   Image->Canvas->Draw(0, 0, Bitmap2);
                   delete Bitmap2;
                }
                catch(...) {
                   delete Bitmap2;
                }
  }
}

Mam coś takiego no i działą ale robi tylko cofa jedna akcje do tyłu mniejsza o to ale istnieje inny problem ponieważ nie jest kasowane po zamknieciu programu tzn jak odpale program cos narysuje i znowu cos narysuje i klikne opcje edycja cofnij to mi cofnie to co namalowałem i zamkne porgram i znowu odpale i odrazu klikne edycja cofnij to pokaże mi sie to co namalowałem wczesniej i nie wiem jak to skasowac tak jak by w pamieci był ten obrazek

Re: Edycja Cofnij

Nowy postNapisane: wtorek, 29 maja 2012, 09:12
przez Cyfrowy Baron
Cała ta Edycja - Cofnij w tym kodzie odbywa się poprzez schowek:

Frytek18 napisał(a):
KOD cpp:     UKRYJ  
Bitmap2->Assign(Clipboard());


a po zamknięciu programu schowek nie jest opróżniany więc Cofnij powoduje wklejenie zawartości schowka do Image o ile w schowku jest jakaś grafika. Co można z tym zrobić? Można np. opróżnić zawartość schowka po wklejeniu bitmapy:

KOD cpp:     UKRYJ  
Clipboard()->Clear();


Używanie schowka do przechowywania historii zdarzeń w Image nie jest dobrym pomysłem, gdyż możesz przechowywać tylko jedno zdarzenie, a poza tym jeżeli umieścisz bitmapę w schowku, a potem coś innego skopiujesz do schowka to bitmapa zostanie usunięta i Cofnij nie zadziała.
Zakładając, że chcesz np. przechowywać historię do 4 zdarzeń można stworzyć w tablicę obiektów TBitmap do przechowywania 4 obiektów i potem po wywołaniu cofnij wczytywać zawartość tych bitmap w odwrotnej kolejności. To jednak złożony problem, a ja nie mam dziś czasu (aż do soboty), żeby napisać ten kod za ciebie. tablicę możesz stworzyć tak:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:
        Graphics::TBitmap *HistoryBMP[4];


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 for(int x = 0; x < 4; x++)
 {
   HistoryBMP[x] = new Graphics::TBitmap();
 }
}


Do takich bitmap odwołujesz się w prosty sposób podając ich numer:

KOD cpp:     UKRYJ  
HistoryBMBP[numer]-> ...
Image1->Canvas->Draw(0, 0, HistoryBMP[numer]);


Pamiętaj, że zanim cokolwiek wkleisz do obiektu typu TBitmap to najpierw musisz ustalić jego rozmiar.

Zamiast tablicą lepiej byłoby posłużyć się jakimś kontenerem, ale to raczej dla Ciebie za trudne.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 15:22
przez event15
Mógłby ktoś lepiej to opisać? Próbuję z tym kodem z postu powyżej coś wymodzić, ale już tracę siły na to. Co chwila dostaję access violation.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 15:31
przez Cyfrowy Baron
Pokaż swój kod, a wskażemy ci błędy.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 16:00
przez event15
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TPoint Origin, MovePt;
bool Drawing;
enum TDrawingTool { dtLine, dtRectangle, dtFreeHand, dtRubber, dtBucket };
TDrawingTool DrawingTool;
TColor tlo;
TBrushStyle OldBrush, CurrentBrush;
TPenStyle OldPen, CurrentPen;
Graphics::TBitmap *HistoryBMP[4];
int i = 0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        tlo = clWhite;
        Image1->Canvas->Brush->Color = tlo;
        SpinEdit1->Value = Image1->Canvas->Pen->Width;
        DoubleBuffered = true;
        for(i = 0; i < 4; i++)
        {
                HistoryBMP[i] = new Graphics::TBitmap;
                HistoryBMP[i]->Width = Form1->Image1->Picture->Width;
                HistoryBMP[i]->Height = Form1->Image1->Picture->Height;
        }
        i = 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
        // Zapis poprzednich danych
        OldBrush    = Image1->Canvas->Brush->Style;
        OldPen      = Image1->Canvas->Pen->Style;

        CurrentBrush    = bsClear;
        CurrentPen      = psSolid;

        // Ustawienie zaznaczenia;
        HistoryBMP[i]->Canvas->Brush->Style = CurrentBrush;
        HistoryBMP[i]->Canvas->Pen->Style   = CurrentPen;


        Drawing = true;
        HistoryBMP[i]->Canvas->MoveTo(X, Y);
        Origin = Point(X, Y);
        MovePt = Origin;

        if(DrawingTool == dtRubber) HistoryBMP[i]->Canvas->Pen->Color = tlo;
        else HistoryBMP[i]->Canvas->Pen->Color = clBlack;

        TVarRec tempvar[2] = {X, Y};
        StatusBar1->Panels->Items[0]->Text = Format("Origin: (%d, %d)", tempvar, 2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{

        HistoryBMP[i]->Canvas->Brush->Style = OldBrush;
        HistoryBMP[i]->Canvas->Pen->Style   = OldPen;

        if (Drawing)
        {
                DrawShape(Origin, Point(X, Y), pmCopy);
                Drawing = false;
        }
        Image1->Canvas->Draw(0, 0, HistoryBMP[i]);
        i++;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X,
                  int Y)
{
        if (Drawing)
        {
                if((DrawingTool == dtFreeHand) || (DrawingTool == dtRubber)) DrawShape(Origin, MovePt, pmCopy);
                else DrawShape(Origin, MovePt, pmNotXor);

                MovePt = Point(X, Y);

                if((DrawingTool == dtFreeHand) || (DrawingTool == dtRubber)) DrawShape(Origin, MovePt, pmCopy);
                else DrawShape(Origin, MovePt, pmNotXor);
        }

        TVarRec tempvar[2] = {X, Y};
        StatusBar1->Panels->Items[1]->Text = Format("Current: (%d, %d)", tempvar, 2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DrawShape(TPoint TopLeft, TPoint BottomRight, TPenMode AMode){
        Image1->Canvas->Pen->Mode = AMode;

        switch (DrawingTool)
        {
                case dtLine:
                {
                        HistoryBMP[i]->Canvas->MoveTo(TopLeft.x, TopLeft.y);
                        HistoryBMP[i]->Canvas->LineTo(BottomRight.x, BottomRight.y);
                        break;
                }
                case dtFreeHand:
                {
                        HistoryBMP[i]->Canvas->LineTo(BottomRight.x, BottomRight.y);
                        break;
                }
                case dtRubber:
                {
                        HistoryBMP[i]->Canvas->LineTo(BottomRight.x, BottomRight.y);
                        break;
                }
                case dtBucket:
                {
                        HistoryBMP[i]->Canvas->FloodFill(TopLeft.x, TopLeft.y, HistoryBMP[i]->Canvas->Pixels[TopLeft.x][TopLeft.y], fsSurface);
                        break;
                }

                case dtRectangle:
                {
                        HistoryBMP[i]->Canvas->Rectangle(TopLeft.x, TopLeft.y, BottomRight.x, BottomRight.y);
                        break;
                }
        }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        DrawingTool = dtRectangle;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        DrawingTool = dtLine;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
        DrawingTool = dtFreeHand;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SpinEdit1Change(TObject *Sender)
{
        HistoryBMP[i]->Canvas->Pen->Width = SpinEdit1->Value;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
        DrawingTool = dtRubber;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button5Click(TObject *Sender)
{
        HistoryBMP[i]->Canvas->Brush->Color = clRed;
        DrawingTool = dtBucket;
}
//---------------------------------------------------------------------------


Z tym, że edytowałem wcześniej już utworzony kod, gdzie zamiast HistoryBMP[i] było wszędzie Image1->.

Swoją drogą jakoś nie pasuje mi takie rozwiązanie, ponieważ np jak zrobię 5 czynności to domyślam się, że przekroczę zakres w historii, co prawdopodobnie walnie mi błędem.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 16:32
przez Cyfrowy Baron
Nie rysuj po historii, lecz po właściwym obiekcie, a po skończeniu rysowania, np. po OnMouseUp przekopiuj rysunek do historii. Zasadę już znasz. Nie masz innej możliwości przechowania historii bitmap niż w bitmapie.

W zdarzeniu Image1MouseUp inkrementujesz zmienną i o jedne przy każdym wywołaniu tego zdarzenia, ale nigdzie nie zerujesz tej zmiennej i nie sprawdzasz czy nie przekroczyła wartości 3. Jeżeli zmienna będzie miała wartość większą niż 3 to masz błąd bo w zdarzeniu DrawShape używasz tej zmiennej do określania bitmapy historii.

Skomplikowałeś to sobie, rysując po historii zamiast kopiować bitmapy do historii.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 17:34
przez event15
Dziękuję.

Moje niedopatrzenie i zmęczenie.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 18:02
przez event15
Dobra, ale aplikacja działa w ten sposób, że mogę rysować tylko tyle razy, ile jest obiektów w tablicy HistoryBMP[].
Musiałbym znaleźć sposób na usuwanie początkowej bitmapy, przesunięcia całej tablicy w lewo i kontynuowania edycji.

Da się zrobić to na tak stworzonych tablicach?


--- EDIT ----
Ok. Trochę posiedziałem i na chwilę obecną przesunąłem tak, jak chciałem elementy tablicy w lewo.
Kod: Zaznacz cały
#include <iostream>

using namespace std;

const int ile = 10; // liczba komórek tablicy
const int pozycja = 0;  // pozycja usuwania

int main()
{
    int tab[ile], i;

    for(i = 0; i < ile; i++) tab[i] = i;
    for(i = 0; i < ile; i++) cout << "tab[" << i << "] = " << tab[i] << endl;
    cout << endl << endl;
// przesuwamy komórki
    for(i = pozycja; i <= ile - 2; i++) tab[i] = tab[i + 1];
// na ostatniej pozycji umieszczamy 0 - w programie aktualną bitmape
    tab[ile - 1] = 0;
// wyświetlamy zawartość tablicy po przesunieciu
    for(i = 0; i < ile; i++) cout << "tab[" << i << "] = " << tab[i] << endl;

    return 0;
}


Co daje wynik:
tab[0] = 0
tab[1] = 1
tab[2] = 2
tab[3] = 3
tab[4] = 4
tab[5] = 5
tab[6] = 6
tab[7] = 7
tab[8] = 8
tab[9] = 9


tab[0] = 1
tab[1] = 2
tab[2] = 3
tab[3] = 4
tab[4] = 5
tab[5] = 6
tab[6] = 7
tab[7] = 8
tab[8] = 9
tab[9] = 0


Teraz tylko zaimplementować to w C++Builderze, mam nadzieję, że uda się.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 18:29
przez Cyfrowy Baron
Da się jeżeli posłużysz się vector'em.

Re: Edycja Cofnij

Nowy postNapisane: niedziela, 3 marca 2013, 20:07
przez Cyfrowy Baron
Nie uzupełniaj tylko pisz nowe posty. Na vector'ach byłoby dużo prościej i nie musiałbyś określać z góry rozmiaru tablicy. Usunięcie elementy vector'a powoduje przesunięcie pozostałych.