How do you programmatically close dialog boxes?

Hi,

How do you close programmatically all the dialog boxes?  Using
ShellExecute I print a file, e.g. "c:\temp\test.xls".  If this is not a
valid Excel file, Excel will bring up a dialog box complaining about
this.  How can I programmatically control this?  Is there a way I could
either close the window or force these dialog boxes to go to a "garbage
window" by specifying a window in the first argument of ShellExecute?
If I don't do this my program hangs next time I try to print another
Excel file.

Any help would be most appreciated!

Thanks!

Frank Kim

P.S. By the way, what is the purpose of the default directory argument
in ShellExecute and FindExecutable?
frankkimAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sapekCommented:
You might set a CBT hook and handle window creation event. If the window to be created is the unwanted dialog, you can forgive the window to be created at all (you can decide by seeing what is the window title, class and parent for example).
As to the default directory I believe it the directory which is made current when the functions do they work.

Adam

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
frankkimAuthor Commented:
Hi sapek,

I have no experience with CBT hooks so please bear with me.
Are you suggesting I create a window with a CBT hook and
pass the handle to that window to ShellExecute?
Do you have any source code as an example?

Thanks for your answer about the default directory.  It makes
sense.  But why would there be a default directory argument for FindExecutable?
0
sapekCommented:
> But why would there be a default directory argument for FindExecutable?

Say you look for x.exe and you have one in system directory and another in c:\temp directory. If you set default dir at c:\temp you should find the copy in this directory. otherwise you should find the copy in system directory (is in path).

>CBT

Do something like this (this is from my MFC app but I think you can figure it out)

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    HWND hwnd;

    switch (nCode)
    {
        case HCBT_CREATE:
           
            hwnd = (HWND)wParam;
           
            if(don't want this window)
                return 1; // nonzero

            break;
    }

    return(CallNextHookEx( ghCBTHook, nCode, wParam, lParam ));
}

//....

ghCBTHook = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
//...

//ShellExecute

// unhook when you are done (ie you don't expect any unwanted dialog anymore
UnhookWindowsHookEx(ghCBTHook);

0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

frankkimAuthor Commented:
Hi Sapek,
How do you determine the class of the window?  Specifically
how do you determine if a window is a dialog box.  I can
determine a window's parent and its title.\
When I open up a bogus Excel file, the dialog window that
says "it's not a valid file" does not seem
to have a parent.  However I don't believe I can rely on
that info to not allow the window to open.

Here's my code.  Thanks so much for the help!

HHOOK ghCBTHook;

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
      HWND hWindow, hParentWindow;
      char windowTitle[256];

      switch (nCode)
      {
      case HCBT_CREATEWND:
            
            // Get the handle to the window that is about to be created.
            hWindow = (HWND)wParam;
            
            // Get the title of the window.
            GetWindowText(hWindow, windowTitle, sizeof(windowTitle));

            // Get the parent of the window.
            hParentWindow = GetParent(hWindow);

            //return 1; // don't want this window

            if (hParentWindow == NULL) {
                  // Window doesn't have a parent
                  // so it's not what we're looking for.
                  break;
            }

            if(TRUE/*don't want this window*/)
                  //return 1; // nonzero
                  return 0;

            break;
      }
      
      return(CallNextHookEx( ghCBTHook, nCode, wParam, lParam ));
}


int WINAPI WinMain(HINSTANCE  hInstance,
                           HINSTANCE  hPrevInstance,
                           LPSTR  lpCmdLine,
                           int  nShowCmd)
{
      
      //....
      
      ghCBTHook = SetWindowsHookEx(WH_CBT, CBTProc,
            AfxGetInstanceHandle(), GetCurrentThreadId());
      //...
      
//      ShellExecute(NULL, "open", "D:\\temp\\blah.xls",
//            NULL, NULL, SW_SHOWNA);
      ShellExecute(NULL, "open", "C:\\My Documents\\Church\\Riders.xls",
            NULL, NULL, SW_SHOWNA);
      
      // unhook when you are done (ie you don't expect any unwanted dialog anymore
      UnhookWindowsHookEx(ghCBTHook);
      
      return 0;
}

0
frankkimAuthor Commented:
By the way, AfxGetInstanceHandle always returns NULL for
some reason and the ASSERT fails.  Do you know why?

0
sapekCommented:
AfxGetInstanceHandle() - this is MFC function.
The third argument for SetWindowsHookEx should be NULL if CBTProc is in the program (not a dll).
One thing I'm not sure. Is the excel error dialog box created in the context of process calling ShellExecute? If so everything is OK. If not, the above code wont catch creation of the dialog. Instead you must you must set a system wide CBT hook, specifing 0 for last parameter of SetWindowsHookEx. In that case CBTProc must be in a dll (not your program module).
When you call ShellExecute don't pass NULL as first argument. It tells what will be parent of the error dialog box.
I thing that best way to tell (in the CBTProc) that window is an error dialog box is to create in your program an invisible, unused window and pass its handle as first arg to ShellExecute. If you see (in CBTProc) a window whose parent is the invisible window it can only be an error dialog created as a result of calling ShellExecute.

Adam

0
frankkimAuthor Commented:
Instead of passing NULL as the third argument for CBTProc
I pass the hInstance parameter that is passed in through WinMain.
Is that okay?
Thanks again!

0
frankkimAuthor Commented:
The Excel dialog box is created in the context of the ShellExecute in this program.
I created a window as you suggested but my CBTProc still
is only called twice (at the beginning when I set up the hook and once after the ShellExecute).
The second time it is called I get a window that has no parent.
Its style is STATIC with style WS_DISABLED.
How can I determine if this window is going to be a dialog
box?
Here is how I created the window.  Any help would be most
appreciated.
      ghMyInvisibleWindow =
            CreateWindow(
            "STATIC",            // window class name
            "",                        // window caption
            WS_DISABLED,      // window style,
            CW_USEDEFAULT,      // initial x position
            CW_USEDEFAULT,      // initial y position
            CW_USEDEFAULT,      // initial x size
            CW_USEDEFAULT,      // initial y size
            NULL,                  // parent window handle
            NULL,                  // window menu handle
            hInstance,            // program instance handle
            NULL);                  // creation parameters

      ShellExecute(ghMyInvisibleWindow, "open", "D:\\temp\\blah.xls",
            NULL, NULL, SW_SHOWNA);

0
sapekCommented:
I hate to write this takes more and more of my time. If you would like me to write you a program to do what you want please adjust to 200 points. Also, it would be easier to send it if you gave me your e-mail address.

Adam

0
frankkimAuthor Commented:
I would love to have you write my program. :)  I've
upgraded the amount of points for this question to 200.
My email address is frankkim@server.net.

0
frankkimAuthor Commented:
Thanks Adam. :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.