6

私は単純に FindDialog を次のように開いています。

FindDialog.Execute;

私の FindDialog.OnFind イベントでは、カーソルを砂時計に変更して大きなファイルを検索したいと考えています。これには数秒かかる場合があります。したがって、OnFind イベントでは次のようにします。

Screen.Cursor := crHourglass;
(code that searches for the text and displays it) ...
Screen.Cursor := crDefault;

テキストの検索中にカーソルが砂時計 (または Vista では回転する円) に適切に変化し、検索が完了するとポインターに戻ります。

ただし、これはメイン フォームでのみ発生します。FindDialog 自体では発生しません。検索中、デフォルトのカーソルは FindDialog に残ります。FindDialog の上にカーソルを移動すると検索が行われますが、カーソルをデフォルトに変更し、メイン フォームの上に移動すると砂時計になります。

これは、起こるべきことのようには見えません。私は何か間違ったことをしていますか、それともすべてのフォームでカーソルを砂時計にするために何か特別なことをする必要がありますか?

参考までに、私は Delphi 2009 を使用しています。

4

2 に答える 2

4

この理由はsthを持っていると思います。Find Dialog がフォームではなく Dialog (Common Dialog) であることと関係があります。

クラス カーソルの設定を試すことができます (ダイアログのコントロールには影響しません)。

procedure TForm1.FindDialog1Find(Sender: TObject);
begin
  SetClassLong(TFindDialog(Sender).Handle, GCL_HCURSOR, Screen.Cursors[crHourGlass]);
  try
    Screen.Cursor := crHourglass;
    try
//    (code that searches for the text and displays it) ...
    finally
      Screen.Cursor := crDefault;
    end;
  finally
    SetClassLong(TFindDialog(Sender).Handle, GCL_HCURSOR, Screen.Cursors[crDefault]);
  end;
end;



編集

別の方法として、検索時に FindDialog をサブクラス化し、WM_SETCURSOR メッセージに「SetCursor」で応答することもできます。メッセージのそれ以上の処理を禁止すると、ダイアログのコントロールは独自のカーソルを設定しません。

type
  TForm1 = class(TForm)
    FindDialog1: TFindDialog;
    ...
  private
    FSaveWndProc, FWndProc: Pointer;
    procedure FindDlgProc(var Message: TMessage);
    ...
  end;

....
procedure TForm1.FormCreate(Sender: TObject);
begin
  FWndProc := classes.MakeObjectInstance(FindDlgProc);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  classes.FreeObjectInstance(FWndProc);
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
begin
  FSaveWndProc := Pointer(SetWindowLong(FindDialog1.Handle, GWL_WNDPROC,
        Longint(FWndProc)));
  try
    Screen.Cursor := crHourGlass;
    try
//    (code that searches for the text and displays it) ...
    finally
      Screen.Cursor := crDefault;
    end;
  finally
    if Assigned(FWndProc) then
      SetWindowLong(FindDialog1.Handle, GWL_WNDPROC, Longint(FSaveWndProc));
//    SendMessage(FindDialog1.Handle, WM_SETCURSOR, FindDialog1.Handle,
//        MakeLong(HTNOWHERE, WM_MOUSEMOVE));
    SetCursor(Screen.Cursors[crDefault]);
  end;
end;

procedure TForm1.FindDlgProc(var Message: TMessage);
begin
  if Message.Msg = WM_SETCURSOR then begin
    SetCursor(Screen.Cursors[crHourGlass]);
    Message.Result := 1;
    Exit;
  end;
  Message.Result := CallWindowProc(FSaveWndProc, FindDialog1.Handle,
      Message.Msg, Message.WParam, Message.LParam);
end;
于 2010-04-18T04:00:33.940 に答える
0

Application.ProcessMessages; を追加してみてください。カーソルを設定した後。

これがうまくいく場合は、必ず母親に電話するか、老婦人が通りを渡るのを手伝うか、木を植えてください。さもなければ、悪魔はあなたの魂の別の小さな部分を所有するでしょう.

于 2010-04-18T03:06:36.743 に答える