Версия для печати


БИБЛИОТЕКА.VCL.TSQLConnection.SQLHourGlass.Восстанавливается всегда обычный курсор
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=884

Рощин С.А.
дата публикации 01-12-2003 16:28

КАТЕГОРИЯБИБЛИОТЕКА.VCL.TSQLConnection.SQLHourGlass.Восстанавливается всегда обычный курсор
ПРОДУКТDelphi 7
ПЛАТФОРМА


Проблема в следующем.
Допустим, выполняются некие долгие операции, в том числе и методы TSQLConnection.Execute. В начале программист меняет курсор экрана на свой собственный, и по завершению хочет вернуть старое значение.

Во время выполнения Execute курсор поменяется на часы а потом на обычную стрелку. Если бы было установлено свойство SQLHourGlass=false, то курсор бы просто поменялся на обычную стрелку, что неожиданно и нежелательно.

В процессе исследования выяснено следующее.

При выполнении метода TSQLConnection.Execute, в начале и в конце выполняется внутренняя процедура, которая меняет курсор (см. модуль SqlExpr):

procedure TSQLConnection.SetCursor(CursorType: Integer);
begin
  if SQLHourGlass or (CursorType = DefaultCursor) then
    if Assigned(ScreenCursorProc) then
      ScreenCursorProc(CursorType);
end;

Легко видеть, что если установлено свойство SQLHourGlass=true то сначала устанавливаются песочные часы, а в конце устанавливается курсор по умолчанию. А в противном случае сначала курсор не меняется, а в конце всегда устанавливается курсор по умолчанию. Это приводит к нежелательному поведению программы.




Типовые решения
  1. ScreenCursorProc - это общедоступная переменная процедурного типа, которая объявлена в модуле DB:

    ScreenCursorProc : procedure (const CurIndex : integer);
    

    Она присваивается при инициализации модуля DBLogDlg:

    procedure SetCursorType(const CurIndex: Integer);
    begin
      Screen.Cursor := TCursor(CurIndex);
    end;
    initialization
    {.....}
      ScreenCursorProc := SetCursorType;
    end.
    

    Процедура SetCursorType выглядит несложно. Она отвечает за изменение курсора при выполнении запросов. Её можно написать по своему вкусу и присвоить переменной ScreenCursorProc. Вот простейший пример процедуры, которая вместо обычных песочных часов делает часы с текстом "SQL" и не меняет курсор на обычный, если он отличен отличен от песочных часов:

    unit DataModule1;
    {...........}
    procedure SetCursorType(const CurIndex: Integer);
    begin
      if CurIndex=0 then begin
        if (Screen.Cursor = crHourGlass) or (Screen.Cursor = crSQLWait) then
          Screen.Cursor := TCursor(CurIndex);
      end else if CurIndex = crHourGlass then Screen.Cursor := crSQLWait
        else Screen.Cursor := TCursor(CurIndex);
    end;
    
    initialization
      ScreenCursorProc := SetCursorType;
    end.