Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.54/56: Рейтинг темы: голосов - 56, средняя оценка - 4.54
XpressMusicMan Музыка24/7
 Аватар для QwertyX
46 / 35 / 3
Регистрация: 27.08.2010
Сообщений: 346

Отловить нажатие клавиш даже если приложение свернуто

03.09.2010, 19:38. Показов 12633. Ответов 28

Студворк — интернет-сервис помощи студентам
Как сделать чтобы даже когда программа в трее или просто не на первом плане, она продолжала слушать заданные кнопки?
То есть у меня программа слушает нажатие кнтр+с... Но как только я выбираю другое окно(к примеру открываю форум, программа перестает слушать кнтр+с, то есть только когда программа открыта она слушает...
Скорее всего та же проблема будет когда она будет прятаться в трей(по любому мне позже ее туда надо будет засунуть ), так что подскажите плз, как решить?
Код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.KeyCode == Keys.C && e.Control)
            {
                IDataObject Data = Clipboard.GetDataObject();
                    if (Data.GetDataPresent(DataFormats.Text))
                    {
                        listBox1.Items.Add((String)Data.GetData(DataFormats.Text));
                    }
                    else
                    {
                        listBox1.Items.Add("Could not retrieve data off the clipboard.");
                    }
                e.Handled = true;
            }
        }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.09.2010, 19:38
Ответы с готовыми решениями:

Отловить нажатие клавиш в приложении
не знаю может мозгов(не спорю, в с# не очень знаю, новичок) нужно реализовать программу, нашёл код на форуме, вставил , но того что...

Нажатие клавиш в неактивное приложение (спам бот для свёрнутой игры)
Доброго времени суток! Стоит сказать что я не давно отошёл от "Hello, World!" а значит тупить я буду жёстко :) 1) Перед тем как...

Как послать нажатие клавиш в приложение при помощи PInvoke SendInput
Как послать нажатие клавиш в приложение при помощи PInvoke SendInput? Читал здесь(http://www.pinvoke.net/default.aspx/user32.sendinput), но...

28
XpressMusicMan Музыка24/7
 Аватар для QwertyX
46 / 35 / 3
Регистрация: 27.08.2010
Сообщений: 346
06.09.2010, 21:40  [ТС]
Студворк — интернет-сервис помощи студентам
Кстати... Фигня такая... в свой проект добавил "хук.кс" и вставил код... не вышло
говорит что пропущена ссылка на "LLKHEventArgs"...
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
06.09.2010, 21:41
Добавь вначало:
C#
1
using Hooks;
1
XpressMusicMan Музыка24/7
 Аватар для QwertyX
46 / 35 / 3
Регистрация: 27.08.2010
Сообщений: 346
06.09.2010, 22:00  [ТС]
Еще раз спасибо
Глупый, глупый нуп я

Добавлено через 17 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
            if (e.Keys == Keys.C && ctrl && e.IsPressed)
            {
                IDataObject data = Clipboard.GetDataObject();
                if (data != null && data.GetDataPresent(DataFormats.Text))
                {
                    this.listBox1.Items.Add((string)data.GetData(DataFormats.Text));
                } // if text
                else
                {
                    this.listBox1.Items.Add("klipboard is empty");
                }
                ctrl = false;
            }
 
            if (e.Keys == Keys.LControlKey || e.Keys == Keys.RControlKey)
                ctrl = e.IsPressed;
Вот так выходит...
Так проблема что при каждом нажатии кнтр+с он загружает предидущую инфу что была в буфере.. а надо чтобы загружал инфу с нынешнего клика... я пытался достать "IDataObject data = Clipboard.GetDataObject();" из ифа, и вставить на строку выше... но то же самое...
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
06.09.2010, 22:04
Может она (инфа) просто не успевает попасть в буфер обмена? Собственно что нужно чтобы программа делала - отлавливала изменения буфера обмена?
0
XpressMusicMan Музыка24/7
 Аватар для QwertyX
46 / 35 / 3
Регистрация: 27.08.2010
Сообщений: 346
06.09.2010, 22:39  [ТС]
Именно... а как сделать?
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
06.09.2010, 23:06
Вроде нужно использовать API SetClipboardViewer, ChangeClipboardChain, GetClipboardViewer... Сам не пробовал, но судя по описанию то что нужно. Если будет свободное время попробую реализовать...

Вот реализация, но работает только под висту и выше...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace ClipShow
{
    public partial class frmMain : Form
    {
        // РАБОТАЕТ ТОЛЬКО ПОД VISTA и >
 
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AddClipboardFormatListener(IntPtr hwnd);
 
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
 
        public frmMain()
        {
            InitializeComponent();
            if (!AddClipboardFormatListener(this.Handle))
                MessageBox.Show("Not inst!");
        }
 
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x031D)
            {
                IDataObject data = Clipboard.GetDataObject();
                if (data != null && data.GetDataPresent(DataFormats.Text))
                {
                    textBox1.Text = (string)data.GetData(DataFormats.Text);
                }
                else
                {
                    textBox1.Text = "clipboard is empty";
                }
            }
 
            base.WndProc(ref m);
        }
 
        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            RemoveClipboardFormatListener(this.Handle);
        }
    }
}
1
XpressMusicMan Музыка24/7
 Аватар для QwertyX
46 / 35 / 3
Регистрация: 27.08.2010
Сообщений: 346
07.09.2010, 08:54  [ТС]
А под ХР шансов не каких нет?

Добавлено через 5 минут
И еще... Как обычно... Если задержать больше 1 сек, будет дублироваться... Хотя на этот раз уже не так страшно...

Добавлено через 53 минуты
И еще 1 ОЧЕНЬ большая проблема...
Прикол в том, что когда надо скопи пастить несколько раз а потом выборочно вставить, ты сначала копи пастишь(все появляется в проге), а потом кликаешь в лист боксе на нужный текст, и он в буфере обмена(то есть можно вставить куда хочешь...)... Но теперь при клике на элемент, из за изменения в буфере обмена, добавляется еще 2 точно таких же строки...
Так как заставить ClipboardViewer реагировать только на первое попадание данных в буфер обмена? Может как нибудь сравнивать новый текст с предыдущим? И если они разные то только тогда вставлять их в листбокс?
0
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8729 / 3681 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
07.09.2010, 16:57
С XP надо по другому делать, если вечером будет свободное время, то попробую...
Цитата Сообщение от QwertyX Посмотреть сообщение
Но теперь при клике на элемент, из за изменения в буфере обмена, добавляется еще 2 точно таких же строки...
Ну так ты же знаешь когда произошел клик в листбокс, обрабатывай это, т.е. если копия произошла из твоего листа, больше в него не добавляй.
Цитата Сообщение от QwertyX Посмотреть сообщение
Может как нибудь сравнивать новый текст с предыдущим? И если они разные то только тогда вставлять их в листбокс?
Можно и так.

Я так понимаю это реализация (программа) множественного буфера обмена?

Добавлено через 7 часов 47 минут
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* SSTREGG, 2010.
 * Данный код должен (но не обязан!) работать начиная с Windows 2000.
 * Подробнее смотри на MSDN.
 * Всё (ну или почти всё) закомментированное можно использовать только в Windows Vista и выше.
 */
 
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
 
namespace ClipShow
{
    public partial class frmMain : Form
    {
        //[DllImport("user32.dll", SetLastError = true)]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //static extern bool AddClipboardFormatListener(IntPtr hwnd);
 
        //[DllImport("user32.dll", SetLastError = true)]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
 
        [DllImport("user32.dll")]
        static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
 
        [DllImport("user32.dll")]
        static extern IntPtr GetClipboardViewer();
 
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
 
        [DllImport("user32.dll", SetLastError = true)]
        static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
 
        IntPtr hWndNextWindow;
 
        //bool IsVista
        //{
        //    get { return Environment.OSVersion.Version.Major >= 6; }
        //}
 
        public frmMain()
        {
            InitializeComponent();
        }
 
        //bool AddClipboardFormatListenerInternal(IntPtr hWnd)
        //{
        //    if (!IsVista)
        //        throw new Win32Exception("Only Windows Vista and 7 are supported this function!");
 
        //    return AddClipboardFormatListener(hWnd);
        //}
 
        //bool RemoveClipboardFormatListenerInternal(IntPtr hWnd)
        //{
        //    if (!IsVista)
        //        throw new Win32Exception("Only Windows Vista and 7 are supported this function!");
 
        //    return RemoveClipboardFormatListener(hWnd);
        //}
 
        protected override void WndProc(ref Message m)
        {
            switch(m.Msg)
            {
                case (0x0001): // WM_CREATE
                    hWndNextWindow = SetClipboardViewer(this.Handle);
                    break;
                case (0x0002): // WM_DESTROY
                    ChangeClipboardChain(this.Handle, hWndNextWindow);
                    break;
                case (0x030D): // WM_CHANGECBCHAIN
                    if (m.WParam == hWndNextWindow)
                        hWndNextWindow = m.LParam;
                    else if (hWndNextWindow != IntPtr.Zero)
                        SendMessage(hWndNextWindow, m.Msg, m.WParam, m.LParam);
                    break;
                case (0x0308): // WM_DRAWCLIPBOARD
                    {
                        // Всё что нужно для отображения пиши здесь. Между { }
                        Debug.WriteLine("БУФЕР ОБМЕНА ИЗМЕНЁН");
                    }
                    SendMessage(hWndNextWindow, m.Msg, m.WParam, m.LParam);
                    break;
            }
 
            //if (m.Msg == 0x031D && IsVista)
            //{
            //    IDataObject data = Clipboard.GetDataObject();
            //    if (data != null && data.GetDataPresent(DataFormats.Text))
            //    {
            //        textBox1.Text = (string)data.GetData(DataFormats.Text);
            //    }
            //    else
            //    {
            //        textBox1.Text = "klipboard is empty";
            //    }
            //}
 
            base.WndProc(ref m);
        }
 
        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            //RemoveClipboardFormatListenerInternal(this.Handle);
        }
    }
}
Оставшееся реализовать несложно, думаю и сам справишься.
1
0 / 0 / 0
Регистрация: 15.09.2014
Сообщений: 8
01.11.2014, 16:23
Ребята, помогите, делаю примерно то же с буфером обмена, нужно при появлении содержимого в буфере, копировать это содержимое в файлик в виде текста.
Задача отловить уведомление о появлении информации в буфере обмена.

Идею понял,
VS 2012 ругается вот на эту строку
protected override void WndProc(ref Message m)

Говорит, что не знает она что такое Message,
делаю все это в рамках консольного приложения, как решить?

using System.Messaging;
вообще не подключается, не знает такого пространства имен

Добавлено через 41 минуту
Наверное неправильно вопрос поставил,
как узнавать об обновлении буфера обмена из консольного приложения?
А вообще, глобально задача сделать фоном работающее приложение, которое отлавливает буфер обмена и сохраняет содержимое в файл. Сравнивать содержимое буфера каждую секунду совсем не хочется, хочется отлавливать событие появления нового содержимого буфера обмена.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.11.2014, 16:23

Отловить нажатие определенной комбинации клавиш, даже когда программа не в фокусе
Бодрого дня или ночи! :D Написал программу и теперь нузно разобраться как сделать в ней управление сочитанием клавиш, а именно нужно,...

Реакция программы на нажатие клавиш, даже если она свернута в трей
Здравствуйте. При нажатии на клавишу D значение переменной klav увеличивается на 1. Static k As Integer = 0 If...

Сделать так, что бы форма реагировала на нажатие клавиш даже если она не активна
Как заставить форму реагировать на нажатие клавиш, при том что она не активна (свернута). Ну например: форма свернута, я нажал на F2, а он...

Отловить нажатие клавиш
Задал мне знакомый лотусист вопрос, теперь сам мучаюсь, инетересно: можно ли в лотусе перехватывать нажатие какой либо клавиши(F12 -...

Отловить нажатие клавиш
Как поставить обработчик я знаю, но я никак не могу сделать правильную проверку на соответствие символу из файла, символ - буква, цифра,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru