Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.12.2015, 07:08   #11
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Спасибо, Filka. Пример работает на ура. Думаю Screen.OnActiveFormChange - то что нужно.

Последний раз редактировалось Sibedir; 30.12.2015 в 07:20.
Sibedir вне форума Ответить с цитированием
Старый 30.12.2015, 07:35   #12
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Пожалуйста.
Filka вне форума Ответить с цитированием
Старый 30.12.2015, 07:50   #13
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

А как быть, если "другой" программист захочет назначить другой обработчик события на Screen.OnActiveFormChange. Попробую через фильтрацию входящих сообщений от системы.
Если не сложно, подскажите, чтоб не искать долго, какое событие лучше отлавливать, чтобы срабатывал при активации новой формы.
Или как?

Последний раз редактировалось Sibedir; 30.12.2015 в 08:18.
Sibedir вне форума Ответить с цитированием
Старый 30.12.2015, 09:04   #14
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Можно чуть подробнее?
Filka вне форума Ответить с цитированием
Старый 30.12.2015, 10:35   #15
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

1. Ловим системное сообщение отвечающее за создание/активацию/появление форм
2. (???) Убедимся, что это первое появление формы
3. Проверяем состояние SPI_GETSNAPTODEFBUTTON, наличие default кнопок
4. Производим соответствующие манипуляции с курсором
Sibedir вне форума Ответить с цитированием
Старый 30.12.2015, 10:38   #16
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Нужно чтобы только при первом появлении формы курсор перемещался, а при последующих нет?
Filka вне форума Ответить с цитированием
Старый 30.12.2015, 10:54   #17
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Так точно.
Ну оно и понятно.

Пока в голову лезет только буфер для форм:
1. создаласть форма - положили её в кучу
2. активировалась форма
Код:
  если её нет в куче то
    ничё не делаем
  иначе
    обработали курсор
    убрали из кучи
Но при слове "буфер" чёт как-то перехачивается с этим заморачиваться. Хотя может и пойдет. В любом случае - теперь тока после НГ.
Всех с наступающим.

Последний раз редактировалось Sibedir; 30.12.2015 в 11:01.
Sibedir вне форума Ответить с цитированием
Старый 30.12.2015, 10:57   #18
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Так пойдёт?
Код:
procedure TForm1.OnActiveFormChange(Sender: TObject);
var
  Form: TCustomForm;
  Pt: TPoint;
begin
  Form := Screen.ActiveCustomForm;
  if (Form <> nil) and (Form.ActiveControl <> nil) then
    if SnapToDefaultButton and (Form.Tag = 0) and (Form.ActiveControl is TButton) then
    begin
      Form.Tag := 1;
      Pt := Form.ActiveControl.ClientOrigin;
      Inc(Pt.X, Form.ActiveControl.ClientWidth div 2);
      Inc(Pt.Y, Form.ActiveControl.ClientHeight div 2);
      Mouse.CursorPos := Pt;
    end;
end;
Filka вне форума Ответить с цитированием
Старый 01.01.2016, 14:24   #19
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Не, Filka, Tag так использовать нельзя. Да и OnActive могут заменить.
Sibedir вне форума Ответить с цитированием
Старый 21.01.2016, 14:06   #20
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Короче вот:
Код:
unit SnapToDefaultButtonUnit;

interface

implementation

uses
  System.SysUtils,
  System.Classes,
  Winapi.Windows;

var
  Hook: HHOOK = 0;
  FWndList: TList;

{ ToolKik }

function WndList: TList;
begin
  if FWndList = nil then FWndList := TList.Create;
  Result := FWndList;
end;

function SnapToDefaultButton: Boolean;
var
  Snap: BOOL;
begin
  Snap := False;
  Result := SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, @Snap, 0) and Snap;
end;

procedure SnapTo(Wnd: HWND);
var
  R: TRect;
  Pt: TPoint;
begin
  if GetWindowRect(Wnd, R) then
  begin
    Pt.X := R.Left;
    Pt.Y := R.Top;
    Inc(Pt.X, (R.Right - R.Left) div 2);
    Inc(Pt.Y, (R.Bottom - R.Top) div 2);
    SetCursorPos(Pt.X, Pt.Y);
  end;
end;

function FindDefButton (aWnd: HWND): HWND;
const
  BS_MASK = $000F;
var
  Buf: array[0..MAX_PATH - 1] of Char;
begin
  if (GetClassName (aWnd, Buf, Length(Buf)) <> 0) and (Buf = 'TButton') then
    if (GetWindowLong (aWnd, GWL_STYLE) and BS_DEFPUSHBUTTON) = BS_DEFPUSHBUTTON then
      Exit(aWnd);
  Result := FindWindowEx (aWnd, 0, nil, nil);
  while Result <> 0 do begin
    Result := FindDefButton (Result);
    if Result <> 0 then
      Exit;
  end;
end;

{ HookProc }

function HookProc (nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  ActWnd: HWND;
  PMesStr: PCBTActivateStruct;
  i: Integer;
begin
  if nCode < 0 then
  begin
    Result := CallNextHookEx(Hook, nCode, wParam, lParam);
    Exit;
  end;

  case nCode of
    HCBT_CREATEWND: begin
      with WndList do begin
        i := IndexOf (Pointer(wParam));
        if i < 0 then
          Add (Pointer(wParam))
      end;
    end;
    HCBT_ACTIVATE: begin
      with WndList do begin
        i := IndexOf (Pointer(wParam));
        if i > -1 then begin
          Delete (i);
          if SnapToDefaultButton then
            SnapTo (FindDefButton(wParam));
        end;
      end;
    end;
  end;

  Result := CallNextHookEx(Hook, nCode, wParam, lParam);
end;

initialization

  if Hook = 0 then
    Hook := SetWindowsHookEx(WH_CBT, @HookProc, 0, GetCurrentThreadId);

finalization

  FreeAndNil(FWndList);
  if Hook <> 0 then
    UnhookWindowsHookEx(Hook);
  Hook := 0;

end.
Больше не могу. Код не без огрех (), но принцип ясен. На ShowMessage так и не заработало. Но мне стало пофиг.

P/S: Filka +5

Последний раз редактировалось Sibedir; 21.01.2016 в 14:10.
Sibedir вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как заставить MS VS E "Петь" на Русском? Xe[N]o Visual C++ 9 27.11.2010 10:08
Продолжения темы про настройку апача для "локального" ииспользования vedro-compota PHP 23 24.07.2010 10:21
настроить при открытии Excel 2003 в окошке "Тип файлов" вывод пункта "Все файлы (*.*)" по умолчанию? Unior Microsoft Office Excel 2 01.03.2009 02:42
Как добавить "значение по умолчанию" в базе Access? bafy БД в Delphi 6 13.02.2009 12:29
Как прописать в ключ "(По умолчанию)" UnD)eaD)Snake Общие вопросы Delphi 4 16.08.2007 12:00