如何确定是否为窗口控件处理了 WM_SETREDRAW?

Ren*_*ann 1 winapi

我使用 Windows 消息 WM_SETREDRAW(请参阅MSDN)来锁定某些控件的重绘。通常,它是成对发送的。
但是在某些情况下,我不能保证这一点(例如,当它由第三方视觉组件的一个 - 通常,但不是每次,成对 - 回调事件触发时)。

如果至少一个控件已被锁定,则已经有一个计数器可以全局锁定各种操作。当消息不是成对发送时,会违反此计数器。

因此,我正在寻找一种可能性来检查控件是否已被锁定。我也很欣赏解决这个问题的替代想法。
先感谢您。

这些是我用于发送的包装例程WM_SETREDRAW

function IsValidWinControlToUnLock(const WinControl: TWinControl): Boolean;
begin
  Result := Assigned(WinControl) and
           (WinControl.Handle <> 0) and
           ControlIsVisible(WinControl); // assure the control and all its ancestors (via Parent) are visible
end;                        

function LockWinControl(const WinControl: TWinControl): Boolean;
begin
  Result := IsValidWinControlToUnLock(WinControl);
  if not Result then exit;

  Inc(MyGlobalLockCounter);

  WinControl.Perform(WM_SETREDRAW, 0);
end;                         

function UnlockWinControl(const WinControl: TWinControl): Boolean;
begin                        
  Result := IsValidWinControlToUnLock(WinControl);
  if not Result then exit;

  WinControl.Perform(WM_SETREDRAW, 1);

  Dec(MyGlobalLockCounter);
end;
Run Code Online (Sandbox Code Playgroud)

请注意, 的结果LockWinControl必须True在调用代码中UnlockWinControl才能被调用。我这样做,因为控制可能已经成为ValidToUnlock但不是ValidToLock首先。

如果没有办法通过 Windows API 获取信息(除了@Sertac Akyuc 所说的那个) - 我已经假设可能没有 - 我正在考虑添加一个额外的参数ChangeGlobalLockCounter(或类似的东西)。在那些讨厌的可能成对的回调例程中,这个新参数将被设置为Falsethen,这样GlobalLockCounter如果不成对调用,它就不会增加或减少,因此不会损坏。进一步的想法?

Ser*_*yuz 5

您可以间接查明窗户是否已锁定以进行绘画。下面的 Delphi 示例利用了无法使锁定的窗口无效的事实:

function IsWindowLocked(Wnd: HWND): Boolean;
begin
  Result := not GetUpdateRect(Wnd, nil, False);
  if Result then begin
    InvalidateRect(Wnd, nil, False);
    Result := not GetUpdateRect(Wnd, nil, False);
    if not Result then
      ValidateRect(Wnd, nil);
  end;
end;
Run Code Online (Sandbox Code Playgroud)


请注意,上面没有绘画开销,但当然比检查柜台花费更多。