また基本的なところ?でつまづいている気がします。教えてください。
検索ダイアログで文字検察するとき、事前のフォーカスが消えてしまい、検索された文字列も、検索ダイアログを消すかフォームをクリックするまでハイライトされません。
過去ログにあったHideSelectionも探したのですが、TInplaceEditのプロパティの中には見当たらず、文法エラーで受け付けてももらえませんでした。
どう振舞ったらよいのでしょうか?
長いですが、コードのおおよそを記載します。
{検索メニューをクリック}
procedure THwdForm.Find1Click(Sender: TObject);
begin
if StringGrid1.ControlCount > 0 then
begin
FindDialog1.FindText := TInplaceEdit(StringGrid1.Controls[0]).SelText;
FindDialog1.Execute;
end;
end;
{「次を検索」ボタンを押す}
procedure THwdForm.FindDialog1Find(Sender: TObject);
begin
if FindDialog1.FindText = '' then
ShowMessage('空文字列は検索できません')
else begin
FindWork(Sender, FindDialog1.FindText);
// FindDialog1.CloseDialog; //これをしないとハイライトしないのが困る
end;
end;
{同列を次行から下まで検索する}
procedure THwdForm.FindWork(Sender: TObject; FText: String);
var
i: Integer;
FoundAt, StartPos: Integer;
begin
with StringGrid1 do
begin
for i:=Row+1 to RowCount-1 do
begin
StartPos := 0;
FoundAt := Pos(FText, Cells[Col, i]);
if FoundAt > 0 then break;
end;
if FoundAt = 0 then
ShowMessage('以降の行に検索文字列は見当たりません')
else begin
Row := i;
Setfocus;
with TInplaceEdit(Controls[0]) do
begin
SelStart := FoundAt + StartPos - 1;
SelLength := Length(FText);
end;
end;
end;
end;
すみません、コードのなかでStartPosとあるのは、細部の消し忘れです。
あ それから、自分の頭のなかで選択とハイライトとフォーカスがぐちゃぐちゃになっていると思います。何卒ご斟酌のほどを
こんな感じでいかがでしょうか?
//〜onDrawCellイベントに〜
procedure THwdForm.StringGrid1DrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
if gdFocused in State then
begin
beforeFocusedCell.X:=ACol; // beforeFocusedCell:TPos (private)
beforeFocusedCell.Y:=ARow; //
end;
if (beforeFocusedCell.X=ACol) and
(beforeFocusedCell.Y=ARow) and
(gdFocused in State = False ) and
((Sender as TStringGrid).Focused=False) then
begin
(Sender as TStringGrid).Canvas.Brush.Color:=(Sender as TStringGrid).Color;
(Sender as TStringGrid).Canvas.FillRect(Rect);
(Sender as TStringGrid).Canvas.DrawFocusRect(Rect);
end;
end;
>選択とハイライトとフォーカスがぐちゃぐちゃになっていると思います。
確かに^^;
スタテツさん、レス有難うございます。残念ながらまだ解決できていません。
DrawCellイベントはよく分からないのですが、次のif条件が満たされない、
>(gdFocused in State = False ) and
>((Sender as TStringGrid).Focused=False) then
つまり操作のなかでフォーカスを失う瞬間がないのではないかと思えました。
どうも現象の説明がよろしくないようです。
検索ダイアログ表示中も、親フォームのハイライトとその移動が見えるようにしていたい、と言ったら正しいのでしょうか?
たどたどしい説明で恐縮です。
質問の意図をよく理解できないままの回答でスミマセン;;
>// FindDialog1.CloseDialog; //これをしないとハイライトしないのが困る
と有ったのでgdFocusedの属性を持つセルをハイライトと呼んでいるのかと思いました。
1□□□□□□□
2□□■■□□□
3□■■■□□□
4□□□□□□□
5□□□□□□□
ここで言うと[2,2]ですが、StringGrid自体のフォーカスが無くなると■になることを指しているのかと思っただけです。
>検索ダイアログ表示中も、親フォームのハイライトとその移動が見えるようにしていたい
正直やりたいことが分かりません。
ハイライトとはここで言う選択領域■であると仮定して、それが移動とあるので一つのCellのみを選択して移動しながら文字検索を行うということにして回答させていただきます。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
FindDialog1: TFindDialog;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FindDialog1Find(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
StringGrid1.DefaultColWidth:=10;
StringGrid1.DefaultRowHeight:=10;
StringGrid1.RowCount:=10;
StringGrid1.ColCount:=10;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FindDialog1.Execute;
end;
procedure TForm1.FindDialog1Find(Sender: TObject);
var i,p:integer;
begin
for i:= 1 to StringGrid1.ColCount-1 do
for p:= 1 to StringGrid1.RowCount -1 do
begin
StringGrid1.Col:=i;
StringGrid1.Row:=p;
Application.ProcessMessages;
sleep(100);
end;
end;
end.
スタテツさん、お世話をおかけして申し訳ありません。
記載されたコードを動かしてみてビックリしました。こんな大それたことを望んだわけではないのです。
しかしお陰さまで、いろいろいじってみて分かったのは、普通に動けば検索中でも選択表示はされるものだ、という点です。
まあ頓馬な質問をしたものだと恥じ入っております。
自分のコードでは何かの拍子で隠れてしまったのだろうと、原因探しを始めました。本日はもう時間切れです。明日には解決の報告ができるようにしたいです。
ドツボにはまって抜けられないので解決マークは打てません。
基礎的な力量の問題と思いますので、勉強して出直したいと思います。
お騒がせして本当に申し訳ありませんでした。
拙い日本語で意味も意図も伝わらなかったと思います。
エチケットとして①そもそもの狙い②起こっている問題③検討経過について、できるだけの整理をさせていただきます。
①工作しているのは簡単なアンケート集計ソフトで、社内配布の手軽さをあてにしてDelphiに手を染めた次第です。
StringGridで各種定義を管理するにあたり、質問項目の登録動作を次のように想定しました。
1.商品Aの評価、商品Bの評価など、部分的に似た言葉の繰り返しが多いので、代表名称を一組入力しコピー→貼り付けで仮登録する。
2.検索文字A、置換文字Bなどで必要な箇所を置換して完成させる。
この場では単純化のため検索問題として提示しましたが、視認しながらの置換が狙いです。
②困った現象というのは、検索ダイアログ表示中、StringGridでの検索結果が見えなくなったことです。用語の使い方が分からなくて余分な混乱をきたしてしまいました。
③ちょうだいしたコードを手がかりにヒナ型を作り検討して確認できたことは、
・goEditingをFalseにしてセル単位の検索なら、何の支障もなくいける。
・InplaceEditorをターゲットにしても、単一のフォームでは動いた。
・それがMDI子フォームにした途端、なぜか表示が隠れてしまう。
・どうもStringGridにActiveが戻れば表示されるが、検索ダイアログにそれが残っているときはうまくいかないようだ。(goEditing=FalseならそれでもOK)
SetFocusの使い方がまずいのか、VBAのActivateみたいなメソッドはないものか、でも多分おもいがけない初歩的ミスの可能性が一番高いだろう、などと先の見えないトンネルに入ってしまいました。
別のテーマに進みます。またご厄介かけるかもしれませんが、よろしくお願いします。冗長な発言、重ねて失礼いたしました。
>・それがMDI子フォームにした途端、なぜか表示が隠れてしまう。
>SetFocusの使い方がまずいのか、…
これでどうかにゃ〜?
MDIでは親フォームにFocusあてるにゃ〜
procedure THwdForm.FindWork(Sender: TObject; FText: String);
var
.......
begin
..............
else begin
Row := i;
MainForm.Setfocus; ← MDIの親フォーム(MainForm)にフォーカス
with TInplaceEdit(Controls[0]) do
..............
にゃ〜さん有難うございます。あっさり解決です。
MDIの親フォームに返すとは思いもよりませんでした。
ほとんど諦めていたのですが、恥はかいてみるものです。
スタテツさん、お世話おかけしました。ご両人に感謝します。
ツイート | ![]() |