home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d6 / RX275D6.ZIP / Units / rxgrids.pas < prev    next >
Pascal/Delphi Source File  |  1999-10-12  |  38KB  |  1,211 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1996 AO ROSNO                   }
  6. {         Copyright (c) 1997, 1998 Master-Bank          }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit RXGrids;
  11.  
  12. {$I RX.INC}
  13. {$W-,T-}
  14.  
  15. interface
  16.  
  17. uses {$IFDEF WIN32} Windows, Registry, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  18.   Messages, Classes, Controls, Graphics, StdCtrls, ExtCtrls, Forms, Menus,
  19.   Grids, RxConst, IniFiles, Placemnt;
  20.  
  21. { TRxDrawGrid }
  22.  
  23. type
  24.   TAcceptKeyEvent = function (Sender: TObject; var Key: Char): Boolean of object;
  25.   TEditLimitEvent = procedure (Sender: TObject; var MaxLength: Integer) of object;
  26.   TEditShowEvent = procedure (Sender: TObject; ACol, ARow: Longint;
  27.     var AllowEdit: Boolean) of object;
  28.   TFixedCellClickEvent = procedure (Sender: TObject; ACol, ARow: Longint) of object;
  29.   TFixedCellCheckEvent = procedure (Sender: TObject; ACol, ARow: Longint;
  30.     var Enabled: Boolean) of object;
  31. {$IFDEF WIN32}
  32.   TInplaceEditStyle = (ieSimple, ieEllipsis, iePickList);
  33.   TEditAlignEvent = procedure (Sender: TObject; ACol, ARow: Longint;
  34.     var Alignment: TAlignment) of object;
  35.   TPicklistEvent = procedure (Sender: TObject; ACol, ARow: Longint;
  36.     PickList: TStrings) of object;
  37.   TEditStyleEvent = procedure (Sender: TObject; ACol, ARow: Longint;
  38.     var Style: TInplaceEditStyle) of object;
  39. {$ENDIF}
  40.  
  41.   TRxDrawGrid = class(TDrawGrid)
  42.   private
  43.     FNoUpdateData: Boolean;
  44.     FFixedCellsButtons: Boolean;
  45.     FPressedCell: TGridCoord;
  46.     FPressed: Boolean;
  47.     FTracking: Boolean;
  48.     FSwapButtons: Boolean;
  49.     FDefaultDrawing: Boolean;
  50.     FIniLink: TIniLink;
  51.     FOnColumnSized: TNotifyEvent;
  52.     FOnRowSized: TNotifyEvent;
  53.     FOnAcceptEditKey: TAcceptKeyEvent;
  54.     FOnGetEditLimit: TEditLimitEvent;
  55.     FOnEditChange: TNotifyEvent;
  56.     FOnShowEditor: TEditShowEvent;
  57.     FOnCancelEdit: TNotifyEvent;
  58.     FOnFixedCellClick: TFixedCellClickEvent;
  59.     FOnCheckButton: TFixedCellCheckEvent;
  60.     FOnChangeFocus: TNotifyEvent;
  61. {$IFDEF WIN32}
  62.     FOnGetEditAlign: TEditAlignEvent;
  63.     FOnEditButtonClick: TNotifyEvent;
  64.     FOnGetPicklist: TPicklistEvent;
  65.     FOnGetEditStyle: TEditStyleEvent;
  66. {$ENDIF}
  67.     function GetStorage: TFormPlacement;
  68.     procedure SetStorage(Value: TFormPlacement);
  69.     procedure IniSave(Sender: TObject);
  70.     procedure IniLoad(Sender: TObject);
  71.     procedure SetFixedButtons(Value: Boolean);
  72.     procedure StopTracking;
  73.     procedure TrackButton(X, Y: Integer);
  74.     function IsActiveControl: Boolean;
  75.     procedure WMCommand(var Message: TWMCommand); message WM_COMMAND;
  76.     procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
  77.     procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
  78.     procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
  79.     procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
  80. {$IFDEF WIN32}
  81.     procedure WMRButtonUp(var Message: TWMMouse); message WM_RBUTTONUP;
  82. {$ENDIF}
  83.   protected
  84.     function CanEditAcceptKey(Key: Char): Boolean; override;
  85.     function CanEditShow: Boolean; override;
  86.     function GetEditLimit: Integer; override;
  87.     procedure TopLeftChanged; override;
  88.     procedure ColWidthsChanged; override;
  89.     procedure RowHeightsChanged; override;
  90.     procedure CallDrawCellEvent(ACol, ARow: Longint; ARect: TRect;
  91.       AState: TGridDrawState);
  92.     procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
  93.       AState: TGridDrawState); override;
  94.     procedure DoDrawCell(ACol, ARow: Longint; ARect: TRect;
  95.       AState: TGridDrawState); virtual;
  96.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  97.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  98.       X, Y: Integer); override;
  99.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  100.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  101.       X, Y: Integer); override;
  102.     procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
  103.     function CreateEditor: TInplaceEdit; override;
  104.     procedure Paint; override;
  105.     procedure EditChanged(Sender: TObject); dynamic;
  106.     procedure DoFixedCellClick(ACol, ARow: Longint); dynamic;
  107.     procedure CheckFixedCellButton(ACol, ARow: Longint;
  108.       var Enabled: Boolean); dynamic;
  109. {$IFDEF WIN32}
  110.     procedure EditButtonClick; dynamic;
  111.     function GetEditAlignment(ACol, ARow: Longint): TAlignment; dynamic;
  112.     function GetEditStyle(ACol, ARow: Longint): TInplaceEditStyle; dynamic;
  113.     procedure GetPicklist(ACol, ARow: Longint; Picklist: TStrings); dynamic;
  114. {$ENDIF}
  115.   public
  116.     constructor Create(AOwner: TComponent); override;
  117.     destructor Destroy; override;
  118.     procedure DrawStr(ARect: TRect; const S: string; Align: TAlignment);
  119.     procedure DrawMultiline(ARect: TRect; const S: string; Align: TAlignment);
  120.     procedure DrawPicture(ARect: TRect; Graphic: TGraphic);
  121.     procedure DrawMasked(ARect: TRect; Graphic: TBitmap);
  122.     procedure InvalidateCell(ACol, ARow: Longint);
  123.     procedure InvalidateCol(ACol: Longint);
  124.     procedure InvalidateRow(ARow: Longint);
  125.     property InplaceEditor;
  126.   published
  127.     property DefaultRowHeight default 18;
  128.     property Options default [goFixedVertLine, goFixedHorzLine, goVertLine,
  129.       goHorzLine, goDrawFocusSelected, goColSizing];
  130.     property IniStorage: TFormPlacement read GetStorage write SetStorage;
  131.     property FixedButtons: Boolean read FFixedCellsButtons write SetFixedButtons
  132.       default False;
  133.     property OnAcceptEditKey: TAcceptKeyEvent read FOnAcceptEditKey
  134.       write FOnAcceptEditKey;
  135.     property OnCancelEdit: TNotifyEvent read FOnCancelEdit write FOnCancelEdit;
  136.     property OnCheckButton: TFixedCellCheckEvent read FOnCheckButton
  137.       write FOnCheckButton;
  138.     property OnChangeFocus: TNotifyEvent read FOnChangeFocus write FOnChangeFocus;
  139.     property OnFixedCellClick: TFixedCellClickEvent read FOnFixedCellClick
  140.       write FOnFixedCellClick;
  141.     property OnColumnSized: TNotifyEvent read FOnColumnSized
  142.       write FOnColumnSized;
  143.     property OnRowSized: TNotifyEvent read FOnRowSized write FOnRowSized;
  144.     property OnGetEditLimit: TEditLimitEvent read FOnGetEditLimit write FOnGetEditLimit;
  145.     property OnEditChange: TNotifyEvent read FOnEditChange write FOnEditChange;
  146.     property OnShowEditor: TEditShowEvent read FOnShowEditor write FOnShowEditor;
  147. {$IFDEF WIN32}
  148.     property OnGetEditAlign: TEditAlignEvent read FOnGetEditAlign write FOnGetEditAlign;
  149.     property OnGetEditStyle: TEditStyleEvent read FOnGetEditStyle write FOnGetEditStyle;
  150.     property OnGetPicklist: TPicklistEvent read FOnGetPicklist write FOnGetPicklist;
  151.     property OnEditButtonClick: TNotifyEvent read FOnEditButtonClick write FOnEditButtonClick;
  152. {$ENDIF}
  153.   end;
  154.  
  155. implementation
  156.  
  157. uses SysUtils, VCLUtils, MaxMin, Consts, AppUtils;
  158.  
  159. const
  160. {$IFDEF WIN32}
  161.   MaxCustomExtents = MaxListSize;
  162. {$ELSE}
  163.   MaxCustomExtents = 65520 div SizeOf(Integer);
  164. {$ENDIF}
  165.   MaxShortInt = High(ShortInt);
  166.  
  167. type
  168.   PIntArray = ^TIntArray;
  169.   TIntArray = array[0..MaxCustomExtents] of Integer;
  170.  
  171. {$IFDEF WIN32}
  172.  
  173. { TRxInplaceEdit }
  174.  
  175. type
  176.   TPopupListbox = class;
  177.  
  178.   TRxInplaceEdit = class(TInplaceEdit)
  179.   private
  180.     FAlignment: TAlignment;
  181.     FButtonWidth: Integer;
  182.     FPickList: TPopupListbox;
  183.     FActiveList: TWinControl;
  184.     FEditStyle: TInplaceEditStyle;
  185.     FListVisible: Boolean;
  186.     FTracking: Boolean;
  187.     FPressed: Boolean;
  188.     procedure ListMouseUp(Sender: TObject; Button: TMouseButton;
  189.       Shift: TShiftState; X, Y: Integer);
  190.     procedure SetAlignment(Value: TAlignment);
  191.     procedure SetEditStyle(Value: TInplaceEditStyle);
  192.     procedure StopTracking;
  193.     procedure TrackButton(X,Y: Integer);
  194.     procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
  195.     procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
  196.     procedure WMKillFocus(var Message: TMessage); message WM_KILLFOCUS;
  197.     procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
  198.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  199.     procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
  200.   protected
  201.     procedure CreateParams(var Params: TCreateParams); override;
  202.     procedure BoundsChanged; override;
  203.     procedure CloseUp(Accept: Boolean);
  204.     procedure DoDropDownKeys(var Key: Word; Shift: TShiftState);
  205.     procedure DropDown;
  206.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  207.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  208.       X, Y: Integer); override;
  209.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  210.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  211.       X, Y: Integer); override;
  212.     procedure PaintWindow(DC: HDC); override;
  213.     procedure UpdateContents; override;
  214.     procedure WndProc(var Message: TMessage); override;
  215.     property ActiveList: TWinControl read FActiveList write FActiveList;
  216.     property PickList: TPopupListbox read FPickList;
  217.   public
  218.     constructor Create(Owner: TComponent); override;
  219.     property Alignment: TAlignment read FAlignment write SetAlignment;
  220.     property EditStyle: TInplaceEditStyle read FEditStyle write SetEditStyle;
  221.   end;
  222.  
  223. { TPopupListbox }
  224.  
  225.   TPopupListbox = class(TCustomListbox)
  226.   private
  227.     FSearchText: string;
  228.     FSearchTickCount: Longint;
  229.   protected
  230.     procedure CreateParams(var Params: TCreateParams); override;
  231.     procedure CreateWnd; override;
  232.     procedure KeyPress(var Key: Char); override;
  233.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  234.   end;
  235.  
  236. procedure TPopupListBox.CreateParams(var Params: TCreateParams);
  237. begin
  238.   inherited CreateParams(Params);
  239.   with Params do begin
  240.     Style := Style or WS_BORDER;
  241.     ExStyle := WS_EX_TOOLWINDOW or WS_EX_TOPMOST;
  242. {$IFDEF RX_D4}
  243.     AddBiDiModeExStyle(ExStyle);
  244. {$ENDIF}
  245.     WindowClass.Style := CS_SAVEBITS;
  246.   end;
  247. end;
  248.  
  249. procedure TPopupListbox.CreateWnd;
  250. begin
  251.   inherited CreateWnd;
  252.   Windows.SetParent(Handle, 0);
  253.   CallWindowProc(DefWndProc, Handle, WM_SETFOCUS, 0, 0);
  254. end;
  255.  
  256. procedure TPopupListbox.KeyPress(var Key: Char);
  257. var
  258.   TickCount: Integer;
  259. begin
  260.   case Key of
  261.     #8, #27: FSearchText := '';
  262.     #32..#255:
  263.       begin
  264.         TickCount := GetTickCount;
  265.         if TickCount - FSearchTickCount > 4000 then FSearchText := '';
  266.         FSearchTickCount := TickCount;
  267.         if Length(FSearchText) < 32 then FSearchText := FSearchText + Key;
  268.         SendMessage(Handle, LB_SELECTSTRING, WORD(-1),
  269.           Longint(PChar(FSearchText)));
  270.         Key := #0;
  271.       end;
  272.   end;
  273.   inherited KeyPress(Key);
  274. end;
  275.  
  276. procedure TPopupListbox.MouseUp(Button: TMouseButton; Shift: TShiftState;
  277.   X, Y: Integer);
  278. begin
  279.   inherited MouseUp(Button, Shift, X, Y);
  280.   TRxInplaceEdit(Owner).CloseUp((X >= 0) and (Y >= 0) and (X < Width) and
  281.     (Y < Height));
  282. end;
  283.  
  284. { TRxInplaceEdit }
  285.  
  286. constructor TRxInplaceEdit.Create(Owner: TComponent);
  287. begin
  288.   inherited Create(Owner);
  289.   FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
  290.   FEditStyle := ieSimple;
  291. end;
  292.  
  293. procedure TRxInplaceEdit.CreateParams(var Params: TCreateParams);
  294. const
  295.   Alignments: array[TAlignment] of {$IFDEF RX_D4}DWORD{$ELSE}Longint{$ENDIF} =
  296.     (ES_LEFT, ES_RIGHT, ES_CENTER);
  297. begin
  298.   inherited CreateParams(Params);
  299.   with Params do Style := Style or Alignments[FAlignment];
  300. end;
  301.  
  302. procedure TRxInplaceEdit.BoundsChanged;
  303. var
  304.   R: TRect;
  305. begin
  306.   SetRect(R, 2, 2, Width - 2, Height);
  307.   if FEditStyle <> ieSimple then Dec(R.Right, FButtonWidth);
  308.   SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@R));
  309.   SendMessage(Handle, EM_SCROLLCARET, 0, 0);
  310. {$IFDEF RX_D3}
  311.   if SysLocale.FarEast then
  312.     SetImeCompositionWindow(Font, R.Left, R.Top);
  313. {$ENDIF}
  314. end;
  315.  
  316. procedure TRxInplaceEdit.CloseUp(Accept: Boolean);
  317. var
  318.   ListValue: string;
  319. begin
  320.   if FListVisible then begin
  321.     if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  322.     if FPickList.ItemIndex > -1 then
  323.       ListValue := FPickList.Items[FPicklist.ItemIndex];
  324.     SetWindowPos(FActiveList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  325.       SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  326.     FListVisible := False;
  327.     Invalidate;
  328.     if Accept and EditCanModify then Text := ListValue;
  329.   end;
  330. end;
  331.  
  332. procedure TRxInplaceEdit.DoDropDownKeys(var Key: Word; Shift: TShiftState);
  333. begin
  334.   case Key of
  335.     VK_UP, VK_DOWN:
  336.       if ssAlt in Shift then begin
  337.         if FListVisible then CloseUp(True) else DropDown;
  338.         Key := 0;
  339.       end;
  340.     VK_RETURN, VK_ESCAPE:
  341.       if FListVisible and not (ssAlt in Shift) then begin
  342.         CloseUp(Key = VK_RETURN);
  343.         Key := 0;
  344.       end;
  345.   end;
  346. end;
  347.  
  348. procedure TRxInplaceEdit.DropDown;
  349. const
  350.   MaxListCount = 8;
  351. var
  352.   P: TPoint;
  353.   Y, J, I: Integer;
  354. begin
  355.   if not FListVisible and Assigned(FActiveList) then begin
  356.     FPickList.Width := Width;
  357.     FPickList.Color := Color;
  358.     FPickList.Font := Font;
  359.     FPickList.Items.Clear;
  360.     with TRxDrawGrid(Grid) do 
  361.       GetPickList(Col, Row, FPickList.Items);
  362.     FPickList.Height := Min(FPickList.Items.Count, MaxListCount) *
  363.       FPickList.ItemHeight + 4;
  364.     FPickList.ItemIndex := FPickList.Items.IndexOf(Text);
  365.     J := FPickList.ClientWidth;
  366.     for I := 0 to FPickList.Items.Count - 1 do begin
  367.       Y := FPickList.Canvas.TextWidth(FPickList.Items[I]);
  368.       if Y > J then J := Y;
  369.     end;
  370.     if FPickList.Items.Count > MaxListCount then
  371.       Inc(J, GetSystemMetrics(SM_CXVSCROLL));
  372.     FPickList.ClientWidth := J;
  373.     P := Parent.ClientToScreen(Point(Left, Top));
  374.     Y := P.Y + Height;
  375.     if Y + FActiveList.Height > Screen.Height then
  376.       Y := P.Y - FActiveList.Height;
  377.     SetWindowPos(FActiveList.Handle, HWND_TOP, P.X, Y, 0, 0,
  378.       SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
  379.     FListVisible := True;
  380.     Invalidate;
  381.     Windows.SetFocus(Handle);
  382.   end;
  383. end;
  384.  
  385. type
  386.   TWinControlCracker = class(TWinControl);
  387.  
  388. procedure TRxInplaceEdit.KeyDown(var Key: Word; Shift: TShiftState);
  389. begin
  390.   if (EditStyle = ieEllipsis) and (Key = VK_RETURN) and (Shift = [ssCtrl]) then
  391.   begin
  392.     TRxDrawGrid(Grid).EditButtonClick;
  393.     KillMessage(Handle, WM_CHAR);
  394.   end
  395.   else inherited KeyDown(Key, Shift);
  396. end;
  397.  
  398. procedure TRxInplaceEdit.ListMouseUp(Sender: TObject; Button: TMouseButton;
  399.   Shift: TShiftState; X, Y: Integer);
  400. begin
  401.   if Button = mbLeft then
  402.     CloseUp(PtInRect(FActiveList.ClientRect, Point(X, Y)));
  403. end;
  404.  
  405. procedure TRxInplaceEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
  406.   X, Y: Integer);
  407. begin
  408.   if (Button = mbLeft) and (FEditStyle <> ieSimple) and
  409.     PtInRect(Rect(Width - FButtonWidth, 0, Width, Height), Point(X,Y)) then
  410.   begin
  411.     if FListVisible then CloseUp(False)
  412.     else begin
  413.       MouseCapture := True;
  414.       FTracking := True;
  415.       TrackButton(X, Y);
  416.       if Assigned(FActiveList) then DropDown;
  417.     end;
  418.   end;
  419.   inherited MouseDown(Button, Shift, X, Y);
  420. end;
  421.  
  422. procedure TRxInplaceEdit.MouseMove(Shift: TShiftState; X, Y: Integer);
  423. var
  424.   ListPos: TPoint;
  425.   MousePos: TSmallPoint;
  426. begin
  427.   if FTracking then begin
  428.     TrackButton(X, Y);
  429.     if FListVisible then begin
  430.       ListPos := FActiveList.ScreenToClient(ClientToScreen(Point(X, Y)));
  431.       if PtInRect(FActiveList.ClientRect, ListPos) then begin
  432.         StopTracking;
  433.         MousePos := PointToSmallPoint(ListPos);
  434.         SendMessage(FActiveList.Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
  435.         Exit;
  436.       end;
  437.     end;
  438.   end;
  439.   inherited MouseMove(Shift, X, Y);
  440. end;
  441.  
  442. procedure TRxInplaceEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
  443.   X, Y: Integer);
  444. var
  445.   WasPressed: Boolean;
  446. begin
  447.   WasPressed := FPressed;
  448.   StopTracking;
  449.   if (Button = mbLeft) and (FEditStyle = ieEllipsis) and WasPressed then
  450.     TRxDrawGrid(Grid).EditButtonClick;
  451.   inherited MouseUp(Button, Shift, X, Y);
  452. end;
  453.  
  454. procedure TRxInplaceEdit.PaintWindow(DC: HDC);
  455. const
  456.   LeftOffs = 3;
  457. var
  458.   R: TRect;
  459.   Flags: Integer;
  460.   W, G, I: Integer;
  461. begin
  462.   if FEditStyle <> ieSimple then begin
  463.     SetRect(R, Width - FButtonWidth, 0, Width, Height);
  464.     Flags := 0;
  465.     if FEditStyle in [iePickList] then begin
  466.       if FActiveList = nil then Flags := DFCS_INACTIVE
  467.       else if FPressed then Flags := DFCS_FLAT or DFCS_PUSHED;
  468.       DrawFrameControl(DC, R, DFC_SCROLL, Flags or DFCS_SCROLLCOMBOBOX);
  469.     end
  470.     else begin { ieEllipsis }
  471.       if FPressed then Flags := BF_FLAT;
  472.       DrawEdge(DC, R, EDGE_RAISED, BF_RECT or BF_MIDDLE or Flags);
  473.       W := 2;
  474.       G := (FButtonWidth - LeftOffs * 2 - 3 * W) div 2;
  475.       if G <= 0 then G := 1;
  476.       if G > 3 then G := 3;
  477.       Flags := R.Left + (FButtonWidth - 3 * W - 2 * G) div 2 + Ord(FPressed);
  478.       I := R.Top + (ClientHeight - W) div 2 {+ Ord(FPressed)};
  479.       PatBlt(DC, Flags, I, W, W, BLACKNESS);
  480.       PatBlt(DC, Flags + G + W, I, W, W, BLACKNESS);
  481.       PatBlt(DC, Flags + 2 * G + 2 * W, I, W, W, BLACKNESS);
  482.     end;
  483.     ExcludeClipRect(DC, R.Left, R.Top, R.Right, R.Bottom);
  484.   end;
  485.   inherited PaintWindow(DC);
  486. end;
  487.  
  488. procedure TRxInplaceEdit.SetAlignment(Value: TAlignment);
  489. begin
  490.   if FAlignment <> Value then begin
  491.     FAlignment := Value;
  492.     RecreateWnd;
  493.   end;
  494. end;
  495.  
  496. procedure TRxInplaceEdit.SetEditStyle(Value: TInplaceEditStyle);
  497. begin
  498.   if Value = FEditStyle then Exit;
  499.   FEditStyle := Value;
  500.   case Value of
  501.     iePickList:
  502.       begin
  503.         if FPickList = nil then begin
  504.           FPickList := TPopupListbox.Create(Self);
  505.           FPickList.Visible := False;
  506.           FPickList.Parent := Self;
  507.           FPickList.OnMouseUp := ListMouseUp;
  508.           FPickList.IntegralHeight := True;
  509.           FPickList.ItemHeight := 11;
  510.         end;
  511.         FActiveList := FPickList;
  512.       end;
  513.     else FActiveList := nil;
  514.   end;
  515.   Repaint;
  516. end;
  517.  
  518. procedure TRxInplaceEdit.StopTracking;
  519. begin
  520.   if FTracking then begin
  521.     TrackButton(-1, -1);
  522.     FTracking := False;
  523.     MouseCapture := False;
  524.   end;
  525. end;
  526.  
  527. procedure TRxInplaceEdit.TrackButton(X,Y: Integer);
  528. var
  529.   NewState: Boolean;
  530.   R: TRect;
  531. begin
  532.   SetRect(R, ClientWidth - FButtonWidth, 0, ClientWidth, ClientHeight);
  533.   NewState := PtInRect(R, Point(X, Y));
  534.   if FPressed <> NewState then begin
  535.     FPressed := NewState;
  536.     InvalidateRect(Handle, @R, False);
  537.   end;
  538. end;
  539.  
  540. procedure TRxInplaceEdit.UpdateContents;
  541. var
  542.   SaveChanged: TNotifyEvent;
  543. begin
  544.   with TRxDrawGrid(Grid) do begin
  545.     Self.Alignment := GetEditAlignment(Col, Row);
  546.     EditStyle := GetEditStyle(Col, Row);
  547.   end;
  548.   SaveChanged := Self.OnChange;
  549.   try
  550.     Self.OnChange := nil;
  551.     inherited UpdateContents;
  552.   finally
  553.     Self.OnChange := SaveChanged;
  554.   end;
  555. end;
  556.  
  557. procedure TRxInplaceEdit.CMCancelMode(var Message: TCMCancelMode);
  558. begin
  559.   if (Message.Sender <> Self) and (Message.Sender <> FActiveList) then
  560.     CloseUp(False);
  561. end;
  562.  
  563. procedure TRxInplaceEdit.WMCancelMode(var Message: TMessage);
  564. begin
  565.   StopTracking;
  566.   inherited;
  567. end;
  568.  
  569. procedure TRxInplaceEdit.WMKillFocus(var Message: TMessage);
  570. begin
  571. {$IFDEF RX_D3}
  572.   if not SysLocale.FarEast then inherited
  573.   else begin
  574.     ImeName := Screen.DefaultIme;
  575.     ImeMode := imDontCare;
  576.     inherited;
  577.     if THandle(Message.WParam) <> TRxDrawGrid(Grid).Handle then
  578.       ActivateKeyboardLayout(Screen.DefaultKbLayout, KLF_ACTIVATE);
  579.   end;
  580. {$ELSE}
  581.   inherited;
  582. {$ENDIF}
  583.   CloseUp(False);
  584. end;
  585.  
  586. procedure TRxInplaceEdit.WMLButtonDblClk(var Message: TWMLButtonDblClk);
  587. begin
  588.   with Message do
  589.     if (FEditStyle <> ieSimple) and PtInRect(Rect(Width - FButtonWidth, 0,
  590.       Width, Height), Point(XPos, YPos)) then Exit;
  591.   inherited;
  592. end;
  593.  
  594. procedure TRxInplaceEdit.WMPaint(var Message: TWMPaint);
  595. begin
  596.   PaintHandler(Message);
  597. end;
  598.  
  599. procedure TRxInplaceEdit.WMSetCursor(var Message: TWMSetCursor);
  600. var
  601.   P: TPoint;
  602. begin
  603.   GetCursorPos(P);
  604.   if (FEditStyle <> ieSimple) and
  605.     PtInRect(Rect(Width - FButtonWidth, 0, Width, Height), ScreenToClient(P)) then
  606.     Windows.SetCursor(LoadCursor(0, IDC_ARROW))
  607.   else inherited;
  608. end;
  609.  
  610. procedure TRxInplaceEdit.WndProc(var Message: TMessage);
  611. begin
  612.   case Message.Msg of
  613.     WM_KEYDOWN, WM_SYSKEYDOWN, WM_CHAR:
  614.       if EditStyle in [iePickList] then
  615.         with TWMKey(Message) do begin
  616.           DoDropDownKeys(CharCode, KeyDataToShiftState(KeyData));
  617.           if (CharCode <> 0) and FListVisible then begin
  618.             with TMessage(Message) do
  619.               SendMessage(FActiveList.Handle, Msg, WParam, LParam);
  620.             Exit;
  621.           end;
  622.         end;
  623.   end;
  624.   inherited;
  625. end;
  626.  
  627. {$ELSE}
  628.  
  629. type
  630.   TRxInplaceEdit = class(TInplaceEdit);
  631.  
  632. {$ENDIF WIN32}
  633.  
  634. { TRxDrawGrid }
  635.  
  636. constructor TRxDrawGrid.Create(AOwner: TComponent);
  637. begin
  638.   inherited Create(AOwner);
  639.   DefaultRowHeight := 18;
  640.   Options := [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine,
  641.     goDrawFocusSelected, goColSizing];
  642.   FIniLink := TIniLink.Create;
  643.   FIniLink.OnSave := IniSave;
  644.   FIniLink.OnLoad := IniLoad;
  645.   FPressedCell.X := -1;
  646.   FPressedCell.Y := -1;
  647. end;
  648.  
  649. destructor TRxDrawGrid.Destroy;
  650. begin
  651.   FOnChangeFocus := nil;
  652.   FIniLink.Free;
  653.   inherited Destroy;
  654. end;
  655.  
  656. function TRxDrawGrid.GetStorage: TFormPlacement;
  657. begin
  658.   Result := FIniLink.Storage;
  659. end;
  660.  
  661. procedure TRxDrawGrid.SetStorage(Value: TFormPlacement);
  662. begin
  663.   FIniLink.Storage := Value;
  664. end;
  665.  
  666. procedure TRxDrawGrid.IniSave(Sender: TObject);
  667. begin
  668.   if (Name <> '') and (FIniLink.IniObject <> nil) then
  669.     InternalSaveGridLayout(Self, FIniLink.IniObject, FIniLink.RootSection +
  670.       GetDefaultSection(Self));
  671. end;
  672.  
  673. procedure TRxDrawGrid.IniLoad(Sender: TObject);
  674. begin
  675.   if (Name <> '') and (FIniLink.IniObject <> nil) then
  676.     InternalRestoreGridLayout(Self, FIniLink.IniObject, FIniLink.RootSection +
  677.       GetDefaultSection(Self));
  678. end;
  679.  
  680. function TRxDrawGrid.CanEditAcceptKey(Key: Char): Boolean;
  681. begin
  682.   if Assigned(FOnAcceptEditKey) then Result := FOnAcceptEditKey(Self, Key)
  683.   else Result := inherited CanEditAcceptKey(Key);
  684. end;
  685.  
  686. function TRxDrawGrid.CanEditShow: Boolean;
  687. begin
  688.   Result := inherited CanEditShow;
  689.   if Result and Assigned(FOnShowEditor) then begin
  690.     FOnShowEditor(Self, Col, Row, Result);
  691.     if not Result then EditorMode := False;
  692.   end;
  693. end;
  694.  
  695. procedure TRxDrawGrid.DrawPicture(ARect: TRect; Graphic: TGraphic);
  696. begin
  697.   DrawCellBitmap(Self, 0, 0, Graphic, ARect);
  698. end;
  699.  
  700. procedure TRxDrawGrid.DrawMasked(ARect: TRect; Graphic: TBitmap);
  701. var
  702.   X, Y: Integer;
  703. begin
  704.   X := (ARect.Right + ARect.Left - Graphic.Width) div 2;
  705.   Y := (ARect.Bottom + ARect.Top - Graphic.Height) div 2;
  706.   DrawBitmapTransparent(Canvas, X, Y, Graphic, Graphic.TransparentColor
  707.     and not PaletteMask);
  708. end;
  709.  
  710. procedure TRxDrawGrid.DrawStr(ARect: TRect; const S: string;
  711.   Align: TAlignment);
  712. begin
  713.   DrawCellTextEx(Self, 0, 0, S, ARect, Align, vaCenter, False
  714.     {$IFDEF RX_D4}, IsRightToLeft {$ENDIF});
  715. end;
  716.  
  717. procedure TRxDrawGrid.DrawMultiline(ARect: TRect; const S: string;
  718.   Align: TAlignment);
  719. begin
  720.   DrawCellTextEx(Self, 0, 0, S, ARect, Align, vaTopJustify, True
  721.     {$IFDEF RX_D4}, IsRightToLeft {$ENDIF});
  722. end;
  723.  
  724. procedure TRxDrawGrid.InvalidateCell(ACol, ARow: Longint);
  725. begin
  726.   inherited InvalidateCell(ACol, ARow);
  727. end;
  728.  
  729. procedure TRxDrawGrid.InvalidateCol(ACol: Longint);
  730. {$IFNDEF WIN32}
  731. var
  732.   I: Longint;
  733. {$ENDIF}
  734. begin
  735. {$IFDEF WIN32}
  736.   inherited InvalidateCol(ACol);
  737. {$ELSE}
  738.   for I := 0 to RowCount - 1 do inherited InvalidateCell(ACol, I);
  739. {$ENDIF}
  740. end;
  741.  
  742. procedure TRxDrawGrid.InvalidateRow(ARow: Longint);
  743. var
  744.   I: Longint;
  745. begin
  746.   for I := 0 to ColCount - 1 do inherited InvalidateCell(I, ARow);
  747. end;
  748.  
  749. procedure TRxDrawGrid.KeyDown(var Key: Word; Shift: TShiftState);
  750. begin
  751.   if not CanGridAcceptKey(Key, Shift) then Exit;
  752.   if not (ssCtrl in Shift) and (Key = VK_ESCAPE) and EditorMode and
  753.     (InplaceEditor <> nil) and InplaceEditor.Visible and
  754.     not (goAlwaysShowEditor in Options) then
  755.   begin
  756.     FNoUpdateData := True;
  757.     try
  758.       HideEditor;
  759.       if Assigned(FOnCancelEdit) then FOnCancelEdit(Self);
  760.     finally
  761.       FNoUpdateData := False;
  762.     end;
  763.   end
  764.   else inherited KeyDown(Key, Shift);
  765. end;
  766.  
  767. procedure TRxDrawGrid.WMCommand(var Message: TWMCommand);
  768. begin
  769.   if (Message.NotifyCode = EN_CHANGE) and
  770.     not (goAlwaysShowEditor in Options) then
  771.   begin
  772.     if (InplaceEditor <> nil) and InplaceEditor.HandleAllocated and
  773.       InplaceEditor.Visible then TRxInplaceEdit(InplaceEditor).Change;
  774.     Message.NotifyCode := 0;
  775.   end;
  776.   inherited;
  777. end;
  778.  
  779. procedure TRxDrawGrid.EditChanged(Sender: TObject);
  780. begin
  781.   if Assigned(FOnEditChange) then FOnEditChange(Self);
  782. end;
  783.  
  784. function TRxDrawGrid.GetEditLimit: Integer;
  785. begin
  786.   Result := inherited GetEditLimit;
  787.   if Assigned(FOnGetEditLimit) then FOnGetEditLimit(Self, Result);
  788. end;
  789.  
  790. procedure TRxDrawGrid.SetEditText(ACol, ARow: Longint; const Value: string);
  791. begin
  792.   if not FNoUpdateData then inherited SetEditText(ACol, ARow, Value);
  793. end;
  794.  
  795. procedure TRxDrawGrid.SetFixedButtons(Value: Boolean);
  796. begin
  797.   if FFixedCellsButtons <> Value then begin
  798.     FFixedCellsButtons := Value;
  799.     Invalidate;
  800.   end;
  801. end;
  802.  
  803. procedure TRxDrawGrid.DoFixedCellClick(ACol, ARow: Longint);
  804. begin
  805.   if Assigned(FOnFixedCellClick) then FOnFixedCellClick(Self, ACol, ARow);
  806. end;
  807.  
  808. procedure TRxDrawGrid.CheckFixedCellButton(ACol, ARow: Longint; var Enabled: Boolean);
  809. begin
  810.   if (ACol >= 0) and (ARow >= 0) and ((ACol < FixedCols) or (ARow < FixedRows)) then
  811.   begin
  812.     if Assigned(FOnCheckButton) then FOnCheckButton(Self, ACol, ARow, Enabled);
  813.   end
  814.   else Enabled := False;
  815. end;
  816.  
  817. procedure TRxDrawGrid.TopLeftChanged;
  818. begin
  819.   if (goRowSelect in Options) and DefaultDrawing then
  820.     InvalidateRow(Self.Row);
  821.   inherited TopLeftChanged;
  822.   if FTracking then StopTracking;
  823. end;
  824.  
  825. procedure TRxDrawGrid.ColWidthsChanged;
  826. begin
  827.   inherited ColWidthsChanged;
  828.   if FTracking then StopTracking;
  829.   if Assigned(FOnColumnSized) then FOnColumnSized(Self);
  830. end;
  831.  
  832. procedure TRxDrawGrid.RowHeightsChanged;
  833. begin
  834.   inherited RowHeightsChanged;
  835.   if FTracking then StopTracking;
  836.   if Assigned(FOnRowSized) then FOnRowSized(Self);
  837. end;
  838.  
  839. procedure TRxDrawGrid.StopTracking;
  840. begin
  841.   if FTracking then begin
  842.     TrackButton(-1, -1);
  843.     FTracking := False;
  844.     MouseCapture := False;
  845.   end;
  846. end;
  847.  
  848. procedure TRxDrawGrid.TrackButton(X, Y: Integer);
  849. var
  850.   Cell: TGridCoord;
  851.   NewPressed: Boolean;
  852. begin
  853.   Cell := MouseCoord(X, Y);
  854.   NewPressed := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y))
  855.     and (FPressedCell.X = Cell.X) and (FPressedCell.Y = Cell.Y);
  856.   if FPressed <> NewPressed then begin
  857.     FPressed := NewPressed;
  858.     InvalidateCell(Cell.X, Cell.Y);
  859.     InvalidateCell(FPressedCell.X, FPressedCell.Y);
  860.   end;
  861. end;
  862.  
  863. function TRxDrawGrid.IsActiveControl: Boolean;
  864. var
  865.   H: Hwnd;
  866.   ParentForm: TCustomForm;
  867. begin
  868.   Result := False;
  869.   ParentForm := GetParentForm(Self);
  870.   if Assigned(ParentForm) then begin
  871.     if (ParentForm.ActiveControl = Self) then
  872.       Result := True;
  873.   end
  874.   else begin
  875.     H := GetFocus;
  876.     while IsWindow(H) and (Result = False) do begin
  877.       if H = WindowHandle then Result := True
  878.       else H := GetParent(H);
  879.     end;
  880.   end;
  881. end;
  882.  
  883. procedure TRxDrawGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
  884.   X, Y: Integer);
  885. var
  886.   Cell: TGridCoord;
  887.   EnableClick, Fixed: Boolean;
  888. begin
  889.   HideEditor;
  890.   if not (csDesigning in ComponentState) and (CanFocus or
  891.     (GetParentForm(Self) = nil)) then
  892.   begin
  893.     SetFocus;
  894.     if not IsActiveControl then begin
  895.       MouseCapture := False;
  896.       Exit;
  897.     end;
  898.   end;
  899.   if (Button = mbLeft) and (ssDouble in Shift) then begin
  900.     if FFixedCellsButtons then begin
  901.       Cell := MouseCoord(X, Y);
  902.       if not ((Cell.X >= 0) and (Cell.X < FixedCols)) and not
  903.         ((Cell.Y >= 0) and (Cell.Y < FixedRows)) then
  904.       begin
  905.         DblClick;
  906.         Exit;
  907.       end;
  908.     end
  909.     else begin
  910.       DblClick;
  911.       Exit;
  912.     end;
  913.   end;
  914.   if Sizing(X, Y) then
  915.     inherited MouseDown(Button, Shift, X, Y)
  916.   else begin
  917.     Cell := MouseCoord(X, Y);
  918.     Fixed := ((Cell.X >= 0) and (Cell.X < FixedCols)) or
  919.       ((Cell.Y >= 0) and (Cell.Y < FixedRows));
  920.     if FFixedCellsButtons and Fixed and not (csDesigning in ComponentState) then
  921.     begin
  922.       if ([goRowMoving, goColMoving] * Options <> []) and
  923.         (Button = mbRight) then
  924.       begin
  925.         Button := mbLeft;
  926.         FSwapButtons := True;
  927.         MouseCapture := True;
  928.       end
  929.       else if (Button = mbLeft) then begin
  930.         EnableClick := True;
  931.         CheckFixedCellButton(Cell.X, Cell.Y, EnableClick);
  932.         if EnableClick then begin
  933.           MouseCapture := True;
  934.           FTracking := True;
  935.           FPressedCell := Cell;
  936.           TrackButton(X, Y);
  937.         end else Beep;
  938.         Exit;
  939.       end;
  940.     end;
  941.     inherited MouseDown(Button, Shift, X, Y);
  942.   end;
  943. end;
  944.  
  945. procedure TRxDrawGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
  946. begin
  947.   if FTracking then TrackButton(X, Y);
  948.   inherited MouseMove(Shift, X, Y);
  949. end;
  950.  
  951. procedure TRxDrawGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
  952.   X, Y: Integer);
  953. var
  954.   Cell: TGridCoord;
  955.   ACol, ARow: Longint;
  956.   DoClick: Boolean;
  957. begin
  958.   if FTracking and (FPressedCell.Y >= 0) and (FPressedCell.X >= 0) then
  959.   begin
  960.     Cell := MouseCoord(X, Y);
  961.     DoClick := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y))
  962.       and (Cell.Y = FPressedCell.Y) and (Cell.X = FPressedCell.X);
  963.     StopTracking;
  964.     if DoClick then begin
  965.       ACol := Cell.X;
  966.       ARow := Cell.Y;
  967.       if (ARow < RowCount) and (ACol < ColCount) then
  968.         DoFixedCellClick(ACol, ARow);
  969.     end;
  970.   end
  971.   else if FSwapButtons then begin
  972.     FSwapButtons := False;
  973.     MouseCapture := False;
  974.     if Button = mbRight then Button := mbLeft;
  975.   end;
  976.   inherited MouseUp(Button, Shift, X, Y);
  977. end;
  978.  
  979. procedure TRxDrawGrid.Paint;
  980. var
  981.   R: TRect;
  982. begin
  983.   FDefaultDrawing := inherited DefaultDrawing;
  984.   inherited DefaultDrawing := False;
  985.   try
  986.     inherited Paint;
  987.   finally
  988.     inherited DefaultDrawing := FDefaultDrawing;
  989.   end;
  990.   if not (csDesigning in ComponentState) and DefaultDrawing and Focused and
  991.     ([goRowSelect, goRangeSelect] * Options = [goRowSelect]) then
  992.   begin
  993.     with Canvas do begin
  994.       Font.Color := Self.Font.Color;
  995.       Brush.Color := Self.Color;
  996.     end;
  997.     if Row >= FixedRows then begin
  998.       R := BoxRect(FixedCols, Row, ColCount - 1, Row);
  999.       if not (goHorzLine in Options) then Inc(R.Bottom, GridLineWidth);
  1000.       DrawFocusRect(Canvas.Handle, R);
  1001.     end;
  1002.   end;
  1003. end;
  1004.  
  1005. procedure TRxDrawGrid.CallDrawCellEvent(ACol, ARow: Longint; ARect: TRect;
  1006.   AState: TGridDrawState);
  1007. begin
  1008.   inherited DrawCell(ACol, ARow, ARect, AState);
  1009. end;
  1010.  
  1011. procedure TRxDrawGrid.DoDrawCell(ACol, ARow: Longint; ARect: TRect;
  1012.   AState: TGridDrawState);
  1013. begin
  1014.   CallDrawCellEvent(ACol, ARow, ARect, AState);
  1015. end;
  1016.  
  1017. procedure TRxDrawGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
  1018.   AState: TGridDrawState);
  1019. var
  1020.   Down: Boolean;
  1021. {$IFDEF WIN32}
  1022.   TempRect: TRect;
  1023.   FrameFlags1, FrameFlags2: DWORD;
  1024. const
  1025.   EdgeFlag: array[Boolean] of UINT = (BDR_RAISEDINNER, BDR_SUNKENINNER);
  1026. {$ENDIF}
  1027. begin
  1028.   if FDefaultDrawing or (csDesigning in ComponentState) then
  1029.     with Canvas do begin
  1030.       Font := Self.Font;
  1031.       if ([goRowSelect, goVertLine] * Options = [goRowSelect]) and
  1032.         not (gdFixed in AState) then Inc(ARect.Right, GridLineWidth);
  1033.       if ([goRowSelect, goHorzLine] * Options = [goRowSelect]) and
  1034.         not (gdFixed in AState) then Inc(ARect.Bottom, GridLineWidth);
  1035.       if (gdSelected in AState) and (not (gdFocused in AState) or
  1036.         ([goDrawFocusSelected, goRowSelect] * Options <> [])) then
  1037.       begin
  1038.         Brush.Color := clHighlight;
  1039.         Font.Color := clHighlightText;
  1040.       end
  1041.       else begin
  1042.         if gdFixed in AState then Brush.Color := FixedColor
  1043.         else Brush.Color := Color;
  1044.       end;
  1045.       FillRect(ARect);
  1046.     end;
  1047.   Down := FFixedCellsButtons and (gdFixed in AState) and Ctl3D and
  1048.     not (csLoading in ComponentState) and FPressed and FDefaultDrawing and
  1049.     (FPressedCell.X = ACol) and (FPressedCell.Y = ARow);
  1050.   inherited DefaultDrawing := FDefaultDrawing;
  1051.   if Down then begin
  1052.     Inc(ARect.Left, GridLineWidth);
  1053.     Inc(ARect.Top, GridLineWidth);
  1054.   end;
  1055.   try
  1056.     DoDrawCell(ACol, ARow, ARect, AState);
  1057.   finally
  1058.     inherited DefaultDrawing := False;
  1059.     if Down then begin
  1060.       Dec(ARect.Left, GridLineWidth);
  1061.       Dec(ARect.Top, GridLineWidth);
  1062.     end;
  1063.   end;
  1064.   if FDefaultDrawing and (gdFixed in AState) and Ctl3D then begin
  1065. {$IFDEF WIN32}
  1066.     FrameFlags1 := 0;
  1067.     FrameFlags2 := 0;
  1068.     if goFixedVertLine in Options then begin
  1069.       FrameFlags1 := BF_RIGHT;
  1070.       FrameFlags2 := BF_LEFT;
  1071.     end;
  1072.     if goFixedHorzLine in Options then begin
  1073.       FrameFlags1 := FrameFlags1 or BF_BOTTOM;
  1074.       FrameFlags2 := FrameFlags2 or BF_TOP;
  1075.     end;
  1076.     if (FrameFlags1 or FrameFlags2) <> 0 then begin
  1077.       TempRect := ARect;
  1078.       if ((FrameFlags1 and BF_RIGHT) = 0) and
  1079.         (goFixedVertLine in Options) then
  1080.         Inc(TempRect.Right, GridLineWidth)
  1081.       else if ((FrameFlags1 and BF_BOTTOM) = 0) and
  1082.         (goFixedVertLine in Options) then
  1083.         Inc(TempRect.Bottom, GridLineWidth);
  1084.       DrawEdge(Canvas.Handle, TempRect, EdgeFlag[Down], FrameFlags1);
  1085.       DrawEdge(Canvas.Handle, TempRect, EdgeFlag[Down], FrameFlags2);
  1086.     end;
  1087. {$ELSE}
  1088.     with Canvas do begin
  1089.       Pen.Color := clBtnHighlight;
  1090.       if FFixedCellsButtons then begin
  1091.         if Down then begin
  1092.           Pen.Color := clBtnShadow;
  1093.           with ARect do begin
  1094.             PolyLine([Point(Left, Bottom - 1), Point(Left, Top),
  1095.               Point(Right, Top)]);
  1096.             Inc(Left, 2); Inc(Top, 2);
  1097.           end;
  1098.         end
  1099.         else Frame3D(Canvas, ARect, clBtnHighlight, clBtnShadow, 1);
  1100.       end
  1101.       else begin
  1102.         Polyline([Point(ARect.Left, ARect.Bottom - 1), ARect.TopLeft,
  1103.           Point(ARect.Right, ARect.Top)]);
  1104.       end;
  1105.     end;
  1106. {$ENDIF WIN32}
  1107.   end;
  1108.   if FDefaultDrawing and not (csDesigning in ComponentState) and
  1109.     (gdFocused in AState) and
  1110.     ([goEditing, goAlwaysShowEditor] * Options <>
  1111.     [goEditing, goAlwaysShowEditor])
  1112.     and not (goRowSelect in Options) then
  1113.     DrawFocusRect(Canvas.Handle, ARect);
  1114. end;
  1115.  
  1116. {$IFDEF WIN32}
  1117. procedure TRxDrawGrid.WMRButtonUp(var Message: TWMMouse);
  1118. begin
  1119.   if not (FGridState in [gsColMoving, gsRowMoving]) then
  1120.     inherited
  1121.   else if not (csNoStdEvents in ControlStyle) then
  1122.     with Message do MouseUp(mbRight, KeysToShiftState(Keys), XPos, YPos);
  1123. end;
  1124. {$ENDIF}
  1125.  
  1126. procedure TRxDrawGrid.WMLButtonDblClk(var Message: TWMLButtonDblClk);
  1127. var
  1128.   Cell: TGridCoord;
  1129. {$IFNDEF WIN32}
  1130.   Form: TForm;
  1131. {$ENDIF}
  1132. begin
  1133.   if FFixedCellsButtons then begin
  1134.     with Message do
  1135.       Cell := MouseCoord(XPos, YPos);
  1136.     if ((Cell.X >= 0) and (Cell.X < FixedCols)) or
  1137.       ((Cell.Y >= 0) and (Cell.Y < FixedRows)) then
  1138.     begin
  1139. {$IFDEF WIN32}
  1140.       SendCancelMode(Self);
  1141. {$ELSE}
  1142.       Form := GetParentForm(Self);
  1143.       if Form <> nil then Form.SendCancelMode(Self);
  1144. {$ENDIF}
  1145.       if csCaptureMouse in ControlStyle then MouseCapture := True;
  1146. {$IFDEF WIN32}
  1147.       if not (csNoStdEvents in ControlStyle) then
  1148. {$ENDIF}
  1149.         with Message do
  1150.           MouseDown(mbLeft, KeysToShiftState(Keys) - [ssDouble], XPos, YPos);
  1151.       Exit;
  1152.     end;
  1153.   end;
  1154.   inherited;
  1155. end;
  1156.  
  1157. procedure TRxDrawGrid.WMKillFocus(var Msg: TWMKillFocus);
  1158. begin
  1159.   inherited;
  1160.   if Assigned(FOnChangeFocus) then FOnChangeFocus(Self);
  1161. end;
  1162.  
  1163. procedure TRxDrawGrid.WMSetFocus(var Msg: TWMSetFocus);
  1164. begin
  1165.   inherited;
  1166.   if Assigned(FOnChangeFocus) then FOnChangeFocus(Self);
  1167. end;
  1168.  
  1169. procedure TRxDrawGrid.WMCancelMode(var Message: TMessage);
  1170. begin
  1171.   StopTracking;
  1172.   inherited;
  1173. end;
  1174.  
  1175. function TRxDrawGrid.CreateEditor: TInplaceEdit;
  1176. begin
  1177. {$IFDEF WIN32}
  1178.   Result := TRxInplaceEdit.Create(Self);
  1179. {$ELSE}
  1180.   Result := inherited CreateEditor;
  1181. {$ENDIF}
  1182.   TEdit(Result).OnChange := EditChanged;
  1183. end;
  1184.  
  1185. {$IFDEF WIN32}
  1186.  
  1187. function TRxDrawGrid.GetEditAlignment(ACol, ARow: Longint): TAlignment;
  1188. begin
  1189.   Result := taLeftJustify;
  1190.   if Assigned(FOnGetEditAlign) then FOnGetEditAlign(Self, ACol, ARow, Result);
  1191. end;
  1192.  
  1193. function TRxDrawGrid.GetEditStyle(ACol, ARow: Longint): TInplaceEditStyle;
  1194. begin
  1195.   Result := ieSimple;
  1196.   if Assigned(FOnGetEditStyle) then FOnGetEditStyle(Self, ACol, ARow, Result);
  1197. end;
  1198.  
  1199. procedure TRxDrawGrid.GetPicklist(ACol, ARow: Longint; PickList: TStrings);
  1200. begin
  1201.   if Assigned(FOnGetPicklist) then FOnGetPicklist(Self, ACol, ARow, PickList);
  1202. end;
  1203.  
  1204. procedure TRxDrawGrid.EditButtonClick;
  1205. begin
  1206.   if Assigned(FOnEditButtonClick) then FOnEditButtonClick(Self);
  1207. end;
  1208.  
  1209. {$ENDIF}
  1210.  
  1211. end.