1

前景ウィンドウが SDImainframe であるかどうかを確認するためのこのコードがあります。

Function Active_window_mf() :Boolean;
var
  FromClass: PChar;
begin

  MFhandle := GetForeGroundWindow;
  GetMem(FromClass, 100);
  GetClassName(MFhandle, PChar(FromClass), 800);
  if StrPas(FromClass) = 'SDIMainFrame' then
    result := true;
end;

ただし、MADExcept は、Getmem 関数に問題があることを報告しています。私のコードの何が問題なのか、誰かが提案できますか?

4

1 に答える 1

16

コードには 3 つの問題があります。まず、メモリを割り当てた場合 ( GetMem)、解放する必要があります ( FreeMem):

GetMem(p, 1024);
try
  // Do sth with the memory
finally
  FreeMem(p);
end;

第二100に、との関係がわかりません800。実際、あなたは嘘をついています。100 バイトのバッファーを割り当て、800 の Unicode 文字を保持するのに十分な大きさであることを Windows に伝えます。

3 番目に、比較が true でない限り、関数の戻り値は未定義です。したがって、手順の先頭に追加するか、result := false最後の 2 行 ( の前end;) を次のように置き換える必要があります。

result := string(FromClass) = 'SDIMainFrame'

とにかく使わないほうがいいGetMemです。私は次のようにします:

var
  CN: array[0..256] of char;
begin
  GetClassName(MFhandle, CN, 256)

また、エラーをチェックする必要があります。GetClassNameを返す場合0、エラーが発生しました。したがって、次のようなことができます

function Active_window_mf(): boolean;
var
  CN: array[0..256] of char;
begin
  result := false;
  if GetClassName(GetForegroundWindow, CN, 257) > 0 then
    result := string(CN) = 'SDIMainFrame';
end;

更新:抽象化レベルに関する David の優れた点によると、次のようにするとよいでしょう。

function ClassNameFromHWND(const Handle: HWND): string;
var
  CN: array[0..256] of char;
begin
  result := '';
  if GetClassName(Handle, CN, 257) > 0 then
    result := CN;
end;

function Active_window_mf(): boolean;
begin
  result := ClassNameFromHWND(GetForegroundWindow) = 'SDIMainForm';
end;
于 2013-03-11T16:04:45.307 に答える