MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / GetWindowTextTimeout

Function GetWindowTextTimeout

source/window.cpp:1361–1466  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1359
1360
1361int GetWindowTextTimeout(HWND aWnd, LPTSTR aBuf, INT_PTR aBufSize, UINT aTimeout)
1362// This function must be kept thread-safe because it may be called (indirectly) by hook thread too.
1363// aBufSize is an int so that any negative values passed in from caller are not lost.
1364// Returns the length of what would be copied (not including the zero terminator).
1365// In addition, if aBuf is not NULL, the window text is copied into aBuf (not to exceed aBufSize).
1366// AutoIt3 author indicates that using WM_GETTEXT vs. GetWindowText() sometimes yields more text.
1367// Perhaps this is because GetWindowText() has built-in protection against hung windows and
1368// thus isn't actually sending WM_GETTEXT. The method here is hopefully the best of both worlds
1369// (protection against hung windows causing our thread to hang, and getting more text).
1370// Another tidbit from MSDN about SendMessage() that might be of use here sometime:
1371// "However, the sending thread will process incoming nonqueued (those sent directly to a window
1372// procedure) messages while waiting for its message to be processed. To prevent this, use
1373// SendMessageTimeout with SMTO_BLOCK set." Currently not using SMTO_BLOCK because it
1374// doesn't seem necessary.
1375// Update: GetWindowText() is so much faster than SendMessage() and SendMessageTimeout(), at
1376// least on XP, so GetWindowTextTimeout() should probably only be used when getting the max amount
1377// of text is important (e.g. this function can fetch the text in a RichEdit20A control and
1378// other edit controls, whereas GetWindowText() doesn't). This function is used to implement
1379// things like WinGetText and ControlGetText, in which getting the maximum amount and types
1380// of text is more important than performance.
1381{
1382 if (!aWnd || (aBuf && aBufSize < 1)) // No HWND or no room left in buffer (some callers rely on this check).
1383 return 0; // v1.0.40.04: Fixed to return 0 rather than setting aBuf to NULL and continuing (callers don't want that).
1384
1385 LRESULT result, length;
1386 if (aBuf)
1387 {
1388 *aBuf = '\0'; // Init just to get it out of the way in case of early return/error.
1389 if (aBufSize == 1) // Room only for the terminator, so go no further (some callers rely on this check).
1390 return 0;
1391
1392 // Below demonstrated that GetWindowText() is dramatically faster than either SendMessage()
1393 // or SendMessageTimeout() (noticeably faster when you have hotkeys that activate
1394 // windows, or toggle between two windows):
1395 //return GetWindowText(aWnd, aBuf, aBufSize);
1396 //return (int)SendMessage(aWnd, WM_GETTEXT, (WPARAM)aBufSize, (LPARAM)aBuf);
1397
1398 // Don't bother calling IsWindowHung() because the below call will return
1399 // nearly instantly if the OS already "knows" that the target window has
1400 // be unresponsive for 5 seconds or so (i.e. it keeps track of such things
1401 // on an ongoing basis, at least XP seems to).
1402 result = SendMessageTimeout(aWnd, WM_GETTEXT, (WPARAM)aBufSize, (LPARAM)aBuf
1403 , SMTO_ABORTIFHUNG, aTimeout, (PDWORD_PTR) &length);
1404 if (length >= aBufSize) // Happens sometimes (at least ==aBufSize) for apps that wrongly include the terminator in the reported length.
1405 length = aBufSize - 1; // Override.
1406
1407 // v1.0.40.04: The following check was added because when the text is too large to to fit in the
1408 // buffer, the OS (or at least certain applications such as AIM) return a length that *includes*
1409 // the zero terminator, violating the documented behavior of WM_GETTEXT. In case the returned
1410 // length is too long by 1 (or even more than 1), calculate the length explicitly by checking if
1411 // there's another terminator to the left of the indicated length. The following loop
1412 // is used in lieu of strlen() for performance reasons (because sometimes the text is huge).
1413 // It assumes that there will be no more than one additional terminator to the left of the
1414 // indicated length, which so far seems to be true:
1415 for (LPTSTR cp = aBuf + length; cp >= aBuf; --cp)
1416 {
1417 if (!*cp)
1418 {

Callers 3

EnumChildFindFunction · 0.85
BIF_DECLFunction · 0.85
EnumChildGetTextFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected