Сложная проблема - установка множества одних и тех же процессов на разные панели
Всем привет,
У меня есть 10 панелей (panel1, panel3, panel5, panel7... panel19) эти панели расположены на форме в точно таком же месте, точно такого же размера (поверх друг друга, все изначально задано как "Visible = False ()")
Все эти панели используются для размещения точно такого же процесса (как и ребенок).
Я создал своего рода нетрадиционный элемент управления вкладками, с помощью которого пользователь может "добавить" еще один из этих дочерних элементов (во-первых, сделав соответствующую панель видимой, во-вторых, переместив ее вперед, в-третьих, запустив процесс, В-четвертых, установив процесс как дочерний) Панель "добавлено", содержащая дочерний элемент, может быть просмотрена в раскрывающемся меню toolstripmenuitem (позже я добавлю способ навигации по панелям).
Вот код, который добавляет пункты меню, относящиеся к каждой панели, которая становится видимой при нажатии на кнопку:
Код:
Dim count As Integer = 1 Private Sub AddProccess_Click(sender As Object, e As EventArgs) Handles AddProcessBtn.Click If count <= 10 Then ' This limits the amount of items that can be added to 10 Dim item As New ToolStripMenuItem item.Name = "ChildWindow" & count & "ToolStripMenuItem" item.Text = "ChildWindow " & count count += 1 ChildrenViewerToolStripMenuItem.DropDownItems.Add(item) ' This relates the the drop-down items that are added when the button is clicked Dim value1 As Integer = ChildrenViewerToolStripMenuItem.DropDownItems.Count ChildrenViewerToolStripMenuItem.Text = "ChildWindow (" & value1 & ")" ' This makes it so that if the item is added to the ViewerMenu, and there is 'x' of the item, then this will happen If count = 1 Then Panel1.Visible = True If count = 1 Then SetChildTimer1.Start() If count = 1 Then Panel1.BringToFront() If count = 1 Then Process.Start("FilePath of the process (hereby know as "^")") If count = 2 Then Panel3.Visible = True If count = 2 Then SetChildTimer2.Start() If count = 2 Then Panel3.BringToFront() If count = 2 Then Process.Start("^") If count = 3 Then Panel5.Visible = True If count = 3 Then SetChildTimer3.Start() If count = 3 Then Panel5.BringToFront() If count = 3 Then Process.Start("^") If count = 4 Then Panel7.Visible = True If count = 4 Then SetChildTimer4.Start() If count = 4 Then Panel7.BringToFront() If count = 4 Then Process.Start("^") If count = 5 Then Panel9.Visible = True If count = 5 Then SetChildTimer5.Start() If count = 5 Then Panel9.BringToFront() If count = 5 Then Process.Start("^") If count = 6 Then Panel11.Visible = True If count = 6 Then SetChildTimer6.Start() If count = 6 Then Panel11.BringToFront() If count = 6 Then Process.Start("^") If count = 7 Then Panel13.Visible = True If count = 7 Then SetChildTimer7.Start() If count = 7 Then Panel13.BringToFront() If count = 7 Then Process.Start("^") If count = 8 Then Panel15.Visible = True If count = 8 Then SetChildTimer8.Start() If count = 8 Then Panel15.BringToFront() If count = 8 Then Process.Start("^") If count = 9 Then Panel17.Visible = True If count = 9 Then SetChildTimer9.Start() If count = 9 Then Panel17.BringToFront() If count = 9 Then Process.Start("^") If count = 10 Then Panel19.Visible = True If count = 10 Then SetChildTimer10.Start() If count = 10 Then Panel19.BringToFront() If count = 10 Then Process.Start("^") End If End Sub
Итак, что же делают "SetChildTimer_"? Ну, приложение, которое я открываю, на самом деле довольно сложное в том смысле, что оно работает от двух процессов, первый из которых-это splashscreen (который, как вы увидите в коде ниже), я решил скрыть. Второй процесс, который "делает свое дело" после завершения splashscreen, - это главное окно, которое я хочу, которое я развернул, как только оно найдено (таймеры установлены на интервал 10 мс для поиска этих процессов и установки их как дочерних).
Вот код для установки дочерних окон:
Код:
' #1
Private Sub Win1SetChildLoader(sender As Object, e As EventArgs) Handles SetChildTimer1.Tick Dim LoaderProcess As Process = Process.GetProcessesByName("splashscreen").FirstOrDefault If LoaderProcess IsNot Nothing Then SetParent(LoaderProcess.MainWindowHandle, Panel1.Handle) ShowWindow(LoaderProcess.MainWindowHandle, SW_HIDE) End If End Sub Private p As Process = Nothing Private Sub WinSetChildMain(sender As Object, e As EventArgs) Handles SetChildTimer1.Tick p = Process.GetProcessesByName("mainwindow").FirstOrDefault Dim r As New RECT If p IsNot Nothing Then GetWindowRect(p.MainWindowHandle, r) SetParent(p.MainWindowHandle, Panel1.Handle) SendMessage(p.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0) End If End Sub ' #2 Private Sub Win2SetChildLoader(sender As Object, e As EventArgs) Handles SetChildTimer2.Tick Dim LoaderProcess2 As Process = Process.GetProcessesByName("splashscreen").FirstOrDefault If LoaderProcess2 IsNot Nothing Then SetParent(LoaderProcess2.MainWindowHandle, Panel3.Handle) ShowWindow(LoaderProcess2.MainWindowHandle, SW_HIDE) End If End Sub Private p2 As Process = Nothing Private Sub Win2SetChildMain(sender As Object, e As EventArgs) Handles SetChildTimer2.Tick p2 = Process.GetProcessesByName("mainwindow").FirstOrDefault Dim r2 As New RECT If p2 IsNot Nothing Then GetWindowRect(p2.MainWindowHandle, r2) SetParent(p2.MainWindowHandle, Panel3.Handle) SendMessage(p2.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0) End If End Sub ' ^^ 8 more of these to make 10, I just haven't witten them yet ' Correct focusing - This ensures that the form remains in focus when interacting with the child, I think Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = WM_ACTIVATE Then SendMessageW(Me.Handle, WM_NCACTIVATE, 1, 0) If p IsNot Nothing AndAlso Not p.HasExited Then SendMessageW(p.MainWindowHandle, WM_NCACTIVATE, 1, 0) End If m.Result = CType(0, IntPtr) Return End If MyBase.WndProc(m) End Sub
Так в чем же моя проблема?
Ну а первое окно, которое я "добавляю" (делая счет 1, а значит активируя SetChildTimer1), работает отлично - оно запускается, таймер обнаруживает процесс "splashscreen" и затем устанавливает его как скрытый дочерний, как только запускается "mainwindow", который устанавливается как "развернутый" в панели.
Однако, когда дело доходит до открытия другого процесса (не забывайте, что это те же самые процессы), он не добавляется как дочерний (в то время как другой (граф 1) счастливо устанавливается как дочерний).
Я решил, что проблема заключается в том, что субподрядчик SetChildTimer запутывается в том, какой процесс добавить, поскольку другой уже запущен, и пытается добавить этот процесс. Но я не уверен.
Итак, как я могу сделать так, чтобы (я думаю) суб-таймер, который устанавливает процессы как дочерние, мог сказать, пытается ли он установить процесс как дочерний, который уже установлен как дочерний на предыдущей панели?
Я надеюсь, что это достаточно подробно, я всегда волнуюсь, что это не так. :P
Большое спасибо за вашу помощь, серьезно, спасибо вам миллион раз!
hellboyf2
Что я уже пробовал:
Все, что было в моих силах, задавая этот вопрос, было действительно моим последним средством.
Ralf Meier
Вы много писали, а иногда (по-моему) и чересчур много ...
Что я предполагаю (но я не уверен) : для каждого нового процесса, который вы хотите запустить, вы должны создать новый экземпляр своего процесса, а затем запустить его. Но я не нашел кодовую часть, где вы это делаете. Также отсутствует метод самого процесса, чтобы увидеть, что происходит внутри. Вся эта информация будет полезна ...
[no name]
Я не совсем понимаю, о чем вы говорите. В настоящее время я открываю процесс, нажав на кнопку "Добавить" новую панель. "Count" относится к числу элементов меню, которые находятся в раскрывающемся списке. Если счетчик равен "x", то процесс начинается, и панель становится видимой на форме и выводится на переднюю часть стопки панелей; см. код ниже:
Если count = 1, то процесс.Start("[вот путь к файлу для файла]") - Итак, если после нажатия на кнопку "Добавить" есть только 1 menustrip подпункты, то процесс запускается и, как вы можете видеть, таймеры, которые относятся к первому обрезанному коду, запускаются, и эти таймеры ищут, есть ли процесс или нет.
Я довольно новичок в этом языке и поэтому не совсем понимаю, что вы подразумеваете под "Для каждого нового процесса, который вы хотите запустить, вы должны создать новый экземпляр вашего процесса, а затем запустить его". Я знаю, что печатал много, но я просто чувствовал, что должен компенсировать неряшливый код.
Большое спасибо за вашу помощь, с уважением,
hbf2
[no name]
Еще один момент: как я могу ссылаться на дочерний процесс (после того, как он был установлен как дочерний для панели) с помощью оператора If?
Возможно, решение J может работать так:
Если [процесс установлен в панели], то
[установите вновь созданный процесс в другой соответствующей панели]
Конец, Если
Чтобы запретить пользователю открывать какие-либо новые процессы с помощью кнопки "Добавить", кнопка "Добавить" может быть включена = False.
Я просто понятия не имею, как программно определить, был ли этот процесс уже установлен как дочерний. Как я уже сказал, я пытался, но у меня это не очень хорошо получается, и мне нужна помощь.
Спасибо :)
Ralf Meier
Чтобы предотвратить недопонимание :
- Процесс обычно представляет собой что-то (возможно, EXE) вне вашего приложения.
- Задача-это метод как часть вашего приложения.
Вы действительно имеете в виду процесс ?.. или вы хотите иметь несколько задач ?
Если вы хотите иметь независимую функциональность, вы должны создать для каждой функциональности собственный экземпляр.
Я приведу вам пример с элементами управления в вашей форме :
- на вашей форме есть несколько кнопок. Каждая кнопка происходит от элемента управления с именем Button, но каждая кнопка является собственным независимым экземпляром этого исходного элемента управления. Чтобы они могли работать независимо, иметь разные свойства и так далее.
То же самое вы имеете с задачами или процессами ...
Ты меня понял ?
Ralf Meier
Внутри вашего 1-го фрагмента кода Вы всегда запускаете один и тот же процесс (именованный процесс). 2-й старт не имеет никакого значения.
Но... где вы приписываете что-то этому процессу-объекту ? В вашем фрагменте кода #2 у вас есть разные процессы (p1 ...), но где вы их используете (или запускаете)?
[no name]
(Что касается запроса на уточнение процесса и задачи) - я имею в виду процесс - внешнее приложение, которое я пытаюсь установить в качестве ребенка в своем собственном приложении (я понимаю, что есть некоторые проблемы, которые могут возникнуть из-за этого, однако с таким приложением, которое мои панели будут воспитывать, эти проблемы, вероятно, не имеют отношения ко мне.
Просто чтобы уточнить, несколько из этих же процессов будут установлены как дочерние внутри разных панелей (panel3, panel5, panel7 [вплоть до] panel19)
Я не слишком уверен, почему я объявил разные процессы по - разному (p1, p2 и т. д.) - Во время программирования этого, я, вероятно, думал, что это может вызвать ошибку, если я буду использовать "p" повсюду. Но все они относятся к одному и тому же процессу, который пользователь может открыть, нажав кнопку "Добавить".
Мне очень жаль, что я так плохо объясняю свою проблему, надеюсь, вы понимаете.
Просто чтобы прояснить, проблема заключается в том, что после установки первого окна процесса в качестве дочернего на моей панели, инициируя код снова, чтобы открыть и установить то же самое имя процесса в другую, отдельную панель, другую панель (чей связанный таймер все еще тикает, чтобы установить процесс внутри другой панели, а не панель, которая уже имеет окно, встроенное в качестве дочернего). Таким образом, по сути, мне просто нужно программно сказать таймеру остановиться, если процесс ("Mainwindow") был встроен, таким образом, встраивание того же процесса в другую панель не будет вмешиваться.
Я написал это в спешке и, вероятно, не связно, так что я понимаю, если вы все еще не понимаете. Сейчас я возвращаюсь домой, так что смогу объяснить более четко/связать скриншоты.
Серьезно, большое спасибо за ваше терпение. :-)
Ralf Meier
ОК... Давайте остановимся на самом главном.
Возможно, у нас есть проблема понимания ... но на это может быть несколько причин. Одна из них может заключаться в том, что мой английский не так хорош, как кажется ... :(
Итак ... еще раз - что вы хотите сделать ?
Вы запускаете "Блокнот" как процесс в панели 1 и запускаете "Блокнот" как процесс в панели 2. Что произойдет, если вы что-то отредактируете ? Должны ли обе панели иметь одинаковое содержание ... или по-другому ? Если я думаю, что вы хотите иметь другой, поэтому вам нужно создать 2-й независимый экземпляр Notepad (или MainWindow, или ...). Но на самом деле у вас есть только один процесс и один экземпляр процесса.