Link to home
Start Free TrialLog in
Avatar of Ballad
Ballad

asked on

I want to detect a modal dialog box, with a given hwnd. The modal dialog box is not created by my thread.

I have asked this qustion before, Q_20556100. Yes, I got a very nice answer from TascoDLX. I tested it on notepad. With success. But it fails when running VB, and testing it on a About box.

My Platform is win2000.

The answer from TascoDLX was (my interpretation):

     GetWindowLong(hwnd,DWL_DLGPROC);
     if(GetLastError()==ERROR_INVALID_INDEX)
           // it is not a dialog box
        else
           // it is a dialog box


Göran
Avatar of DanRollins
DanRollins
Flag of United States of America image

Experts, the original q is:
    https://www.experts-exchange.com/questions/20556100/How-do-I-detect-a-modal-dialog-box.html

The DWL_DLGPROC techique will also "fail" (in that it won't solve your problem) if the app's main window is a dialog box.

It will also fail if the focus window is a non-dialog window that is just dressed up to *look like* a dialog box.  Many programs throw up a window containing a browser control for the Help/About... "dialog".

The answer to this question (well, to the original question) will depend upon the nature of the apps that you are trying to manipulate.  What application programs are these?  If you have some very specific target apps in mind, then you will need to craft a solution that works for those Apps.  Is the VB IDE one of your targets?

For most apps, sending an ESC keypress to the dialog box will close it, and doing so will have no particularly bad consequences if it is not showing a dialog box.

There is a very simple solution if you can modify the target programs.  Is this a possibility?

-- Dan
Avatar of Ballad
Ballad

ASKER

Dear Dan,

I have described my question, and my problems x times.
Does it realy matters if it is a VB app or someoneelse app. Is it not windows in the bottom, nes't pas?

The target app, is in fact a VB app. So please performe this small excercise:

Create a VB app with a about box. Can You detect that this about box is a dialog box? If you can I will send you $100 immediately. I am very serious about this.

Göran

I cannot modify the target program. If I could there would not be any problems.
I do all of my work in VC++ -- I can't build a VB app.  Is there a standard program in my WinNT directory, or one I could download from the Web that would be a satisfactory test app?

-- Dan
I will agree with Dan that it may be a window masquerading as a dialog.

Am I right in assuming that the code in question is throwing you an ERROR_INVALID_INDEX (hence, the wrong answer)?

If it is, then it is not a 'true' dialog box.

You may try calling GetWindowLong(hwnd,GWL_STYLE) and GetWindowLong(hwnd,GWL_EXSTYLE) to determine the given window style flags and extended window style flags, respectively.

Having not seen your target app, I can't begin to guess what styles are defined.  But, in this particular case, you may be able to distinguish between the different window types by checking the styles.

If you've got MS Spy++ (comes with Visual Studio, for one), determining the window styles becomes extremely easy.  Otherwise, you may have to lookup the associated values manually.  I know in Visual C++ the values are located in WINUSER.H, but I'm a bit sketchy on VB.  If you need help determining the flag values, let me know.

Good luck and Godspeed.
If you can restrict your requirements to one particular application, you can get result. For example, for VB program showing About box, my solution (check if owner window is disabled) should work, you can see this running Spy++. Having window handle we can find owner window using GetWindow(hWnd, GW_OWNER). If IsWindowEnabled returns 0 for owner, we can guess that hWnd is modal dialog.

When we try to control other process windows, there are no 100% working ways. For example, to stop other process, we first try to do this by "nice" way, if this doesn't work, just kill it.

By the way, modal dialog may not respond for WM_CLOSE, OK or CANCEL messages. There is no one solution, try to use number of ways and don't excpect 100% results.
enum ModalDialogTest
{
    Probably_Modal_Dialog,
    Probably_Something_Else
};

ModalDialogTest IsModalDialog(HWND hwnd)
{
    HWND hOwner = GetWindow(hwnd, GW_OWNER);

    if ( hOwner )
    {
        if ( ! IsWindowEnabled(hOwner) )
            return Probably_Modal_Dialog;
    }

    return Probably_Something_Else;
}

>>I will send you $100 immediately. I am very serious about this

Try this:

void CD13Dlg::OnButton1()
{
     HWND hwndTarget= ::FindWindow(0, "About Windows" );

     EnableWindow(false);  // disable and hide me, making other window frontmost
     ShowWindow(SW_HIDE);

     Sleep( 1000 ); // allow time for other window to activate
     ::SetForegroundWindow( hwndTarget );

     INPUT rI;
     memset( &rI, 0, sizeof(rI) );
     rI.type= INPUT_KEYBOARD; rI.ki.wVk= VK_ESCAPE;  rI.ki.dwFlags= 0;                SendInput(1,&rI, sizeof(rI) );
     rI.type= INPUT_KEYBOARD; rI.ki.wVk= VK_ESCAPE;  rI.ki.dwFlags= KEYEVENTF_KEYUP;  SendInput(1,&rI, sizeof(rI) );

     ShowWindow(SW_SHOWNORMAL);
     EnableWindow(true);
}

-- Dan

I'll take cash, money order, or cashier's check.  Please, no credit cards.  Personal checks will require 10 days to clear.
-- Dan
Avatar of Ballad

ASKER

Do you think you will get any many from this answer?

I can also close a window. That was not the issue.

For the x+1 times:

Construct a function:

bool IsWindowModal(HWND hwnd);

Göran


>>Construct a function:... bool IsWindowModal(HWND hwnd);

As I explained in the previous question, and AlexFM has also pointed out, one cannot be 100% certain, or more importantly, the distinction is arbitrary and basically irrelevant.  For the X+2th time...

Fact:
A "modal dialog' could just as easily be -- and often is -- a modeless dialog that has it own message pump working in a way that is similar to the system message pump employed by traditional (Win32 DialogBox API) modal dialogs.

Fact:
A window can act just like a modal dialog (preventing access to its parent window's U/I), but not be a dialog box at all.

Fact:
A process can subclass any window and make it do anything at all -- for instancee, a true Modal Dialog could pass commands to its parent in such a way that it acts as if it were a modeless dialog.

Fact:
Based upon your description of your problem, having an IsModal() fn would not solve that problem.

Fact:
When I asked you for a testcase application program, you ignored my request.  So Instead of attempting to work on a meaningless question, I instead worked on one that will provide you with a solution to your stated problem.

-- Dan
I hope those aren't Hong Kong "dollars."  U.S. Currency only, please.
Avatar of Ballad

ASKER

Of course I can send you a VB app, with an about box.

You are a little bit pissed. sorry.

I just asked you a simple question. How to detect a modal box. That was the question. If you think the question is not solvable, say so, that is, bool IsWindowModal(HWND hwnd); is meaningless, okay,

But one thing is very sure: If I put my mouse outside that box, and press the left button, nothing happens. So if Windows knows. Wy can't I also know?

Does this work?

bool IsWindowModal(HWND hwnd)
{
   HWND hwndNext = GetNextWindow(hwnd, GW_HWNDNEXT);
   if (hwndNext == NULL)
      return false;
   return !(IsWindowEnabled(hwndNext));
}

Do me a favor and let me where it craps out if it doesn't work.
>>If I put my mouse outside that box, and press the left button, nothing happens.

I don't think you are paying attention.  If you click outside of a modal dialog of the foreground application, any of several things might happen:

1) If you click on the desktop, nothing happens.

2) If you click on another application's window, that window is made the active window and its application is made into the foreground app.

3) If you click on the disabled parent window that started the modal dialog, you should hear a short beep.

In case #3, that is because the modal dialog has the input focus for that application.  The click gets sent to the window you clicked, which is a disabled top-level window.  A disabled window does not accept input from the user.  So the system provides an audible notification that you are clicking the wrong window and please look around for a modal dialog that needs to be closed.

-=-=-=-==-=-=-
>>I can also close a window. That was not the issue.

Modal dialogs enforce themselves as being enabled.  This is also true of "fake" modal dialogs (modless dialogs acting like modal dialogs).  The reason is pretty obvious when you think about it:  The parent window is always disabled while the dialog is up.  So it is impossible to interact with the main window -- one is forced to interact with the dialog box.  So, if the dialog box is disabled, then the entire application cannot accept user input!

The point is... you MUST close the modal dialog if you want to send button clicks to the parent window and if you want them to be processed.

However, MOST messages can still be processed by the parent window, even when a modal dialog is running.  It may be possible to send a WM_COMMAND to your target window to do a graceful logoff, without ever closing the dialog box.  In other words, forget about simulating mouse clicks -- just send the correct command ID.  For instance, in a little test app, I was able to bring up the "about..." box, then pass a command code for File>Open and bring up that dialog overtop of the About box.  To learn the correct WM_COMMAND wParam to send, use Spy++ to record window messages while you manually click that button.

Of course that applies only if you are still looking for a solution to your actual problem.  If, on the other hand, you inexplicably still want an IsModalDialog() fn to work with a VB app, then provide me with a testcase EXE and I'll provide you with a function that will work every time WITH THAT APP.  Then show me the kwan.

-- Dan
ASKER CERTIFIED SOLUTION
Avatar of TascoDLX
TascoDLX

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
TascoDLX, look at my previuos post.
(Cash, credit card is OK as well).
Avatar of Ballad

ASKER

To TascoDLX,

Thanks for your answer I am satisfied. There is a document in MSDN Home > ... > Windowing > Windows that describes the window features. Should have read that before I asked the question.

So please, send me a note to info@estetica.se, and tell me how you want the $100 to be payed. A promise is a promise.

Göran
LOL!  Now pay TascoDLX for the answer provided by AlexFM.  THAT is delicious irony.  Funniness abounds!  This thread has been a rollicking good time.  

>>...Should have read that before I asked the question.
Oh, oh, my side hurts!

-- Dan
Now I have to read other people's suggestions too?!?  I thought that was the job of the person asking the question?  (Whoops!)

Sorry for stepping on your toes, Alex (Ballad's fault).  If you really want the $100, it's yours.

Just remember the first rule of Experts Exchange:

"Say it with conviction!"
Avatar of Ballad

ASKER

you know guys why I chose TascoDLX? yes beacuse he provided me with an answer, right away. This is not a forum for thoughts and assumptions (of course it can be, but not in my case). I have no time with that. Just a simple answer.

If I ask the question: What is 1 -1? I am not interested that numbers are an abelian group, and -1 is the inverse of 1, and that 0 is the identity element.

that is that.
Thank you, Ballad.  I respect your decision.

Seriously though, keep your $100.  You earned it.

Just remember:

"Say it with conviction!"
Ballad,
>> you know guys why I chose TascoDLX? yes beacuse he provided me with an answer, right away

But AlexFM provided the exact same answer righter-awayer.

Let'd face it, the real reason is because you did not bother to read the previous posts.  If you had done that, then you would know that both TascoDLX's and AlexFM's solutions cannot possibly be accurate in every case.  At least AlexFM's version of the function returned a descriptive enumeration rather than an inacurate BOOL.

>>I have no time with that. Just a simple answer.
I'll be careful not to explain anything to you in the future.  Unless I need a good laugh.

-- Dan
TascoDLX, I think expert should read previous answers.
Alex,

Once again, I am truly sorry for duping your post.

(I must stop giving advice so late at night.  It's not so much the quality of my advice, but the quality of my brain.)

However, I will not claim 100% of the responsibility.  If Ballad had accepted your answer two days earlier, we'd have better things to talk about.

One thing's for sure:

It's not what you say... it's how you say it.