?
Solved

How do I detect a modal dialog box?

Posted on 2003-03-19
18
Medium Priority
?
1,036 Views
Last Modified: 2013-12-03
I want to detect a modal dialog box, with a given hwnd. The modal dialog box is not created by my thread.
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
  • 8
  • 4
  • 3
  • +2
18 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 8166889
From MSDN topic DialogBoxParam:

The DialogBoxParam function uses the CreateWindowEx function to create the dialog box. DialogBoxParam then sends a WM_INITDIALOG message (and a WM_SETFONT message if the template specifies the DS_SETFONT or DS_SHELLFONT style) to the dialog box procedure. The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style), disables the owner window, and starts its own message loop to retrieve and dispatch messages for the dialog box.

When the dialog box procedure calls the EndDialog function, DialogBoxParam destroys the dialog box, ends the message loop, enables the owner window (if previously enabled), and returns the nResult parameter specified by the dialog box procedure when it called EndDialog.

This can give a direction. Call IsWindowEnabled for parent window. This is not a universal solution, but may work in your case.
0
 

Author Comment

by:Ballad
ID: 8167314
I don't want to create a dialog box. I want to be able to decide that it is a dialog box.
0
 
LVL 86

Expert Comment

by:jkr
ID: 8168327
Identify the window class name. If it is '#32770', it is a dialog (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windowclasses/aboutwindow.asp), e.g.

HWND hWnd = ...;
char acClassName [ 255];

GetClassName ( hWnd, acClassName, sizeof ( acClassName));

if ( !lstrcmp ( acClassName, "#32770")) {

// window is a dialog

} else {

// window is NOT a dialog

}


0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

Author Comment

by:Ballad
ID: 8170101
thanks, but there are class names != #32770 which are still dialogs, so the question remains...
0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8171849
Try:

GetWindowLong(hWnd, DWL_DLGPROC)

If that fails (returns 0), and GetLastError() returns ERROR_INVALID_INDEX, it's not a dialog box.

I don't know of any way to distinguish between modal and modeless dialog boxes, though.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 8171858
I mean, check if window's parent is disabled. If yes, this is modal dialog. Additional criteria is class name, as jkr writes.
Applying these two conditions can give a good result (I don't think 100% right, but may be acceptable).
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8171930
Here is an important consideration:
In MFC, and OWL, and presumably many how-grown foundation classes, ALL MODAL dialog boxes are actuallu MODELESS dialog boxes.

The underlying support simulates the "internal message pump" that "true" modal dialogs use.

SO!  Even if you were to ascertain that a particular dialog is a modeless dialog, odds are that it is really a acting as modal dialog and you'd have what's called a "false negative" on your modal test!

Now, take a few minutes and describe your question in more detail.  Explain WHY you want to detect a modal dialog box and what you intend to do when you find one.  It's not me being idly curious... it's me trying to solve your ACTUAL problem and not some (possibly unrelated) sub-problem.

-- Dan
0
 

Author Comment

by:Ballad
ID: 8172463
reply to DanRollins:

I have two applications that my application supervise. My application is meant to be a single sign on app. That is, if you logon on one app my singlesignon app will logon the other app as well. The problem is in logging off. If you logoff one app and the other has a dialog box, I want to kill that dialog window, or perhaps emulate a CANCEL push, to get rid of the window. But I must detect that it is a dialog box. Thats my problem.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8172896
If you send a WM_QUIT to an App's main window, it should shut itself down, even if a modal dialog is being displayed.

If you have control of the source on both apps, you can use RegisterWindowMessage to define a custom message, say WM_MyShutDownNotice.  Then when one app is shutting down, broadcast that message, or post it to the other app.  Then when you get that message, handle it by cleaning up and shutting down.

-- Dan
0
 

Author Comment

by:Ballad
ID: 8173171
I made a test on notepad. The about box is very much modal. It has no parent. So that fails that test (to AlexFM).

When I try GetWindowLong(hWnd, DWL_DLGPROC) and GetLastError(), in my little test app, on that about box I get 0 and ERROR_ACCESS_DENIED resp. Because that about box is not created by me but by notepad. (TascoDLX).

To Dan: Is the bottom line, what you are saying, that I can't decide wether it is a modal box or not?
0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8176982
Ballad,

GetWindowLong() gave you ERROR_ACCESS_DENIED because it *IS* a dialog box and it won't let you touch its DialogProc.

As for determining modal and modeless, there are quite a few factors that could fudge your test.

Bottom line:  With the IsWindowEnabled() method, you can ONLY assume a modal dialog box if GetParent() returns a valid hWnd *AND* IsWindowEnabled() return FALSE.

If someone has another method of determining modal or modeless, I'd sure love to see it.
0
 

Author Comment

by:Ballad
ID: 8177146
i must melt this, have a cold so my brain is not on top ..sorry
0
 

Author Comment

by:Ballad
ID: 8177511
TascoDLX: Why is this true?

"GetWindowLong() gave you ERROR_ACCESS_DENIED because it *IS* a dialog box and it won't let you touch its DialogProc."

I mean that I got ERROR_ACCESS_DENIED because we are two separate processes, my app and notepad. To receive an address to another dialog box procedure in another process is meaningless in win2000 or WinNT. We cannot communicate, unless we use hooks.



0
 
LVL 3

Accepted Solution

by:
TascoDLX earned 2000 total points
ID: 8177940
You're right about the address of the DialogProc being meaningless.  In this case, the address of DialogProc is totally irrelevant.  Here's why:

GetWindowLong() can be called on a HWND in another process and return a valid result.

If you call GetWindowLong(hWnd, GWL_STYLE), you'll get that window's style flags.  If you call GetWindowLong(hWnd, GWL_WNDPROC), you'll invariably get ERROR_ACCESS_DENIED.

However, if you call GetWindowLong(hWnd, DWL_DLGPROC), a check is performed to see if that particular variable (index) exists.

If the window you are testing is a regular window, it won't find the index and will give you ERROR_INVALID_INDEX.

On the other hand, if the window you are testing is a dialog, it will find the index but won't let you touch the DialogProc if it's not in your process.  So it gives you ERROR_ACCESS_DENIED.

Also, as a side note, if the window you're testing defined extra window bytes (cbWndExtra in RegisterClass()), it may return valid data and no error.  In this case, the window is not a dialog.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8179022
>> what you are saying, that I can't decide wether it is a modal box or not?

I'm saying that in the situation that you described, you might not need to know.

Anyway, you could try either of these methods:

1) Enumerate the desktop windows using EnumWindows(), determine which is the correct window, obtain the thread ID with GetWindowThreadProcessId(), and post a WM_QUIT message via PostThreadMessage() to terminate the application.

2) Use the TOOLHELP APIs. Use Process32First() and Process32Next() to enumerate the tasks, determine which is the correct task, and call TerminateApp() to kill the application.

Note that the GetWindowThreadProcessId and GetWindowLong(...,GWL_HINSTANCE) APIs could come in handy.

-- Dan
0
 
LVL 3

Expert Comment

by:TascoDLX
ID: 8179371
Don't mean to be curt, but this will work for most standard dialog boxes:

   PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(nID, BN_CLICKED), 0);

Possible values for nID are IDOK, IDCLOSE, IDCANCEL, IDABORT, IDIGNORE, IDNO.

For a simple 'About' box, IDOK will work.

Obviously, every situation is going to be different.  IDCANCEL may work, IDCLOSE may work.  I'm sure there are situations where none of them will work.  You may have to post the WM_CLOSE message directly.  Or you may not have a clue.

I don't know what kind of apps you're working with, but if you're dealing with any application (user's choice), you'll probably run into situations where you can't close a dialog.  Sometimes, you just don't know.
0
 

Author Comment

by:Ballad
ID: 8179387
to DanRollins: I don't want to kill the app. I want to make a graceful logout. The app has a logout button in a toolbar. But the problem is, once again, that I can not emulate a mouse click on that logout button if I have a modal window, waiting for input. So if I know that the window is modal, I can simply send a WM_CLOSE to that window, it closes, and I can emulate a nice logout. When that is done, the apps, login window appears and I can start the login process on the two apps again. Referring to previous comment, describing my single sign on app.

Thanks anyhow that you all take part in my problem. It is very important that I solve it.
0
 

Author Comment

by:Ballad
ID: 8179474
Thanks TascoDLX, very ingenious.
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
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…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

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