c # - Bring et vindue til forgrunden uden vindueshåndtag

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et Windows CE-indlejret 6,0-program, der åbner en anden app i baggrunden, og jeg vil medbringe den anden app til forsiden. Jeg prøvede først SetParent med tredjeparts app'ens MainWindowHandle, og det fungerede ikke. Jeg prøvede derefter SetActiveWindow på samme MainWindowHandle igen, og det fungerede ikke. Det fik mig til at tro, at MainWindowHandle var rodet op, og når jeg udskriver det på konsol, det er altid 0. Dette bringer mig til mit første spørgsmål: Er det muligt, at dev for appen glemte at nævne, hvad MainWindow er? Eller tildeles det automatisk i .NET?


For det andet, nu da denne tilgang mislykkedes, forsøgte jeg at EnumWindows, så hent ID'en for hvert vindue og match det til processen. Id, jeg vidste for mit krævede program. Dette gav mig en undtagelse 0x80131515 siger 'EnumWindows' understøttes ikke. Jeg har kun importeret EnumWindows fra CoreDll. Andet spørgsmål: Hvad kunne der være årsagen til denne fejl? Hvad gør jeg forkert?


Undskyld! Her er nogle kode (Antag VCProcess er allerede startet):


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

Bedste reference


Din OEM må ikke have inkluderet support til EnumWindows. Du kan prøve FindWindow i stedet. [4] [5]


Jeg ville nok P/Invoke SetForegroundWindow at gøre dette. SetActiveWindow virker ikke, hvis applikationen er i baggrunden. [6] [7]


-PaulH





Rediger


P/Invoking EnumWindows kan ikke kaste en System.NotSupportedException (medmindre du smider det i din kode) og GetLastError () ville ikke returnere en HRESULT COR\_E\_NOTSUPPORTED. Der er noget fisk i din kode.

Andre referencer 1


Jeg besvarer dette spørgsmål efter at have det samme problem og har det løst.


Selvom OEM'er måske ikke indeholder visse dele af operativsystemet som en del af WindowsCE (det er dens modulære arkitektur), er det også rigtigt, at et opkald som EnumWindows eller de fleste andre lave niveauer kræver det, er i sig selv del af operativsystemet, og det ville være vanvittigt at fjerne dem.


Jeg har faktisk modtaget en besked fra en Microsoft-ingeniør (!), Som påpegede, at problemet er den måde, hvorpå tilbagekaldelsen er defineret. Mens jeg forsøgte forskellige tilgange (delegerede, intPtr vs int og andre) gav han følgende svar, der faktisk fungerer godt i WindowsCE 5/6 til forskellige enheder:


' [[EnumWindows-opkaldet fra .Net/C # -applikationen resulterer i NotSupportedException 0x80131515'-fejlen, fordi den kun understøtter Integer returtyper: I2, I4 osv. Dette gælder for alle tilbagekaldelsesmetoder og kan variere afhængigt af det anvendte opkald]] '


Så i stedet for at definere din tilbagekaldelse som du gjorde (jeg forsøgte også delegerede, WinProcs og andre uden succes), definerer du det som:


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


som fungerer perfekt !!


Følgende er min arbejdskode, der implementerer denne tilgang og fungerer fejlfrit i forskellige enheder, der kører PocketPC/WindowsCE osv.


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.