--- ---
The solution I use is to register a window procedure for the radio buttons. You can trap the Windows messages there.
procedure TSuperRadioGroup.RegisterWndProc; var BtnHnd: hWnd; ItrBtn: Integer; begin inherited; HasWndProc := True; BtnHnd := GetWindow(Handle, GW_CHILD); ItrBtn := 0; while BtnHnd > 0 do begin if GetWindowLong(BtnHnd, GWL_USERDATA) <> 0 then raise Exception.Create('Userdata may not be used'); ButtonHandle[ItrBtn] := BtnHnd; OrigWndProc[ItrBtn] := GetWindowLong(BtnHnd, GWL_WNDPROC); SetWindowLong(BtnHnd, GWL_USERDATA, Longint(self)); SetWindowLong(BtnHnd, GWL_WNDPROC, Longint(@RadioBtnWndProc)); Inc(ItrBtn); BtnHnd := GetWindow(BtnHnd, GW_HWNDNEXT); end; end;
In the RadioBtnWndProc window procedure you can use this code to get at the radio group object and the specific button:
Obj := TObject(GetWindowLong(WndHnd, GWL_USERDATA)); if Obj is TSuperRadioGroup then begin RadioGrp := TSuperRadioGroup(Obj); for ItrBtn := 0 to RadioGrp.Items.Count - 1 do begin if WndHnd = RadioGrp.ButtonHandle[ItrBtn] then begin OrigWndProc := RadioGrp.OrigWndProc[ItrBtn]; break; end; end; end;
If the message is not completely handled, you need to call the original window procedure at the end of your specialized window procedure:
Result := CallWindowProc( Pointer(OrigWndProc), WndHnd, Msg, WParam, LParam) ;