?
Solved

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

Posted on 2003-03-23
24
Medium Priority
?
1,239 Views
Last Modified: 2013-12-03
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
0
Comment
Question by:Ballad
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 6
  • 5
  • +1
24 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 8191739
Experts, the original q is:
    http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_20556100.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
0
 

Author Comment

by:Ballad
ID: 8191819
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.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8192250
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
0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
LVL 3

Expert Comment

by:TascoDLX
ID: 8192878
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.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 8193495
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.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 8194653
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;
}

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8197953
>>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

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8204452
I'll take cash, money order, or cashier's check.  Please, no credit cards.  Personal checks will require 10 days to clear.
-- Dan
0
 

Author Comment

by:Ballad
ID: 8204606
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


0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8205149
>>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
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8205158
I hope those aren't Hong Kong "dollars."  U.S. Currency only, please.
0
 

Author Comment

by:Ballad
ID: 8206699
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?

0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8207324
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.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8207531
>>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
0
 
LVL 3

Accepted Solution

by:
TascoDLX earned 2000 total points
ID: 8209434
Ballad, ignore my last message.

Turns out it was the owner, not the parent, of the window that is disabled.

Try this:

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

99.9% certain this time.  Pay me!
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 8209492
TascoDLX, look at my previuos post.
(Cash, credit card is OK as well).
0
 

Author Comment

by:Ballad
ID: 8212069
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
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8212762
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
0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8213062
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!"
0
 

Author Comment

by:Ballad
ID: 8213290
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.
0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8213367
Thank you, Ballad.  I respect your decision.

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

Just remember:

"Say it with conviction!"
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8213795
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
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 8215669
TascoDLX, I think expert should read previous answers.
0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8215839
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.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …

764 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