VBStreets конференция

Целият вкус на програмирането!

  • Списък на форумитеVisual basicVisual Basic 1-6
  • Променете размера на шрифта
  • ЧЗВ
  • вход

Въпрос за събитията. Как да се справим със заекването на формата.

Въпрос за събитията. Как да се справим със заекването на формата.

Не, тя прави нещо съвсем различно. Той просто обработва натрупаните кликвания, клавиши и др.
Системата прехвърля контрола върху себе си, когато пожелае.

Като цяло решението на проблема е просто да се принудят функциите на DoEvents в тесни места.

Ще покажа парче код с коментари
Код: Изберете всички '*****************************
„това парче не е важно за разбирането
'времето за изпълнение е някъде от 0,05 сек до 3 сек
Частен Sub mnuWriteToDisk_Click ()
ReDim буфери (0)
Извикайте WriteModule (SelectedItemMenuMod) 'SelectedItemMenuMod - променлива с номера на елемента от списъка
'записва сервизния информационен модул, за да завинтва палачинки
ReDim буфери (0)
Крайна под
'******************************

'******************************
'но това нещо записва всички маркирани
'ако не направете DoEvents
'след това, докато всичко работи, тогава формулярите за кандидатстване висят
'и нищо не се случва с бутона STOP
Частен Sub mnuWriteAllToDisk_Click ()

Dim XX като байт
Затъмнете NextMod като етикет

ProgressBarMod.Min = 0
ProgressBarMod.Max = 100

bStopMOD = Невярно
За XX = 1 До (lw1.ListItems.Count)
lw1.ListItems.Item (XX) .Selected = True
SelectedItemMenuMod = XX
Ако lw1.ListItems.Item (XX) .Checked = False След това преминете към NextMod

ReDim буфери (0)
Call CallModule (SelectedItemMenuMod)
ReDim буфери (0)

DoEvents 'ТОВА Е ТОВА.
преди да проверите бутона STOP
'можете да прободете няколко парчета в процедурата
'където бих искал да закача нещо (обратното на "вися")

Ако bStopMOD = Вярно тогава
ProgressBarMod.Value = 0
ProgressBarMod.DrawProgressBar
Излезте от под
Край ако

NextMod: ProgressBarMod.Value = Int ((XX * 100) \ (lw1.ListItems.Count))
ProgressBarMod.DrawProgressBar
lw1.Опресняване

Следващата XX
ProgressBarMod.Value = 0
ProgressBarMod.DrawProgressBar
Крайна под
'******************************

Wildwhiteash В горния пример Doevents се появява след процедурата. Това имам предвид, че опашката все пак трябва да достигне DoEvents и тя ще дойде след процедурата "Call CallModule (SelectedItemMenuMod)" .
Ето кода, който използвам:
Код: Изберете всички strComputer = "."
Задайте objWMIService = GetObject (_
"winmgmts: \\" & strComputer & "\ root \ cimv2")
Задайте colPings = objWMIService.ExecQuery _
("Изберете * От Win32_PingStatus където Address = '192.168.1.1'")

За всеки objStatus в сравнения
Ако IsNull (objStatus.StatusCode) _
или objStatus.StatusCode <> 0 Тогава
WScript.Echo "Компютърът не отговори."
Иначе
Wscript.Echo "Компютърът отговори."
Край ако
Следващия

Така че, за мен, докато IsNull (objStatus.StatusCode) не работи, програмата вече не се изпълнява и отнема няколко секунди, за да изчака, за което програмата е "затворена". Добавянето на DoEvents в реда отгоре или отдолу не решава проблема, защото чакаме изпълнението на горната функция.
Ако греша, поправете.

Antonariy Бихте ли обяснили как да направите това.

Какво друго съм пробвал:
Разгледахме пример за многопоточност от горната връзка. Опитах се да пусна кода си в друга нишка - неуспешно. Изглежда, че фоновата нишка няма достъп до WMI.

Реших да потърся готов контрол за работа с icmp. Оказа се, че има такива. Например тук е OstroSoft.com. С този контрол е дори по-лесно, отколкото с WMI. Но все пак формата „замръзва“, когато откачате компютри, но като цяло тя стана много по-добра. Ще се спра на този вариант. Въпреки че в свободното си време ще се опитам да организирам pinging във фонова нишка.

Основното тук не е това.
Основно - в първото изречение, тип проект - Active EXE.
Това е единственият легален начин за създаване на многонишкова програма във VB.

Пишете обект, който ще има метод Ping и събитие PingComplete. От вашата основна програма вие създавате този обект, извиквате метода Ping и той ще повиши събитието PingComplete при завършване. Освен това този метод ще работи в отделна нишка и няма да постави на пауза програмата ви.

ако самият пинг не се изпълнява в метод. Важно е.

Като цяло, тук е празното.

2vv
„Параметърът не е задължителен“ означава на първо място, че трябва да се отървете от русифицирания VB6.

На второ място, че параметър, който не е незадължителен, по някаква причина не сте задали.

На работа има версия на английски. Така че дори класът не може да го отвори. Написва "Грешка при автоматизацията" на реда:
Задайте lPing = Нов PingExe.PingClass

Вкъщи няма такава грешка. Връзката към класа в проекта беше регистрирана.
Може би има някои сложни настройки в VB ?

Проблемът, описан в поста по-горе, е решен. Проектът беше на работния плот. Английският VB6 не може да работи с руски папки.

Връщайки се към темата, как да зададете параметър, който не е незадължителен.
Декларирам клас:
Затъмнявайте Събития lPing като PingExe.PingClass

класът има събитие PingComplete, което получава стойност след преминаване на процедурата Ping (това е метод на клас). Така че mPing_PingComplete - "Аргументът не е задължителен". Не разбирам какъв е уловът.

Той знае как. Това не беше проблемът.

На линията mPing_PingComplete такава грешка не може да възникне. Може да се случи, ако събитието е описано с параметри, но вие го генерирате без параметри, като това:
Код: Изберете всички публични събития PingComplete (успех като булево, изчакване като единично)

За да е по-лесно, ще ви покажа какво съм написал
Тази процедура на основната форма анкетира клетките на таблицата и присвоява статус:
Код: Изберете всички частни подпрограми ()
Dim i
За i = 1 до 15 Стъпка 1
IP_ADR = CStr (GrdTable.TextMatrix (i, 1))
Ако Len (IP_ADR) <> 0 Тогава
lPing.Ping IP_ADR
Ако lPing_PingComplete <> 0 Тогава
Налично = "ОФЛАЙН"
GrdTable.Row = i
GrdTable.Col = 3
GrdTable.CellBackColor = vbRed
Иначе
Налично = "ОНЛАЙН"
GrdTable.Row = i
GrdTable.Col = 3
GrdTable.CellBackColor = vbGreen
Край ако
GrdTable.TextMatrix (i, 3) = Наличен
„WinsockInit
'GrdTable.TextMatrix (i, 2) = HostByAddress (IP_ADR)
Иначе
Край ако
Следващия
Крайна под

Това е модулът на класа:
Код: Изберете явно всички опции
Затъмнява с таймери за събития като таймер
Затъмнете формата като форма1
Затъмнява IpAdr като низ
Dim objPing
Затъмнете objStatus
Затъмнете рет толкова дълго
Публично събитие PingComplete (Статусът е дълъг)

Публичен подпинг (IP_ADR като низ)
IpAdr = IP_ADR
Задайте objPing = GetObject ("winmgmts:"). ExecQuery ("изберете * от Win32_PingStatus където адрес = '" & IpAdr & "'")
За всеки objStatus в objPing
Ако IsNull (objStatus.StatusCode) Или objStatus.StatusCode <> 0 Тогава
Ret = 1
Иначе
Ret = 0
Край ако
Следващия
Timer.Enabled = Вярно
Крайна под
Частен подклас_Инициализиране ()
Задайте формуляр = нов формуляр1
Заредете формуляр
Задайте таймер = форма
Крайна под
Частен подклас_Terminate ()
Задайте таймер = Нищо
Разтоварване на формуляра
Задайте формуляр = Нищо
Крайна под
Частен таймер на таймера ()
Timer.Enabled = Невярно
RaiseEvent PingComplete (Ret)
Крайна под

Като цяло lPing_PingComplete не дава нищо. Вярно, все още не съм разбрал напълно как да работя със събития.

2vv, ти си писал глупости, без да разбереш какво ти е било посъветвано.
lPing_PingComplete не е променлива.
Вашият код трябва да бъде такъв: lPing.Ping IP_ADR
Всичко.
Останалото е записано в събитието lPing_PingComplete.

Освен това начинът, по който го направихте, няма да ви помогне да се отървете от спирачките.
Самият пинг трябва да бъде в рутинния таймер, а не в метода на пинг. В метода Ping задавате вътрешни променливи и стартирате таймера.