Вывести окно на передний план без оконной ручки - PullRequest
0 голосов
/ 19 апреля 2011

У меня есть встроенное приложение Windows CE 6.0, которое открывает другое приложение в фоновом режиме, и я хочу перенести другое приложение на передний план. Сначала я попробовал SetParent с MainWindowHandle стороннего приложения, и он не работал. Затем я снова попробовал SetActiveWindow на том же MainWindowHandle, и это не сработало. Это заставило меня поверить, что MainWindowHandle испортился, и когда я печатаю его на консоли, его всегда 0. Это подводит меня к моему первому вопросу: возможно ли, что разработчик приложения забыл упомянуть, что такое MainWindow? Или он назначается автоматически в .NET?

Во-вторых, теперь, когда этот подход не удался, я попытался выполнить EnumWindows, затем получить идентификатор для каждого окна и сопоставить его с идентификатором процесса, который я знал для своей требуемой программы. Это дало мне исключение 0x80131515 о том, что EnumWindows не поддерживается. Я импортировал EnumWindows из CoreDll просто отлично. Второй вопрос: что может быть причиной этой ошибки? Что я делаю не так?

Извините! Вот некоторый код (Предположим, 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;
    }

Ответы [ 2 ]

1 голос
/ 03 апреля 2015

Я отвечаю на этот вопрос после того, как у меня возникла та же проблема и была решена.

Несмотря на то, что OEM-производители могут не включать некоторые части ОС в состав WindowsCE (такова природа модульной архитектуры), также верно, что такие вызовы, как EnumWindows или большинство других низкоуровневых вызовов, являются неотъемлемой частью ОС, и было бы безумно удалять их.

Я действительно получил сообщение отинженер Microsoft (!), который указал, что проблема заключается в том, как определяется обратный вызов.Хотя я пробовал разные подходы (делегаты, intPtr против int и другие), он дал следующий ответ, который на самом деле хорошо работает в WindowsCE 5/6 для разных устройств:

" [« EnumWindows call from.Приложение Net / C # приводит к ошибке 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.

1 голос
/ 19 апреля 2011

Ваш OEM не должен включать поддержку EnumWindows . Вместо этого вы можете попробовать FindWindow .

Я бы, вероятно, P / Invoke SetForegroundWindow , чтобы сделать это. SetActiveWindow не работает, если приложение находится в фоновом режиме.

-PaulH


Редактировать

P / Invoking EnumWindows не может вызвать исключение System.NotSupportedException (если вы не выбросите его в свой код), и GetLastError () не вернет HRESULT COR_E_NOTSUPPORTED. В вашем коде есть что-то подозрительное.

...