Если Вы обеспокоены нападениями на XSS, кодирование Ваших выходных строк к HTML является решением. Если Вы не забываете кодировать каждый выходной символ к формату HTML, нет никакого способа выполнить успешное нападение XSS.
Читать дальше пользовательские данные Очистки: Как и где сделать это
Получение окна прогресса, постоянно отображаемого поверх (мертвой) формы, является сложным требованием. Обычно это выполняется с помощью перегрузки Form.Show (владелец). В вашем случае это вызывает проблемы, WF не оценит принадлежность формы владельца другому потоку. Это можно обойти, вызвав P / вызов SetWindowLong () для установки владельца.
Но теперь возникает новая проблема: окно прогресса срывается вверх, как только оно пытается отправить сообщение своему владельцу. Как ни странно, эта проблема исчезает, когда вы используете Invoke () вместо BeginInvoke () для обновления хода выполнения. Типа, вы все еще можете решить проблему, наведя указатель мыши на границу отключенного владельца. На самом деле вам придется использовать TopMost для определения Z-порядка. Более реалистично, Windows просто не t поддерживать то, что вы пытаетесь сделать. Вы знаете настоящее исправление, оно находится в начале вашего вопроса.
Вот код для экспериментов. Предполагается, что ваша прогрессивная форма называется dlgProgress:
Imports System.Threading
Public Class ShowProgress
Implements IDisposable
Private Delegate Sub UpdateProgressDelegate(ByVal pct As Integer)
Private mOwnerHandle As IntPtr
Private mOwnerRect As Rectangle
Private mProgress As dlgProgress
Private mInterlock As ManualResetEvent
Public Sub New(ByVal owner As Form)
Debug.Assert(owner.Created)
mOwnerHandle = owner.Handle
mOwnerRect = owner.Bounds
mInterlock = New ManualResetEvent(False)
Dim t As Thread = New Thread(AddressOf dlgStart)
t.SetApartmentState(ApartmentState.STA)
t.Start()
mInterlock.WaitOne()
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
mProgress.BeginInvoke(New MethodInvoker(AddressOf dlgClose))
End Sub
Public Sub UpdateProgress(ByVal pct As Integer)
mProgress.Invoke(New UpdateProgressDelegate(AddressOf dlgUpdate), pct)
End Sub
Private Sub dlgStart()
mProgress = New dlgProgress
mProgress.StartPosition = FormStartPosition.Manual
mProgress.ShowInTaskbar = False
AddHandler mProgress.Load, AddressOf dlgLoad
AddHandler mProgress.FormClosing, AddressOf dlgClosing
EnableWindow(mOwnerHandle, False)
SetWindowLong(mProgress.Handle, -8, mOwnerHandle)
Application.Run(mProgress)
End Sub
Private Sub dlgLoad(ByVal sender As Object, ByVal e As EventArgs)
mProgress.Location = New Point( _
mOwnerRect.Left + (mOwnerRect.Width - mProgress.Width) \ 2, _
mOwnerRect.Top + (mOwnerRect.Height - mProgress.Height) \ 2)
mInterlock.Set()
End Sub
Private Sub dlgUpdate(ByVal pct As Integer)
mProgress.ProgressBar1.Value = pct
End Sub
Private Sub dlgClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
EnableWindow(mOwnerHandle, True)
End Sub
Private Sub dlgClose()
mProgress.Close()
mProgress = Nothing
End Sub
'--- P/Invoke
Public Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As IntPtr) As IntPtr
If IntPtr.Size = 4 Then
Return SetWindowLongPtr32(hWnd, nIndex, dwNewLong)
Else
Return SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
End If
End Function
Private Declare Function EnableWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal enabled As Boolean) As Boolean
Private Declare Function SetWindowLongPtr32 Lib "user32.dll" Alias "SetWindowLongW" (ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As IntPtr) As IntPtr
Private Declare Function SetWindowLongPtr64 Lib "user32.dll" Alias "SetWindowLongW" (ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal dwNewLong As IntPtr) As IntPtr
End Class
Пример использования:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Using dlg As New ShowProgress(Me)
For ix As Integer = 1 To 100
dlg.UpdateProgress(ix)
System.Threading.Thread.Sleep(50)
Next
End Using
End Sub
Я знаю, что это немного грязно, но разве вы не можете просто выполнить работу в диалоговом окне ??
Я имею в виду что-то вроде
Dialog.MyShowDialog(callback);
и выполняйте всю работу в обратном вызове, а также обновление пользовательского интерфейса.
Таким образом, вы сохраните поведение ShowDialog, позволяя вызывать другой код.
Некоторое время назад я написал сообщение в блоге по этой теме (речь идет о формах всплеска, но идея та же). Код написан на C #, но я постараюсь преобразовать его, разместив здесь (скоро ...).