2011-04-18 53 views
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; 
    } 
+1

问题是缺少重要的东西:代码。 – user7116 2011-04-18 21:25:50

回答

1

您的OEM必须没有列入EnumWindows支持。您可以尝试使用FindWindow

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

-PaulH


编辑

P /调用EnumWindows的不能抛出System.NotSupportedException(除非你把它扔在你的代码),并且GetLastError()将不会返回HRESULT COR_E_NOTSUPPORTED。你的代码中有些东西是可疑的。

+0

我怀疑EnumWindows可以从操作系统中省略。我希望看到实际的调用代码。 – ctacke 2011-04-19 02:27:19

+0

我也不这么认为,但是MSDN页面中有一个提示它可以。 “...并且某些设备可能不支持此API。” (除非他们坚持所有WCE API的免责声明,只是因为)http://msdn.microsoft.com/en-us/library/ms960376.aspx – PaulH 2011-04-19 03:06:31

+0

是的,这是全部免责声明。我会采取严重的内核黑客攻击来移除它,然后移除它可能会破坏壳牌。 – ctacke 2011-04-19 13:17:26

1

我在回答这个问题后有相同的问题并解决。

尽管原始设备制造商可能不会将操作系统的某些部分作为WindowsCE的一部分(是其模块化体系结构的一部分),但EnumWindows或其他大多数低级别调用也是如此问题,本质上是操作系统的一部分,它将被删除它们是疯狂的。

我实际上收到了一位微软工程师(!)的回复,其中指出问题在于回调的定义方式。虽然我尝试了不同的方法(代表,intPtr vs int和其他),但他给出了以下答案,在WindowsCE 5/6中对于不同的设备实际上效果很好:

”The“EnumWindows call from .Net/C#Application结果引发NotSupportedException 0x80131515” 的错误,因为它仅支持整数返回类型:I2,I4等。这适用于所有的回调方法,并且可根据通话使用]变化“

所以不是定义回调像你一样(我试图委托人,WinProcs和其他人也不成功),将其定义为:

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

这是完美的作品!

以下是我实现这个方法的工作代码和运行的掌上电脑/ 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。