Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Problemas con checkado en checkbox de otra aplicacion (https://www.clubdelphi.com/foros/showthread.php?t=86770)

aguml 30-09-2014 12:47:03

Problemas con checkado en checkbox de otra aplicacion
 
hola amigos, estoy viendo como puedo hacer para, desde mi proceso, marcar un checkbox de otro proceso. 
Lo primero que hago es usar FindWindow para obtener el hwnd de la ventana. 
Luego uso EnumChildWindow para recorrer todos los elementos de la ventana. 
En el callback busco que la clase sea TCheckBox y si es asi retorno en LParam el hwnd del TCheckBox.
Luego uso la siguiente macro para activar/desactivar el checkbox: 
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx 

Todo funciona correctamente ¿Donde está el problema? El problema es que, aunque aparezca checkado, si pongo una comprobacion en la "victima" tipo if(CheckBox1->Checked == true)... La comprobacion da como resultado que no está checkado y al pulsar sobre el se vuelve a marcar como si no lo estuviese antes. 
¿Alguna idea de como arreglarlo?


escafandra 30-09-2014 19:24:42

En teoría no vas mal encaminado, debería funcionar, si no lo hace se debe a la gestión de la VCL. Puedes ir un paso más allá y simular un click del ratón

Saludos.

aguml 30-09-2014 19:39:09

Como las dos aplicaciones son mias ¿que tal si cambio el wndproc del checkbox por uno mio y dentro gestiono el evento BM_SETCHECK?

escafandra 30-09-2014 20:02:09

En ese caso usa un mensaje de usuario y lo gestionas como quieras.

Saludos.

aguml 30-09-2014 20:42:05

escafandra no se ni que es eso de un mensaje de usuario pero supongo será un mensaje inventado por mi ¿no?
Ya lo he conseguido así pero mandando el mensaje original. ¿es mejor usar uno propio para no pisar la funcion original o algo asi?

Te pongo el link con los fuentes de los dos procesos que son clones pero solo cambia que uno busca a Proceso A y el otro a Proceso B, y en todas las partes que uno hace referencia a Proceso B, el otro hace referencia a Proceso A.
Link: Aqui

Me gustaria que le echaras un vistazo y me comentaras que cambiarias. Es el proyecto que uso en el tema de procesos que charlan entre si pero para hacerlos sincronicos o asincronicos uso un checkbox que al marcarlo en un proceso tambien se marca en el otro y, dependiendo del estado de ese checkbox, se desactiva el boton de enviar mensaje al enviar y se activa al recibir para hacerlo sincronico o nunca se desactiva para hacerlo asincronico.

escafandra 01-10-2014 00:39:30

Los mensajes de usuario comienzan a partir del WM_USER, sirven para crear tus propios mensajes.

Cuando tenga un rato miro ese código. :)


Saludos.

ecfisa 01-10-2014 01:37:07

Hola aguml.

Creo que lo complicas usando WndProc para capturar el mensaje, es mas simple:

Emisor:
codigo
Código PHP:

...
void wmCopyData(charWndClasscharWndTitlecharmsg
{
  
HANDLE hRecept;
  
COPYDATASTRUCT cds;

  
hRecept FindWindow(WndClassWndTitle);
  if (
hRecept != 0) {
    
cds.dwData 0;
    
cds.cbData strlen(msg)+1;
    
cds.lpData = (char*)msg;
    
SetForegroundWindow(hRecept);
    
SendMessage(hReceptWM_COPYDATA0, (LPARAM)& cds);
  } else
    
MessageBox(0,"Receptor no encontrado",""MB_ICONERROR);
}

// ej. envio 
void __fastcall TfrmSender::Button1Click(TObject *Sender)
{
 
wmCopyData("TfrmReceiver""Receiver"Edit1->Text.c_str());


Receptor:
header
Código PHP:

...
class 
TfrmReceiver : public TForm
{
__published:

private:
  
void __fastcall OnWMCopyData(TWMCopyDatamsg);

protected:
  
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER
(WM_COPYDATATWMCopyDataOnWMCopyData)
  
END_MESSAGE_MAP(TForm)

public:
  
__fastcall TfrmReceiver(TComponentOwner);
};
... 

codigo
Código PHP:

...
void __fastcall TfrmReceiver::OnWMCopyData(TWMCopyDatamsg)
{
  
ShowMessage("Mensaje recibido: " String((char*)msg.CopyDataStruct->lpData));
}
... 

Saludos :)

aguml 01-10-2014 10:20:43

Ok, cambiado.
Con respecto a lo que hago para gestionar lo del CheckBox ¿como lo ves? ¿como lo mejorarías? Es que acabo de aprender lo de cambiar el WndProc y lo aplico a todo jejeje :o

ecfisa 01-10-2014 17:59:36

Hola aguml.

No estoy diciendo que esté mal usar WndProc, lo que sucede es que Builder ya tiene definido ese mensaje y te evitas la comprobación de si el mensaje fué otro.

A ver si este ejemplo te dá otra idea... En el form emisor pone un TButton y un TCheckBox y en el receptor tres TCheckBox (CheckBox1, CheckBox2 y CheckBox3) .

Emisor:
Código PHP:

...
struct data_struct {
  
char className[255];
  
char caption[255];
  
int xy;
  
TColor color;
  
bool state;
ds;

void __fastcall TfrmSender::Button1Click(TObject *Sender)
{
  
HANDLE hRecept FindWindow("TfrmReceiver""Receiver");
  if (
hRecept != 0) {
    
COPYDATASTRUCT cds;
    
strcpy(ds.className"TCheckBox");  
    
strcpy(ds.caption,"CheckBox2");     
    
ds.50;
    
ds.30;
    
ds.color clYellow;
    
ds.state CheckBox1->Checked;
    
cds.dwData 0;
    
cds.cbData sizeof(ds);
    
cds.lpData = &ds;
    
ShowWindow(hReceptSW_SHOW);
    
SetForegroundWindow(hRecept);
    
SendMessage(hReceptWM_COPYDATA0, (LPARAM)& cds);
  } else
    
MessageBox(0,"Receptor no encontrado",""MB_ICONERROR);


Receptor:

header
Código PHP:

class TfrmReceiver : public TForm
{
__published:
  
TCheckBox *CheckBox1;
  
TCheckBox *CheckBox2;
  
TCheckBox *CheckBox3;

private:
  
void __fastcall OnWMCopyData(TWMCopyDatamsg);

protected:
  
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER
(WM_COPYDATATWMCopyDataOnWMCopyData)
  
END_MESSAGE_MAP(TForm)

public:
  
__fastcall TfrmReceiver(TComponentOwner);
}; 

code
Código PHP:

struct data_struct {
  
char className[255];
  
char caption[255];
  
int xy;
  
TColor color;
  
bool state;
ds;

void __fastcall TfrmReceiver::OnWMCopyData(TWMCopyDatamsg)
{
  
memcpy(&dsmsg.CopyDataStruct->lpDatasizeof(data_struct));

  for(
int i 0ComponentCounti++) {
    
TCheckBox *cb static_cast<TCheckBox*>(Components[i]);
    if (
cb->ClassNameIs(ds.className) && cb->Caption == ds.caption) {
      
cb->Left    ds.x;
      
cb->Top     ds.y;
      
cb->Color   ds.color;
      
cb->Checked ds.state;
    }
  }


Saludos :)

aguml 01-10-2014 19:08:36

Guauuu pues si que es potente este método.


La franja horaria es GMT +2. Ahora son las 12:09:21.

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