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

时间:2014-12-08 17:36:02

标签: 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;

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

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

1 个答案:

答案 0 :(得分:2)

您可以间接查明窗口是否已锁定以进行绘画。下面的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;


请注意,上面没有绘画开销,但当然它比检查计数器花费更多。