win32: avoid sending LM_CHANGE message when clearing TRadioButton siblings and when setting TRadioButton checked property programatically. Send LM_CHANGE when TRadioButton is unchecked. Don't toggle TRadioButton state when it's already checked. Part of 0017139 and 0017104

git-svn-id: trunk@27050 -
This commit is contained in:
blikblum 2010-08-10 16:52:13 +00:00
parent 9d03b45223
commit 8d7d250608
2 changed files with 37 additions and 22 deletions

View File

@ -559,16 +559,22 @@ var
var var
Parent: TWinControl; Parent: TWinControl;
Sibling: TControl; Sibling: TControl;
WinControl: TWinControlAccess absolute Sibling;
PreviousCheckState: LRESULT;
i: Integer; i: Integer;
begin begin
Parent := RadioButton.Parent; Parent := RadioButton.Parent;
for i:= 0 to Parent.ControlCount - 1 do for i:= 0 to Parent.ControlCount - 1 do
begin begin
Sibling := Parent.Controls[i]; Sibling := Parent.Controls[i];
if (Sibling is TRadioButton) and (Sibling<>RadioButton) and if (Sibling is TRadioButton) and (Sibling <> RadioButton) then
(TRadioButton(Sibling).HandleAllocated) then begin
Windows.SendMessage(TRadioButton(Sibling).Handle, BM_SETCHECK, // Pass previous state through LParam so the event handling can decide
Windows.WParam(BST_UNCHECKED), 0); // when to propagate LM_CHANGE (New State <> Previous State)
PreviousCheckState := Windows.SendMessage(WinControl.WindowHandle, BM_GETCHECK, 0, 0);
Windows.SendMessage(WinControl.WindowHandle, BM_SETCHECK,
Windows.WParam(BST_UNCHECKED), Windows.LParam(PreviousCheckState));
end;
end; end;
end; end;
@ -1106,10 +1112,6 @@ begin
{IME Windows the composition has finished} {IME Windows the composition has finished}
if Assigned(WindowInfo) then WindowInfo^.IMEComposed:=True; if Assigned(WindowInfo) then WindowInfo^.IMEComposed:=True;
end; end;
BM_SETCHECK:
begin
LMessage.Msg := LM_CHANGED;
end;
WM_CANCELMODE: WM_CANCELMODE:
begin begin
LMessage.Msg := LM_CANCELMODE; LMessage.Msg := LM_CANCELMODE;
@ -1240,6 +1242,9 @@ begin
// to handle checkbox state ourselves, according to msdn state // to handle checkbox state ourselves, according to msdn state
// sequence goes from checked->cleared->grayed etc. // sequence goes from checked->cleared->grayed etc.
Flags := SendMessage(lWinControl.Handle, BM_GETCHECK, 0, 0); Flags := SendMessage(lWinControl.Handle, BM_GETCHECK, 0, 0);
//dont update the check state if is TRadioButton and is already checked
if (Flags <> BST_CHECKED) or not (lWinControl is TRadioButton) then
begin
if (Flags=BST_CHECKED) then if (Flags=BST_CHECKED) then
Flags := BST_UNCHECKED Flags := BST_UNCHECKED
else else
@ -1248,9 +1253,10 @@ begin
Flags := BST_INDETERMINATE Flags := BST_INDETERMINATE
else else
Flags := BST_CHECKED; Flags := BST_CHECKED;
//pass a different values in WParam and WParam to force sending LM_CHANGE
Windows.SendMessage(lWinControl.Handle, BM_SETCHECK, Windows.SendMessage(lWinControl.Handle, BM_SETCHECK,
Windows.WPARAM(flags), 0); Windows.WPARAM(Flags), Windows.LPARAM(Flags + 1));
end;
LMessage.Msg := LM_CLICKED; LMessage.Msg := LM_CLICKED;
end; end;
BN_KILLFOCUS: BN_KILLFOCUS:
@ -2334,9 +2340,17 @@ begin
end; end;
BM_SETCHECK: BM_SETCHECK:
begin begin
if (WParam = BST_CHECKED) and (lWinControl is TRadioButton) then //LParam holds previous state
//Propagate LM_CHANGED when state is changed
if LParam <> WParam then
LMessage.Msg := LM_CHANGED;
if lWinControl is TRadioButton then
begin
//Uncheck siblings
if WParam = BST_CHECKED then
ClearSiblingRadioButtons(TRadioButton(lWinControl)); ClearSiblingRadioButtons(TRadioButton(lWinControl));
end; end;
end;
WM_ENDSESSION: WM_ENDSESSION:
begin begin
if (Application<>nil) and (TWin32WidgetSet(WidgetSet).AppHandle=Window) and if (Application<>nil) and (TWin32WidgetSet(WidgetSet).AppHandle=Window) and

View File

@ -1613,7 +1613,8 @@ begin
else else
Flags := Windows.WParam(BST_INDETERMINATE); Flags := Windows.WParam(BST_INDETERMINATE);
end; end;
Windows.SendMessage(ACustomCheckBox.Handle, BM_SETCHECK, Flags, 0); //Pass the same state through lParam to avoid the OnChange event be fired
Windows.SendMessage(ACustomCheckBox.Handle, BM_SETCHECK, Flags, LPARAM(Flags));
end; end;
{ TWin32WSToggleBox } { TWin32WSToggleBox }