Solved

HTASK?

Posted on 1998-06-26
16
655 Views
Last Modified: 2008-02-01
in Microsoft Visual C++ 1.52, in the function "OnActivateApp",  one of the arguments passed into the function is a handle to an HTASK structure.  In the online help provided there is no mention of the HTASK structure.  After doing a small amount of investigative work, we know roughly what HTASK is.  Our question is, with the handle to the HTASK passed into the function, how do we determine CWnd object attached to it.  There is a function "GetWindowTask" which finds the handle of the HTASK structure associated with the passed CWnd, but we want to go the opposite direction.  Got any ideas?
0
Comment
Question by:shikari
  • 9
  • 7
16 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
Comment Utility
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
A task (application) may have lots of top-level windows.  So there is  not way to use the
""handle to the HTASK passed into the function, ... [to] determine CWnd object attached to it"  There may be many CWnd's associated witht he task.  But you don't need to.  This member procedure is being called for the CWnd that was activated.  See for the task to become active, one of it (potentially many) top-level windows had the be activated.  This procedure is called for the one that was activated.  

Does that help?
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Correction:  I seem to have remembered a little wrong.  This is called for every top-level window of the task being activated, not just the one that was activated.  (Similarly, it is called for every top-level window of the task being deactivated.)
0
 

Author Comment

by:shikari
Comment Utility
This function "OnActivateApp", is called both when the application is being activated and de-activated.  There are two arguments passed to the function, "BOOL bActive" which specifies whether the application is being activated or de-activated, and the handle to the HTASK.  When the application is being de-activated, the handle points to the HTASK that being activated, but for some reason, the application that is supposed to be activated doesn't receive a WM_ACTIVATEAPP message, so we just decided to do it manually inside our program, whenever it is being de-activated.  In order to do this, we need to know the application that is being activated.  Does this clairify, at all, what we're trying to do?
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
I see.

You can use EnumWindows() to enumate all the top-level windows to find the windows of the other task. (That sort of approach is the only way since there may be more than one window for the task.)

However, that sounds like a patch.  It would be better to find out why the application is not getting an ACTIVATEAPP message when activating.  I can help you with that if you are interested.
0
 

Author Comment

by:shikari
Comment Utility
Yeah, if you could help us out with finding out why the other application is not getting an ACTIVATEAPP message it would be great.  
The reason why we started doing all of this was in our application there is a modeless dialog box to display the progress of some procedure (e.g. converting a file), but with the modeless dialog box, the user could select some of the menu items which would interfere with the ongoing procedure and produce an error in the application.  But we didn't want to make the progress dialog modal because we still wanted the user to be able to switch applications since some conversions and such, could take as long as 15 minutes or more.  So we implemented a "PreTranslateMessage" function that would intercept the user's attempts to access functions when the progress dialog box is up.  But once we did that we encountered difficulties switching applications, which led us to implement the "OnActivateApp" function, since we were and are unable to determine the cause of the difficulties in switching applications.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
In that case, helping you with the ACTIVATEAPP message problem would still be helping you with a patch.  The heart of the problem is the dialog box.  It sounds like you need a modal, not modeless, dialog.  A modal dialog will prevent the user from accessing other windows in your application, but they can still access other windows in the system.  

If you really want a modeless dialog, but want it to act at least partly like a modal dialog (i.e. prevent access to some of your windows.)  Disable the windows that you don't want the user to access.  This will make the modeless dialog function more like a modal dialog.  

I can still help you track down the message problem, but I think that is a mistake.  Best to solve the problem at its source.
0
 

Author Comment

by:shikari
Comment Utility
Yeah, now I'm thinking we need a modal as well.  I'm not sure how to use a modal with a progress bar though.  Think you could help?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 22

Expert Comment

by:nietod
Comment Utility
That may be getting out of may area of expertise.  I program in using windows API, not MFC.  Plus I don;t use much of the built in stuff.  Like I implement my own modal dialogs and my own buttons etc.  

But I can try.  What is the problem you are faced with?  Is the progress bar on the dialog or another window?
0
 

Author Comment

by:shikari
Comment Utility
The progress bar is on the dialog.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
Okay, but why is this a problem?  Why could you have a progress bar with a modeless dialog and not a modal one?
0
 

Author Comment

by:shikari
Comment Utility
well, we tried to make the dialog box modal by saying
CDialog::CDialog(CProgressStatus::IDD);
CDialog::DoModal();
which made the box modal but the progress bar never showed up!
are we using the right functions to create the modal box? is there any other way to do it?

0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
somethign I wasn't thinking about, if you use a modal dialog when you call DoModal(), the DoModal() procedure doesn't return until the dialog is closed.  Thus you can't use this to display the dialog and then continue execution in the same instruction stream.  Thus you can't do.

Dlg.DoModal()
TranslateFile();

because the TranslateFile(0 procedure is not called until the dialog is closed.  If that is what you were trying, it won't work (I'm probably not telling you anything new there).  To make this work with a modal dialog, you would need to do the TranslateFile in a different thread.  

But if you aren't using multiple threads and don't want to, another option is that you can use a modeless dialog and make it act like a modal dialog.  (Which is what you had tried, so thismight be the best approcach.)  To do this just dissable the other windows of your application, or at least the ones you want to prevent the user from accessing.  I don't use window's modal dialogs in my program.  I use a regular window that has styles that make it look like a dialog and I make the window disable its parent on the WM_NCCREATE message and enable its parent again on the WM_NCDESTROY message.  This works well for my purposes and probably would for you.
0
 

Author Comment

by:shikari
Comment Utility
thank you. that helps a little. The only problem is i'm not sure where to disable the other windows from.
we basically need to restrict the user access to all the functions in the program while this particular update is happening and we don't want to go into the code of every function and disable it one by one b/c that would be very tedious and a problem when new functions are added. so, is there a way to disable every function in one shot while still allowing the user to press cancel to exit the dialog box.
and if i'm supposed to use WM_NCCREATE or WM_NCDESTROY i'm not exactly sure where to use it.
if you could help me out in disabling all the functions in one shot, i'd really appreciate it.
thanks.
0
 
LVL 22

Expert Comment

by:nietod
Comment Utility
I'm not sure what you mean by "functions"  If you mean functions in terms of code.  You don't need to disable those.  Instead you will prevent them from running.

If you mean functions in terms of UI features the user can access (buttons, menus etc) those are disabled by disabling their windows or by disabling on of their ancestor windows.
For example, if you have a MDI interface and you want to put up a "modal" dialog that disables everything in the main MDI window (the menus, toolbar buttons, and all the MDI children).  You just need to disable the MDI main window when you display the "modal" dialog window.  If you want to put up a "modal" dialog that disables on of the document windows, but still allows the user to use the other document windows and menus, etc, you would disable just the document window.

If that doesn't help, can you try describe the user interface to me.  Like what windows there are and what are their relationships.  What windows, if any can be accessed when the "modal" dialog is up.

You don't need to "hook" the create and destroy messages to handle this.  You can handle the disabling "manually".  You will create and display the "modal" dialog.  Then, since its not really modal, the code continues to run, so you can then disable all the windows you would like.  when you destroy the modal dialog, you then manually enable the windows that you had disabled.  

But if you will have lots of "modal"  dialogs and if this fits your design, you can make the dialog window automatically disable its parent when it is created and make it automatically enable its parent again when it is destroyed.  You can do this by placing the appropriate code in the onNCCREATE and onNCDESTROY handlers.  (I don't use MFC so if  can't give you a decent example in MFC, but I can do it in the regular API.)  The code would just get the dialog window's parent's handle and call EnableWindow() on it.  Then the code would call the default window procedure to handle the message as ussual.  It would look a little like this

BOOL SomeClass::OnNcCreate( LPCREATESTRUCT lpCreateStruct )
{
   CWnd *Parent = GetParent();

   Parent->EnableWindow(false);
   // somehow let default window procedure handle.  I don't know how that works in MFC.
}

void SomeClass::OnNcDestroy( )
{
   CWnd *Parent = GetParent();

   Parent->EnableWindow(true);
   // somehow let default window procedure handle.  I don't know how that works in MFC.
}

That should give you the idea.
0
 

Author Comment

by:shikari
Comment Utility
We put in the window enable code, took out some of our code including onactivateapp, and now it seems to be working.  Thanks a lot, you've been a big help.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now