Страница: 1 |
Страница: 1 |
Вопрос: Создание/удаление MDI по таймеру
Добавлено: 12.09.06 14:10
Автор вопроса: AlV
Задача в следующем: с некоторым временным интервалом проверяются условия (запрос из БД). В зависимости от полученного значения нужно создать МДИокно или закрыть ранее созданное.
Все работает в диалоговом режиме (по кнопке, меню), но при вызове процедуры создания новой формы по таймеру выдается ошибка типа "элементы управления одного потока не могуть быть родительскими для элементов управления другого потока".
Подскажите вариант решения.
Ответы
Всего ответов: 9
Номер ответа: 1
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #1
Добавлено: 12.09.06 21:05
показуй свою процеДУРУ ))))))))
Номер ответа: 2
Автор ответа:
AlV
Вопросов: 1
Ответов: 4
Профиль | | #2
Добавлено: 13.09.06 05:42
Это не одна процедура, а большой кусок кода. Смысла выкладывать нет. Вопрос в принципе о работе таймера и МДИ.
Я понял так, что при создании объекта "Таймер" создается отдельный поток, в котором возможны вызовы паблик функций из другого потока. Если по таймеру создавать обычное окно (не дочернее) то оно создается, а при попытке сделать его дочерним выдается приведенная выше ошибка. Получается, что новое окно открывается в потоке таймера, а не основной процедуры. Т.о. мой вопрос можно сформулировать следующим образом - как из одного потока создать нужное окно в другом потоке?
Номер ответа: 3
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #3
Добавлено: 13.09.06 10:09
При создании объекта "Таймер" твое окно всего лишь будет получать сообщения WM_TIMER. Никаких потоков не создается.
Ответ тут один - криво создаешь окно.
Номер ответа: 4
Автор ответа:
Viper
ICQ: 249094859
Вопросов: 0
Ответов: 310
Профиль | | #4
Добавлено: 13.09.06 10:48
Интересно а как в VB (не в NET) можно узреть ошибку "элементы управления одного потока не могуть быть родительскими для элементов управления другого потока"? Какие в VB потоки? И таки хочется узреть таки код!
Номер ответа: 5
Автор ответа:
AlV
Вопросов: 1
Ответов: 4
Профиль | | #5
Добавлено: 13.09.06 11:57
Выставляю куски кода.
' ОСНОВНОЙ КЛАСС
Public Class Form1
Inherits System.Windows.Forms.Form
...
Private myTimer As Threading.Timer
...
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
 im myT As New Threading.TimerCallback(AddressOf myTimeEvent2)
 im aTimer As New System.Threading.Timer(myT, Me, 0, 1000)
Me.myTimer = aTimer
End Sub
...
Shared Sub myTimeEvent2(ByVal source As Object)
 im _obj As Form1 = CType(source, Form1)
...
' ОПРЕДЕЛЕННЫЕ ПРОВЕРКИ И ПРОЧЕЕ
_obj.Refresh_all()
End Sub
Public Sub Refresh_all()
' обновить все формы
 im _form2 As Form6
 im _form As Form2
...
n = Me.MdiChildren.Length()
If n > 0 Then
For i = 0 To n - 1
If Microsoft.VisualBasic.Left(Me.MdiChildren(i).Name, 6) = "Schema" Then
_form2 = CType(Me.MdiChildren(i), Form6)
_form2.refr()
Else
_form = CType(Me.MdiChildren(i), Form2)
_form.redraw()
End If
End If
Next
End If
End Sub
' ДАЛЕЕ ЕСТЬ МЕНЮ
Public Sub myClick_Menu(ByVal sender As System.Object, ByVal e As System.EventArgs)
 im _obj As myMenu
_obj = CType(sender, myMenu)
Me.MainProc(_obj.Name_MainMenu)
End Sub
Public Sub MainProc(ByVal NameItem As String)
' активизация MDIWindow
...
Select Case Microsoft.VisualBasic.Trim(NameItem)
Case "Schema"
 im nw As New Form6
nw.MdiParent = Me
nw.Name = "Schema"
nw.Show()
Case "...."
 im new_wind As New Form2
new_wind.MdiParent = Me
new_wind.Show()
...
End Select
End Sub
...
End Class
' ДОЧЕРНЕЕ ОКНО 1 ТИПА
Public Class Form2
Inherits System.Windows.Forms.Form
Public Sub redraw()
' нарисовать график
...
End Sub
...
End Class
' ДОЧЕРНЕЕ ОКНО 2 ТИПА
Public Class Form6
Inherits System.Windows.Forms.Form
Public Sub refr()
' статистика с сервера БД
...
_zn = ds.Tables(0).Rows(0).ItemArray(0)
If _zn> ... Then
Me.ParentForm.MainProc("..."
' т.е. из дочернего окна 2 типа вызываем создание дочернего окна 1 типа
End If
End Sub
...
End Class
По кнопкам и при вызове из меню все отрабатывает корректно. Ошибка возникает при обновлении по таймеру. Конкретно на строке
new_wind.MdiParent = Me
Номер ответа: 6
Автор ответа:
Fever
Вопросов: 60
Ответов: 808
Профиль | | #6
Добавлено: 13.09.06 16:50
A)
Dim nw As New Form6
set nw =new Form6
nw.MdiParent = Me
B)вызывай процедуру с менюхой по таймеру.
Номер ответа: 7
Автор ответа:
AlV
Вопросов: 1
Ответов: 4
Профиль | | #7
Добавлено: 14.09.06 09:51
Не катит. Та же самая ошибка.
Номер ответа: 8
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #8
Добавлено: 14.09.06 11:32
Мля, ну надо сразу говорить что ты про .NET.
Тебе собственный код ни о чем не говорит?
Private myTimer As Threading.Timer
Попробуй System.Windows.Forms.Timer, System.Timers.Timer или SetTimer. Смотря что тебе подойдет.
Номер ответа: 9
Автор ответа:
AlV
Вопросов: 1
Ответов: 4
Профиль | | #9
Добавлено: 14.09.06 13:34
Сорри, новичок на форуме. А он называется VBNET, т.ч. думал, что по умолчанию считается .НЕТ
Поиграюсь.
А вот что уже нарыл.
Навтыкал в тесте проги в разных местах такие операторы:
Console.WriteLine("Timer=" & AppDomain.GetCurrentThreadId)
Console.WriteLine(" Form2=" & AppDomain.GetCurrentThreadId)
Console.WriteLine(" Form1=" & AppDomain.GetCurrentThreadId)
Рузультат исполнения
Load Form1 = 2756 - загрузка основной формы
Timer=496 - таймер
Timer=496
Timer=496
...
Timer=496
Form2=2756 - создали дочернее окно
Timer=496
Timer=496
...
Timer=496
Form1=496 - обновление по таймеру
Form2=496
Timer=496
Timer=496
...
Timer=496
Form2=2756 - создали второе дочернее окно
Timer=496
Timer=496
...
Т.Е. явно присутствует 2 потока!
Обновление дочек происходит из потока Таймера, а создание из основного потока.
Поэтому и при создании новой дочки под Таймером выдается ошибка.