Bring a window to foreground without window handle

0

I have a Windows CE embedded 6.0 application that opens another app in the background, and I want to bring the other app to the front. I first tried SetParent with the third party app's MainWindowHandle and it didnt work. I then tried SetActiveWindow on the same MainWindowHandle again and it didnt work. This led me to believe that the MainWindowHandle was messed up, and when I print it on the console, its always 0. This brings me to my first question: Is it possible that the dev for the app forgot to mention what the MainWindow is? Or is it assigned automatically in .NET?

Secondly, now that that approach failed, I tried to EnumWindows, then get the ID for each window and match it to the process Id I knew for my required program. This gave me an exception 0x80131515 saying "EnumWindows" is not supported. I have imported EnumWindows from CoreDll just fine. Second question: what could be the cause of this error? What am I doing wrong?

Sorry! Here's some code (Assume VCProcess has already been started):

    [DllImport("coredll.dll")]
static extern int EnumWindows(CallbackDef callback, int lParam);

    [DllImport("coredll.dll")]
    static extern int GetWindowThreadProcessId(IntPtr hWnd, int pid);

    static void Main()
    {
        callBackPtr = new CallBackPtr(Report);  
        EnumWindows(callBackPtr, 0);
    }

    public static bool Report(int hwnd, int lParam)
    {
        int pid = 0;
        GetWindowThreadProcessId(hWnd, pid);
        if (pid == VCProcessId)
        {
            SetForegroundWindow(hWnd);
        }
        MessageBox.show("Window handle is "+hwnd);
        return true;
    }
c#
.net
windows
windows-ce
compact-framework2.0
asked on Stack Overflow Apr 18, 2011 by Rishi • edited Apr 19, 2011 by Rishi

2 Answers

1

Your OEM must not have included support for EnumWindows. You could try FindWindow instead.

I would probably P/Invoke SetForegroundWindow to do this. SetActiveWindow does not work if the application is in the background.

-PaulH


Edit

P/Invoking EnumWindows can't throw a System.NotSupportedException (unless you throw it in your code) and GetLastError() wouldn't return an HRESULT COR_E_NOTSUPPORTED. There's something fishy in your code.

answered on Stack Overflow Apr 18, 2011 by PaulH • edited Apr 19, 2011 by PaulH
1

I am answering this question after having the same issue and having it resolved.

While it is true that OEMs may not include certain portions of the OS as part of WindowsCE (being the nature of its modular architecture), it is also true that a call like EnumWindows, or most other low level calls for that matter, are intrinsically part of the OS and it would be crazy to remove them.

I actually received a message back from a Microsoft engineer (!) which pointed out that the issue is the way the callback is defined. While I tried different approaches (delegates, intPtr vs int, and others) he gave the following answer that actually works well in WindowsCE 5/6 for different devices:

"[The “EnumWindows call from .Net/C# Application results in NotSupportedException 0x80131515” error because it ONLY supports Integer return types: I2, I4 etc. This applies to all callback methods and may vary depending on the call being used]"

So INSTEAD OF defining your callback as you did (I tried delegates, WinProcs and others unsuccessfully as well), define it as:

[DllImport("coredll.dll")]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int EnumWindows(IntPtr callPtr, int param);

which works perfectly!!

The following is my working code implementing this approach and works flawlessly in different devices running PocketPC/WindowsCE etc:

public delegate int CallBackPtr(int hwnd, int param);

[DllImport("coredll.dll")]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int EnumWindows(IntPtr callPtr, int param);

private static List<IntPtr> windows = new List<IntPtr>();

private static int CallBackMethod(int hwnd, int param)
{
    windows.Add(new IntPtr(hwnd));
    return 1;   
}

private static void GetAllWindowsHandles()
{
   // using a delegate does NOT work.
   //EnumWindows(delegate(IntPtr wnd, IntPtr param)
   //{
   //    windows.Add(wnd);
   //    return true;
   //}, IntPtr.Zero);

   CallBackPtr callbackPtr = CallBackMethod;
   IntPtr cb = Marshal.GetFunctionPointerForDelegate(callbackPtr);
   EnumWindows(cb, 0);
}

CJ.

answered on Stack Overflow Apr 3, 2015 by Carlos J.

User contributions licensed under CC BY-SA 3.0