2

ListViewが垂直スクロールを開始して終了するときにイベントをキャッチする方法はありますか?
まず、LVN_BEGINSCROLLおよびLVN_ENDSCROLL通知をキャッチしようとしましたが、結果は期待したものを正当化できませんでした。たぶん私はこれらの通知を処理しようとして間違っていました(親形式でWM_NOTIFYメッセージを処理し、そのハンドラーでMsg.NMHdr.codeをチェックしました)。
また、ListViewのWM_VSCROLLメッセージを処理しようとし、ScrollCode=SB_ENDSCROLLを確認しました。しかし、BeginScrollイベントを検出する方法は?
また、ListViewをマウスホイールでスクロールすると、WM_VSCROLLが表示されません。代わりに、WM_MOUSEWHEELメッセージが表示されます。WM_MOUSEWHEELメッセージで必要なイベントを検出して処理する方法は?デルタ、つまりWM_MOUSEWHEELメッセージのwParamの上位ワードをチェックすることで可能ですか?

または私は何ができますか?
ありがとう。

4

1 に答える 1

4

LVN_BEGINSCROLLLVN_ENDSCROLLComCtrl32 v6でのみ動作するため、アプリでXPテーマが有効になっている場合は、試してみると問題なく動作します。しかし、それらのタイミングはあなたが期待しているものとは異なり、それがあなたを混乱させている可能性があります。

WM_VSCROLLそれ自体が必要なものに対してより適切に機能し、ComCtl32v6に依存しません。また、マウスホイールのスクロールも処理しますが、ホイールの開始/終了スクロール通知のタイミングは、次の動きがいつ発生するかわからないため、LVN_BEGINSCROLLおよびLVN_ENDSCROLL通知のように機能します。したがって、ホイールの各ティックは独立して処理されます。

を使用WM_VSCROLLする場合、ブール変数を使用してスクロール状態を追跡し、BeginScrollを検出できるようにすると、メッセージによってEndScrollが通知されます。

これを試して:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, ComCtrls;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    IsScrolling: Boolean;
    PreviousWndProc: TWndMethod;
    procedure ListViewWndProc(var Message: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Commctrl;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  PreviousWndProc := ListView1.WindowProc;
  ListView1.WindowProc := ListViewWndProc;
end;

procedure TForm1.ListViewWndProc(var Message: TMessage);
{
type
  NMLVSCROLL = record
    hdr: NMHDR;
    dx: Integer;
    dy: Integer;
  end;
  LPNMLVSCROLL = ^NMLVSCROLL;
}
begin
  PreviousWndProc(Message);
  case Message.Msg of
    {
    CN_NOTIFY:
    begin
      case TWMNotify(Message).NMHdr^.code of
        LVN_BEGINSCROLL:
        begin
          if not IsScrolling then
          begin
            IsScrolling := True;
            // do something...
            // use LPNMLVSCROLL(Message.LParam) if needed...
          end;
        end;
        LVN_ENDSCROLL:
        begin
          if IsScrolling then
          begin
            IsScrolling := False;
            // do something...
            // use LPNMLVSCROLL(Message.LParam) if needed...
          end;
        end;
      end;
    end;
    }
    WM_VSCROLL:
    begin
      if TWMVScroll(Message).ScrollCode = SB_ENDSCROLL then
      begin
        if IsScrolling then
        begin
          IsScrolling := False;
          // do something...
        end;
      end
      else if not IsScrolling then
      begin
        IsScrolling := True;
        // do something...
      end;
    end;
  end;
end;

end.
于 2012-09-06T17:59:34.770 に答える