3

我在 .Net 中有用户控制,我在 WndProc 中使用命中测试来允许在运行时用鼠标调整它的大小。

问题是在命中测试成功后(鼠标按下、拖动以调整大小、鼠标释放),控件按 Z 顺序向上跳跃并破坏它在表单中的位置。

我需要命中测试,因为它是一个非常定制的控件。

WndProc 中有没有办法阻止控件更改它的 Z 顺序?

谢谢。

命中测试代码:

protected override void WndProc(ref Message m) {
  if (!DesignMode && Sizeable && (m.Msg == Win32Wrapper.WM_NCHITTEST)) {
    Point Hit = new Point((int)m.LParam & 0xFFFF, (int)m.LParam >> 16);
    Hit = this.PointToClient(Hit);
    int DistToBorder = 5;
    if (Hit.X < DistToBorder) {
      if (Hit.Y < DistToBorder) {
        m.Result = (IntPtr)Win32Wrapper.HTTOPLEFT;
        return;
      }
      if (Hit.Y > this.ClientRectangle.Bottom - DistToBorder) {
        m.Result = (IntPtr)Win32Wrapper.HTBOTTOMLEFT;
        return;
      }
      m.Result = (IntPtr)Win32Wrapper.HTLEFT;
      return;
    }
    else if (Hit.X > ClientRectangle.Right - DistToBorder) {
      if (Hit.Y < DistToBorder) {
        m.Result = (IntPtr)Win32Wrapper.HTTOPRIGHT;
        return;
      }
      else if (Hit.Y > this.ClientRectangle.Bottom - DistToBorder) {
        m.Result = (IntPtr)Win32Wrapper.HTBOTTOMRIGHT;
        return;
      }
      m.Result = (IntPtr)Win32Wrapper.HTRIGHT;
      return;
    }
    else if (Hit.Y < DistToBorder) {
      m.Result = (IntPtr)Win32Wrapper.HTTOP;
      return;
    }
    else if (Hit.Y > this.ClientRectangle.Bottom - DistToBorder) {
      m.Result = (IntPtr)Win32Wrapper.HTBOTTOM;
      return;
    }
  }
4

4 回答 4

6

为防止 Z 顺序更改,您应该捕获WM_WINDOWPOSCHANGING消息并设置SWP_NOZORDER标志。

于 2009-07-15T18:43:28.927 回答
1

没有答案,但是您是否尝试过使用他的ControlDesigner而不是滚动您自己的 deigner 模式交互?

于 2009-02-28T14:03:55.047 回答
1

窗口对话框通过控件窗口的 z 顺序管理选项卡顺序和焦点,获得焦点的控件被提升到顶部。

如果您希望您的自定义控件保留其相对 z 定位,请确保其属性不指示其 TABSTOP 或以其他方式能够接收焦点。即如果禁用它会工作吗?

不利的一面是,即使您成功阻止控件的 z 顺序更改,它也会在用户与其他控件交互时隐式地重新定位。

于 2009-05-17T11:28:03.437 回答
1

你确定是命中测试导致了问题吗?你如何调整控件的大小?一种选择是使用传递 SWP_NOZORDER 标志的 p-invoke 调用 SetWindowPos。

于 2009-10-29T06:52:40.903 回答