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

Emm*_*iah 4 delphi winapi window

  1. 我创建了一个无标题窗口.
  2. 我手动(或编程)调整大小,使其高度为30像素或更少.
  3. 然后当我抓住底部边框以垂直调整它时,它的行为就像我拖动顶部边框一样.实际上,在调试程序时,WM_SIZING参数包含WMSZ_TOP而不是WMSZ_BOTTOM.

我的程序是用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;
Run Code Online (Sandbox Code Playgroud)

Ser*_*yuz 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;
Run Code Online (Sandbox Code Playgroud)

  • @Emmanuel - 不客气.我没有测试过但如果您需要对左右和/或角尺寸采用类似的覆盖,我不会感到惊讶.你可能需要扩展它,但你明白了. (2认同)

Emm*_*iah 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;
Run Code Online (Sandbox Code Playgroud)