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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.05.2013, 00:31   #1
noname_06
Пользователь
 
Регистрация: 18.01.2009
Сообщений: 49
Счастье Error: regular procedure and method pointer

Использую D7. Есть код, перевод с С++
Если добавляю его в новый проект (temp-rabotaet.rar в аттаче), все компилируется и работает. Если добавляю в свое приложение - получаю ошибку компиляции.
*О необходимости вызова функции в callback как static; читал, но D7 не поддерживает его (и работает без этого), в D XE3: [dcc32 Error] Unit1.pas(40): E2376 STATIC can only be used on non-virtual class methods.
Код:
program DisableLowLevelKeys;

uses
 Windows, Messages;

const
 LLKHF_ALTDOWN  = KF_ALTDOWN shr 8;
 WH_KEYBOARD_LL = 13;

type

 TKBDLLHOOKSTRUCT = record
   vkCode: DWORD;
   scanCode: DWORD;
   flags: DWORD;
   time: DWORD;
   dwExtraInfo: DWORD;
 end;
 PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;

var
 hhkLowLevelKybd: HHOOK;

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

function LowLevelKeyboardProc(nCode: integer;  wParam: WPARAM;  lParam: LPARAM): LRESULT; stdcall;
var
 fEatKeystroke: boolean;
 p: PKBDLLHOOKSTRUCT;
begin
 fEatKeystroke := false;
 if nCode = HC_ACTION then
   begin
     case wParam of
       WM_KEYDOWN,
       WM_SYSKEYDOWN,
       WM_KEYUP,
       WM_SYSKEYUP:
         begin
           p := PKBDLLHOOKSTRUCT(lParam);
           fEatKeystroke := ((p^.vkCode = VK_LWIN) or (p^.vkCode = VK_RWIN)) or
                            ((p^.vkCode = VK_TAB) and ((p^.flags and LLKHF_ALTDOWN) <> 0)) or
                            ((p^.vkCode = VK_ESCAPE) and ((p^.flags and LLKHF_ALTDOWN) <> 0)) or
                            ((p^.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) <> 0)) or
                            ((p^.vkCode = VK_F4) and ((p^.flags and LLKHF_ALTDOWN) <> 0));
         end;
     end;
   end;
 if fEatKeystroke then
   result := 1
 else
   result :=  CallNextHookEx(0, nCode, wParam, lParam);
end;

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

begin
 // Install the low-level keyboard & mouse hooks
 hhkLowLevelKybd := SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);

 // Keep this app running until we're told to stop
 ShowMessage('Work');

 // Remove hooks
 UnhookWindowsHookEx(hhkLowLevelKybd);
end.
Вложения
Тип файла: rar temp-rabotaet.rar (5.9 Кб, 9 просмотров)
Тип файла: rar test-ne-rabotaet.rar (28.7 Кб, 11 просмотров)

Последний раз редактировалось noname_06; 13.05.2013 в 01:03.
noname_06 вне форума Ответить с цитированием
Старый 13.05.2013, 09:56   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Код:
hhkLowLevelKybd := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, hInstance, 0);
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 13.05.2013, 13:58   #3
noname_06
Пользователь
 
Регистрация: 18.01.2009
Сообщений: 49
По умолчанию

@LowLevelKeyboardProc пробовал, требует передать функции параметры, а что ей передавать то и не в курсе. Отдельно создавать функцию и отлавливать WPARAM и LPARAM? Непонятно, почему в пустом проекте работает, а в других не хочет.
noname_06 вне форума Ответить с цитированием
Старый 14.05.2013, 21:22   #4
iworm2009
Пользователь
 
Регистрация: 07.05.2013
Сообщений: 51
По умолчанию

Код:
program DisableLowLevelKeys;

uses
 winapi.Windows, vcl.dialogs, Messages;

const
 LLKHF_ALTDOWN  = KF_ALTDOWN shr 8;
 WH_KEYBOARD_LL = 13;

type

 TKBDLLHOOKSTRUCT = record
   vkCode: DWORD;
   scanCode: DWORD;
   flags: DWORD;
   time: DWORD;
   dwExtraInfo: DWORD;
 end;
 PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;

var
 hhkLowLevelKybd: HHOOK;

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

function LowLevelKeyboardProc(nCode: integer;  wParam: WPARAM;  lParam: LPARAM): LRESULT; stdcall;
var
 fEatKeystroke: boolean;
 p: PKBDLLHOOKSTRUCT;
begin
 fEatKeystroke := false;
 if nCode = HC_ACTION then
   begin
     case wParam of
       WM_KEYDOWN,
       WM_SYSKEYDOWN,
       WM_KEYUP,
       WM_SYSKEYUP:
         begin
           p := PKBDLLHOOKSTRUCT(lParam);
           fEatKeystroke := ((p^.vkCode = VK_LWIN) or (p^.vkCode = VK_RWIN)) or
                            ((p^.vkCode = VK_TAB) and ((p^.flags and LLKHF_ALTDOWN) <> 0)) or
                            ((p^.vkCode = VK_ESCAPE) and ((p^.flags and LLKHF_ALTDOWN) <> 0)) or
                            ((p^.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) <> 0)) or
                            ((p^.vkCode = VK_F4) and ((p^.flags and LLKHF_ALTDOWN) <> 0));
         end;
     end;
   end;
 if fEatKeystroke then
   result := 1
 else
   result :=  CallNextHookEx(0, nCode, wParam, lParam);
end;

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

begin
 // Install the low-level keyboard & mouse hooks
 hhkLowLevelKybd := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, hInstance, 0);

 // Keep this app running until we're told to stop
 ShowMessage('Work');

 // Remove hooks
 UnhookWindowsHookEx(hhkLowLevelKybd);
end.
не вдумываясь получил на выхлоп ShowMessage('Work') .. у меня хе3
iworm2009 вне форума Ответить с цитированием
Старый 14.05.2013, 21:43   #5
iworm2009
Пользователь
 
Регистрация: 07.05.2013
Сообщений: 51
По умолчанию

если пишите в юните то ничего не меняется в порядке использования. объявлять в секции private ее не надо.

Последний раз редактировалось iworm2009; 14.05.2013 в 21:53.
iworm2009 вне форума Ответить с цитированием
Старый 15.05.2013, 00:09   #6
noname_06
Пользователь
 
Регистрация: 18.01.2009
Сообщений: 49
По умолчанию

Цитата:
Сообщение от iworm2009 Посмотреть сообщение
выхлоп ShowMessage('Work')
Любопытненько, как это Delphi не опознал родную до мозга костей процедуру
Цитата:
Сообщение от iworm2009 Посмотреть сообщение
если пишите в юните то ничего не меняется в порядке использования.
В теории - да, на практике - как видите влияет.
Цитата:
Сообщение от iworm2009 Посмотреть сообщение
объявлять в секции private ее не надо
Пардон, а где тогда? Объявлять как public, или, может, как метод от TForm1?
noname_06 вне форума Ответить с цитированием
Старый 15.05.2013, 02:25   #7
iworm2009
Пользователь
 
Регистрация: 07.05.2013
Сообщений: 51
По умолчанию

1. выхлоп - это значит showmessage произошел
2. на практике ничего не поменял
3 в вашем нерабочем примере убрал из private, и поднял тело функции выше ее первого использования дописав stdcall;
а и естесственно не LowLevelKeyboardProc а @LowLevelKeyboardProc

ps. у вас есть рабочий пример, разве не видно разницы
iworm2009 вне форума Ответить с цитированием
Старый 15.05.2013, 03:43   #8
iworm2009
Пользователь
 
Регистрация: 07.05.2013
Сообщений: 51
По умолчанию

если вам все таки оч надо функцию привязать к форме то вызов как то так
Код:
hhkLowLevelKybd:= SetWindowsHookEx(WH_KEYBOARD_LL, @TForm1.LowLevelKeyboardProc, hInstance, 0);
iworm2009 вне форума Ответить с цитированием
Старый 15.05.2013, 04:56   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Сообщение от iworm2009 Посмотреть сообщение
если вам все таки оч надо функцию привязать к форме то вызов как то так
Код:
hhkLowLevelKybd:= SetWindowsHookEx(WH_KEYBOARD_LL, @TForm1.LowLevelKeyboardProc, hInstance, 0);
нельзя так, вызов метода отличается от вызова процедуры, ибо в первый передается Self
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 15.05.2013, 06:28   #10
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Как уже сказали, выкинуть из методов формы вообще (ни private, ни public, просто в модуле положить, Вы ведь даже не обращаетесь к членам формы в функции), в старых дельфи нельзя использовать указатели на методы класса для передачи в винапи. После переброски функции в модуль использовать с @ или функцией Addr
Теория http://www.gunsmoker.ru/2008/12/static-delphi.html

Последний раз редактировалось phomm; 15.05.2013 в 06:33.
phomm вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Run-time error 1004: Method Range of object Global failed failed sa920 Microsoft Office Excel 8 01.07.2012 22:40
Выдает ошибку [Error] Unit1.pas(46): Method identifier expected ckbdf16 Помощь студентам 5 24.06.2011 09:22
[DCC Error] Project2.dpr(22): E2009 Incompatible types: 'method pointer and regular procedure' TwiX Общие вопросы Delphi 1 15.02.2010 09:14
Ошибка [Error] UPER.pas(57): Incompatible types: 'Integer' and 'Pointer' Pirotexnik Общие вопросы Delphi 4 27.03.2009 11:04