WM_SIZING中用于高度非常小的窗口的错误边信息

时间:2013-12-01 12:39:28

标签: delphi winapi window

  1. 我创建了一个无标题窗口。
  2. 我手动(或以编程方式)调整其大小,使其高度为30像素或更低。
  3. 当我抓住底部边框以垂直调整大小时,它表现为 如果我拖动顶部边框。实际上,在调试程序时,WM_SIZING参数包含WMSZ_TOP而不是WMSZ_BOTTOM。
  4. 我的程序是用Delphi编写的,基本上问题可以通过以下FormCreate的主窗体重现:

    procedure TForm2.FormCreate(Sender: TObject);
    
      var oldStyle : LongInt;
      var newStyle : LongInt;
    
    begin
      //  Adapt windows style.
    
      oldStyle := WINDOWS.GetWindowLong (
                              handle,
                              GWL_STYLE);
    
      newStyle := oldStyle              and
                  (not WS_CAPTION)      and
                  (not WS_MAXIMIZEBOX);
    
      WINDOWS.SetWindowLong(
                  handle,
                  GWL_STYLE,
                  newStyle);
    
      //  SetWindowPos with SWP_FRAMECHANGED needs to be called at that point
      //  in order for the style change to be taken immediately into account.
    
      WINDOWS.SetWindowPos(
                  handle,
                  0,
                  0,
                  0,
                  0,
                  0,
                  SWP_NOZORDER     or
                  SWP_NOMOVE       or
                  SWP_NOSIZE       or
                  SWP_FRAMECHANGED or
                  SWP_NOACTIVATE);
    end;
    

2 个答案:

答案 0 :(得分:7)

对我来说,操作系统看起来像是一个错误。在测试用例的条件下,命中测试处理错误,默认窗口过程返回HTTOP时应该返回HTBOTTOM。您可以覆盖命中测试处理以获得解决方法:

procedure TForm1.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  if (Message.Result = HTTOP) and
      (Message.Pos.Y > Top + Height - GetSystemMetrics(SM_CYSIZEFRAME)) then
    Message.Result := HTBOTTOM;
end;

答案 1 :(得分:5)

干得好,谢谢。我确认这是一个操作系统错误,与delphi无关(我能够使用WINDOWS API创建一个简单的窗口重现问题)。

我现在最终得到了:

procedure TForm2.WMNcHitTest(
                     var msg : TWMNCHitTest);
begin
  inherited;

  case msg.result of

      HTTOP:
        begin
          if msg.pos.y > top + height div 2 then
              msg.result := HTBOTTOM;
        end;

      HTTOPRIGHT:
        begin
          if msg.pos.y > top + height div 2 then
              msg.result := HTBOTTOMRIGHT;
        end;

      HTTOPLEFT:
        begin
          if msg.pos.y > top + height div 2 then
              msg.result := HTBOTTOMLEFT;
        end;

  end;
end;