程序中需要用PageControl来实现多窗口的标签管理,但是不管是标准控件还是dev的cxPageControl,都没能完全实现双击关闭的功能。现在可以实现的功能是:双击(或者鼠标中键)点击,由cxPageControl实现OnDoubleClick或者OnMouseDown事件,可以调用pageControl.ActivePage.Destroy方法来关闭当前激活的Sheet。现在的难点在于:我想实现的是功能是双击任意一个标签,即关闭被双击的标签。
我之前有过两个思路:
    1、当鼠标双击的时候,判断鼠标的坐标位置,然后和标签的x坐标进行对比,但是在实现过程中困难在于,sheet的left属性返回的是sheet窗体的left(一般就是0或者1),而不是标签的x坐标。
    2、在cxPageControl中,有OnClick事件,在OnClick事件中,把被点击的Sheet设置为ActivePage,再双击就可以实现关闭功能。这个方法的难点在于,1、如果程序响应了OnClick事件,那么就不再响应OnDoubleClick事件了;2、怎么在OnClick事件中判断当前点击的是哪个页面?(貌似如果这个问题解决了,就可以直接用思路1解决问题了。)先给出50分做铺垫,如果很快有合适的解决方案,将追加到100分!今天在线等到4点半,明天上班后继续等。

解决方案 »

  1.   


    procedure TForm1.TabSheet1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if GetTickCount - aTemp < 500 then
        (Sender as TTabSheet).Destroy;
      aTemp := GetTickCount;               //其中aTemp定义在类中(private下)变量 
    end;
    标准的TPageControl没有Click事件,那么久在MouseDown中利用两次操作时间差来判定其是否为双击动作.当然,这个时间差可以自行设定,但是VCL控件中很多地方都是设置为500。这个事件对于每个TabSheet都要进行关联设置,这样,每个TabSheet就可以实现双击关闭了!
      

  2.   

    自己写一个消息捕获的过程
    begin
      if (Msg.message = WM_LBUTTONDBLCLK) and (Msg.hwnd = PageControl1.Handle) then
      begin
        if PageControl1.ActivePageIndex = 0 then Exit;
        PageControl1.ActivePage.TabVisible := False;
      end;
    end;
      

  3.   


    procedure DoMessage(var Msg: TMsg; var Handled: Boolean) ;procedure TForm1.DoMessage(var Msg: TMsg; var Handled: Boolean);
    begin
      if (Msg.message = WM_LBUTTONDBLCLK) and (Msg.hwnd = PageControl1.Handle) then
      begin
        if PageControl1.ActivePageIndex = 0 then Exit;
        PageControl1.ActivePage.TabVisible := False;
      end;
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Application.OnMessage := Self.DoMessage;
    end;
      

  4.   


    那把MouseDown写成一个通用的事件,你每创建一个TabSheet的时候就对其OnMouseDown时间赋值就可以了
      

  5.   

    merrymin:
    我现在在窗口类当中增加了一个过程
    TFmAirMain = class(TForm)
      
      ……
      ……
      Procedure DoSheetMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
    private
      function AddNewPage(cap: String) : TcxTabSheet;
    public
    end;在DoSheetMouseDown的实现中就用的你所提到的方法。现在,我在AddNewPage中新增一个sheet,并指定事件:
      Result := TcxTabSheet.Create(self);
      with Result do
      begin
        PageControl := cxPageControl1;
        Caption := cap;
        TabVisible := True;
        OnMouseDown := DoSheetMouseDown;
      end;但是在程序中DoSheetMouseDown并没有响应,不管我怎么双击,都不能进入DoSheetMouseDown过程,请问这是怎么回事啊?
      

  6.   

    我很久前寫過一個多頁簽瀏覽器
    首先事件是在pagecontrol1上,你的好像寫在TabSheet
    pagecontrol1.OnMouseDown := pagemousedown;
    然後雙擊事件是這樣子寫
    procedure TForm1.pagemousedown(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
        if (ssDouble in Shift) or (ssRight in Shift) then  n4.Click;//雙擊關閉頁簽
    end;
      

  7.   

    這樣來具體關閉pagecontrol1.pages[tabindex].free;
      

  8.   

    继承一个新的step 1. 在构造函数里 给 TControlStyle 加上 csClickEvents
    step 2. 加上 property OnDblClick;
    step 3. 写个过程[如procedure kill(sender: tobject);],OnDblClick取得这个过程地址即可.
    step 4. done!!!
      

  9.   

    一句话点醒梦中人啊,以前我好像还真试过,点击标签,sheet是不会响应的,如果把这个事件定义在PageControl里面,应该可以响应的。
    不过n4.click是啥意思捏?莫非是你做了一个弹出菜单?n4是关闭按钮?
    pagecontrol1.tabindex是ActivePage的索引吗?那用ActivePage行不行呢?如果是用ActivePage的话,是不是说双击任意表情之后,那个page已经就变成ActivePage了呢?
    家里电脑没环境,明天上班之后试试,呵呵
      

  10.   


    樓主很聰明,這兩句只是從中截取的。n4確實是一個彈出菜單,關閉頁簽還關係到待關閉TABSHEET上資源的釋放,以及對關閉后的當前頁是前一頁還是后一頁,還有對頁簽數是否>0的判斷等,所以隨便取兩句給你了