0

我有一个 Windows CE 嵌入式 6.0 应用程序,它在后台打开另一个应用程序,我想把另一个应用程序放在前面。我首先使用第三方应用程序的 MainWindowHandle 尝试了 SetParent,但它没有用。然后我再次在同一个 MainWindowHandle 上尝试了 SetActiveWindow,但它没有用。这让我相信 MainWindowHandle 搞砸了,当我在控制台上打印它时,它总是 0。这让我想到了我的第一个问题:应用程序的开发人员是否有可能忘记提及 MainWindow 是什么?还是在.NET 中自动分配?

其次,既然这种方法失败了,我尝试 EnumWindows,然后获取每个窗口的 ID 并将其与我知道的所需程序的进程 ID 匹配。这给了我一个异常 0x80131515 说“EnumWindows”不受支持。我已经从 CoreDll 导入了 EnumWindows 就好了。第二个问题:这个错误的原因可能是什么?我究竟做错了什么?

对不起!这是一些代码(假设 VCProcess 已经启动):

    [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;
    }
4

2 回答 2

1

在遇到同样的问题并解决后,我正在回答这个问题。

虽然 OEM 可能不会将操作系统的某些部分作为 WindowsCE 的一部分包含在内(这是其模块化架构的本质),但确实如此,像 EnumWindows 这样的调用或大多数其他低级别调用本质上都是操作系统的一部分,删除它们会很疯狂。

我实际上收到了来自 Microsoft 工程师 (!) 的一条消息,指出问题在于回调的定义方式。虽然我尝试了不同的方法(代表、intPtr 与 int 等),但他给出了以下答案,该答案在 WindowsCE 5/6 中适用于不同的设备:

" [“来自 .Net/C# 应用程序的“EnumWindows 调用导致 NotSupportedException 0x80131515”错误,因为它仅支持整数返回类型:I2、I4 等。这适用于所有回调方法,并且可能因所使用的调用而异] "

所以不要像你一样定义你的回调(我尝试了委托、WinProcs 和其他失败的方法),将它定义为:

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

效果很好!!

以下是我实现这种方法的工作代码,并且可以在运行 PocketPC/WindowsCE 等的不同设备中完美运行:

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。

于 2015-04-03T13:58:45.593 回答
1

您的 OEM 不得包含对EnumWindows的支持。你可以试试FindWindow

我可能会 P/Invoke SetForegroundWindow来做到这一点。如果应用程序在后台, SetActiveWindow不起作用。

-保罗H


编辑

P/Invoking EnumWindows 不能抛出 System.NotSupportedException(除非你在代码中抛出它)并且 GetLastError() 不会返回 HRESULT COR_E_NOTSUPPORTED。你的代码有问题。

于 2011-04-18T21:23:15.393 回答