Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Помогите, пожалуйста, решить непосильную задачу для моего ума.  (Прочитано 24769 раз)
0 Пользователей и 1 Гость смотрят эту тему.
BiT
Гость
« : 02-07-2008 08:59 » 

Помогите, пожалуйста, решить непосильную задачу для моего ума.

Я хочу сделать приложение, которое находило нужное, приложения, Handle окна запоминало его. Для последующей работы с ним.

Теперь постараюсь объяснить смысл работы программы:

Я запускаю свою программу!  Несколько окон  блокнота нахожу нужный Handle окна запоминаю его и посылаю ему сочетание клавиш (CTRL + C ) программа ловит нажатие клавиш и посылает блокноту ( F1 ) или текст ). Как мне программно и визуально сделать.
Нужно чтоб было на форме выбор горячих клавиш и выбор действий их.
И если можно с описание что на форму положить и куда код прописывать.
                {Я начинающий Делфист очень жду вашей помощи}
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #1 : 02-07-2008 09:18 » 

BiT, попробуй четче изложить что тебе надо.
1. Непонял:
Цитата
Несколько окон  блокнота нахожу нужный Handle окна
Если несколько окон блокнота, по каким параметрам надо находить хендл окна.
2.
Цитата
и посылаю ему сочетание клавиш (CTRL + C )
Кому ему? Своему приложению или блокноту?
3.
Цитата
нахожу нужный Handle окна запоминаю его
А если окно закрыли, хендл уже не валидный, то что? Отслеживать закрытие окон?

P.S. Вот пример, мягко говоря, неаккуратного использования родного языка для изъяснения собственных мыслей.
Записан
BiT
Гость
« Ответ #2 : 02-07-2008 09:42 » 

1. По заголовку или Handle Активного окна
2. чтоб моя программа среагировала на нажатие клавиш (CTRL + C )  и послала в блокнот f1
3. А зачем мне несуществующее окно)

P.S.  Я за собой заметил)
 
Записан
Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 02-07-2008 10:14 » 

BiT, почитай немного SDK.
Handle окна можно получить по его классу, или заголовку.
В своей программе ставишь обработчик на (CTRL+C), который отправит необходимому Handle нужное сообщение.
Проверить существование окна поможет IsWindowExists (ну примерно так).
Записан
BiT
Гость
« Ответ #4 : 02-07-2008 10:54 » 

Я весь инет перерыл,  книг за пол года прочел, что за свои 27 не прочел, как я понял для меня непосильно решение задачи без явного примера (Поймите тяжко начинать)
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #5 : 02-07-2008 11:39 » 

Я весь инет перерыл

ну видимо не весь Улыбаюсь
http://www.delphihelp.org/get_handle_class_cur_window.html
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
BiT
Гость
« Ответ #6 : 02-07-2008 12:14 » 

У меня все это есть! просто не знаю, как все это обеднить.
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #7 : 02-07-2008 13:06 » 

BiT, обеднить? или объединить? вот в чем вопрос Улыбаюсь Купи толковую книгу.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #8 : 02-07-2008 16:44 » 

BiT, честно говоря, не совсем понятно назначение и смысл твоей программы.
Если ты хочешь, чтобы за тебя написали программу - то это врядли.
Из того что я понял, порядок действий:
1. Создаешь новое Form-Application.
2. Ложишь на форму компонент TComoboBox со  списком комбинаций горячих клавиш.
3. В обработчике OnChange комбобокса прописываешь код удаления предыдущей регистрации горячих клавиш UnregisterHotKey (см. MSDN) и регистрации  новой комбинации RegisterHotKey (см. MSDN)
4. Создаешь обработчик для сообщения WM_HOTKEY, в котором прописываешь действия по поиску окна и нажатию клавиши:
   - Для поиска по заголовку функции API FindWindow, FindWindowEx (см. MSDN)
   - Для поиска активного окна можно воспользоваться функцией GetForegroundWindow (см. MSDN)
   - Для отправки F1 блокноту используем API функцию SendMessage с сообщением WM_KEYDOWN, WM_KEYUP
Записан
DrGluck
Постоялец

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 03-07-2008 08:31 » 

Вроде все просто, непонятно в чем проблема.  Не понял
Ты не инет серфи, а MSDN читай.
Записан

Good user - dead user
BiT
Гость
« Ответ #10 : 03-07-2008 12:35 » 

Спасибо я так и понял, что все просто так не дается. Буду читать MSDN. Я если честно только пол года пытаюсь программировать.
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #11 : 03-07-2008 14:32 » 

BiT, если что будет непонятно конкретно по функциям, спрашивай, поможем.
Записан
BiT
Гость
« Ответ #12 : 09-07-2008 03:55 » 

Подскажите, что тут не так почему  по горячей клавиши не отправляется f1 в блокнот.



private

  procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
    { Private declarations }
  public

    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormDestroy(Sender: TObject);
begin
UnRegisterHotKey(Handle, 0);
end;

procedure TForm1.WMHotKey(var Msg: TWMHotKey);
           var
   wnd: HWND;
    begin
inherited;
  wnd := FindWindow('notepad', nil);

PostMessage(wnd, WM_KEYDOWN, VK_F1, 0);
     end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterHotKey(Handle, 0, MOD_CONTROL , Ord('A'));
end;

end.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 09-07-2008 06:50 » 

сначала вот тут:
wnd := FindWindow('notepad', nil);

проверял, находится ли хендл ? Может notepad.exe ?
Записан

zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #14 : 09-07-2008 06:59 » 

1. Правила плохого тона в качестве уникального индентификатора использовать 0:
вместо
Код:
RegisterHotKey(Handle, 0, MOD_CONTROL , Ord('A'));
надо создать уникальный индентификатор типа:
Код:
id_HotKeyRun:=GlobalAddAtom('D0273960-97C4-42F0-9C7B-51DF618682F2');
RegisterHotKey(Handle, id_HotKeyRun, MOD_CONTROL , Ord('A'));

соответственно
UnRegisterHotKey(Handle, id_HotKeyRun);
2.
Код:
SendMessage(wnd, WM_KEYDOWN, VK_F1, 0);
SendMessage(wnd, WM_KEYUP, VK_F1, 0);

Ну и поставь в дебаге точки останова на WM_HOTKEY, заходит ли туда при нажатии "A", определяется ли хендл окна?
Записан
BiT
Гость
« Ответ #15 : 09-07-2008 07:31 » 

У меня проблема в отправки клавиш F1 не посылается, а Enter Tap  пробел посылает без проблем.
Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #16 : 09-07-2008 09:01 » 

BiT, что то как-то не ясно, что вы понимаете послать F1 это же функционально нагруженная клавиша, может вы хотите просто в блокноте видеть напечатаное "F1"? или как?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
BiT
Гость
« Ответ #17 : 09-07-2008 09:11 » 

Я хочу, что при отправки F1 открылась справка в блокноте.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 09-07-2008 09:16 » 

отправь блокноту сообщение WM_HELP
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 09-07-2008 09:20 » 

в общем, spy++ показывает после нажатия F1 такую картину )


* note.PNG (14.37 Кб - загружено 628 раз.)
Записан

BiT
Гость
« Ответ #20 : 09-07-2008 09:23 » 

Да я просто привожу пример на блокноте я пишу совсем другую программу. Где По нажатию горячих клавиш передавалась клавиша F1 В заданое приложение.
« Последнее редактирование: 10-07-2008 04:44 от BiT » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 09-07-2008 10:31 » 

tесли программа своя, зачем какие то клавиши туда передавать ? ) Это требуется только для чужих программ - так как их уже не поменять
Записан

BiT
Гость
« Ответ #22 : 09-07-2008 17:17 » 

Может, у кого есть, похожий исходник скиньте, пожалуйста (тока без dll)
Спасибо.
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #23 : 09-07-2008 17:22 » 

BiT, тогда сделай так:
Код:
wnd := FindWindow('notepad', nil);
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
Будет работать сто пудов.
Записан
BiT
Гость
« Ответ #24 : 09-07-2008 18:49 » 

Самое интересное, что так работает

procedure TForm1.Button1Click(Sender: TObject);
    var
   wnd: HWND;
   begin
wnd := FindWindow('notepad', nil);
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

end;

end.



А так нет)

procedure TForm1.WMHotKey(var Msg: TWMHotKey);
           var
   wnd: HWND;
    begin
inherited;
wnd := FindWindow('notepad', nil);
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

     end;
Записан
Feodora
Помогающий

ru
Offline Offline
Пол: Женский
Солнце мяуобразное


« Ответ #25 : 09-07-2008 19:35 » 

BiT, для того, чтобы отрабатывали "горячие клавиши", их надо сначала зарегестрировать. да и инхеритед в обработчике виндового сообщения особо смысла не несёт - у него нет предка, как такового, он встраивается в очередь, и будет или не будет выполняться предыдущий / последующий message - будет зависеть только от Msg.Result соответствующего месэджа. формально - второй пример очень правильно делает, что не работает. если б он работал - винда бы просто зависла при нажатии любой кнопки.

а реально - подозреваю, что функция из второго примера не получает управление никогда (т.к. подозреваю также, что HotMessage  банально не зарегестрирован). Поставьте брэйкпойнт на неё, потом расскажете Улыбаюсь
Записан

Кошки все красавицы
У кошек трудное детство
Кошкам нравится нравиться
Кошкам хочется хотеться

"... Я обожаю неприличные вопросы. После них пересматриваешь теорию Дарвина..." (Иржи Грошек, "Легкий завтрак в тени Некрополя")
Basurman
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 09-07-2008 20:49 » 

Самое интересное, что так работает

procedure TForm1.Button1Click(Sender: TObject);
    var
   wnd: HWND;
   begin
wnd := FindWindow('notepad', nil);
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

end;

end.



А так нет)

procedure TForm1.WMHotKey(var Msg: TWMHotKey);
           var
   wnd: HWND;
    begin
inherited;
wnd := FindWindow('notepad', nil);
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

     end;

Во втором варианте, после вызова унаследованного метода происходит очистка полей сообщения (по крайней мере некоторых).
Это последствия реализации компонентов Delphi.
Надо выполнять пользовательскую обработку, и только затем вызывать унаследованные методы.
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #27 : 09-07-2008 22:08 » 

Feodora, согласен inherited здесь ни к чему, но проблема не в инхеритед.

Проблема в том, что  не активное окно приложения  не может вызвать SetForegroundWindow:
Цитата
Windows 2000/XP: No menus are active.

With this change, an application cannot force a window to the foreground while the user is working with another window. Instead, Foreground and Background Windows will activate the window (see SetActiveWindow) and call the function to notify the user. However, on Microsoft Windows 98 and Windows Millennium Edition (Windows Me), if a nonforeground thread calls SetForegroundWindow and passes the handle of a window that was not created by the calling thread, the window is not flashed on the taskbar.

MSDN

поэтому вот лекарство:
Код:
procedure TForm1.WMHotKey(var Msg: TWMHotKey);
var
   wnd: HWND;
begin
 wnd := FindWindow('notepad', nil);
 SetActiveWindow(Handle);//делаем свое окно активным
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
end;
« Последнее редактирование: 09-07-2008 22:11 от zubr » Записан
BiT
Гость
« Ответ #28 : 10-07-2008 04:15 » 

Окно становиться активным но не че не происходит!
Записан
BiT
Гость
« Ответ #29 : 10-07-2008 04:18 » 

Окно становиться активным но не че не происходит!


Код:
procedure TForm1.WMHotKey(var Msg: TWMHotKey);
var
   wnd: HWND;
begin
 wnd := FindWindow('notepad', nil);
 SetActiveWindow(Handle);//делаем свое окно активным
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
end;


И в этом случае становиться активным но тоже не че не происходит.

Код:
procedure TForm1.WMHotKey(var Msg: TWMHotKey);
           var
   wnd: HWND;
    begin
inherited;
wnd := FindWindow('notepad', nil);
 SetForegroundWindow(wnd);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
 keybd_event(VK_F1, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);

     end;



Я незнаю как это делать еще)  (Поставьте брэйкпойнт на неё, потом расскажете)



Осталась только на вас надежда Поиск не рулит книги купил начиная от 400 и кончая 700р тоже не рулят про один винамп пишут.  деньги тока зря потратил(
« Последнее редактирование: 10-07-2008 07:57 от BiT » Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines