DrawGrid/StringGridでFixedCellをクリックできるようにする方法
13 DrawGridStringGridDrawCell-3 動作確認 Delphi2007 更新日 2007/12/30(日)

『DrawGrid/StringGridのDefaultDrawingを使わないDrawCellの使い方』の続きになります。

DrawGridとStringGridはFixedCellをクリックする動作は
対応していませんが、DrawCellで独自で描画することで
そのような動作をしているようにすることができます。

下記がそのソース。

コンポーネントを作った方がいいような気もしますが
とりあえず、これで実現することもできます。

FixedCellをクリックしたかどうかを判定するのは
MouseUpイベントにコードを追記するとよいでしょう。

────────────────────
procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGridInitialize;
  StringGrid1.DefaultDrawing := False;
  {↓フラグ初期化}  
  FMouseDownGridPoint := Point(-1, -1);
end;

procedure TForm1.StringGridInitialize;
var
  i, j: Integer;
begin
  for i := 0 to StringGrid1.RowCount - 1 do
  begin
    for j := 0 to StringGrid1.Rows[i].Count - 1 do
    begin
      StringGrid1.Cells[j, i] := IntToStr(i)+'行'+IntToStr(j)+'列';
    end;
  end;
end;

//マウスDown時にフラグON
procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ACol, ARow: Longint;
begin
  TStringGrid(Sender).MouseToCell(X, Y, ACol, ARow);
  FMouseDownGridPoint := Point(ACol, ARow);
  TStringGrid(Sender).Repaint;
end;

//マウスが離れたらフラグOFF
procedure TForm1.StringGrid1MouseLeave(Sender: TObject);
begin
  FMouseDownGridPoint := Point(-1, -1);
  TStringGrid(Sender).Repaint;
end;

//マウスUpでもフラグOFF
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  ACol, ARow: Longint;
begin
  TStringGrid(Sender).MouseToCell(X, Y, ACol, ARow);

  FMouseDownGridPoint := Point(-1, -1);
  TStringGrid(Sender).Repaint;
end;


procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  PenBuffer: TPen;
  BrushBuffer: TBrush;
  FontBuffer: TFont;
  DC: HDC;
  R: TRect;

  {↓FixedCellの枠を描画する}
  procedure DrawFixedFrame(ARect: TRect; Click: Boolean=False);
  begin
    if (Sender as TDrawGrid).Ctl3D then
    with (Sender as TDrawGrid) do
    begin
      Canvas.Pen.Style := psSolid;
      Canvas.Pen.Mode := pmCopy;
      with ARect do begin
        if Click then
          Canvas.Pen.Color := clBtnShadow
        else
          Canvas.Pen.Color := clBtnHighlight;
        Canvas.MoveTo( Right - 1, Top );
        Canvas.LineTo( Left, Top);
        Canvas.LineTo( Left, Bottom - 1 );
        if Click then
          Canvas.Pen.Color := clBtnHighlight
        else
          Canvas.Pen.Color := clBtnShadow;
        Canvas.LineTo( Right - 1, Bottom - 1 );
        Canvas.LineTo( Right - 1, Top );
      end;
    end;
  end;

  {↓パラメータを一時保存}
  procedure BufferingOn;
  begin
    with Sender as TDrawGrid do
    begin
      PenBuffer.Assign(Canvas.Pen);
      BrushBuffer.Assign(Canvas.Brush);
      FontBuffer.Assign(Canvas.Font);
    end;
  end;

  {↓パラメータを復帰}
  procedure BufferingOff;
  begin
    with Sender as TDrawGrid do
    begin
      Canvas.Pen.Assign(PenBuffer);
      Canvas.Brush.Assign(BrushBuffer);
      Canvas.Font.Assign(FontBuffer);
    end;
  end;
  
begin
  PenBuffer := TPen.Create;
  BrushBuffer := TBrush.Create;
  FontBuffer := TFont.Create;
  BufferingOn;

  with Sender as TDrawGrid do begin

  {↓固定セル}
  if gdFixed in State then
  begin
    if (FMouseDownGridPoint.X=ACol)
      and (FMouseDownGridPoint.Y=ARow) then
    begin
      Canvas.Brush.Color := FixedColor;
      Canvas.FillRect(Rect);
      {↑セル内を色で塗りつぶす}
      {↓文字描画}
      if Sender is TStringGrid then
      begin
        Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2,
          TStringGrid(Sender).Cells[ACol, ARow]);
      end;
      DrawFixedFrame(Rect, True);
      {↑クリック時の枠を描画}
    end else
    begin
      Canvas.Brush.Color := FixedColor;
      Canvas.FillRect(Rect);
      {↑セル内を色で塗りつぶす}
      {↓文字描画}
      if Sender is TStringGrid then
      begin
        Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2,
          TStringGrid(Sender).Cells[ACol, ARow]);
      end;
      DrawFixedFrame(Rect);
      {↑枠を描く}
    end;
  end else

  {↓セレクトセル}
  if gdSelected in State then
  begin
    {↓DrawFocusSelectedの場合はFocusedセルの色が違う}
    if (goDrawFocusSelected in Options)
      and (ACol = Col) and (ARow = Row) then
    begin
      {↓選択色}
      Canvas.Brush.Color := clHighlight;
      Canvas.FillRect(Rect);
      if Sender is TStringGrid then
      begin
        Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2,
          TStringGrid(Sender).Cells[ACol, ARow]);
      end;
      Canvas.DrawFocusRect(Rect);
      {↑枠を描く}
    end else
    if (ACol = Col) and (ARow = Row) then
    begin
      {↓通常セル色}
      Canvas.Brush.Color := clWindow;
      Canvas.FillRect(Rect);
      if Sender is TStringGrid then
      begin
        Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2,
          TStringGrid(Sender).Cells[ACol, ARow]);
      end;
      Canvas.DrawFocusRect(Rect);
      {↑枠を描く}
    end else
    begin
      Canvas.Brush.Color := clHighlight;
      Canvas.FillRect(Rect);
      {↓文字描画}
      if Sender is TStringGrid then
      begin
        Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2,
          TStringGrid(Sender).Cells[ACol, ARow]);
      end;
      {枠描画処理は無し}
    end;
  end else

  {↓普通のセル}
  begin
    Canvas.Brush.Color := clWindow;
    Canvas.FillRect(Rect);
    {↓文字描画}
    if Sender is TStringGrid then
    begin
      Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2,
        TStringGrid(Sender).Cells[ACol, ARow]);
    end;
  end;

  end;
  BufferingOff;
  PenBuffer.Free;
  BrushBuffer.Free;
  FontBuffer.Free;
end;
────────────────────
これが動作画面です。

クリックするとFixedCellが凹むように描画されます。

参考────────────────────
StringGridで固定セルをクリックするには
http://hpcgi1.nifty.com/MADIA/DelphiBBS/wwwlng.cgi?print+200711/07110102.txt