Luke DeStevens

Hey all,

I have an instance of an application running and I have it open a status display window. I want the application to continue running, but I don't want the user to be able to make it the active window before the status display window closes. You know, I want to set it up so that if the user tries to click off of the status display window, the application window blinks, but stays greyed out and inactive.

I'm told that Dialog.DoModal() halts the application until the Dialog finishes (such as for FolderBrowserDialog, which returns a file path upon completion), so I don't want to do that. I basically want the Status Window to lock the application from access when the process starts and unlock the application as part of the Status Window's destruction call.

What do you think

Thanks in advance.

Luke




Re: Visual C++ General Lock an application while another window is open

Sdi

Modal dialogs don't "halt" anything. They disable their owner, but the owner window continues to receive and process messages. Did you try a modal dialog to see if it does what you want





Re: Visual C++ General Lock an application while another window is open

Simple Samples

If a modal dialog does not do what you need to do, then explain what it is that you need to happen that does not happen.






Re: Visual C++ General Lock an application while another window is open

Sahir Shah

Luke DeStevens wrote:

I have an instance of an application running and I have it open a status display window. I want the application to continue running, but I don't want the user to be able to make it the active window before the status display window closes. You know, I want to set it up so that if the user tries to click off of the status display window, the application window blinks, but stays greyed out and inactive.

You can call SetWindowPos from OnActivate and change it's Z order i.e. turn on a flag in the application dialog when the status window is shown. When the user tries to activate the application window, if this flag is on, SetWindowPos should be called to change the application window's Z order. Pass the the status windows handle as the second parameter to place the application window just below the status window if you want it shown that way.

Luke DeStevens wrote:

I'm told that Dialog.DoModal() halts the application until the Dialog finishes (such as for FolderBrowserDialog, which returns a file path upon completion), so I don't want to do that. I basically want the Status Window to lock the application from access when the process starts and unlock the application as part of the Status Window's destruction call.

Yes you are right. Dialog.DoModal() is a blocking call that does not return until the modal dialog is closed.





Re: Visual C++ General Lock an application while another window is open

Luke DeStevens

Question: If I start a new thread just before running Dialog.DoModal(), does the separate thread keep running

My code looks like this:

Code Block

// start the Export thread

HANDLE exportThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadFunc, (LPVOID)this, 0, 0);

// start the CUPDialog (should be a separate thread)

CUPDialog progress((HWND)swHWnd, TrackProgress, &m_progressData);

progress.DoModal();

// terminate Export thread

TerminateThread(exportThread, IDCANCEL);

Basically, the started thread begins exporting, updating m_progressData as it completes portions of the operation. The CUPDialog is the progress window that updates while watching m_progressData. It's implemented using threads also. Once the code hits progress.DoModal(), does the export thread continue to run

Yeah, I've been trying to get a progress dialog working for the past week and a half. It's rather depressing. This one (CUPDialog) compiles fine and I think I have my brain wrapped around how it should work, but it doesn't show up at all. I'm working on writing my own, but working with the threads and the pointers to functions has been driving me nuts. If the thread above does in fact continue to run, then I think I can make it work. At worst, I think I have enough knowledge to write my own progress window.






Re: Visual C++ General Lock an application while another window is open

Simple Samples

Read the TerminateThread documentation; do not use TerminateThread as part of your normal design.

I don't know what an export thread is.

Are you using MFC Are you using CWinThread






Re: Visual C++ General Lock an application while another window is open

Andreas Masur

Luke DeStevens wrote:
What do you think

Luke,

I actually do not see the need for any thread necessarely (and not for displaying a modal dialog anyway). From your description, you want to prevent the user from working with your main dialog while your application does some work in the background. Therefore, you want to display a status dialog (hopefully) displaying the progress of your work in the background.

In general this is pretty good design (from a GUI standpoint) and also pretty straight-forward. Is there any special need why the background work needs to be done in the main dialog class If not (and I somewhat assume this), simply do you background processing inside the status dialog class. Depending on what your work is, you may actually use a worker thread for doing the processing to leave the main thread processing the message queue. This will also allow you to update the status dialog accordingly.





Re: Visual C++ General Lock an application while another window is open

Luke DeStevens

Sam,

Whoa, thanks for the pointer on TerminateThread. Guess I'm going to have to do a bit more reading on threading then. That's just how one of the other controls I had downloaded had done it, but looking at that code, it appears implemented as a last-ditch effort inside of several nested if statements.

There is no specific export thread. That's basically what my background process thread will be doing: exporting a 3D structure created in SolidWorks (a CAD program) in FBX format. The overall solution is a plugin for this program.

No, I'm not using MFC. The plugin is entirely ATL. I am simply using CreateThread to start the thread. I don't know how a thread goes about ending on its own or how I should do it. We talked about threads once in my Software Engineering course back in college, but it was a short exercise and I never fully grasped the execution. Seeing TerminateThread used in an example, I thought it would work. I see how bad that is.

As far as MFC goes, I had actually downloaded what looked like a really good progress window class from CodeProject, but got a bunch of compile and linking errors. It took several days, but the final outcome was that it used MFC and apparently you can't combine ATL and MFC as both define _DllMain.

http://www.codeproject.com/miscctrl/progresswnd.asp

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=2251985&SiteID=1

I'm actually modeling my own CProgressWindow after that, but using ATL and WTL.






Re: Visual C++ General Lock an application while another window is open

Luke DeStevens

Andreas,

I'd like to avoid threading (since a thread would slow down processing noticeably), but my analysis seems to indicate the need. The way I see it, I have two tasks that I need to perform simultaneously:

Task 1: The SolidWorks addin (the background program) performs the export procedure using recursive calls

Task 2: The ProgressWindow tracks the progress, updates, and displays the progress as a percentage bar

I figure there are several models I could use to approach this problem.

Model 1: CProgressWindow is a modeless display. (single thread)

1. Exporter creates a CProgressWindow

2. Exporter continues the operation

3. Exporter updates CProgressWindow (information and display)

4. Exporter completes the operation

5. Exporter destroys the CProgressWindow

6. Exporter finsihes, returns control to SolidWorks

Notes: CProgressWindow must be globally viewable. Since exportation involves layered recursive calls (AddChildren calls AddComponent which calls AddChildren for each child of that node), how do I handle if Cancel is pressed

Model 2: CProgressWindow executes the operation (single thread)

1. Exporter creates a CProgressWindow, passes it a pointer to itself, and waits for return

2. CProgressWindow runs Exporter->AddChildren(component)

3. Exporter->AddChildren updates CProgressWindow

4. Exporter->AddChildren finishes

5. CProgressWindow closes

6. Exporter finishes, returns control to SolidWorks

Notes: AddChildren must be public now instead of private. component must be visible (unless I want to play the parameter relay game, which I don't). May involve pointers to functions and generic parameters (LPVOID), especially if I want to make CProgressWindow generic and useable in other programs without alteration.

Model 3: Model 2 with 2 threads; CProgressWindow and Exporter->AddChildren

1. Exporter creates a CProgressWindow as a separate thread

2. Exporter continues operation WHILE CProgressWindow watches tracking variables

3. Exporter modifies tracking variables as operation progresses (in self or in CProgressWindow )

4. Exporter completes operation WHILE CProgressWindow shows complete.

5. CProgressWindow gets closed (user clicks OK, thread gets killed)

6. Exporter continues, returns control to SolidWorks (may allow to happen before step 5)

Notes: processing time consumed by CProgressWindow's while(>100%) watch/update loop. CProgressWindow must be globally viewable. Requires a static function for the thread to start, which requires whatever functions that static function calls to be public; thus AddChildren must be public.

Model 4: Model 2 with threading

1. Exporter creates CProgressWindow, passes it a pointer to itself, and waits for return

2. CProgressWindow invokes Exporter->Export(component) as a separate thread (using CreateThread )

3. Export thread runs WHILE CProgressWindow continues to update.

4. Export thread finishes and terminates

5. CProgressWindow displays complete, waits for user to click OK.

6. CProgressWindow closes and returns control to Exporter

7. Exporter finishes and returns control to SolidWorks.

Note: Most of the same notes as 2 and 3 above.

For most of these models, it seems that CProgressWindow must be globally viewable in order for the method containing Save(part) to update it. I figure the best way to do this is to create a global pointer to a CProgressWindow, then point it to the CProgressWindow on instantiation. I would have to unpoint it before exiting the initializing method, of course.

But yeah, dealing with threads and pointers to static functions seems necessary. I'd love to hear your approach, because if I can ditch threading and static functions, I'm all ears. Threading seems to waste processing time and static functions seem unsecure. I also hate the idea of making AddChildren and component public.

Thanks in advance.

Luke






Re: Visual C++ General Lock an application while another window is open

Viorel.

Luke DeStevens wrote:

[...] I basically want the Status Window to lock the application from access when the process starts and unlock the application as part of the Status Window's destruction call.

What do you think

Maybe the EnableWindow function can help you When your status window is created, use EnableWindow(FALSE) for your main window. When it is destroyed, call EnableWindow(TRUE).





Re: Visual C++ General Lock an application while another window is open

Luke DeStevens

Viorel, thanks. Since the window is an application within which my addin is running, I don't know if I have explicit access to that window. I do have a CComPtr to it, though. I'll play around with it. Again, thanks.