Solved

Activate minimized window

Posted on 2011-03-09
15
763 Views
Last Modified: 2012-05-11
I have an app that is used to open or restore another program.  If the program isn't running, it starts it.  If the program is running already, it brings the window to the front and activates it.

After getting the correct HWND handle, SetForegroundWindow(handle) works fine UNLESS the other program has been minimized, then it does nothing.

I've tried ShowWindow(handle, SW_RESTORE) and several other functions, but haven't been able to get it to cooperate.  Rather than spend a ton of time trying to figure this out, I'll just ask people who know the answer.

How can I activate the minimized window, restore it, and bring it to the front?

Thanks
0
Comment
Question by:theclay
  • 5
  • 5
  • 4
  • +1
15 Comments
 
LVL 16

Expert Comment

by:HooKooDooKu
ID: 35086508
Have you tried sending the application a WM_SYSCOMMAND with a wParam of SC_RESTORE?

0
 
LVL 33

Expert Comment

by:sarabande
ID: 35086511
i think you have to do that in the application which gets activated. it should handle WM_ACTIVATE_APP message and should restore with ShowWindow when being minimized.

Sara
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 35086684
Use the IsIconic() API to determine if the window is minimized.  If yes, use ShowWindow() API with SW_SHOWNORMAL to restore before calling SetForegroundWindow().

IsIconic():
http://msdn.microsoft.com/en-us/library/ms633527(VS.85).aspx

    "Determines whether the specified window is minimized (iconic)."
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:theclay
ID: 35086765
I am activating a 3rd party application which I have no control over, so I can't run anything in that app's message handler.

ShowWindow(handle, SW_SHOWNORMAL) on the window causes a window to pop up labeled .NET-BroadcastEventWindow...
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 35086800
You sure you have the right handle?...can we see some more code?
0
 
LVL 33

Expert Comment

by:sarabande
ID: 35086880
if you have admin rights you could hook the foreign app and handle WM_ACTIVATE_APP in the hook dll.

Sara
0
 

Author Comment

by:theclay
ID: 35086892
Sending the WM_SYSCOMMAND message does the same thing.

The process works fine as long as the logger.exe program is not minimized.  If it's not minimized I can bring it to the front simply by calling SetForegroundWindow.

BTW this is on Win2K and WinXP machines. :(

void ActivateHighQWindow(DWORD dwProcessId)
{
      g_hwnd = NULL;
      g_nFound = 0;
 
      EnumWindows(FindHwndFromPID, (LPARAM)dwProcessId);
 
      if(g_hwnd)  // we found one...
      {
            SendMessage(g_hwnd, WM_SYSCOMMAND, SC_RESTORE, NULL);
            SetForegroundWindow(g_hwnd);
      }
             
      // nothing found :-(

}
 
BOOL CALLBACK FindHwndFromPID(HWND hwnd, LPARAM lParam)
{
    DWORD   dwPID2Find = (DWORD)lParam;
    DWORD   dwPID = 0;
 
    if(GetWindowThreadProcessId(hwnd, &dwPID))
    {
            if(dwPID == dwPID2Find)
        {
                  g_hwnd = hwnd;
               return (FALSE);
        }
    }
 
    return(TRUE);
}

//This returns the dwProcessId which is passed to ActivateHighQWindow()
DWORD CHighQUpdateDlg::GetHighQWindow()
{
      LPCTSTR progname = "Logger.exe";
            
      HANDLE hSnapshot;
      PROCESSENTRY32 pe32;
      ZeroMemory(&pe32,sizeof(pe32));
      DWORD dwPID = -1;

      hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);
 
      pe32.dwSize = sizeof(PROCESSENTRY32);

      if(Process32First(hSnapshot,&pe32))
      {
            do
            {
                  if(!_tcscmp(pe32.szExeFile,progname))
                  {
                        dwPID = pe32.th32ProcessID;
                        break;
                  }

            }while(Process32Next(hSnapshot,&pe32));
      }

      return dwPID;
}
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 35086989
*Not a C++ programmer*

Try something like:
if(g_hwnd)  // we found one...
      {
            if (IsIconic(g_hwnd) != 0)
            {
                  ShowWindow(g_hwnd, SW_SHOWNORMAL);
            }
            SetForegroundWindow(g_hwnd);
      }

Open in new window

0
 
LVL 33

Expert Comment

by:sarabande
ID: 35086998
the SetForegroundWindow works but it does not change from iconized to normal.

the ShowWindow only works in process' own message queue.

Sara

0
 

Author Comment

by:theclay
ID: 35087084
Sara,

Do you know of a good online tutorial that would teach hook concepts pretty much from the ground up?  This is completely new to me.  I'll do some searching myself in the mean time.
0
 
LVL 33

Accepted Solution

by:
sarabande earned 250 total points
ID: 35087294
hooking is not so difficult granted you have the access rights necessary to hook a foreign app.

you need to provide a dll which is accessible from the hooked app.

you need to know the instance handle of the app to get hooked and call SetWindowsHookEx to install the hook.

i will look for sample code as well cause it is some time ago i did it myself and will return later.

Sara

0
 

Author Comment

by:theclay
ID: 35087303
@Idle_Mind: I wanted to test the call to showwindow before encasing it in an iconic code if statement.  I tested the code with the program minimized so the iconic check wasn't necessary.  Oddly enough, when I do add the iconic check with the program minimized, it still returns 0.  That may be a separate issue.

Either way, when I call ShowWindow on an outside program I get the weird .NET_BroadcastEvent blah blah blah window.  I'm thinking Sara has the correct answer.  I'm just a hobby programmer - don't know if I'll have the time or expertise to tackle a hook dll.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 35087342
Sorry I can't be more help.  I've successfully used the same approach "as is" in C# and VB.Net applications so I though I'd just throw it out there.  As stated, though, I am not a C++ programmer so I'm not sure what other issues need to be considered.

Hopefully Sara and the others can put you on the right path.  =)
0
 

Author Comment

by:theclay
ID: 35087483
Thanks for your input and time.  I'm a little behind the times but I'm working with what I have.  I'll keep playing with it.  Wonder why it works in C# but not C++?
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 250 total points
ID: 35087655
Just to make sure I wasn't crazy, here is a tested version that works in C# (VS2010 runninng on Win 7 Pro x64).  It correctly brought focus to Notepad and Restored it when necessary:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FocusApp("notepad");
        }

        private const int SW_SHOWNORMAL = 1;

        [DllImport("user32.dll")]
        static extern int IsIconic(IntPtr hWnd);

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        private void FocusApp(string ExeName)
        {
            Process[] processes = Process.GetProcessesByName(ExeName);
            if (processes.Length == 0)
            {
                Process.Start(ExeName);
            }
            else
            {
                // Restore the window if it is minimized...
                if (IsIconic(processes[0].MainWindowHandle) != 0)
                {
                    ShowWindow(processes[0].MainWindowHandle, SW_SHOWNORMAL);
                }

                // Make it the foreground window...
                SetForegroundWindow(processes[0].MainWindowHandle);
            }
        }

    }
}

Open in new window

0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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

Suggested Solutions

Title # Comments Views Activity
What is sub-make ? 2 71
incorrect syntax near the order by 10 43
what is the best Integrated development environment 2 21
troubleshoot a python script 8 26
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

820 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