3

TListviewチェックボックスを使用して、リスト内の項目にイベントが発生したかどうかを示す場所があります。

チェックボックスのステータスを読み取って設定することはできますが、実際にやりたいことは、ユーザーがマウス クリックでステータスを変更できないようにすることです。

OnClickCheckを使用して状態を逆にTCheckList設定できますchecked

同じことは a では機能しませんTListview。それらの瞬間、チェックボックスがターゲットにされていることがわかりますがOnMouseDown、クリックが通過するのを無効にすることはできません..

procedure TMF.ListViewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
   MyHitTest : THitTests;
begin
   MyHitTest := (Sender as TListView).GetHitTestInfoAt(X,Y);
   if htOnStateIcon in MyHitTest then
      (Sender as TListView).OnMouseDown := nil;
end;

提案?

4

3 に答える 3

1

ウィンドウ プロシージャをフックして、VCL イベント処理が行われる前に項目がチェックされた状態を強制することができます。

  TForm1 = class(TForm)
    ...
  private
    fLVWndProc: TWndProc;
  end;


  procedure TForm1.FormCreate(Sender: TObject);
  begin
    // Save the original window proc and install the hook

    fLVWndProc := Listview1.WindowProc;
    Listview1.WindowProc := LVWndProcHook;
  end;



  procedure TForm1.LVWndProcHook(var aMessage: TMessage) ;
  var
    notify: PNMListView;
    bItemState: Boolean;
  begin
    if (aMessage.Msg = CN_NOTIFY)
     and (PNMHdr(aMessage.LParam).Code = LVN_ITEMCHANGED) then
    begin
      notify := PNMListView(aMessage.LParam);

      if ((notify.uChanged and LVIF_STATE) <> 0) then
      begin
        // Determine actual item state and re-apply it before continuing
        bItemState := GetUnderlyingItemState(notify.iItem);
        ListView_SetCheckState(notify.hdr.hwndFrom, notify.iItem, bItemState);
      end;
    end;

    //original ListView message handling
    fLVWndProc(aMessage) ;
  end;
于 2013-10-29T20:15:30.173 に答える