Solved

Activate minimized window

Posted on 2011-03-09
15
770 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
[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
  • 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 34

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 86

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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 86

Expert Comment

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

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 86

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 34

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 34

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 86

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 86

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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Computer science students often experience many of the same frustrations when going through their engineering courses. This article presents seven tips I found useful when completing a bachelors and masters degree in computing which I believe may he…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

738 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