Search code examples
delphidelphi-xe2

Error with "uses" in Delphi XE2


Hi I have a problem with the following code, the problem is that I seem to forget a component when using "use" because it always gives me the error "tagBITMAP", the code is as follows:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,Vcl.Graphics,Vcl.Imaging.jpeg,Windows;



procedure capturar_pantalla(nombre: string);

// Function capturar() based in :
// http://forum.codecall.net/topic/60613-how-to-capture-screen-with-delphi-code/
// http://delphi.about.com/cs/adptips2001/a/bltip0501_4.htm
// http://stackoverflow.com/questions/21971605/show-mouse-cursor-in-screenshot-with-delphi
// Thanks to Zarko Gajic , Luthfi and Ken White

var
  aca: HDC;
  tan: TRect;
  posnow: TPoint;
  imagen1: TBitmap;
  imagen2: TJpegImage;
  curnow: THandle;

begin

  aca := GetWindowDC(GetDesktopWindow);
  imagen1 := TBitmap.Create;

  GetWindowRect(GetDesktopWindow, tan);
  imagen1.Width := tan.Right - tan.Left;
  imagen1.Height := tan.Bottom - tan.Top;
  BitBlt(imagen1.Canvas.Handle, 0, 0, imagen1.Width, imagen1.Height, aca, 0,
    0, SRCCOPY);

  GetCursorPos(posnow);

  curnow := GetCursor;
  DrawIconEx(imagen1.Canvas.Handle, posnow.X, posnow.Y, curnow, 32, 32, 0, 0,
    DI_NORMAL);

  imagen2 := TJpegImage.Create;
  imagen2.Assign(imagen1);
  imagen2.CompressionQuality := 60;
  imagen2.SaveToFile(nombre);

  imagen1.Free;
  imagen2.Free;

end;

//



begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Someone can help me?


Solution

  • The issue here is one of scope. Both the Windows unit and the Graphics unit define a type named TBitmap. The compiler can see both types and the scoping rules are that the last defined is the one the the compiler uses.

    Since the Windows unit is introduced after Graphics, your code is finding the TBitmap defined in the Windows unit. But you want the one defined in the Graphics unit.

    Solve the problem by moving Windows to appear before Graphics in the uses clause.

    Now, alternatively you could leave the uses clause alone and fully specify the type: Vcl.Graphics.TBitmap. I think you'll agree that re-ordering the uses clause is preferable.

    As an aside, I don't think very much of this code. It completely neglects to check the Win32 API return values for errors. I suggest that once you can make it compile, you add error checking. The function Win32Check from SysUtils is your friend. And some try/finally to protect the bitmaps' lifetime is also needed.