Suppose you have a data-critical type of application where you would not want a non-authored user to work with the data. Such an application could automatically minimize to the TaskBar if no user activity has taken place in a lengthy time.
When the application button is clicked (on the TaskBar) the application will restore to its previous state.
What if you need to display a password dialog *before* the application is restored to make sure an authorized user is accessing it.
Application.OnRestore - no go
Taking a quick look at the TApplication object reveals the OnRestore event, which occurs when the previously minimized application is restored to its normal size.Note the "when is restored", not "before it gets restored".
Even though you could again minimize the application by calling Application.Minimize; inside the Application.OnRestore event handler, some form flickering will appear, and we do not want that.
HookMainWindow - React Before OnRestore is fired
The TApplication exposes a method called HookMainWindow that allows you to insert your own message handler to be executed and intercept messages sent to your application before they are handled by the Application object.HookMainWindow is declared under TApplication as:
procedure HookMainWindow(Hook : TWindowHook) ;Where the method pointer TWindowHook is declared as:
type
TWindowHook = function(var Message : TMessage) : Boolean of object;
Handling WM_SYSCOMMAND's SC_RESTORE Using HookMainWindow
First, in the MainForm's OnCreate hook the hook :)Make sure you "unhook" when the main for is destroyed.
Most importantly, handle the "SC_RESTORE" system command by displaying a (modal) password dialog and returning true if the user can continue working with the restored application.
typeThat's all.
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject) ;
procedure FormDestroy(Sender: TObject) ;
private
function AppHook(var msg: TMessage): boolean;
end;
implementation
procedure TMainForm.FormCreate(Sender: TObject) ;
begin
Application.HookMainWindow(AppHook) ;
end;
function TMainForm.AppHook(var msg: TMessage): boolean;
begin
result := false;
if (msg.Msg = WM_SYSCOMMAND) and (msg.WParam = SC_RESTORE) then
result := MessageDlg('Are you an Admin?', mtWarning, mbYesNo, 0) = mrNo;
end;
procedure TMainForm.FormDestroy(Sender: TObject) ;
begin
Application.UnhookMainWindow(AppHook) ;
end;

