W2K GetWindowText() bug of feature?

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

  • arjenk|IA
  • Registratie: Januari 2000
  • Laatst online: 04-12-2011
Ik heb net een paar uur besteed naar het opsporen van een bug die een crash veroorzaakte onder W2K.

Stukje code:
code:
1
2
3
4
5
    char buf[32];
    int len = GetWindowText(hwnd, buf, sizeof(buf)-1);
    while (len > 0 && isspace(buf[len-1]))
      --len;
    buf[len] = '\0';

Vrij simpel. Haalt gewoon tekst op uit een edit control, stript spaties ed en zet er weer netjes een NUL in. Dit werkt onder 95, 98 en NT4 al een aantal jaren zonder problemen. Maar onder W2K was het raak.

Wat gebeurt er? Het lijkt er op dat W2K de werkelijke lengte van de string in de edit control teruggeeft in plaats van het aantal karakters dat daadwerkelijk naar de buffer is gekopieerd (max 31 in bovenstaande code). En dan overschrijf je de stack met die '\0' ... Niet simpel te vinden dus. Wel simpel te verhelpen met een extra regeltje code.

Maar erg comfortabel voelt het niet. Ik kan er ook nergens iets over vinden! Ben ik nou al jaren in de bonen, of is er iemand die hier meer over weet?

Verwijderd

Soortgelijks ook al meegemaakt met GetTempPath.
Die riep ik altijd aan met een buffer van 80 chars (moet ruim voldoende zijn), maar voor W2K heb ik dat aan moeten passen naar 255.
Ben bang dat er wel meer API calls zijn die een lptstr (PChar in Delphi termen) vullen die sinds W2K dit probleem vertonen...

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 14-09 17:42

Gerco

Professional Newbie

Op donderdag 04 oktober 2001 03:21 schreef Afterlife het volgende:
Soortgelijks ook al meegemaakt met GetTempPath.
80 chars is daar niet genoeg voor, daar moet je MAX_PATH chars voor nemen (sinds Win95 al 260 stuks), dus die vlieger gaat niet op.

Van die GetWindowText() is wel vreemd. Staat er niets over in de MSDN?

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • arjenk|IA
  • Registratie: Januari 2000
  • Laatst online: 04-12-2011
Niks in MSDN, ook niet bij MS. Dit soort ongein kost je onevenredig veel tijd. Vooral omdat in dit geval de stack eraan ging zodat je ook niet veel aan je debugger hebt.

Bij GetTempPath() ligt het toch wat anders; stukje uit MSDN:
If the function succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer, not including the terminating null character. If the return value is greater than nBufferLength, the return value is the size of the buffer required to hold the path.
En dat is wel weer logisch, want aan een half pad heb je niets.

Verwijderd

Op donderdag 04 oktober 2001 08:24 schreef Gerco het volgende:
80 chars is daar niet genoeg voor, daar moet je MAX_PATH chars voor nemen (sinds Win95 al 260 stuks), dus die vlieger gaat niet op.
Hallo? Ik geef de buffer lengte toch netjes mee?
Werkte uit de kunst voor Win9x en NT4, alleen W2000 heeft zo z'n eigen ideeen...

Verwijderd

Op vrijdag 05 oktober 2001 01:57 schreef arjenk het volgende:
Bij GetTempPath() ligt het toch wat anders; stukje uit MSDN:
[..]

En dat is wel weer logisch, want aan een half pad heb je niets.
Klinkt logisch, maar verklaar dan maar 's waarom volstrekte jibberish werd teruggegeven wanneer de buffer op 80 stond, en gewoon "C:\TEMP" met een buffer van 255 chars.
"C:\TEMP" past toch best wel binnen 80 chars, toch? :)

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 14-09 17:42

Gerco

Professional Newbie

Op vrijdag 05 oktober 2001 04:01 schreef Afterlife het volgende:
Klinkt logisch, maar verklaar dan maar 's waarom volstrekte jibberish werd teruggegeven wanneer de buffer op 80 stond, en gewoon "C:\TEMP" met een buffer van 255 chars.
"C:\TEMP" past toch best wel binnen 80 chars, toch? :)
Ja, dat lijkt me wel idd. Gaf hij geen required buffersize terug toen je je 80 chars had?

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • arjenk|IA
  • Registratie: Januari 2000
  • Laatst online: 04-12-2011
Op vrijdag 05 oktober 2001 04:01 schreef Afterlife het volgende:

[..]

Klinkt logisch, maar verklaar dan maar 's waarom volstrekte jibberish werd teruggegeven wanneer de buffer op 80 stond, en gewoon "C:\TEMP" met een buffer van 255 chars.
"C:\TEMP" past toch best wel binnen 80 chars, toch? :)
Ok. Toch ook iets om rekening mee te houden :(

Maar niemand iets over GetWindowText() :?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

that's it, ik ga nou toch ECHT even visual studio + msdn installeren hoor... brb :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

hmmm de enige verklaring waar ik op kan komen is de volgende:

als jij GetWindowText aanroept dan wordt er een WM_GETTEXT message verzonden naar de window waarvan jij de text wilt weten. De desbetreffende windowproc zorgt ervoor dat de text wordt gekopieerd naar de door jouw opgegeven buffer, en retourneert het aantal characters dat gekopieerd moet worden... tenminste, dat is de bedoeling. Programmeurs van apps zijn natuurlijk vrij om hun eigen windowproc te schrijven, en dus kunnen ze er ook een maken die een verkeerde waarde retourneert bij de message WM_GETTEXT.

Ik weet niet in wat voor context je GetWindowText wilt aanroepen... op een window van een andere applicatie? of een window van je eigen app?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op zaterdag 06 oktober 2001 03:09 schreef OiSyN het volgende:
Ik weet niet in wat voor context je GetWindowText wilt aanroepen... op een window van een andere applicatie? of een window van je eigen app?
Volgens de docs mag GetWindowText niet op een window van een andere app maar moet je dan met de hand een WM_GETTEXT message sturen.

Overigens staat er in de docs wel iets over een known problem in GetWindowText on Win2k, maar dat betreft non-text controls zoals iconviews e.d.

Professionele website nodig?


  • Crazy D
  • Registratie: Augustus 2000
  • Laatst online: 17-09 08:12

Crazy D

I think we should take a look.

't Verbaast me op zich niet zo heel erg dat het in W2k niet meer werkt, ze hebben een hoop verbouwt, en misschien hebben ze bedacht dat je de functie gewoon moet aanroepen met een buffer die groot genoeg is ;) (soort van "possible bug" bugfix... :?)
't Verbaast me meer dat je 'm sowieso aanroept met een buffer die niet groot genoeg is... ik heb altijd "geleerd" eerst de textlength op te vragen, dan buffer groot genoeg maken, en dan pas de tekst op te vragen.

Exact expert nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zaterdag 06 oktober 2001 05:00 schreef curry684 het volgende:

[..]

Volgens de docs mag GetWindowText niet op een window van een andere app maar moet je dan met de hand een WM_GETTEXT message sturen.
mag wel, het mag alleen geen control zijn in een andere app :)
The GetWindowText function copies the text of the specified window's title bar (if it has one) into a buffer. If the specified window is a control, the text of the control is copied. However, GetWindowText cannot retrieve the text of a control in another application.

[..]

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.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • arjenk|IA
  • Registratie: Januari 2000
  • Laatst online: 04-12-2011
GetWindowText() is een superdun schilletje om WM_GETTEXT heen, dat is duidelijk. WM_GETTEXT doet precies hetzelfde!!

Dat het zo lang geduurd heeft voordat ik hier tegenaan liep kwam idd omdat ik meestal eerst GetWindowTextLength() gebruik om uit te vinden hoe groot m'n dynamische buffertje zijn moet. Maar in dit geval gaat het om een edit control waarin een lijst (gescheiden door comma's) van getallen wordt ingevoerd. Die edit control heeft een spinnertje dat alleen maar enabled is wanneer er een enkel getal in staat. Om nou te checken of dat spinnertje enabled/disabled moet zijn (en die check wordt tig keer gedaan) gebruik ik een statisch buffertje op de stack dus - gewoon om een boel overbodige overhead te vermijden. Het is dan ook niet nodig altijd alles te lezen, gewoon voldoende om te zien of er een nummertje of iets anders in staat.

Dat MS een boel verandert heeft in W2K geloof ik ook wel. Ik vind alleen dat ze van de API af moeten blijven! Maar omdat ik er nergens iets over vinden kan (ook niet op andere fora), ga je wel aan jezelf twijfelen. Waarom loopt niemand anders hier tegen aan?? Of gebruikt iedereen MFC :r

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

maar ik zie de fout nog steeds niet, behalve dat de returnwaarde niet klopt... waarom zou je de returnwaarde uberhaupt gebruiken?

je doet gewoon
code:
1
buffer[31] = '\0';

als de window text in de buffer past dan kopieert ie die \0 toch wel mee, en als ie niet past dan moet je m zelf zetten op de laatste plaats... probleem opgelost

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op maandag 08 oktober 2001 10:05 schreef arjenk het volgende:
GetWindowText() is een superdun schilletje om WM_GETTEXT heen, dat is duidelijk. WM_GETTEXT doet precies hetzelfde!!
Er is een macro voor iedere message die je gebruikt om informatie te trekken uit controls... :*

Professionele website nodig?

Pagina: 1