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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Обработка событий от меню в потоке?  (Прочитано 4464 раз)
0 Пользователей и 1 Гость смотрят эту тему.
baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


« : 10-12-2010 06:33 » 

Коллеги, возникла очередная проблема, может кто-то подскажет путь..
Есть Windows-приложение на C#, оно запускает несколько thread'ов.
Каждый thread использует обект типа System.Windows.Forms.NotifyIcon для отображения своей иконки в трее..
По клику на иконке должно показываться контекстное меню.
Если вкратце и по существу, то класс, который запускет поток, инициализирует иконку/меню так:
Код: (Text)
class Class1
{
    private System.Windows.Forms.NotifyIcon notifyIcon;
    private MenuItem menuItemExitWatcher;
   
    private void menuItemExitWatcher_Click(object sender, EventArgs e)
    {
        // just write log record
    }

    private void initMenu()
    {
        notifyIcon = new NotifyIcon();
        notifyIcon.ContextMenu = new ContextMenu();
        menuItemExitWatcher = new MenuItem();
        notifyIcon.Icon = new System.Drawing.Icon("c:\\path_to_icon\\icon.ico");
        notifyIcon.Visible = true;
        notifyIcon.ContextMenu.MenuItems.AddRange(new MenuItem[] { menuItemExitWatcher });
        menuItemExitWatcher.Index = notifyIcon.ContextMenu.MenuItems.Count - 1; // Last
        menuItemExitWatcher.Text = "E&xit";
        menuItemExitWatcher.Enabled = true;
        menuItemExitWatcher.Click += new System.EventHandler(menuItemExitWatcher_Click);
    }
}

После этого класс запускает новый поток с функцией Execute внутри себя.
Иконка появляется.
Проблема в следующем: при клике на иконку ничего не происходит. Попытка повесить на нее обработчик события Click ничего не дает - событие не приходит вообще.
Если делать без потоков, то проблема немного другая, но помогает понять суть первой..
Если поставить перед void Main() модификатор [STAThread], и вызывать инициализацию иконки/меню в контексте основного потока (но все еще в объекте класса - не статическом), то при правом клике по иконке меню появляется. Однако, при клике на пункт меню опять же событие не приходит. При еще одном клике на любой пункт меню приходит первое событие.
Как я понял из курения интернета - проблема связана с разными потоками и обработкой событий. То есть события то ли приходят не туда, то ли ждут в очереди, которая не так обрабатывается.. Что-то похожее есть, вроде,  тут..
Хочется иметь несколько потоков, управляющих своими иконками.
Кто подскажет решение или путь в котором двигаться?
Жаль
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
кот глобальный и пушистый
Глобальный модератор

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


« Ответ #1 : 10-12-2010 06:40 » 

baldr, а spy++ что показывает - куда сообщения от иконки приходят ? Подозреваю, что в окно рабстола, либо в главное окно приложения
так как иконке нужен хендл окна, куда слать сообщения. А некий хендл есть, иначе система бы просто убрала иконку автоматически
Записан

baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


« Ответ #2 : 10-12-2010 06:52 » 

Проблема в том, что у приложения нет окна Жаль
Spy++ вот что-то такое показывает (логировал сообщения для Notification Area)...
Код:
<02022> 00120046 S WM_MOUSEACTIVATE hwndTopLevel:0007004A nHittest:HTCLIENT uMsg:WM_RBUTTONDOWN
<02023> 00120046 R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<02024> 00120046 S WM_SETCURSOR hwnd:00120046 nHittest:HTCLIENT wMouseMsg:WM_RBUTTONDOWN
<02025> 00120046 R WM_SETCURSOR fHaltProcessing:False
<02026> 00120046 P WM_RBUTTONDOWN fwKeys:MK_RBUTTON xPos:8 yPos:11
<02027> 00120046 S TB_HITTEST pptHitTest:016BFD18
<02028> 00120046 R TB_HITTEST iIndex:0
<02029> 00120046 S TB_GETBUTTONINFOW iID:0 lptbbi:016BFCDC
<02030> 00120046 R TB_GETBUTTONINFOW iIndex:False
<02031> 00120046 S TB_GETBUTTONINFOW iID:0 lptbbi:016BFCCC
<02032> 00120046 R TB_GETBUTTONINFOW iIndex:False
<02033> 00120046 S WM_NOTIFY idCtrl:18 pnmh:016BF9E8
<02034> 00120046 R WM_NOTIFY
<02035> 00120046 S TB_BUTTONCOUNT
<02036> 00120046 R TB_BUTTONCOUNT nCount:23
хз кому оно шлет.. Жаль
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
кот глобальный и пушистый
Глобальный модератор

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


« Ответ #3 : 10-12-2010 07:14 » 

baldr, создай ему окно - приёмник. Можно одно для всех иконок, наверное, даже. Но лучше - в процедуре потока своё для каждой иконки

Добавлено через 1 минуту и 34 секунды:
то есть, иконку выводить в трей от имени этого окошка. Для теста появи окно и наведи на него прицел спая - будут ли приходить сообщения, когда по иконке водишь

Добавлено через 1 минуту и 2 секунды:
хз кому оно шлет.. Жаль
это не оно шлёт, это сообщения к окну Notification Area Улыбаюсь
« Последнее редактирование: 10-12-2010 07:17 от Алексей1153 » Записан

baldr
Команда клуба

ru
Offline Offline
Пол: Мужской
Дорогие россияне


« Ответ #4 : 10-12-2010 07:23 » 

Алексей1153++, а нафига мне окна? Я, конечно, понимаю, что можно, наверное, их скрыть.. Но если приложению не нужны окна - зачем я буду их таскать за собой..
Мне кажется, должен быть еще способ...
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
Алексей++
кот глобальный и пушистый
Глобальный модератор

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


« Ответ #5 : 10-12-2010 07:39 » 

baldr, тогда так: команду, выбранную в меню, не обязательно получать через сообщение. Например, АПИшное TrackPopUpMenu с флагом TPM_RETURNCMD вернёт выбранную команду. Можно тут же обработать. Как в дотнете - не знаю
Записан

Dimka
Деятель
Команда клуба

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

« Ответ #6 : 10-12-2010 10:53 » 

Цитата: baldr
После этого класс запускает новый поток с функцией Execute внутри себя.
Тут хотелось бы поподробнее. Какой поток обрабатывает события операционной системы? Где находится основной цикл приложения?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Джон
просто
Администратор

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

« Ответ #7 : 10-12-2010 11:51 » 

Ага, тестовый проектик в прицепе не помешал бы.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines