powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / А как грамотно организовать "очередь сообщений"
26 сообщений из 26, показаны все 2 страниц
А как грамотно организовать "очередь сообщений"
    #38295575
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача вытекает из рассуждений в этой теме:
Хочу понять логику "уведомлений в трей".
AntonariyДобавлять в коллекцию новые сообщения и брать из нее первое сообщение (удаляя) и не показывать следующее, пока юзер не кликнет тултип.

Т.е.
произошло событие - добавили сообщение в "конец очереди"
если в очереди есть сообщение - взяли первое - показали в трей как Notification
пользователь закрыл Notification, или оно вышло по таймауту, или приложение его удалило -удалили сообщение
пользователь щелкнул по Notification - выполнили команду в соответствии с типом и параметрами тек. сообщения -удалили сообщение.
Удалив сообщение, смотрим не остался ли кто в очереди, если да, то берем первое и т.д.

Ну, модификации - показать сообщение без очереди если у него какой-то приоритет, выкинуть его (не обязательно первое), если оно уже не актуально и т.д.

Я с коллекциями по жизни не очень то сталкивался. Даже не знаю.

Мне приходит в голову массив плавающей длины, с данным паровозом вроде как привык работать:


Код: vbnet
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.
Private Type MyMessage
   m_type as MessageType 'enum?
   m_parameter as string
   ...
End Type

Private Type AppMessages
  m_MyMessages() As MyMessage
End Type

Public app_messages As AppMessages

'Инициализация

ReDim app_messages.m_MyMessages(0 To 0) 'очистка-0-й элемент не используется

'Добавление
    Dim new_message As MyMessage
    with new_message
      .m_type =...
      ...
    endif
     ReDim Preserve app_messages.m_MyMessages(0 To UBound(app_messages.m_MyMessages)) + 1)
     app_messages.m_MyMessages(UBound(app_messages.m_MyMessages)) =new_message
    'сюда же сразу вызов в трей если нет текущего активного сообщения
    If UBound(app_messages.m_MyMessages)=2 then 'кроме добавленного сообщения ничего нет 
        'показать в трей app_messages.m_MyMessages(1)
    end if

'Удаление (пусть первого элемента)
   if UBound(app_messages.m_MyMessages)>2 then '0-не используется, 1-удаляемое, 2-следующее и т.д.
     'сдвиг на единицу к началу
     for i=1 to UBound(app_messages.m_MyMessages)-1
       app_messages.m_MyMessages(i)=app_messages.m_MyMessages(i+1)
     next
   endif
   'удаляем последнее (сдвинуто вперед) 
   ReDim Preserve app_messages.m_MyMessages(0 To UBound(app_messages.m_MyMessages)) - 1)
    'сюда же сразу вызов в трей если чего-то осталось
    If UBound(app_messages.m_MyMessages)>1 then 'есть сообщение хотя бы одно 
       'показать в трей app_messages.m_MyMessages(1)
    end if



Ну, типа набросал алгоритм.

Сразу вопрос.
Код: vbnet
1.
ReDim app_messages.m_MyMessages(0 To 0) 'очистка-0-й элемент не используется


А как сделать ReDim чтоб НИ ОДНОГО элемента не осталось.
Без "технического" нулевого элемента массива.

Сойдет так?
Или все таки заморачиваться с коллекцией?

Еще вижу варианты: скрытый ListView, таблица в БД (хотя это уже думаю излишки).
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38295624
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Заморочки как раз с массивом, с коллекцией их нет.

Код: vbnet
1.
2.
3.
4.
5.
6.
Dim col As New Collection

col.Add msg 'добавляется в конец очереди
Set msg = col(1) 'первый элемент очереди
col.Remove 1 'удаление первого элемента, остальные автоматически сдвигаются
Set col = New Collection 'обнуление

Но в коллекции нельзя хранить переменные пользовательского типа, только примитивные или объекты.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38295675
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

Я не уверен что смогу обойтись без пользовательского типа при описании сообщения.
Чем тогда мой вариант с массивом плох? и где там могут быть заморочки?
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38295696
ВМоисеев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Дмитрий77, сегодня, 09:36 [14426369]
>Чем тогда мой вариант с массивом плох ...

Рассмотрите вариант "кольцевого" массива. Два указателя (индекса) - на чтение и на запись.
Запись - по указателю и его увеличение с проверкой на границу массива
Чтение - проверка на равенство с указателем чтения, если нет, читаем и увеличиваем с проверкой на границу массива
Что делать с переполнением, решайте сами - затирать последний или пропускать текущий

С уважением, Владимир.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38295711
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Я не уверен что смогу обойтись без пользовательского типа при описании сообщения.Вариант первый - сериализация в стринг.
Вариант второй - создание своего класса "Сообщение и информация о нём".
Дмитрий77Чем тогда мой вариант с массивом плох? и где там могут быть заморочки?А чем он хорош? ну кроме того, что это ЛИЧНО ВЫ не хотите изучить работу с коллекцией (что, кстати, совсем несложно).

Дмитрий77А как сделать ReDim чтоб НИ ОДНОГО элемента не осталось.
Без "технического" нулевого элемента массива.
Erase
Однако НАСТОЯТЕЛЬНО рекомендую этого не делать - определение, в каком из трёх состояний находится массив, будет затруднительным, и если определить состояние "удалён, не определён" нетрудно, то различить варианты "определён, но не инициализирован" и "определён и инициализирован", не задействуя обработчик ошибок, трудновато.
Держите в массиве нулевой элемент, но не используйте его для хранения данных. Так снимутся все вопросы с зачисткой. Впрочем, нулевой элемент не будет мотаться зря - как раз его удобно использовать в качестве промежуточного буфера при обмене местами двух элементов массива (сортировка, сжатие).
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38295945
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Antonariy,

Я не уверен что смогу обойтись без пользовательского типа при описании сообщения.И не обязательно. Можно свойству класса присвоить пользовательский тип.
Дмитрий77Чем тогда мой вариант с массивом плох?Исключительно количеством кода.
Дмитрий77и где там могут быть заморочки?У тебя их не будет. Они могут быть у того, кто будет поддерживать этот код после тебя. 4 строчки с коллекцией понятней, чем полтора десятка с массивом, согласись.
ВМоисеевРассмотрите вариант "кольцевого" массива.А это еще более заморочено. И не нужно.

Коллекция по сути является очередью и не требует никаких экстра плясок с бубном в этом смысле.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38295961
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyКоллекция по сути является очередью
Эммм... а нет ли ссылочки на описание НАЧИНКИ коллекции? как она организована, внутренняя её механика?

По её поведению у меня всегда было подозрение, что унутре это всего лишь динамический массив указателей на элементы... но нигде не смог найти ответы на некоторые достаточно важные вопросы - например, может ли добавление/удаление элементов поменять взаимное расположение ранее существовавших элементов при обработке в итераторе For Each? гарантировано ли сохранение индекса элемента, если все изменения выполняются на элементах с бОльшими индексами? и т.п...
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296008
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaAntonariyКоллекция по сути является очередью
Эммм... а нет ли ссылочки на описание НАЧИНКИ коллекции? как она организована, внутренняя её механика?На bbs.vbstreets.ru спроси, тамошний модер крутой спец по потрохам VB.

AkinaПо её поведению у меня всегда было подозрение, что унутре это всего лишь динамический массив указателей на элементы... Не исключено. Я же имел ввиду поведение с точки зрения сферической очереди: добавляешь в конец, удаляешь из начала, индексы элементов сдвигаются.

Akinaможет ли добавление/удаление элементов поменять взаимное расположение ранее существовавших элементов при обработке в итераторе For Each?Если ты добавляешь/удаляешь внутри For Each, то очередная итерация приведет к ошибке "коллекция была изменена".
Присвоить элементу коллекции новое значение нельзя. Можно изменить само значение.

Akinaгарантировано ли сохранение индекса элемента, если все изменения выполняются на элементах с бОльшими индексами? и т.п...Да. Обход коллекции с ее изменением нужно начинать с конца.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296029
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вообще то коллекции не сортированы. так что я бы не стал забиваться на сохранение индекса (при удалении внутренних элементов). но на planetsourcecode были примеры сортировок для коллекций на основе синтетических ключей. если нужны возможности быстрой и гарантированной сортировки , то лучше ищите готовые классы по работе с массивами (по ключевым словам: пузырьковая сортировка и тп)
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296034
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Konst_Oneвообще то коллекции не сортированы. так что я бы не стал забиваться на сохранение индексаТо есть если я удаляю из середины, то элементы в начале могут перемешаться или вообще ускакать в конец? Не говори ерунды. Нет ни одной причины, по которой это может произойти. Я всегда полагался на неизменность индексов и ни разу они меня не подвели.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296043
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нет, конечно никуда они не перескочат, я про другое: если нужна сквозная непрерывная нумерация (без разрывов), то индекс коллекции для этих целей не подходит
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296051
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему? Индекс сквозной и непрерывный. Другое дело, что он не сохраняется за элементом, но это естественно и очевидно.
Порядок элементов не меняется, это самое главное.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296073
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
согласен
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296113
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Никакое количество экспериментов не может служить доказательством теории."
AntonariyТо есть если я удаляю из середины, то элементы в начале могут перемешаться или вообще ускакать в конец? Не говори ерунды. Нет ни одной причины, по которой это может произойти. Я всегда полагался на неизменность индексов и ни разу они меня не подвели.
AntonariyПорядок элементов не меняется, это самое главное.
Вот именно об этом моменте я и говорю. Гарантируется ли неизменность порядка элементов? Меня интересует - есть ли гарантия, что такое поведение абсолютно? или наоборот - что теоретически есть условия, при которых эта регулярно наблюдаемая зависимость поломается?
А на то, чтобы не менять коллекцию в итераторе, у меня мозгов вполне достаточно...
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296176
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Никакое количество экспериментов не может быть гарантией"

Нет ничего абсолютного, кроме самого абсолюта. Кто-то вломится в память процесса и натопчет там, или ты сам решишь поиграться с памятью и налажаешь — вот тебе и теоретические условия. Означает ли это, что нужно защищать процесс от несанкционированного доступа?

Не доводи до абсурда.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296237
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То, что вмешательство нештатными средствами может изменить заложенные алгоритмы работы - очевидно.
Однако выяснение точного штатного алгоритма работы для любых штатных операций и любых входных параметров в допустимом диапазоне я лично абсурдом не считаю... все, в том числе и я, на текущий момент полагают, что добавление либо удаление либо изменение элемента с номером индекса "зю" не вызывает изменения индексов элементов, номера которых менее этого "зю". Однако нет ни доказательства, что так будет всегда, ни условий, когда будет иначе. Между "истина" и "пока вроде истина" - есть некоторая разница. ИМХО.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296258
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ок. Не можешь без гарантий — не пользуйся. Не доверяешь никакому опыту — не пользуйся.

Мне все равно.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296561
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaПо её поведению у меня всегда было подозрение, что унутре это всего лишь динамический массив указателей на элементы... но нигде не смог найти ответы на некоторые достаточно важные вопросы - например, может ли добавление/удаление элементов поменять взаимное расположение ранее существовавших элементов при обработке в итераторе For Each? гарантировано ли сохранение индекса элемента, если все изменения выполняются на элементах с бОльшими индексами? и т.п...На внутреннюю организацию ограничений не накладывается (и по гамбургскому счёту, даже программист, её пишущий, может не знать всех деталей реализации, так как может пользоваться библиотечными классами вроде ассоциативных массивов (скажем, std::map), которые могут меняться от библиотеки к библиотеке и от версии к версии). Для поддержки For Each коллекция должна поддерживать интерфейс IEnumVariant . Но описание этого интерфейса не накладывает существенных ограничений на реализацию метода IEnumVariant::Next() , не понятно из описания, влияет ли на enumeration sequence вставка/удаление элемента. Более того, в описании метода Reset() есть такие слова:IEnumVARIANT::Reset methodThere is no guarantee that exactly the same set of variants will be enumerated the second time as was enumerated the first time. Although an exact duplicate is desirable, the outcome depends on the collection being enumerated. You may find that it is impractical for some collections to maintain this condition (for example, an enumeration of the files in a directory).Из чего напрашивается вывод, что Next() может вести себя как пожелает программист, реализующий коллекцию.

В качестве примера реализации Microsoft в описании IEnumVariant ссылается на пример Lines Sample . Не вдавался в подробности, но с виду safe array VARIANT-ов (что обеспечивает скорость доступа O(1) к элементу по индексу). Возможно, похожая реализация и у VBA.Collection. А, может, и нет.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296569
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyНо в коллекции нельзя хранить переменные пользовательского типа, только примитивные или объекты.В Variant можно засунуть пользовательский тип, если он описан в библиотеке типов (и имеет GUID).
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296581
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктAntonariyНо в коллекции нельзя хранить переменные пользовательского типа, только примитивные или объекты.В Variant можно засунуть пользовательский тип, если он описан в библиотеке типов (и имеет GUID).В справке по VB таких тонкостей нет :)
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296643
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про коллекции я честно перечитал 3 страницы книги (Семейства там это называется), но ничего большего чем написал Antonariy во втором посте из книги не вычитал.

Сдается мне, прочитав все рассуждения, что идея с массивом() + Redim [Preserv] таки проще и понятней будет.
По крайней мере я логически понимаю что я делаю и не доверяю свою логику автоматике начинка которой вызывает такие дебаты.
Тем более эта технология с массивами и вложенными пользовательскими типами у меня "отработана".

AkinaДмитрий77А как сделать ReDim чтоб НИ ОДНОГО элемента не осталось.
Без "технического" нулевого элемента массива.
Erase
Однако НАСТОЯТЕЛЬНО рекомендую этого не делать - определение, в каком из трёх состояний находится массив, будет затруднительным, и если определить состояние "удалён, не определён" нетрудно, то различить варианты "определён, но не инициализирован" и "определён и инициализирован", не задействуя обработчик ошибок, трудновато.
Держите в массиве нулевой элемент, но не используйте его для хранения данных. Так снимутся все вопросы с зачисткой. Впрочем, нулевой элемент не будет мотаться зря - как раз его удобно использовать в качестве промежуточного буфера при обмене местами двух элементов массива (сортировка, сжатие).
Ну, так я и делаю. Всегда могу сделать UBound, и знаю что следующий элемент будет UBound+1, а если UBound=0, то значит массив "пустой". На абсолютно пустой массив UBound ведь ругается.

Да, кстати.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
'Удаление (пусть первого элемента)
   if UBound(app_messages.m_MyMessages)>1 then '0-не используется, 1-удаляемое, 2-следующее и т.д.
     'сдвиг на единицу к началу
     for i=1 to UBound(app_messages.m_MyMessages)-1
       app_messages.m_MyMessages(i)=app_messages.m_MyMessages(i+1)
     next
   endif



app_messages.m_MyMessages(i)=app_messages.m_MyMessages(i+1)
(для пользовательского типа)
не подведет?
Или правильнее:
Код: vbnet
1.
2.
3.
app_messages.m_MyMessages(i).m_type =app_messages.m_MyMessages(i+1).m_type 
app_messages.m_MyMessages(i).m_parameter =app_messages.m_MyMessages(i+1).m_parameter
... 



Вот это наверно излишки (на другой код глядючи)
Код: vbnet
1.
2.
3.
4.
5.
Private Type AppMessages
  m_MyMessages() As MyMessage
End Type

Public app_messages As AppMessages



Достаточно думаю
Код: vbnet
1.
Public AppMessages() As MyMessage
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296667
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyВ справке по VB таких тонкостей нет :)Ну... просто, пытаясь передать UDT в Public-методы, принимающие Variant, ещё на этапе компиляции наталкиваешься на ошибку "Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions" (что-там говорится в справке, уже не помню), и начинаешь думать, как переводить это с иезуитского на человеческий. При переводе выходит, что если UDT объявить в классе с Public instancing-ом, то, вроде, должно получиться. То есть объявляем Public Type в Public-классе в проекте типа, например, ActiveX DLL, и ссылаемся на этот проект в своём. Либо другой вариант, пишем на ODL/IDL свою библиотеку типов, компилируем, ссылаемся.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296684
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати говоря
Akina различить варианты "определён, но не инициализирован" и "определён и инициализирован", не задействуя обработчик ошибок, трудновато
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Dim a() ' As Long, String ...

If (Not a) = -1 Then
    Debug.Print "array as not been initialized"
Else
    Debug.Print "array as been initialized " & UBound(a)
End If

ReDim a(2)

If (Not a) = -1 Then
    Debug.Print "array as not been initialized"
Else
    Debug.Print "array as been initialized " & UBound(a)
End If


Этого тоже не найдешь в документациях, но работает как часы. Впрочем, как и коллекция.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296695
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бенедикт"Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions"Я уже забыл этот текст, а теперь увидел и вспомнил, что типы, объявленные в публичных классах вполне себе добавлялись. Просто в standart exe нельзя сделать публичный класс.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38296745
ВМоисеев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Antonariy, сегодня, 12:00 [14427351]
>А это еще более заморочено. И не нужно.

Может быть Вы и правы, но опыт показывает эффективность подобной конструкции (извините что на C#)
//=========================================================================================

static int изССД = 0; //-- индекс записи
static int ичССД = 0; //-- индекс чтения
const int рцмССД = 1024; //-- размер циклического массива СообщенияСерверуДанных в сообщениях
static byte[][] СообщенияСерверуДанных = new byte[рцмССД][];

//-- Читаем сообщение из циклического массива СообщенияСерверуДанных
//-- выход: byte[] - байтовая строка сообщения
//=================================================
byte[] fЧтениеСообщенияСерверуДанных_lock() {
byte[] xbb;
lock(СообщенияСерверуДанных) {xbb=fЧтениеСообщенияСерверуДанных();}
return xbb;
}
byte[] fЧтениеСообщенияСерверуДанных() {
byte[] xbb = null;
if (изССД != ичССД) { //-- Есть не обработанный запрос
xbb = СообщенияСерверуДанных[ичССД]; СообщенияСерверуДанных[ичССД] = null;
ичССД= (++ичССД) % рцмССД;
}
return xbb;
}
void fЗаписьСообщенияСерверуДанных_lock(byte[] bbb) {
lock (СообщенияСерверуДанных) { fЗаписьСообщенияСерверуДанных(bbb); }
}
void fЗаписьСообщенияСерверуДанных(byte[] bbb) {
СообщенияСерверуДанных[изССД] = bbb; //-- Запись тела сообщения
изССД = (++изССД) % рцмССД;
if (изССД == ичССД) ичССД = (++ичССД) % рцмССД; //-- При необходимости изменим индекс чтения
}

Использую для случая, когда несколько пишут, один читает. Небольшое изменение - и несколько пишут, несколько читают. Могу писать неограниченное количество сообщений (реально остаются последние). Схема допускает оптимизацию, если известна мах. длина обрабатываемых сообщений.

С уважением, Владимир.
...
Рейтинг: 0 / 0
А как грамотно организовать "очередь сообщений"
    #38297220
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyДмитрий77Чем тогда мой вариант с массивом плох?Исключительно количеством кода.
Дмитрий77и где там могут быть заморочки?У тебя их не будет. Они могут быть у того, кто будет поддерживать этот код после тебя. 4 строчки с коллекцией понятней, чем полтора десятка с массивом, согласись.
Ну вроде сделал, не так уж много кода получилось и довольно аккуратно:

Код: vbnet
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.
Public AppMessages() As MyMessage
'========
  'инициализация массива сообщений в трей
  ReDim AppMessages(0 To 0) 'очистка-0-й элемент не используется
'========

Public Sub AddTrayMessageToQueue(new_message As MyMessage)
  'добавление сообщения в конец массива
  ReDim Preserve AppMessages(0 To UBound(AppMessages) + 1)
  AppMessages(UBound(AppMessages)) = new_message
  
  'вывод в трей сообщения, если нет текущего активного
  If UBound(AppMessages) = 1 Then 'кроме добавленного сообщения ничего нет
    'показать в трей AppMessages(1)
    ShowTrayNotification AppMessages(1)
  End If
End Sub

Public Sub RemoveTrayMessageFromQueue(need_action As Boolean)
  'если пользователь кликнул на Notification, то производятся действия согласно сообщению
  'NIN_BALLOONUSERCLICK
  If need_action Then
    With AppMessages(1)
      'выполнение команд
    End With
  End If
  'если оно закрылось по таймауту, было закрыто крестиком либо из кода приложения, то ничего не делаем
  'NIN_BALLOONTIMEOUT либо NIN_BALLOONHIDE
  
  'удаляем сообщение из очереди сдвигом элементов массива на единицу и удалением крайнего элемента
  'сдвиг на единицу если оно не единственное
  If UBound(AppMessages) > 1 Then '0-не используется, 1-удаляемое, 2-следующее и т.д.
    Dim i As Long
    For i = 1 To UBound(AppMessages) - 1
       AppMessages(i) = AppMessages(i + 1)
    Next
  End If
  
  'удаляем старший элемента массива
  ReDim Preserve AppMessages(0 To UBound(AppMessages) - 1)
  
  'если в очереди остались сообщения, то выводим первое из них в трей
  If UBound(AppMessages) > 0 Then
    'показать в трей AppMessages(1)
    ShowTrayNotification AppMessages(1)
  End If
End Sub

'========

    Case WM_MySysTrayNotify 'уведомления Tray -вместо WM_MOUSEMOVE
...
        Case NIN_BALLOONUSERCLICK 'пользователь кликнул по Notification
          RemoveTrayMessageFromQueue True
        Case NIN_BALLOONTIMEOUT 'пользователь закрыл Notification крестиком либо выход по таймауту
          RemoveTrayMessageFromQueue False
        Case NIN_BALLOONHIDE 'от приложения поступила команда убрать Notification
          RemoveTrayMessageFromQueue False



Причем AddTrayMessageToQueue и RemoveTrayMessageFromQueue самодостаточны (полностью управляют очередью, реальным выводом в трей и выполнением команд при кликаньи на Notification) - не нужно никаких чудо-таймеров которые за всем этим следят.
Сейчас код проходит первые испытания в реальном приложении, вроде как полет нормальный.
...
Рейтинг: 0 / 0
26 сообщений из 26, показаны все 2 страниц
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / А как грамотно организовать "очередь сообщений"
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]