美文网首页
BCB动态库和OCX里面CM_MOUSELEAVE和CM_MOU

BCB动态库和OCX里面CM_MOUSELEAVE和CM_MOU

作者: bingo_hzy | 来源:发表于2019-02-21 17:40 被阅读0次

    由于改造封装一个BCB的OCX,在MFC里面调用,导致原来许多使用的CM_MOUSELEAVE和CM_MOUSEENTER消息失效,这两个消息是VCL的自定义消息,依赖于VCL的消息循环,源于TApplication.DoMouseIdle方法,而该方法由TApplication.Idle调用,Idle是TApplication.HandleMessage的消息处理循环的一部分。最终HandleMessage消息处理循环由TApplication.Run启动;显然在DLL和OCX里面的TApplication对象都不会调用Run方法。因为原来的代码里面大量使用了这两个消息,全部去改也是不现实的。既然如此,只好自己实现这两个消息,首先在我的OCX设置鼠标钩子:

    mhhook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseProc, NULL, GetCurrentThreadId());
    

    然后在钩子过程函数里调用自已实现的DoMouseIdle;

    LRESULT CALLBACK TXXXXXXXX::MouseProc(int code, WPARAM wParam, LPARAM lParam)
    {
        if(wParam == WM_MOUSEMOVE)
        {
            msThis->DoMouseIdle();
        }
        return CallNextHookEx(mhhook, code, wParam, lParam);
    }
    
    TControl* TXXXXXXXXX::DoMouseIdle()
    {
      TControl* CaptureControl;
      TPoint P;
    
      GetCursorPos(&P);
      TControl* Result = FindDragTarget(P, true);
      CaptureControl = GetCaptureControl();
      if(FMouseControl != Result)
      {
        if (((FMouseControl != NULL) && (CaptureControl == NULL)) ||
          ((CaptureControl != NULL) && (FMouseControl == CaptureControl)))
            FMouseControl->Perform(CM_MOUSELEAVE, 0, 0);
        FMouseControl = Result;
        if (((FMouseControl != NULL) && (CaptureControl == NULL)) ||
          ((CaptureControl != NULL) && (FMouseControl == CaptureControl)))
          FMouseControl->Perform(CM_MOUSEENTER, 0, 0);
      }
      return Result;
    }
    

    DoMouseIdle是根据Pas源码改的。至此整个功能就完成了。

    相关文章

      网友评论

          本文标题:BCB动态库和OCX里面CM_MOUSELEAVE和CM_MOU

          本文链接:https://www.haomeiwen.com/subject/kqsdyqtx.html