我使用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
不会增加或减少,因此不会被破坏,如果不是称为成对。进一步的想法?
答案 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;
请注意,上面没有绘画开销,但当然它比检查计数器花费更多。