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

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

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

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

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

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

Не я его создал, а поток. Например ShowMessage.
Sibedir вне форума Ответить с цитированием
Старый 20.01.2016, 06:33   #12
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Может, угадал:
Код:
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    //...
  private
    procedure WMSnap(var Msg: TMessage); message WM_USER + 1;
    //...
  end;
//...
implementation
//...
var
  Hook: HHOOK;

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 CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if nCode < 0 then
  begin
    Result := CallNextHookEx(Hook, nCode, wParam, lParam);
    Exit;
  end;

  case nCode of
    HCBT_ACTIVATE:
      PostMessage(Form1.Handle, WM_USER + 1, 0, 0);
  end;

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

procedure TForm1.FormCreate(Sender: TObject);
begin
  Hook := SetWindowsHookEx(WH_CBT, @CBTProc, 0, GetCurrentThreadId);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnhookWindowsHookEx(Hook);
end;

procedure TForm1.WMSnap(var Msg: TMessage);
var
  Buf: array[0..MAX_PATH - 1] of Char;
  H: HWND;
begin
  H := GetFocus;
  if H <> 0 then
    if GetClassName(H, Buf, Length(Buf)) <> 0 then
      if (Buf = 'TButton') {and SnapToDefaultButton} then
        SnapTo(H);
end;
Filka вне форума Ответить с цитированием
Старый 20.01.2016, 15:26   #13
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Не угадал?
Filka вне форума Ответить с цитированием
Старый 20.01.2016, 18:02   #14
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Конечно угадал, Filka
Это всё замечательно. Но я хочу доламать свой комп... допилить свой код, чтобы это и в диалоговых окнах работало.
Я эту тему потому и забросил, что теперь мне нужен будет глобальный хук. Или я опять не прав?

--------------------------------------------------------
А. Вот, кстати, вдруг кто-нибудь тоже фигнёй помаяться захочет
LocalHook.zip

Ну самое полезное там это
Код:
function GetMessageName (aMessageID: UINT   ): TWM_Name;

Последний раз редактировалось Sibedir; 20.01.2016 в 18:06.
Sibedir вне форума Ответить с цитированием
Старый 21.01.2016, 05:52   #15
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Цитата:
чтобы это и в диалоговых окнах работало
Каких именно?
Код:
function GetMessageName (aMessageID: UINT): TWM_Name;
Вот ещё: http://blog.dummzeuch.de/2014/08/24/...es-to-strings/
Есть ещё функция RegisterWindowMessage. А с помощью функции GetClipboardFormatName можно узнать имена зарегистрированных сообщений:
Код:
procedure EnumMsgs(Lines: TStrings);
var
  Buf: array[Byte] of Char;
  I: Integer;
begin
  if Assigned(Lines) then
  begin
    Lines.BeginUpdate;
    try
      Lines.Clear;
      for I := $C000 to $FFFF do
        if GetClipboardFormatName(I, Buf, Length(Buf)) > 0 then
          Lines.Add(Format('%x = %s', [I, Buf]));
    finally
      Lines.EndUpdate;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.ScrollBars := ssBoth;
  EnumMsgs(Memo1.Lines);
  Caption := IntToStr(Memo1.Lines.Count);
end;
Filka вне форума Ответить с цитированием
Старый 21.01.2016, 09:56   #16
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

За GetClipboardFormatName отдельное спасибо. Я бы ни за что не догадался. Надо внимательнее читать коменты. Задолбался с переводчиками по msdn лазить.

Так это чё, недокументированная особенность?
Так изначально было задумано? Или это они просто для передачи сообщений тот же механизм выделения буферов используют что и для Ctrl+C/Ctrl+V (ну или наоборот)? Я думал для Clipboard отдельный API-функционал есть. Я понимаю, что в WindowsOS всё на сообщениях основывается. Но не понятно тогда, если для Clipboard нужен механизм сообщений, то почему для механизма сообщений нужен Clipboard? Или это просто они оба используют специальный обособленный механизм для регистрации/нумерации имён/строк (типа одна и та же функция под разными именами раздаётся)? Или это только для пользовательских сообщений? (ведь системные они или чётко определены или используются в строго заданном контексте).

// ----------------------------------------------------------

Почти конец истории

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


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при работе с БД Antohka Помощь студентам 1 10.07.2015 08:38
Ошибка при работе автофильтра ruavia3 Microsoft Office Excel 5 21.09.2009 15:05
ошибка при работе с указателем Vladss Общие вопросы C/C++ 22 29.07.2009 03:58
ошибка при работе с файлом Juffin Общие вопросы Delphi 3 11.04.2009 21:37
Ошибка при работе с БД malevich БД в Delphi 8 25.11.2007 15:10