Przypisanie OnClick do obiektu TImage

0

Nastepujace przypisanie wyrzuca blad:

karty[j].image->OnClick=Card::Click;

[C++ Error] Unit1.cpp(31): E2034 Cannot convert 'void (_fastcall Card::*)(TObject *)' to 'void (_fastcall * (_closure )(TObject *))(TObject *)'

Card:

void __fastcall Card::Click(TObject *Sender){
    image->Height=50;
};

Klasa:

class Card{
public:
        int top,left,bottom,right;
        TImage *image;
        Card();
        void __fastcall Click(TObject *Sender);
};

Nie do konca rozumiem co tu jest nie tak..

0

klasa Card musi pochodzić od TObject

class Card : public TObject {
0

Poprawilem, ale dalej to samo.

Unit1.h:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Card.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 Card karty[25];

  for(int i=0,j=0; i<5; ++i)
 {
    for(int g=0; g<5; ++g,++j)
    {
     karty[j].image->Left=g*105+5;
     karty[j].image->Top=i*105+5;
     karty[j].image->Tag=reinterpret_cast<int>(this);
     karty[j].image->Cursor=crHandPoint;
     karty[j].image->OnClick=Card::Click;
     }
 }

}

Card.cpp:

#include "Card.h"
#include "Unit1.h"

Card::Card(){
  image = new TImage(Application);
  image->Parent=Form1;
  image->Picture->LoadFromFile("IMG/1.bmp");
  image->Width=100;
  image->Height=120;
};

void __fastcall Card::Click(TObject *Sender){
    image->Height=50;
};

Card.h:

#ifndef CardH
#define CardH
#include <ExtCtrls.hpp>
class Card : public TObject{
public:
        int top,left,bottom,right;
        TImage *image;
        Card();
        void __fastcall Click(TObject *Sender);
};
#endif
0

Albo przenieś to do konstruktora: image->OnClick=&Click;
Albo karty[j].image->OnClick=&(karty[j].Click);

0

Pierwsze rozwiązanie działa jak najbadziej, ale drugie nie. Jest w ogóle możliwość przypisania tej funkcji poza obszarem klasy?

1

Poprawione.
Z tym że i tak to nie zadziała (nieco później się przekonasz), ponieważ wszystkie 25 obiektów tablicy karty zostaną zniszczone po zakończeniu FormCreate.
Trzeba dodać Card *karty[25]; - do składowych klasy w pliku Unit1.h
W FormCreate dodać: for(int i=0;i<25;++i) karty[i]=new Card();
W FormCreate wszędzie pozmieniać karty[j]. na karty[j]-> w tym to miejsce co przed chwila poprawiłem.

Lepiej przestań kombinować i zrób po ludzku:
Unit1.h:

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
private:	// User declarations
   struct { TImage *img; int JakasLiczba; AnsiString JakisNapis; } tb[25];
   void __fastcall imgClick(TObject *Sender);
public:		// User declarations
   __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit1.cpp:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
  {
   for(int i=0,y=0;y<5;++y)
     {
      for(int x=0;x<5;++x,++i)
        {
         TImage *img=new TImage(this);
         img->BoundsRect=Bounds(4+84*x,4+84*y,80,80);
         img->Parent=this;
         img->Picture->LoadFromFile("test.bmp");
         img->OnClick=imgClick;
         img->Tag=i;
         tb[i].img=img;
         tb[i].JakasLiczba=rand();
         tb[i].JakisNapis="abc";
        }
     }
  }
//---------------------------------------------------------------------------

void __fastcall TForm1::imgClick(TObject *Sender)
  {
   TImage *img=(TImage*)Sender;
   int i=img->Tag;
   tb[i].img->Visible=false;
  }
//---------------------------------------------------------------------------
0

Już się przekonałem! :D
Super, działa. Ale zrodziło się kolejne pytanie. Chciałbym teraz mieć możliwość aby kliknąć na jeden element, następnie na drugi i zamienić je ze sobą miejcami.
karty[j].image->Tag=reinterpret_cast<int>(this) Jeżeli dobrze to rozumiem zapisuje mi adres elementu do tagu, w jaki sposób mógłbym to wykonać? Potrzebowałbym dwóch funkcji OnClick?

1

Po kliknięciu masz indeks klikniętego obrazka: int i=img->Tag;
Dodaj składową int prev;
W konstruktorze ustaw na: -1
Po kliknięciu sprawdzaj jeżeli: (prev>0) to wymieniamy i z prev po czym prev ustawiamy na -1 w przeciwnym przypadkuy ustawiamy prev na i

0

Dzięki!

void __fastcall TForm1::imgClick(TObject *Sender)
  {
   TImage *img=(TImage*)Sender;
   int i=img->Tag,pom;
   if(prev>0)
    {
     pom=prev;
     prev=i;
     i=prev;
     prev=-1;
    }
   else
     prev=i;
  }

czy o to chodziło? Bo działać to nie działa. :/

0

Wymienić: tb[i] z tb[prev] z tym że wymienić musisz obrazki, nie obiekty, nie indeksy, nie teksty, nie liczby.

0
void __fastcall TForm1::imgClick(TObject *Sender)
  {
   TImage *img=(TImage*)Sender;
   TPicture *pom;
   int i=img->Tag;

   if(prev>=0)
    {
     pom=karty[prev].image->Picture;
     karty[prev].image->Picture=karty[i].image->Picture;
     karty[i].image->Picture=pom;
     prev=-1;
    }
   else
     prev=i;
  }

Ok, doszedłem do tego, ale teraz zamiast zamieniać obrazki, to wybieram jeden obrazek i po kliknięciu w drugi zamienia drugi na pierwszy a pierwszy pozostaje ten sam.

1

Zastanów się ... skąd masz te obrazki ?
Nie musisz wymieniać, wystarczy ponownie załadować.
Jeżeli już chcesz wymieniać to:

TBitmap *bmp=new TBitmap(this);
try
  {
   bmp->Assign(karty[prev].image->Picture);
   karty[prev].image->Picture->Assign(karty[i].image->Picture);
   karty[i].image->Picture->Assign(bmp);
  }
__finally
  {
   delete bmp;
  }
0
void __fastcall TForm1::imgClick(TObject *Sender)
  {
   TImage *img=(TImage*)Sender;
   TImage *pom = new TImage(this);
   int i=img->Tag;
   if(prev>=0)
    {
     pom->Picture=karty[prev].image->Picture;
     karty[prev].image->Picture=karty[i].image->Picture;
     karty[i].image->Picture=pom->Picture;
     prev=-1;
    }
   else
     prev=i;
  }

Udało się w ten sposób, dzięki!

1

Nie udało się, masz wycieki pamięci, nie wspominając już o kontrolce która pojawia się i znika, może komputer jest zbyt szybki i tego nie zauważasz, ale tak jest.

0

Ok, zajęło mi trochę zrozumienie tego kodu który wrzuciłeś. Bardzo doceniam, że chce Ci się pomagać.

Kolejna sprawa - Mam obrazek TImage, czy da się w jakiś sposób wypełnić np. wszystkie całkowicie białe miejsca innym kolorem?

1 użytkowników online, w tym zalogowanych: 0, gości: 1