لماذا لا يتغير المؤشر إلى الساعة الرملية في FindDialog في Delphi؟

StackOverflow https://stackoverflow.com/questions/2660799

سؤال

أنا ببساطة فتح 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.

هل كانت مفيدة؟

المحلول

أعتقد أن سبب هذا قد حصل على sth. لا يمكن العثور على حوار "العثور على حوار ليس نموذجًا ولكن مربع حوار (مربع حوار مشترك).

يمكنك محاولة تعيين مؤشر الفصل (ليس له تأثير على عناصر التحكم في الحوار) ؛

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;

نصائح أخرى

حاول إضافة Application.ProcessMessages ؛ بعد تعيين المؤشر.

إذا نجح هذا ، فتأكد من الاتصال بأمك ، أو ساعد سيدة عجوز في عبور الشارع ، أو ربما تزرع شجرة. خلاف ذلك ، سوف يمتلك الشيطان قطعة صغيرة أخرى من روحك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top