Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 458727
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T22:42:02+00:00 2026-05-12T22:42:02+00:00

Preface: I know this is an unusual/improper way to do this. I can do

  • 0

Preface: I know this is an unusual/improper way to do this. I can do this with a “real” ShowDialog(), background worker/thread, and so on. I’m not looking for help doing it that way; I am trying to do specifically what I describe here, even if it is ugly. If this is impossible for X reason, please let me know though.


I have created a fancy progress dialog for some of our long running operations. I need to have this dialog shown on a new thread while having processing continue on the calling (UI in most cases) thread.

This has 3 real requirements:

  • Prevent user interaction with the calling form (similar to ShowDialog(this))
  • Keep the progress dialog above the main window (it can fall behind now)
  • Allow the main thread to continue processing

What I have looks like this (and works just fine so far, as far as running goes, except for those issues above):

Using ... ShowNewProgressDialogOnNewThread() ...
      Logic
      UpdateProgress() //static
      Logic
      UpdateProgress() //static, uses Invoke() to call dialog
      ...
End Using  // destroys the form, etc

I have tried a few ways to do this:

  • ShowDialog() on BackgroundWorker / Thread
  • Action.BeginInvoke() which calls a function
  • ProgressForm.BeginInvoke(… method that calls ShowDialog… )
  • Wrapping main form in a class that implements IWin32Window so it can be called cross-threaded and passed to ShowDialog() – this one failed somewhere later one, but at least causes ShowDialog() to not barf immediately.

Any clues or wisdom on how to make this work?

Solution (For Now)

  • The call to EnableWindow is what did what I was looking for.
  • I do not experience any crashes at all
  • Changed to use ManualResetEvent
  • I set TopMost, because I couldn’t always guarantee the form would end up on top otherwise. Perhaps there is a better way.
  • My progress form is like a splash screen (no sizing, no toolbar, etc), perhaps that accounts for the lack of crashes (mentioned in answer)
  • Here is another thread on the EnableWindow topic (didn’t reference for this fix, tho)
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T22:42:02+00:00Added an answer on May 12, 2026 at 10:42 pm

    Getting the progress window consistently displayed on top of the (dead) form is the difficult requirement. This is normally handled by using the Form.Show(owner) overload. It causes trouble in your case, WF isn’t going to appreciate the owner form belonging to another thread. That can be worked around by P/Invoking SetWindowLong() to set the owner.

    But now a new problem emerges, the progress window goes belly-up as soon as it tries to send a message to its owner. Somewhat surprisingly, this problem kinda disappears when you use Invoke() instead of BeginInvoke() to update progress. Kinda, you can still trip the problem by moving the mouse over the border of the disabled owner. Realistically, you’ll have to use TopMost to nail down the Z-order. More realistically, Windows just doesn’t support what you are trying to do. You know the real fix, it is at the top of your question.

    Here’s some code to experiment with. It assumes you progress form is called 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
    

    Sample usage:

      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
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

BACKGROUND: I should preface this by saying I'm not trying to get someone to
To preface this, the most I know about text encoding I learned from Joel
Preface : I'm honestly not sure if this should be on StackOverflow, SuperUser or
To preface this, I know there are discussions on this in various places. Half
Preface: This is the first real swing program I have done. I have a
Let me preface this by saying this is not an actual situation of mine
Let me preface this by saying that I know the ContactCenter sample is just
Let me preface this (Because I know I'll get this eventually in the responses)
Preface: I'm not sure what resources are. I need this form (which is working
I will preface this question with the disclaimer that I know there are many

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.