delphi event-handling mouseevent delphi-7

Detener la propagación de eventos en Delphi 7



event-handling mouseevent (2)

Como han dicho TLama y TOndrej, hay algunas maneras de lograr lo que estás intentando:

  1. Para hacer if Assigned(Control.OnMouseUp) then Exit; en su controlador de eventos OnClick

  2. Para "anular la asignación" del evento OnClick al asignar OnMouseUp (y viceversa)

Ambos enfoques lograrán lo que usted ha detallado, aunque "desasignar" el evento OnClick será lo mejor para el rendimiento (en una pequeña medida) ya que no realizará la instrucción if repetidamente.

Estoy atascado en un problema en Delphi 7 sobre la propagación del evento (debido a mi ignorancia).

Se me pide que adjunte dinámicamente un controlador de eventos OnMouseUp en algunos controles de un formulario (y estoy de acuerdo con eso), pero si el OnMouseUp está presente, el evento OnClick en ese control no debe procesarse.

Fondo

Si está preguntando la razón detrás de esto, bueno, estoy a cargo de modificar una vieja aplicación de supervisión de producción (suspiro) que de ahora en adelante debe acomodar un comportamiento condicional para algunos controles, en respuesta directa a un clic anterior en una función especial botón.

Algunos de esos controles ya tienen un manejador de eventos OnClick ; la primera solución que se le ocurrió al equipo fue intervenir puntualmente en cada controlador OnClick y gestionar las acciones contextuales en relación con el estado del botón de función especial.

Sugerí aprovechar el diseño orientado a objetos que ya existe para los formularios de solicitud: todos ellos heredan del mismo objeto ancestro personalizado, así que OnMouseUp insertar un método de inicialización allí para adjuntar dinámicamente eventos OnMouseUp a los controles que están declarados a apoyarlo en subclases.

La necesidad

No estoy pidiendo una validación o cuestionamiento sobre la (posible falta de) bondad de diseño sobre todo esto (por cierto, después de pensar mucho y razonar, parecía ser el camino por el que podemos caminar con menos dolor); mi problema es que para que tal diseño tenga lugar, tendría que permitir que los controladores de eventos OnMouseUp conectados OnMouseUp detengan la propagación de eventos a los eventos OnClick preexistentes en esos controles.

¿Es posible con Delphi 7?


Tenga en cuenta que lo siguiente no responde explícitamente la pregunta aquí. Es más una propuesta para el rediseño de los eventos OnClick en lugar de agregar OnMouseUp adicional. Se trata de cómo redireccionar el controlador de eventos OnClick (si se le asignan algunos) de todos los componentes (se pueden filtrar, si es necesario) a otro manejador de eventos OnClick (común). Incluye también un método para restaurarlos al estado original.

En el siguiente ejemplo, trataré de mostrarle cómo reemplazar y, opcionalmente, restaurar los controladores de eventos OnClick (si el componente ha escrito algunos) por el específico. Esto se hace para todos los componentes que tienen el evento OnClick publicado, por lo que no necesita saber de antemano si la clase de componente tiene el evento OnClick disponible o no (pero puede ser modificado simplemente para usar solo una clase específica).

El código consiste de lo siguiente:

  • OnSpecialClick : es el controlador de eventos de todos los eventos de OnClick vinculados cuando llamas al procedimiento ReplaceOnClickEvents, ten en cuenta que debe publicarse para que sea visible para RTTI.

  • Button1Click - representa aquí el antiguo controlador de eventos que debe reemplazarse, está vinculado al evento Button1.OnClick en el momento del diseño

  • ReplaceOnClickEvents - método, que itera a través de todos los componentes en el formulario y las verificaciones
    si el iterado actualmente tiene asignado el manejador de eventos OnClick; si es así, lo almacena en una colección de respaldo y reemplaza este controlador de evento por OnSpecialClick

  • RestoreOnClickEvents - método, que restaura los controladores de eventos OnClick originales; itera a través de la colección de respaldo y asigna los métodos de evento a sus instancias de componentes almacenados

  • CheckBox1Click : este evento de clic de casilla de verificación está destinado a ser el cambio entre el modo común y el modo especial (el estado comprobado CheckBox1 significa que es el modo especial), solo este evento OnClick no se sustituye por la llamada ReplaceOnClickEvents (porque no estaría capaz de restaurar el modo a la normalidad)

Y aquí está:

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, TypInfo, StdCtrls, Contnrs; type TEventBackup = class Component: TComponent; OnClickMethod: TMethod; end; type TForm1 = class(TForm) Button1: TButton; CheckBox1: TCheckBox; procedure Button1Click(Sender: TObject); procedure CheckBox1Click(Sender: TObject); private procedure ReplaceOnClickEvents; procedure RestoreOnClickEvents; published procedure OnSpecialClick(Sender: TObject); end; var Form1: TForm1; EventBackupList: TObjectList; implementation {$R *.dfm} procedure TForm1.OnSpecialClick(Sender: TObject); begin ShowMessage(''Hi, I''''m an OnSpecialClick event message!''); end; procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(''Hi, I''''m just that boring original OnClick event message!''); end; procedure TForm1.ReplaceOnClickEvents; var I: Integer; Component: TComponent; EventMethod: TMethod; EventBackup: TEventBackup; begin for I := 0 to ComponentCount - 1 do begin Component := Components[I]; if Component = CheckBox1 then Continue; if IsPublishedProp(Component, ''OnClick'') then begin EventMethod := GetMethodProp(Component, ''OnClick''); if Assigned(EventMethod.Code) and Assigned(EventMethod.Data) then begin EventBackup := TEventBackup.Create; EventBackup.Component := Component; EventBackup.OnClickMethod := EventMethod; EventBackupList.Add(EventBackup); EventMethod.Code := MethodAddress(''OnSpecialClick''); EventMethod.Data := Pointer(Self); SetMethodProp(Component, ''OnClick'', EventMethod); end; end; end; end; procedure TForm1.RestoreOnClickEvents; var I: Integer; EventBackup: TEventBackup; begin for I := 0 to EventBackupList.Count - 1 do begin EventBackup := TEventBackup(EventBackupList[I]); SetMethodProp(EventBackup.Component, ''OnClick'', EventBackup.OnClickMethod); end; EventBackupList.Clear; end; procedure TForm1.CheckBox1Click(Sender: TObject); begin if CheckBox1.Checked then ReplaceOnClickEvents else RestoreOnClickEvents; end; initialization EventBackupList := TObjectList.Create; EventBackupList.OwnsObjects := True; finalization EventBackupList.Free; end.