KSCさんのカキコで突然思い出しました.
ワード操作フォームExとエクセル操作フォームExの,
「ウィンドウのクラス名とタイトル取得コード」がUnicode対応に
なっていませんでした.
GetMemなどのメモリ確保はバイト単位ですので,メモリリークを起こす
場合があります.
この種のエラーはやっかいで,その時点で必ずしもエラーが発生するとは
限りません.場合によってはアプリ終了後ということになって,中々
どこが悪いコードなのか特定できないことが多いのです.
今のところ動作していますので(するハズ),適当な時期に修正してきます.
ただし,コピペして使用しないでください.
サンプルプログラム集にも同様の間違いがあるかも知れません.
この手のコーディングが初めてに近い方のために,参考コードを以下に
書いておきます.
以下のコードであれば,Unicodeとかに関係なく動作するハズです.
MAX_PATHはDelphiのバージョンによって違います.256または512です.
具体的な数値を与えてもいいのですが,便利なのでこの値を使っています.
-1としていることに大した意味はありません.
PCharを使ったコードの方がいいかな?
//-----------------------------------------------------------------
// ウィンドウハンドルからウィンドウのタイトルを取得
//-----------------------------------------------------------------
function GetWindowTextStr(hWindow: HWND): String;
var
Buffer : array [0..MAX_PATH-1] of Char;
Len : Integer;
begin
//hWindowのタイトル部の文字列長さを取得(+1はNull終端文字分)
//APIのGetWindowTextLengthも内部でこのコードを実行していてMSDNでは
//他のプロセスの文字列長さ取得にGetWindowTextLengtを使用するように
//との記述がある
Len := SendMessage(hWindow, WM_GETTEXTLENGTH, 0, 0) + 1;
//念のためNull文字で埋める
FillChar(Buffer, Len, #0);
//文字列を取得
SendMessage(hWindow, WM_GETTEXT, Len, LongInt(Addr(Buffer)));
Result := String(Buffer);
end;
//------------------------------------------------------------------
// ウィンドウハンドルからウィンドウのクラス名を取得
//------------------------------------------------------------------
function GetClassNameStr(hWindow: HWND): String;
var
Buffer : array [0..MAX_PATH-1] of Char;
Len : Integer;
begin
//念のためNull文字で埋める
FillChar(Buffer, Length(Buffer), #0);
Len := GetClassName(hWindow, Buffer, Length(Buffer));
//Result := String(Buffer);も結果は同じ
SetString(Result, Buffer, Len);
end;
まいった.まいった.
KSCさんのカキコがなかったら気づかなかったかも知れません.
|