Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/56: Рейтинг темы: голосов - 56, средняя оценка - 4.68
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585

Сброс фокуса с элементов управления

06.02.2013, 15:43. Показов 11005. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется форма с событием FormMouseWheelDown/Up. На форме есть панель, на панели очень много различных элементов управления, например TrackBar. Когда мышкой изменяешь значение TrackBar, на нем остается фокус. Хотелось бы после того, как пользователь перенесет указатель мыши с панели на "клиентскую" область формы, чтобы фокус сросился (переключился на форму). Иначе одновременно с FormMouseWheelDown формы срабатывает и изменение TrackBar'а.

SetFocus() в обработчике MouseMove формы не помогает.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.02.2013, 15:43
Ответы с готовыми решениями:

Выполнение в фоновом потоке - перехват фокуса элементов управления
День добрый Я разрабатываю приложение, которое управляет другим, "большим" приложением через com interop. На одном из этапов программы,...

Событие потери фокуса элементом управления
То есть есть текстбокс пользователь в него вписал что то и щелкнул на другой элемент управления, после этого надо проверить что вписал...

Удержание фокуса на TextBox при клике на другие элементы управления
Как сделать так, что бы не снимался фокус с текстбокса, когда нажимаешь на кнопку?

23
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
06.02.2013, 16:39
Цитата Сообщение от znseday Посмотреть сообщение
SetFocus() в обработчике MouseMove формы не помогает.
А в обработчике OnExit?

Цитата Сообщение от znseday Посмотреть сообщение
после того, как пользователь перенесет указатель мыши с панели на "клиентскую" область формы
Можно с флагом замутить:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
flag = true; // Взводим флаг если мышь навелась на панель
}
//------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
if( (X>Panel1->Width+Panel1->Left  || X<Panel1->Left || // Снаружи формы
     Y>Panel1->Height+Panel1->Top  || Y<Panel1->Top)
     && flag)
   {
   flag = false; // Сбросить флаг
   Edit1->SetFocus(); // Произвести необходимое действие
   }
}
Можно еще по изменению имени смотреть:
C++
1
((TPanel*)Sender)->Name
Если Panel1, то взвести флаг.
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
06.02.2013, 18:38  [ТС]
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Edit1->SetFocus(); // Произвести необходимое действие
Мне, наоборот, нужно сбросить фокус со всех элементов управления.
Когда я говорил про SetFocus(), я имел ввиду MainForm->SetFocus().
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
07.02.2013, 11:45
Цитата Сообщение от znseday Посмотреть сообщение
Мне, наоборот, нужно сбросить фокус со всех элементов управления.
Когда я говорил про SetFocus(), я имел ввиду MainForm->SetFocus().
Я понял. Борланд сам по умолчанию передает фокус с формы на любой компонент, если тот умеет его принимать.
Для проверки на тыканье по форме вызываем значение фокуса:
C++
1
2
3
4
5
void __fastcall TForm1::FormClick(TObject *Sender)
{
Form1->Focused();
ShowMessage((int)Form1->Focused());
}
Если на форме есть только Lable, то значение будет 1, так как он не имеет свойства фокуса, а вот если бросим на форму хотя бы один Edit, то уже 0.

Решений мне в данный момент видится три:
1) Использовать какой-либо контейнер-фон (такую же панель) и по выходу с требуемой панели передавать фокус не самой форме, а этой панели-подложке.
2) Скрыть какой-либо компонент из видимости пользователя: убрать за пределы формы, закрыть другим компонентом сверху, сделать visible=false и так далее, и на него переводить фокус.
3) Обратиться в раздел форума по WinApi, - там находятся крутые ребята.
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
07.02.2013, 20:02  [ТС]
Цитата Сообщение от SatanaXIII Посмотреть сообщение
2) Скрыть какой-либо компонент из видимости пользователя: убрать за пределы формы, закрыть другим компонентом сверху, сделать visible=false и так далее, и на него переводить фокус.
Пробовал - вылетает стандартная ошибка "Нельзя передать фокус невидимому компоненту", ну.., что-то в этом роде, дословно не помню.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
07.02.2013, 22:36
Цитата Сообщение от znseday Посмотреть сообщение
Пробовал - вылетает стандартная ошибка "Нельзя передать фокус невидимому компоненту", ну.., что-то в этом роде, дословно не помню.
да просто кладете на форму чекбокс, ставите ему Top=-20 и ему передаете фокус (и больше вы его не увидите...)
1
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
07.02.2013, 23:58  [ТС]
На уровне пользователя это, конечно, решит проблему, но хотелось бы чего-нибудь более человеческого (программистского).
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
08.02.2013, 00:10
... и если вдруг это "более программистское" обернется текстом в 10-15 строк (и более, что вероятно), - все равно?
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
08.02.2013, 11:51  [ТС]
Да, я хочу рассмотреть все варианты
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
08.02.2013, 12:19
Единственное, что я придумал это
C++
1
2
3
4
Panel1->SetFocus();
Panel1->Enabled = false;
Panel1->Enabled = true;
ShowMessage((int)Form1->Focused()); // Выдаст единичку
Но это какая-то хрень.
Так что я бы тоже с удовольствием поглядел бы на возможные решения.
0
return (true);
 Аватар для mimicria
1977 / 1112 / 221
Регистрация: 19.04.2011
Сообщений: 2,346
08.02.2013, 12:34
Лучший ответ Сообщение было отмечено как решение

Решение

C++
1
Form1->DefocusControl(TrackBar1, 0);
3
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
08.02.2013, 12:34
В чем, собственно, проблема? Как я ее понял, нужно при "уходе" с трекбара сразу убирать с него фокус, чтоб колесико мыши по нему не ездило. Так это можно прописать в onMouseMove на панель или форму (перенос фокуса), или в обработчике колеса добавить анализ на позицию мыши (в области трекбара или нет).
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
08.02.2013, 14:48  [ТС]
Цитата Сообщение от nick42 Посмотреть сообщение
Так это можно прописать в onMouseMove на панель или форму (перенос фокуса), или в обработчике колеса добавить анализ на позицию мыши (в области трекбара или нет).
А что в обработчик события писать то?


Цитата Сообщение от mimicria Посмотреть сообщение
Form1->DefocusControl(TrackBar1, 0);
Контролов ооочень много, не хотелось бы каждый раз перебирать все. Цикл по кнтролам организовать тоже не очень просто. Контролы физически расположены на различных окнах, часть из которых "причалена" на панель.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
08.02.2013, 15:12
Цитата Сообщение от znseday Посмотреть сообщение
Контролов ооочень много
C++
1
2
this->SetFocus();
this->DefocusControl(this, 0);
1
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
08.02.2013, 15:23
Цитата Сообщение от znseday Посмотреть сообщение
А что в обработчик события писать то?
В параметрах у обработчика FormMouseWheelDown( (или Up) есть MousePos, - вот и анализировать MousePos.x , MousePos.y: попадают ли на трэкбар. Только учесть, что MousePos - позиция на экране, а не на форме. (Писать пример лень, - там много длинных слов суммировать надо).
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
08.02.2013, 16:01
Для ленивых:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift,
      int WheelDelta, TPoint &MousePos, bool &Handled)
{
if(MousePos.x > Form1->Left + Form1->TrackBar1->Left &&
   MousePos.x < Form1->Left + Form1->TrackBar1->Left + Form1->TrackBar1->Width &&
   MousePos.y > Form1->Top  + Form1->TrackBar1->Top &&
   MousePos.y < Form1->Top  + Form1->TrackBar1->Top + Form1->TrackBar1->Height)
   {
   this->TrackBar1->SetFocus();
   Edit2->Text = "Inside";
   }
 else
   {
   this->DefocusControl(this, 0);
   Edit2->Text = "Outside";
   }
}
Только тормознуто работает - по событию MouseWheel сначала изменит положение ползунка, а потом только уберет фокус.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
08.02.2013, 17:58
Нужно использовать Handled. Кроме того нужно учитывать ширину бордюра и если этот бар на панели, то и ее положение.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33192 / 21488 / 8233
Регистрация: 22.10.2011
Сообщений: 36,870
Записей в блоге: 12
08.02.2013, 18:20
Цитата Сообщение от znseday Посмотреть сообщение
Контролов ооочень много, не хотелось бы каждый раз перебирать все. Цикл по кнтролам организовать тоже не очень просто.
А не надо перебирать все контролы - тебе достаточно подменить WndProc своего трекбара, чтобы по CM_MOUSELEAVE делать ему DefocusControl, и всего делов...
0
18 / 18 / 7
Регистрация: 20.03.2012
Сообщений: 585
08.02.2013, 20:08  [ТС]
Цитата Сообщение от UI Посмотреть сообщение
тебе достаточно подменить WndProc своего трекбара, чтобы по CM_MOUSELEAVE делать ему DefocusControl, и всего делов...
Вот я и говорю: делать это придется для всех трэкбаров, которых ооочень много. (я не прав?)

Добавлено через 21 минуту
Всем спасибо за наводки. Получилось. Итого:

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
void __fastcall TMainForm::FormMouseEnter(TObject *Sender)
{
    this->SetFocus();
    this->DefocusControl(this, 0);
    flagMouseInClient = true;
}
 
void __fastcall TMainForm::FormMouseLeave(TObject *Sender)
{
    flagMouseInClient = false;
}
 
void __fastcall TMainForm::FormMouseWheelUp(TObject *Sender, TShiftState Shift, TPoint &MousePos,
          bool &Handled)
{
    if (!flagMouseInClient) return;
 
       // далее - всякий программный код
}
 
void __fastcall TMainForm::FormMouseWheelDown(TObject *Sender, TShiftState Shift, TPoint &MousePos,
          bool &Handled)
{
    if (!flagMouseInClient) return;
 
    // далее - всякий программный код
}
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33192 / 21488 / 8233
Регистрация: 22.10.2011
Сообщений: 36,870
Записей в блоге: 12
08.02.2013, 21:41
Цитата Сообщение от znseday Посмотреть сообщение
делать это придется для всех трэкбаров, которых ооочень много
По мне - так было бы проще написать один-единственный Interceptor-класс, который переопределил бы свою WndProc, и неважно, сколько там у тебя этих трэкбаров, все будут работать одинаково...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef TB_HPP
#define TB_HPP
 
namespace MyNamespace
{
    class TTrackBar : public Comctrls::TTrackBar
    {
    public:
        inline __fastcall virtual TTrackBar(Classes::TComponent* AOwner) : Comctrls::TTrackBar(AOwner) {}
    protected:
        virtual void __fastcall WndProc(Winapi::Messages::TMessage &Message)
        {
            if(Message.Msg == CM_MOUSELEAVE) GetParentForm(this, True)->DefocusControl(this, 0);
            Comctrls::TTrackBar::WndProc(Message);
        }
    };
};
#define TTrackBar MyNamespace::TTrackBar
 
#endif
, и подключить этот hpp-файл ко всем своим формам, на которых есть TTrackBar-ы до описания класса формы...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
08.02.2013, 21:41
Помогаю со студенческими работами здесь

Нужен элемент управления со сворачиваемым списком, похожий на панель элементов управления в VS
Нужен элемент управления со сворачиваемым списком, как панель элементов в VS, желательно с возможностью установки чекбокса есть набор...

Уход фокуса с одного Edit-а и получение фокуса другим
Доброе время суток, есть пара Edit, можно ли как то отловить момент когда человек закончил набирать текст в одном и начал это делать в...

Как сделать чтобы панели элементов управления находились "элементы управления" нужного формата?
По умолчанию формат &quot;элемента управления&quot; &quot;Поле&quot;: высота - 0,556 см; ширина - 3,0 см; шрифт - 11. Как сделать чтобы по...

Сброс элементов в листе
Здравствуйте, проблема в следующем: //Есть глобальный лист List&lt;string&gt; items = new List&lt;string&gt;(); //1 метод static void...

Работа с ToggleButton, удержание фокуса на вкладке, блокировка элементов на ленте
Здравствуйте! Делаю БД, появилось несколько вопросов по работе с пользовательской лентой. Первое, прописываю toggleButton в XML : ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru