2011-04-18 52 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。