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

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

06.02.2013, 15:43. Показов 11185. Ответов 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
33411 / 21521 / 8236
Регистрация: 22.10.2011
Сообщений: 36,922
Записей в блоге: 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
33411 / 21521 / 8236
Регистрация: 22.10.2011
Сообщений: 36,922
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru