How can I save currently used cursor into the stream (resource or file)?
Asked Answered
F

2

3

Does anyone know how to save the cursor (currently used by my application, even if it's custom or animated) into the stream or file, so that I'll be able to send it over network to another computer where my application load and use it ? Simply, I want to clone the cursor from a remote computer.

As I found in this article, most of icon functions can be used for cursors as well, but I can't find any easy to translate example. Here's one example using COM, but I'm not sure if the IPicture interface is useable also for cursors. Here for instance is the discussion about saving the image into the *.cur file, but I can't find anything suitable for saving and loading cursors into stream, resource or something what I'll be able to send over network and load on a target computer.

P.S. there's no SaveCursorToFile function as you might expect.

Thanks for any suggestions

Fredric answered 4/8, 2011 at 11:43 Comment(1)
I doubt that its possible at all. It sounds like you're doing a remote access system (I know, now I'm Clippy, eh?) - You might be able to send the entire screen, cursor and all, over to the other side, using the Nexxus SupportMe or Nexxus Portal components for Delphi. nexusdb.com/support/index.phpSuber
F
2

I think that DrawIconEx might be useful to help with this. With it you can simply draw the entire cursor image to a certain canvas. There is also possibility to draw the specified animated cursor frame by passing its index into the istepIfAniCur parameter. The following example shows how to save the current cursor into the stream (Button1Click) and load it back and display (Button2Click).

The other question is how to detect if the cursor is animated.

var
  Stream: TMemoryStream;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Stream := TMemoryStream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Stream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Picture: TPicture;
  CursorInfo: TCursorInfo;
begin
  Picture := TPicture.Create;

  CursorInfo.cbSize := SizeOf(CursorInfo);
  GetCursorInfo(CursorInfo);

  Picture.Bitmap.Transparent := True;
  Picture.Bitmap.Width := GetSystemMetrics(SM_CXCURSOR);
  Picture.Bitmap.Height := GetSystemMetrics(SM_CYCURSOR);

  DrawIconEx(
              Picture.Bitmap.Canvas.Handle, // handle to the target canvas
                                         0, // left coordinate
                                         0, // top coordinate
                        CursorInfo.hCursor, // handle to the current cursor
                                         0, // width, 0 for autosize
                                         0, // height, 0 for autosize
                                         0, // animated cursor frame index
                                         0, // flicker-free brush handle
                                  DI_NORMAL // flag for drawing image and mask
            );

  Picture.Bitmap.SaveToStream(Stream);
  Picture.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Picture: TPicture;
begin
  Stream.Position := 0;

  Picture := TPicture.Create;
  Picture.Bitmap.Transparent := True;
  Picture.Bitmap.Width := GetSystemMetrics(SM_CXCURSOR);
  Picture.Bitmap.Height := GetSystemMetrics(SM_CYCURSOR);
  Picture.Bitmap.LoadFromStream(Stream);

  SetBkMode(Canvas.Handle, TRANSPARENT);
  Canvas.FillRect(Rect(0, 0, 32, 32));
  Canvas.Draw(0, 0, Picture.Graphic);

  Picture.Free;
end;
Fredric answered 6/8, 2011 at 23:13 Comment(0)
U
2

Have a look here: IconsToFile.pas.

This also saves (static) cursors. Can be tested with:

hIconToFile('C:\Temp\Demo.cur', GetCursor, BitC32);

Works. You might have to adjust the bit rate though. I think it will have trouble with animated cursors, but might be enough to get you started.

Ullrich answered 4/8, 2011 at 13:14 Comment(0)
F
2

I think that DrawIconEx might be useful to help with this. With it you can simply draw the entire cursor image to a certain canvas. There is also possibility to draw the specified animated cursor frame by passing its index into the istepIfAniCur parameter. The following example shows how to save the current cursor into the stream (Button1Click) and load it back and display (Button2Click).

The other question is how to detect if the cursor is animated.

var
  Stream: TMemoryStream;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Stream := TMemoryStream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Stream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Picture: TPicture;
  CursorInfo: TCursorInfo;
begin
  Picture := TPicture.Create;

  CursorInfo.cbSize := SizeOf(CursorInfo);
  GetCursorInfo(CursorInfo);

  Picture.Bitmap.Transparent := True;
  Picture.Bitmap.Width := GetSystemMetrics(SM_CXCURSOR);
  Picture.Bitmap.Height := GetSystemMetrics(SM_CYCURSOR);

  DrawIconEx(
              Picture.Bitmap.Canvas.Handle, // handle to the target canvas
                                         0, // left coordinate
                                         0, // top coordinate
                        CursorInfo.hCursor, // handle to the current cursor
                                         0, // width, 0 for autosize
                                         0, // height, 0 for autosize
                                         0, // animated cursor frame index
                                         0, // flicker-free brush handle
                                  DI_NORMAL // flag for drawing image and mask
            );

  Picture.Bitmap.SaveToStream(Stream);
  Picture.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Picture: TPicture;
begin
  Stream.Position := 0;

  Picture := TPicture.Create;
  Picture.Bitmap.Transparent := True;
  Picture.Bitmap.Width := GetSystemMetrics(SM_CXCURSOR);
  Picture.Bitmap.Height := GetSystemMetrics(SM_CYCURSOR);
  Picture.Bitmap.LoadFromStream(Stream);

  SetBkMode(Canvas.Handle, TRANSPARENT);
  Canvas.FillRect(Rect(0, 0, 32, 32));
  Canvas.Draw(0, 0, Picture.Graphic);

  Picture.Free;
end;
Fredric answered 6/8, 2011 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.