私たちのプログラミング部門は、サードパーティ製コンポーネントのバグと思われるものを追跡するために、非神話的な人月を費やしました。著作権で保護されたソース コードは次のとおりです。
function TGDIPPicture.GetImageSizes: boolean;
var
multi: TGPImage;
pstm: IStream;
hGlobal: THandle;
pcbWrite: Longint;
begin
result := false;
if Empty then
Exit;
if FDataStream.Size = 0 then
Exit;
hGlobal := GlobalAlloc(GMEM_MOVEABLE, FDataStream.Size);
if (hGlobal = 0) then
raise Exception.Create('Could not allocate memory for image');
try
pstm := nil;
// Create IStream* from global memory
CreateStreamOnHGlobal(hGlobal, TRUE, pstm);
pstm.Write(FDataStream.Memory, FDataStream.Size,@pcbWrite);
multi := TGPImage.Create(pstm);
FWidth := multi.GetWidth;
FHeight := multi.GetHeight;
Result := true;
multi.Free;
finally
GlobalFree(hGlobal);
end;
end;
問題は TMS の AdvOfficeTabSet にあることがわかりました。タブを追加するとクラッシュし、タブを追加しなければクラッシュしませんでした。(クラッシュは、実際の問題の 10 ステップ後に発生する、デバッグ不可能なアプリのハングの 1 つです)。
Raymond Chen のアドバイスに従って、GMEM_MOVEABLE を GPTR に置き換えたところ、問題が解決したようです。
上記のコードに GMEM_MOVEABLE を使用する正当な理由があるかどうか、誰か教えていただけないでしょうか。私の知る限り、これはクリップボード専用であり、常に GlobalAlloc と共に使用する必要があります。
私がこれを入力しているときに、別のプログラマーが私のコードを使用して GlobalFree 関数でエラーを受け取りました。したがって、どうやらこれも機能しません。ここで本当に助けが必要です!
*CreateStreamOnHGlobal は Windows API 関数です。(明らかにGMEM_MOVEABLE を好む)
*TGPImage は TMS の GDI+ ライブラリの実装の一部です。