procedure TForm1.WMSysCommand;
begin
if (Msg.CmdType = SC_MOVE) then <---- something like this?
...
if Msg.CmdType = SC_CLOSE then //close doesn't work
without this
Close;
if (Msg.CmdType = SC_MINIMIZE) or // - button (upper
right of form next to X button)
(Msg.CmdType = SC_MAXIMIZE) or // single pane button
(Msg.CmdType = SC_RESTORE) then begin // double pane button
if EncartaButton5.Caption = 'Start' then begin
Mouse.CursorPos := (Point( (Screen.DesktopWidth div 2) -
25,
(Screen.DesktopHeight div 2) +
35));
case MessageDlg('Monitoring suspended. Start monitoring?',
mtConfirmation, [mbYes, mbNo], 0) of
mrYes : begin
RxTrayIcon1.Icon :=
RxTrayIcon1.Icons.Icons[0];
Button5Click(nil);
end;
mrNo : RxTrayIcon1.Icon :=
RxTrayIcon1.Icons.Icons[2];
end;
end;
Form1.Hide;
end;
//// DefaultHandler(Msg); //take this out to stop min/max/stop
action
end;
Call inherited.
> procedure TForm1.WMSysCommand;
> begin
>
> if (Msg.CmdType = SC_MOVE) then <---- something like this?
Something like that. Check the documentation about wm_SysCommand to
learn how to interpret the wParam parameter of that message. *Never*
skip the "remarks" section.
> ...
>
> if Msg.CmdType = SC_CLOSE then //close doesn't work
> without this
> Close;
It doesn't work because you're doing it wrong. See below.
> if (Msg.CmdType = SC_MINIMIZE) or // - button (upper
> right of form next to X button)
> (Msg.CmdType = SC_MAXIMIZE) or // single pane button
> (Msg.CmdType = SC_RESTORE) then begin // double pane button
> if EncartaButton5.Caption = 'Start' then begin
You're basing your program logic on the string contents of a UI control.
This will be a major pain if you ever want to release your product in
multiple languages. Or if you ever change the caption of the control in
the Object Inspector and forget that other pieces of code were relying
on that value.
Keep a Boolean flag in your program that determines whether it's in
"start" mode. Check that flag here. Also, assign a TAction to your
button, and then handle the action's OnUpdate event. In the event
handler, assign the action's Caption property according to the current
state of the "start" flag. Assigning the action's properties will
automatically assign any connected controls' properties, including the
button's caption. (That's assuming that TEncartaButton's author bothered
to handle actions. If not, dump that control and find one with a more
competent author.)
Also, I strongly encourage you to give your controls meaningful names.
Does the purpose of that control really have any relation to the fact
that it is the fifth TEncartaButton that you dropped on your form in the
Form Designer? I doubt it.
> Mouse.CursorPos := (Point( (Screen.DesktopWidth div 2) -
> 25,
> (Screen.DesktopHeight div 2) +
> 35));
What's with the magic numbers?
I suspect you're trying to "help" the user by moving the cursor to some
place related to the place you expect the dialog box to appear. Is that
right? Stop that. Moving the cursor around can confuse the user. There
is already an OS feature that the user can choose to enable that moves
the cursor to the default button when a dialog box appears.
When there are multiple monitors, are DesktopHeight and DesktopWidth
really what you want to use anyway?
> case MessageDlg('Monitoring suspended. Start monitoring?',
> mtConfirmation, [mbYes, mbNo], 0) of
> mrYes : begin
> RxTrayIcon1.Icon :=
> RxTrayIcon1.Icons.Icons[0];
> Button5Click(nil);
I refer to my comment about meaningful names.
> end;
>
> mrNo : RxTrayIcon1.Icon :=
> RxTrayIcon1.Icons.Icons[2];
> end;
> end;
>
> Form1.Hide;
Really? Pressing the form's maximize button causes it to disappear?
Also, if you have two instances of the TForm1 class, pressing the
caption buttons of *either* form will always cause the same *single*
form to disappear. If you want to act one whichever form whose message
handler is running, then omit the receiver of the method call. That
causes the call to be directed to the default Self value instead.
> end;
>
> //// DefaultHandler(Msg); //take this out to stop min/max/stop
> action
> end;
You're commenting out the wrong call. You shouldn't be calling
DefaultHandler in the first place. You should be calling inherited.
DefaultHandler calls the default handler for the given message, but
inherited will call the handler of the immediate ancestor. That may or
may not be the same as the default handler.
Your code could be made much cleaner:
begin
case Msg.CmdType and $fff0 of
sc_Minimize, sc_Maximize, sc_Restore: begin
Msg.Result := 0;
if InStartMode then begin
if MessageDlg('Monitoring is suspended; start monitoring?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin
StartMonitoring;
end else begin
DoNotStartMonitoring;
end;
Hide;
end;
end;
else
inherited;
end;
end;
procedure TForm1.StartMonitoring;
begin
RxTrayIcon1.Icon := RxTrayIcon1.Icons.Icons[0];
Button5Click(Self);
end;
procedure TForm1.DoNoStartMonitoring;
begin
RxTrayIcon1.Icon := RxTrayIcon1.Icons.Icons[2];
end;
Key differences:
Minimal reliance of the current names of UI controls.
Doesn't move the mouse cursor to a place the user didn't put it.
Allows for the possibility of the user closing the dialog without
pressing either button. In that case, its modal result is mrCancel,
which I assume you would want to treat the same as mrNo.
Gives names to actions performed in response to user actions. Still to
do: Figure out better names for DoNoStartMonitoring and Button5Click.
Passes a useful Sender parameter to Button5Click, in case the method
cares who called it. (If it doesn't care, then maybe there should be a
separate no-parameter method for StartMonitoring to call instead, and
then Button5Click can call that no-parameter method as well.)
Sets the result of the message, like MSDN instructs.
Masks out the lower four bits of the command, like MSDN instructs.
Defers to higher up the inheritance chain for commands this class
doesn't care about, including sc_Close, sc_Move, sc_HScroll,
sc_MonitorPower, sc_ScreenSave, and sc_TaskList.
--
Rob
That's the risk (or benefit) of posting to a GOOD noewsgroup <g>
Alan Lloyd
That's the risk (or benefit) of posting to a GOOD noewsgroup <g>
Alan Lloyd