I've got a TBitBtn
on a TFrame
with a click event that causes the button's own frame to get unparented from its container (effectively removing it) and stored for later restoration:
implementation
var
StoredFrames: TStack<TFrame>;
procedure TCustomFrame.BitBtnClick(Sender: TObject);
begin
// Some business logic
Self.ActiveControl := nil;
Self.Parent := nil;
StoredFrames.Push(Self);
end;
Later, the frame is reparented into its container and thus redisplayed. However, the blue highlighting the button got from the mouse when it was clicked, before getting stored, remains on the button:
After restoration, other controls can receive the same highlighting at the same time, but the button does not lose its highlighting until the frame is destroyed. How can I manually reset or remove this button highlighting?
Things I've tried:
Application.ProcessMessages
in the click handler- Disabling the button on store, enabling on restore
- Various kinds of repainting/layout invalidation
CodePudding user response:
This might not be the most elegant solution, but it gets work done
private
{ Private declarations }
FRepaintTimer: TTimer;
procedure OnRepaintTimer(Sender: TObject);
public
{ Public declarations }
end;
implementation
{$R *.dfm}
procedure TFrame5.BitBtn1Click(Sender: TObject);
begin
if not Assigned(FRepaintTimer) then
begin
FRepaintTimer := TTimer.Create(Self);
FRepaintTimer.Interval := 50;
FRepaintTimer.OnTimer := OnRepaintTimer;
end;
BitBtn1.Enabled := False;
FRepaintTimer.Enabled := True;
end;
procedure TFrame5.OnRepaintTimer(Sender: TObject);
begin
//Self.ActiveControl := nil;
Self.Parent := nil;
BitBtn1.Enabled := True;
FRepaintTimer.Enabled := False;
end;
Since timers are limited resource, maybe you could Hide/Show frames instead of making use of Parent and use OnHide/OnShow events from TFrame and Enable/Disable your buttons there.
CodePudding user response:
Per solution provided by @BlurrySterk in comments,
BitBtn.Perform(WM_MOUSELEAVE, 0, 0);
before unparenting the button's frame resets the button highlighting.