При разработке приложений на Delphi иногда возникает необходимость изменить курсор мыши на изображение песочных часов во время выполнения длительных операций, таких как поиск по большим файлам. Это стандартная практика, позволяющая пользователю визуально понять, что программа занята выполнением задачи и не игнорируется.
Описание проблемы
Разработчик столкнулся с проблемой, когда курсор мыши не изменялся на песочные часы в диалоговом окне поиска, несмотря на то что в основном приложении изменения происходили корректно. В коде использовался следующий подход:
FindDialog.Execute;
В событии OnFind диалога поиска разработчик хотел изменить курсор на песочные часы для поиска по большим файлам:
Screen.Cursor := crHourglass;
(code, который выполняет поиск и отображает результаты)
Screen.Cursor := crDefault;
Проблема заключалась в том, что курсор менялся на песочные часы только в основном приложении, а в диалоговом окне поиска изменений не происходило.
Подтвержденное решение
Проблема была решена путем изменения курсора класса диалога, используя функцию SetClassLong. Это позволяет изменить курсор для всего диалога, а не только для отдельных элементов управления. Вот пример кода, который решает проблему:
procedure TForm1.FindDialog1Find(Sender: TObject);
begin
SetClassLong(TFindDialog(Sender).Handle, GCL_HCURSOR, Screen.Cursors[crHourGlass]);
try
try
// Код, который выполняет поиск и отображает результаты
finally
Screen.Cursor := crDefault;
end;
finally
SetClassLong(TFindDialog(Sender).Handle, GCL_HCURSOR, Screen.Cursors[crDefault]);
end;
end;
Также было предложено альтернативное решение, включающее подклассирование диалога и обработку сообщений WM_SETCURSOR во время поиска. Это позволяет изменить курсор для диалога и его элементов управления.
Альтернативное решение
Подклассирование диалога и обработка сообщений WM_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
// Код, который выполняет поиск и отображает результаты
finally
Screen.Cursor := crDefault;
if Assigned(FWndProc) then
begin
SetWindowLong(FindDialog1.Handle, GWL_WNDPROC, Longint(FSaveWndProc));
SetCursor(Screen.Cursors[crDefault]);
end;
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;
Заключение
Изменение курсора мыши на песочные часы в диалоговом окне поиска в Delphi может быть выполнено с помощью изменения курсора класса диалога или подклассирования диалога с обработкой соответствующих сообщений. Оба подхода были успешно применены разработчиками и подтверждены в качестве рабочих решений.
Инструкция для разработчика по изменению курсора мыши на песочные часы в диалоговом окне поиска в среде разработки Delphi для визуального индикации выполнения длительных операций.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS