Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   gestionar eventos de componente dinamico (https://www.clubdelphi.com/foros/showthread.php?t=83886)

aguml 10-08-2013 09:07:30

gestionar eventos de componente dinamico
 
pues mi duda es que si por ejemplo creo un boton usando new ¿Como controlo sus eventos para que por ejemplo al pulsar el boton se ejecute un codigo. Un ejemplo por favor. El componente que estoy usando no es visual, su owner es null, y lo creo en un hilo pero supongo que será igual.

Casimiro Noteví 10-08-2013 10:03:25

Haz una búsqueda, es un tema tratado muchísimas veces.
Ejemplo, aquí.

aguml 10-08-2013 10:39:52

gracias amigo pero no me expliqué del todo bien, lo que no se es donde tendria que hacer eso en el proyecto de c++builder, ¿En el .hpp del hilo? ¿Como seria eso?

aguml 10-08-2013 12:52:20

Voy a intentar explicarlo mejor, el componente es un componente que nos permite debuggear un programa y hago esto:

THilo.h:

Código:

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

#ifndefHiloDbgH
#defineHiloDbgH

#include<SysUtils.hpp>
#include<Classes.hpp>
#include<SysInit.hpp>
#include<System.hpp>
#include<DbgCLS.hpp>

//---------------------------------------------------------------------------
classTHilo:publicTThread
{
__published:// IDE-managed Components
        __fastcall THilo(void);
        __fastcall ~THilo(void);
        void __fastcall THilo::Resume(void);
        void __fastcall THilo::SetRuta(AnsiString path);
        void __fastcall THilo::BreakSystemBP(void);
        void __fastcall THilo::BreakHBP(void);
protected:
        void __fastcall THilo::Execute(void);
private:// User declarations
        TDbgCLS*DbgCLS;
        AnsiStringRuta;
public:// User declarations
};
//---------------------------------------------------------------------------
#endif

THilo.cpp:

Código:

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

#pragma hdrstop

#include"HiloDbg.h"
//---------------------------------------------------------------------------

#pragmapackage(smart_init)

__fastcall THilo::THilo(void):TThread(true)//Constructor
{
        FreeOnTerminate=true;
        DbgCLS=newTDbgCLS(NULL);
}
//---------------------------------------------------------------------------

__fastcall THilo::~THilo(void)//Destructor
{
        if(DbgCLS)
                deleteDbgCLS;
}
//---------------------------------------------------------------------------

void __fastcall THilo::SetRuta(AnsiString path)
{
        Ruta= path;
}

void __fastcall THilo::Resume(void)
{
        if(DbgCLS)
        {
                DbgCLS->OnBreakSystemBP=BreakSystemBP;
                DbgCLS->OnBreakHBP=BreakHBP;
                DbgCLS->InitDebug();
                DbgCLS->DebugLoop();
        }
}

void __fastcall THilo::Execute()
{

}

void __fastcall THilo::BreakHBP()
{
        switch(DbgCLS->GetLastAddr())
        {
                case0x00AD40FB:
                        DbgCLS->SetEIP(0x00AD4169);
                        DbgCLS->WriteLog("Paramos en el HBP de 0x00AD40FB");
                break;

                case0x00AD4173:
                        DbgCLS->SetEIP(0x00AD4183);
                        DbgCLS->WriteLog("Paramos en el HBP de 0x00AD4173");
                break;
        }
}
//---------------------------------------------------------------------------

void __fastcall THilo::BreakSystemBP()
{
        if(DbgCLS!= NULL &&Ruta!= NULL)
        {
                DbgCLS->ExeName=Ruta;
                DbgCLS->SetHBP(0x00AD40FB,0);
                DbgCLS->WriteLog("Ponemos un HBP en 0x00AD40FB en ejecución");
                DbgCLS->SetHBP(0x00AD4173,0);
                DbgCLS->WriteLog("Ponemos un HBP en 0x00AD4173 en ejecución");
                DbgCLS->LogBP();
        }
}
//---------------------------------------------------------------------------

Form1.cpp:
Código:

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

#include<vcl.h>
#pragma hdrstop

#include"Unit1.h"
#include"HiloDBG.h"
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
#pragma link "DbgCLS"
#pragma resource "*.dfm"

TForm1*Form1;
THilo*HiloDbg;

//Declaracion de funciones
bool __stdcall LanzarHilo();//Funcion del hilo

//Variables globales necesarias para la creacion del hilo del debugger
HANDLE hThread;
DWORD ThreadId;
intDataThread=1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent*Owner)
        :TForm(Owner)
{
}
//---------------------------------------------------------------------------

bool __stdcall LanzarHilo()
{
        bool retval =true;
        //En esta funcion entramos al crear el hilo y lanzamos dentro el debugger
        HANDLE DinesatRadio9=CreateFile(AnsiString(ExtractFilePath(Application->GetNamePath())+"DinesatRadio9.exe").c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
        HiloDbg=newTHilo();

        if(DinesatRadio9!= INVALID_HANDLE_VALUE)
        {
                CloseHandle(DinesatRadio9);
                //Si el hilo se ha creado bien deshabilitamos el boton para
                //crear el hilo y habilitamos el de terminar el hilo
                Form1->ButtonCrearHilo->Enabled=false;
                Form1->ButtonTerminarHilo->Enabled=true;
                HiloDbg->SetRuta("DinesatRadio9.exe");
                HiloDbg->Resume();//lanzamos el hilo
        }
        else 
        {
                MessageBoxA(Application->Handle,"No  se encuentra DinesatRadio9.exe y se abrirá un cuadro de diálogo para  buscar el ejecutable.\nPara evitar este trámite, coloca este ejecutable  en el directorio de instalación de Dinesat Radio 9.","Información", MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
                if(Form1->OpenDialog1->Execute())
                {
                        DinesatRadio9=CreateFile(Form1->OpenDialog1->FileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
                        if(DinesatRadio9!= INVALID_HANDLE_VALUE)
                        {
                                CloseHandle(DinesatRadio9);
                                if(ExtractFileName(Form1->OpenDialog1->FileName)=="DinesatRadio9.exe")
                                {
                                        //Si el hilo se ha creado bien deshabilitamos el boton para
                                        //crear el hilo y habilitamos el de terminar el hilo
                                        Form1->ButtonCrearHilo->Enabled=false;
                                        Form1->ButtonTerminarHilo->Enabled=true;
                                        HiloDbg->SetRuta(Form1->OpenDialog1->FileName);
                                        HiloDbg->Resume();//lanzamos el hilo
                                }
                                else
                                {
                                        MessageBoxA(Application->Handle,"El archivo seleccionado no es DinesatRadio9.exe. Inténtelo de nuevo","Atención", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
                                        retval =false;
                                }
                        }
                        else
                        {
                                MessageBoxA(Application->Handle,"No se pudo abrir DinesatRadio9.exe. Inténtelo de nuevo","Atención", MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
                                retval =false;
                        }
                }
        }
        return retval;
}
//----------------------------------------------------------------------------

void __fastcall TForm1::ButtonCrearHiloClick(TObject*Sender)
{
        //Creamos el hilo del debugger
        if(LanzarHilo()==false)
        {
                MessageBoxA(Application->Handle,"No se ha podido iniciar el Loader correctamente.\n Cierre la aplicación e intentelo de nuevo.","Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
        }
        else
        {
                ButtonCrearHilo->Enabled=true;
                ButtonTerminarHilo->Enabled=false;
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ButtonTerminarHiloClick(TObject*Sender)
{
        //Terminamos el hilo del debugger
        //TerminateThread(hThread,ThreadId);
        HiloDbg->Suspend();
        HiloDbg->Terminate();
        //Habilitamos el boton para crear el hilo y deshabilitamos el de terminar el hilo
        ButtonCrearHilo->Enabled=true;
        ButtonTerminarHilo->Enabled=false;
}
//---------------------------------------------------------------------------

El problema que tengo es que primero desde el boton hago que se lance el hilo suspendido (eso creo) y en el constructor creo el componente TDbgCLS y en el evento Resume le asigno dos procedimientos a los procedimientos breaksystembp y breakhbp del componente para poder controlar esos eventos usando mis procedimientos y acto seguido hago que funcione el componente. El problema está en que primero entra en el constructor, luego pasa al Resume cuando yo deseo y ejecuta todo el codigo sin quedarse en el Loop del debugger y acto seguido termina el programa sin dar ningun tipo de error ni pasar por el destructor ni nada, o sea que no hace absolutamente nada, ni entra en las funciones breaksystembp, ni breakhbp, ni nada. ¿que hago mal?
Espero que se me haya entendido ahora.

ecfisa 10-08-2013 18:19:01

Cita:

Empezado por aguml (Mensaje 465329)
pues mi duda es que si por ejemplo creo un boton usando new ¿Como controlo sus eventos para que por ejemplo al pulsar el boton se ejecute un codigo. Un ejemplo por favor. El componente que estoy usando no es visual, su owner es null, y lo creo en un hilo pero supongo que será igual.

Hola aguml.

Ejemplo:

.h
Código:

...
class TForm1 : public TForm
{
...
private:
  void __fastcall btClick(TObject *Sender);
...

.cpp
Código:

...
void __fastcall TForm1::btClick(TObject *Sender)
{
  ShowMessage("Click");
}


void __fastcall TForm1::FormCreate(TObject *Sender)
{
  TButton *bt = new TButton(this);
  bt->Name = "btNew";
  bt->Caption = "Nuevo";
  bt->Top  = 10;
  bt->Left = 10;
  bt->OnClick = btClick;
  bt->Parent = this;
}

Saludos :)

aguml 10-08-2013 19:39:52

el problema no es ese, ya que el componente se crea y todo pero en resume del hilo, el procdimiento del componente que se llama debugloop o algo asi, de ahi no debe de salir hasta que se termine el proceso que estoy debugeando pero por alguna razon no pasa eso, el proceso no arranca y salgo del loop y cuando termina el resume, al terminar el hilo no pasa por el destructor del hilo y la aplicacion continua y cuando termina la funcion que crea el hilo mi aplicacion termina sin ningun tipo de excepcion.

ecfisa 10-08-2013 21:51:46

Hola aguml.

Lamentablemente no conozco el componente TDbgCLS, sus eventos y procedimientos. Tal vez exista alguna bibliografía para revisar esos detalles pero no encontré nada al respecto.

Saludos. :)

aguml 10-08-2013 22:09:11

es de un compañero del grupo de google de CracksLatinoS llamado stzwei y es opensource, si te interesa te lo paso con los fuentes, ayuda y demas. El problema con el que me encuentro es que para que el componente funcione correctamente y funcionen los hardware breakpoints y que no se quede colgado el form hay que crearlo en un hilo.


La franja horaria es GMT +2. Ahora son las 21:32:50.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi