7

関数のGetWindowText戻り値は次のように文書化されています

関数が成功した場合、戻り値はコピーされた文字列の長さ(文字数)であり、終了ヌル文字は含まれません。ウィンドウにタイトルバーまたはテキストがない場合、タイトルバーが空の場合、またはウィンドウまたはコントロールハンドルが無効な場合、戻り値はゼロです。拡張エラー情報を取得するには、GetLastErrorを呼び出します。

GetLastErrorさて、このメソッドを呼び出してゼロの戻り値を受け取ったとき、適切な値を返すかどうかをどうやって知ることができますか?結局のところ、ゼロは失敗を示すために使用されるだけでなく、ウィンドウテキストが空であることを意味する場合もあります。その場合GetLastError、未定義の値は返されません。

私自身のアイデア:

  • GetWindowText最初は、成功すると最後のエラーが0に設定されるのではないかと思いました。しかし、テストはそれがそうではないことを示しています(そして、もしそうなら、これは文書化されていないので、とにかくそれを信頼することはできませんでした)。
  • 次に、GetWindowText成功時に最後のエラーが変更されない可能性があると考えたので、呼び出しの前に自分で0に設定すると、最後のエラーが変更されたかどうかを確認できます。テストはこれがうまくいくかもしれないことを示しています、しかしそれはこのように倍増されていないので、私はそれに頼ることができません。(そして、これは具体的な状況と実装に大きく依存すると思いGetWindowTextます。)
  • そしてもちろん、最初にを使用してウィンドウのテキストの長さを確認してから、長さが0より大きい場合にのみGetWindowTextLength呼び出すことができます。ただし、との呼び出しの間にウィンドウがテキストを変更した場合はどうなりますか?繰り返しになりますが、エラーを示すゼロの戻り値に依存することはできませんでした。GetWindowTextGetWindowTextLengthGetWindowText

GetWindowTextでは、失敗したかどうかを確実に判断するにはどうすればよいでしょうか。

4

2 に答える 2

4

SetLastError(ERROR_SUCCESS)事前に完全に安全でサポートされています。

最終エラー コードのドキュメントでは、関数が成功時に最終エラー値をクリアする場合とクリアしない場合があることを明確にしています。ただし、関数が成功した場合、関数は last-error 値を変更しないかゼロに設定しますが、決してエラー値に変更しないことは確かです。

WinAPI 関数の実装規則は次のように要約できます。

  1. SetLastErrorエラーが発生しない場合は呼び出さないでください。
  2. ヘルパー関数が API の失敗を引き起こさないエラー コードを設定する場合は、SetLastError(0)致命的ではない内部エラーが呼び出し元に表示されないように呼び出すか、API へのエントリで返されたものを呼び出しRestoreLastErrorて渡します。GetLastError
  3. API が SEH 例外をスローせずに失敗した場合は、SetLastErrorそれを報告するために呼び出します (ヘルパー関数が既に行っていない場合)。

文書化された動作「一部の関数SetLastErrorは成功時にゼロで呼び出す」は、ポイント 2 の結果です。

于 2012-10-23T14:10:33.570 に答える
1

GetLastError()はい、その通りです。実際に使用して違いを確認することはできません。かわいくない。私が考えることができる唯一の回避策は、IsWindow()後で使用することです。それが TRUE を返す場合、ゼロの戻り値は実際には「空の文字列」を意味します。ただし、これは不正なバッファ ポインタを渡すことには対応していません。うまくいけば、コードで簡単に回避できます。

于 2012-10-23T11:49:26.823 に答える