不要把单击事件写在wm_lbuttondown事件中,写在wm_lbuttonclick事件中

解决方案 »

  1.   

    wm_lbuttonclick 编译时说这个消息是没有的。没定义?
      

  2.   

    就是左键单击事件啊,对了,是buttonclick事件,没有l啊
      

  3.   

    我的程序能实现左右键单双击共四个事件的处理: http://rbsky.myetang.com/SuperEx.exe,你先看着,我把代码给你抽出来,我记得当时实现时也折腾了好一会儿,实现后觉得很EZ了
      

  4.   

    代码一时不知放哪儿了,原理是这样的:
    trayicon在你鼠标左键双击时会先收到一条WM_LButtonDown、
    紧接着会收到WM_LBUTTONDBLCLK说明用户是双击而非单击
    所以你在LButtonDown中的处理不应该是直接的单击处理,而是一个类似超时处理的循环,其时间长短会用到API GetDoubleClickTime(触发双击的最大时间间隔,再大了就是单击两次了),当已超时而未触发LBUTTONDBLCLK时说明真是单击,否则是因为双击而触发的,就只执行LBUTTONDBLCLK而不招待LButtonDown好了
      

  5.   

    好的,谢谢 redbirdli(火鸟)
      

  6.   

    眼见为实,找到了代码,上半部分是对左右键四个事件的处理,下半部分是我的Trayicon代理的实现:
    procedure Tmain.wndProc(var Msg: TMessage) ;//重载并自定义消息
    var poss:TPoint;CurrentTime :longint;
        Para:array [0..MAX_PATH] of char;
    begin
       GetCursorPos(Poss);  //得到当前鼠标位置
      with msg do
      begin
        if msg =wm_MyCall then
        Begin
          if WParam=0 then //这是程序的主图标消息
          begin
            CurrentTime:=gettickcount;//得到当前开机时间
            case LParam of
            WM_LBUTTONDBLCLK:
            begin
              Mine.Tag :=1;// 双击事件时不处理单击
              MineClick(nil);        //双击事件为窗口是否显示的切换
            end;
            wm_LButtonDown:
            begin
             Mine.Tag:=0;
             while ((gettickCount)<(CurrentTime+GetDoubleClickTime)) and (Mine.Tag=0) do
             application.ProcessMessages;
            if Mine.Tag=0 then TrackPopupMenu(mn.handle,tpm_BottomAlign or tpm_RightAlign,Poss.X,Poss.Y,0,handle,nil);
           //PopMenu(self);
     //       timClk.Enabled:=true;//将处理单击的时钟激活,到时处理单击
            end;
            WM_RBUTTONDBLCLK:
            begin
              //FowTimTimer(self);//如字符跟踪则将活动窗口Caption还原
              Mine.Tag :=1;// 双击事件时不处理单击
              MnexitClick(nil);
              halt;
            end;
            wm_RButtonDown:
            begin
              Mine.Tag:=0;
              while ((gettickCount)<(CurrentTime+GetDoubleClickTime)) and (Mine.Tag=0) do
              application.ProcessMessages;
              if Mine.Tag=0 then TrackPopupMenu(mnrun.handle,tpm_BottomAlign or tpm_RightAlign,Poss.X,Poss.Y,0,handle,nil);
            end;
            End;
          end
          else //这是程序表生成的图标消息
          begin
            case LParam of
              wm_LButtonDown:
              for CurrentTime:=0 to prglist.Items.Count-1 do
              begin
                 if prglist.Items[CurrentTime].ImageIndex<>WParam-1 then continue;
                 N8Click(mnrun.Items[CurrentTime]);
                 break;
              end;
              wm_RButtonDown:shellabout(handle,Myname,'火鸟软件出品   [email protected]',application.icon.handle);
            end;
          end;
        end
        else
        begin
          if msg=ReCall then//这是由新运行的程序传来的,高字节是命令行及参数,低字节是长度
          begin
            if WParam>0 then
            begin
              //para:=strAlloc(LParam);
              GlobalGetAtomName(WParam,@para,LParam);
              GlobalDeleteAtom(WParam);
      if (wordat(para,':2')=2) or (wordat(para,':2')=3) then messagebox(handle,'请先将运行中的超人关闭',myname,mb_ok+MB_ICONINFORMATION)
              else
              begin
                //para:=pchar(copy(para,wordat(para,':2')-1,LParam));
                //if filesafe(para) then FileOper(para,handle);
                if main.icosva.Hint='' then
                  if filesafe(copy(para,wordat(para,':2')-1,LParam)) then
                    FileOper(copy(para,wordat(para,':2')-1,LParam),screen.ActiveForm.handle);
              end;
              //StrDispose(para);
            end
            else
            begin
              if top=-1000 then MineClick(Nil);
              SetForegroundWindow(application.handle);
              FlashWindow(handle,false);
              delay(0.1);
              FlashWindow(handle,true);
              Refresh ; 
            end;
          end;       case WParam of   //WM_SYSCOMMAND
            Hot_Lock:
            fmlock.showmodal;
            Hot_Key:
            begin
              if top=-1000 then MineClick(Nil);
              SetForegroundWindow(application.handle);
              Refresh ;
            end;
            SC_MINIMIZE:
            begin
              MineClick(self);
              exit;
            end;
    {        SC_MAXIMIZE,SC_RESTORE:
            begin
              LogPopClick(TopOn);
              exit;
            end;}
         end;
        end;
      end;
      inherited wndProc(Msg);    //继承
    end;
      

  7.   

    对了,除写个循环外,你也可以用一个触发时间等于GetDoubleClickTime的时钟控件或用API SetTimer实现
      

  8.   

    API,强大有趣,无所不能,我喜欢!
    互勉共进吧!
      

  9.   

    是的,谢谢,好象就是这句话
    while ((gettickCount)<(CurrentTime+GetDoubleClickTime)) and (Mine.Tag=0) do
     application.ProcessMessages;
    就是判断2次点击的时间的间隔如果在双击范围内,那就application.ProcessMessages;//这句话应该是跳过的意思。