如何动态分配Windows消息处理程序?

时间:2018-10-02 07:39:06

标签: delphi vcl

我们可以像这样在编译时覆盖特定消息的处理程序:

SELECT
    invoice_month,
    time_of_month,
    ARRAY_AGG(id) invoice_ids
FROM (
    SELECT
        id,
        invoice_month,
        -- Categorize as end or beginning of month
        CASE
            WHEN month_rank <= 10 THEN 'beginning'
            WHEN month_reverse_rank <= 10 THEN 'end'
            ELSE 'bug' -- Should never happen. Just a fall back in case of a bug.
        END AS time_of_month
    FROM (
        SELECT
            id,
            invoice_month,
            dense_rank() OVER (PARTITION BY invoice_month ORDER BY invoice_date) month_rank,
            dense_rank() OVER (PARTITION BY invoice_month ORDER BY invoice_date DESC) month_rank_reverse
        FROM (
            SELECT
                id,
                invoice_date,
                to_char(invoice_date, 'Mon-yy') AS invoice_month
            FROM public.invoice
            WHERE invoice_date BETWEEN date '2017-10-01' AND date '2018-09-30'
        ) AS fiscal_year_invoices
    ) ranked_invoices
    -- Get first and last 10
    WHERE month_rank <= 10 OR month_reverse_rank <= 10
) first_and_last_by_month
GROUP BY
    invoice_month,
    time_of_month

是否可以在不使用message关键字声明方法的情况下动态创建消息处理程序?

1 个答案:

答案 0 :(得分:-1)

没有内置的语法构造可动态覆盖消息处理程序。但是,有许多方法可以实现相同的行为。正如David所建议的那样,您可以覆盖WndProc并在那里处理。否则,您也可以这样做:

type
  { Return false to call inherited handler }
  TConditionalHandler = reference to function(var msg : TMessage) : boolean;

  TForm1 = class(TForm)   
  private
    FDoOnPaint : TConditionalHandler;
    procedure DoOnPaint(var msg : TMessage); message WM_PAINT;
  end;

其中(例如)

procedure TForm1.DoOnPaint(var msg: TMessage);
begin
  if Assigned(FDoOnPaint) then begin
    { Allow handler to choose if inherited is called... }
    if not FDoOnPaint(msg) then inherited;
  end else
    inherited;
end;

允许您动态附加处理程序

if not Assigned(FDoOnPaint) then begin
    FDoOnPaint := function(var msg : TMessage) : boolean
                  begin
                    self.Caption := DateTimeToStr(Now);
                    result := false; { Not actually doing any painting... call inherited }
                  end;