Solved

Activate minimized window

Posted on 2011-03-09
15
747 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 32

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
 

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 32

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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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 32

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 32

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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Report events not being triggered 8 100
scoreUp challenge 14 48
I could not build boost code, 10 51
wordmultiple challenge 12 90
A short article about a problem I had getting the GPS LocationListener working.
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
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 …

707 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now