Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#] GetWindowText is leeg wanneer window is geminimaliseerd

Pagina: 1
Acties:
  • 361 views sinds 30-01-2008
  • Reageer

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 30-11 09:44
Hallo,

Van een process probeer ik alle open formulieren/windows te vinden en hiervan de titel op te slaan. Dit werkt goed wanneer de Windows niet geminimaliseerd zijn (het maakt dus niet uit of ze wel of niet zichtbaar zijn). Wanneer ik het window echter minimaliseer is de tekst die ik terug krijg leeg.

Van het window kan ik ook de WindowInfo opvragen. Deze klopt dan wel (afmetingen van het formulier e.d.).

Heeft iemand enig idee hoe dit kan en hoe ik dit op moet lossen?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);

        [DllImport("user32.dll", EntryPoint = "GetWindowTextLengthA")]
        public static extern int GetWindowTextLengthA(IntPtr hwnd);

        [DllImport("user32.dll", EntryPoint = "GetWindowTextA")]
        public static extern int GetWindowTextA(
        IntPtr hwnd,
        StringBuilder lpString,
        int cch
        );

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        private void MyEnumThreadWindowsProc(IntPtr hwnd, IntPtr lParam)
        {
            // Get the title and window info
            Win32.STRINGBUFFER limitedWindowTitle;
            Win32.WINDOWINFO windowInfo = new Win32.WINDOWINFO();
            windowInfo.cbSize = (uint)Marshal.SizeOf(windowInfo);

            StringBuilder test = new StringBuilder(512);

            Win32.GetWindowText(hwnd, out limitedWindowTitle, 256);
            Win32.GetWindowInfo(hwnd, ref windowInfo);
            Win32.GetWindowTextA(hwnd, test, 256);

            System.Windows.Forms.MessageBox.Show(Win32.GetWindowTextLengthA(hwnd).ToString());

            String windowTitle = limitedWindowTitle.szText;

            System.Windows.Forms.MessageBox.Show(windowTitle);
        }


Zowel de lengte, als het resultaat van GetWindowText en GetWindowTextA zijn leeg. Dit werkt dus allemaal wel correct wanneer het formulier niet geminimaliseerd is.

...


  • Jehjoa
  • Registratie: September 2007
  • Laatst online: 30-10 09:04
Ik weet niks van C#, maar ik neem aan dat de MSDN documentatie voor de Windows API hetzelfde is als voor C++.

Als je de beschrijving van GetWindowText op MSDN bekijkt, zie je bij Remarks het volgende staan:
If the target window is owned by the current process, GetWindowText causes a WM_GETTEXT message to be sent to the specified window or control. If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string. This behavior is by design. It allows applications to call GetWindowText without becoming unresponsive if the process that owns the target window is not responding. However, if the target window is not responding and it belongs to the calling application, GetWindowText will cause the calling application to become unresponsive.

To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.
Geeft niet bepaald aan waarom het niet werkt met een geminimaliseerd venster, maar het raadt wel een andere manier aan om de tekst van een venster uit een ander proces op te vragen. WM_GETTEXT sturen naar je hWnd, dus.

Good luck, have fun. :*)

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 30-11 09:44
Hm, bedankt voor je input, ga ik dadelijk ook even proberen. Ik ben inmiddels iets meer te weten gekomen door de laatste Marshal error op te halen. Deze is 1008 wanneer ik geen tekst terug heb gekregen, en 0 wanneer ik wel tekst terug heb gekregen. Ik kan alleen nergens de betekenis van deze code vinden :)

...


  • ATS
  • Registratie: September 2001
  • Laatst online: 28-11 20:56

ATS

Let dan ook even op de waarschuwing in het aangehaalde stuk in de reactie van Jehjoa: als het programma waarvan je de titel op wil halen hangt, dan hangt jouw programma ook met deze methode! Dat wil je waarschijnlijk niet. Ik zou daarom het ophalen van de titels in een aparte thread doen, die je kan terminaten als dat nodig is (time out ofzo) zonder dat je hele applicatie hangt.

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


  • Jehjoa
  • Registratie: September 2007
  • Laatst online: 30-10 09:04
Als die Marshal error hetzelfde is als een normale Windows error (oftewel: Als het niet iets C# of .NET specifieks is) dan betekent fout 1008 ERROR_NO_TOKEN: An attempt was made to reference a token that does not exist.

  • Jehjoa
  • Registratie: September 2007
  • Laatst online: 30-10 09:04
Volgens mij is het net andersom, ATS.
If the target window is owned by another process and has a caption, GetWindowText retrieves the window caption text. If the window does not have a caption, the return value is a null string. This behavior is by design. It allows applications to call GetWindowText without becoming unresponsive if the process that owns the target window is not responding.
Als een venster dat toebehoort aan een ander proces geen titel heeft, retourneert GetWindowText een nullstring om te voorkomen dat je eigen proces blijft hangen.
However, if the target window is not responding and it belongs to the calling application, GetWindowText will cause the calling application to become unresponsive.
Maarrrrrrr als je GetWindowText gebruikt op een venster in je eigen proces, waarvan de vensterprocedure toevallig net met een ingewikkelde operatie bezig is (of hij hangt simpelweg in een loop), DAN blijft de rest van je programma ook hangen. Hetgeen eigelijk logisch is.

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 30-11 09:44
Het timeout verhaal klopt inderdaad, en daar maak ik ook nog wel een oplossing voor. Als eerste moet ik dit voor elkaar zien te krijgen.

Het rare is dat ik nu geen error code meer krijg bij een lege return string. Het rare is ook dat wanneer ik de applicatie test vanuit de console ipv mijn Remote Desktop (zit op mijn werk op dit moment), het wel allemaal goed werkt.

...


  • Jehjoa
  • Registratie: September 2007
  • Laatst online: 30-10 09:04
Heb je WM_GETTEXT al geprobeerd of gebruik je nog steeds GetWindowText?

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 30-11 09:44
Ik gebruik nog steeds GetWindowText en het werkt nu allemaal goed. Zal wel iets te maken hebben gehad met de remote desktop denk ik ... vaag.

...


  • Jehjoa
  • Registratie: September 2007
  • Laatst online: 30-10 09:04
"Vaag" is inderdaad een goed woord om de MSDN documentatie te beschrijven. 8)7

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 30-11 09:44
Hm, het probleem is nog niet opgelost blijkt. Ik heb op dit moment hetzelfde probleem weer. Ik heb het ook geprobeerd door WM_GETTEXT te versturen via SendMessage. Wanneer de tekst die opgehaald is via GetWindowText echter leeg is, is de buffer die met de SendMessage is verzonden ook leeg. (beiden kunnen dan dus niet de titel ophalen).

Het rare is dat overige Windows van hetzelfde process (o.a. 1 met de titel GDI+) niet leeg zijn.
Iemand nog ideeën?

Edit:

Het is trouwens niet duidelijk aan te geven wanneer dit zo is. Het niet kunnen vinden van de titel gebeurt soms ook wanneer deze niet is geminimaliseerd.

[ Voor 15% gewijzigd door IceM op 10-09-2007 18:56 ]

...


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
Speelt het probleem alleen nog met RDC? Want ik had met een macro-tooltje er ook problemen mee als je de RDC sloot dat hij ook niet meer goed verder liep. Als je de RDC minimaliseerde werkte het wél...

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Waarom denk je dat het window een caption heeft, als het geminimaliseerd is?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
MSalters schreef op maandag 10 september 2007 @ 21:35:
Waarom denk je dat het window een caption heeft, als het geminimaliseerd is?
omdat die caption dan onderin de taakbalk staat/het window een hwind blijft houden/je vanuit je eigen programma de caption nog wel kan vinden :) ?

[ Voor 15% gewijzigd door roy-t op 10-09-2007 21:41 ]

~ Mijn prog blog!


  • IceM
  • Registratie: Juni 2003
  • Laatst online: 30-11 09:44
riezebosch schreef op maandag 10 september 2007 @ 20:01:
Speelt het probleem alleen nog met RDC? Want ik had met een macro-tooltje er ook problemen mee als je de RDC sloot dat hij ook niet meer goed verder liep. Als je de RDC minimaliseerde werkte het wél...
Ik neem aan dat je met RDC Remote Desktop Client bedoeld? Nee, het probleem lijkt daar los van te staan. Wanneer ik met behulp van de onderstaande code de win32 error ophaal krijg ik: error: 87 The parameter is incorrect. ERROR_INVALID_PARAMETER. (de eerder genoemde 1008 was niet de correcte foutcode, dit had met het ophalen van de win32 error te maken).

C#:
1
2
int lastErrorCode = Marshal.GetLastWin32Error();
System.ComponentModel.Win32Exception t = new System.ComponentModel.Win32Exception(lastErrorCode); 


En een Window die een titel heeft, heeft altijd een caption. Wanneer ik met bijv. Winspector de open windows bekijk staat deze er wel altijd tussen.

[ Voor 5% gewijzigd door IceM op 11-09-2007 08:51 ]

...

Pagina: 1