Solved

mouse cursor as file-bitmap

Posted on 1998-12-26
28
627 Views
Last Modified: 2010-04-04
I want to replace my mouse cursor with a bitmap-file
(so..loadfromfile) . At this moment I use Timage wich
I move with onmousemove: (example. onmousemove over image3)
cimage.left:=(x + image3.left) - (cimage.width div 2); cimage.top:=(y + image3.top) - (cimage.height div 2);

But.. since I have to move over alot components , and some components don't even have the onmousemove event... I think it's better to replace the mouse-cursor..

But.. hOW?
-external BITmap file..
-larger then 32*32 p's
0
Comment
Question by:skatan187
  • 15
  • 6
  • 3
  • +3
28 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 1353208
If you want Windows to handle all this cursor stuff for you, you'll have to convert the bitmap to an icon (look at winAPI "CreateCursor"). Then - I guess - you can just put the handle of the created cursor into TControl.Cursor. Please look at the example that you find in the documentation of TControl.Cursor.

Regards, Madshi.
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353209
Is it possible to convert a bitmap wich is larger then the standard size of a .cur file to a cur file (I have AXialis-AX cursor for this). And whill delphi display it?

and.. do you have some sample source to load an external .cur file? and I want to use the cursor only in one panel ...

SkAtAn
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1353210
skatan187,

what about overiding the Hint component?

Regards, Zif.
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353211
And how do I do that?
I am not a professional delphi programmer eh =)

I tried to make a large .cur file and it's possible.. but will
delphi accept these large cur files.. and! the mousePOINT (where the mouse XY coordinates acually are) must be in te centre of this bitmap ! (maybe I am asing to much .. dunno =)
SkA



0
 

Expert Comment

by:aacrg
ID: 1353212
Try to use TImageList. There is a function to add a bitmap with a transparency mask. After that you added a bitmap you can use it as Icon, too. Look at the functions DragImage, DragMove ... With this functions you can move your Image over the screen. Samples you'll find in the Win32Api help and in the source code of TTreeView and TListView. I've not tested with big Images but with normal Icons it works quite good.
rg
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1353213
It must be possible to create cursors bigger than 32x32, since if you install the cursor options and go to control panel/mouse, you can install very large cursors.
And I don't think, that Delphi will have problems with that, since Delphi does not implement the cursor drawing, but let Windows do the work.
Sorry, have no sources for loading an external cur file...  :-(

Regards, Madshi.
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353214
>>
Sorry, have no sources for loading an external cur file...  :-(

<<

if yha have this..
and it works with a 64*64 cur file..
-> correct answer =)
points:=points+30





0
 

Expert Comment

by:teechong
ID: 1353215
Here's one solution, but it uses an external .CUR file not .BMP file:

1) Use DevStudio to create the large cursor
   a) File, New, Files tab, Cursor File
   b) Image menu, New Device Image, Custom
   c) enter size of the cursor you want
   d) select the standard 32x32 cursor and delete (Image menu, Delete Device Image
   e) specify hotspot

2) Use the LoadCursorFromFile API to do the job:

const
  crMyCursor = 5;

procedure TForm1.FormCreate(Sender: TObject);
begin
      Screen.Cursors[crMyCursor] := LoadCursorFromFile ('LargeCur.cur');
      Cursor := crMyCursor;
end;

I've got a working demo, if you need.

Hope this helps.

TC
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353216
ow.. and the cursor may only change when in panel1
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353217
I will test this first..

0
 
LVL 1

Author Comment

by:skatan187
ID: 1353218
I will test this first..

0
 
LVL 1

Author Comment

by:skatan187
ID: 1353219
Screen.Cursors[crMyCursor] := LoadCursorFromFile ('LargeCur.cur');

I found the same answer in uddf faq,..
but id didn't worked ,, i'll try again anyhow
dunno if THIS works? because the cursor my only change in panel1
panel1.Cursors[crMyCursor] := LoadCursorFromFile
0
 

Expert Comment

by:teechong
ID: 1353220
The line
Screen.Cursors[crMyCursor] := LoadCursorFromFile (...);
is only used to make the cursor available to other components.

The line
Cursor := crMyCursor;
actually sets the cursor for the component.

If you want the cursor to appear like that over all your TControl components, do this in your formcreate:
for i := 0 to ComponentCount-1 do begin
    if Components[i] is TControl then
        TControl(Components[i]).Cursor := crMyCursor;
end;

or you can do
Screen.Cursor := crMyCursor;
to make it a global cursor for your app (note that no matter what you do, Windows will only set the cursor for your app, when you move it out of your app, Windows changes the cursor).

TC
0
 

Expert Comment

by:teechong
ID: 1353221
Oops! SKA, I just remembered that Windows (or rather the display drv) won't let you display native cursors that are larger than what it supports as specified in the GetSystemMetrics API (SM_CXCURSOR, SM_CYCURSOR).

So unless your display driver can support it, even if you can create and load a 64x64 cursor, it will not show as 64x64.

TC

0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Expert Comment

by:aacrg
ID: 1353222
What's about my comment (using TImageList)? Why don't you try it? I'm quite shure it works.

regards rg.
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353223
nope .. it didn't worked

aacrg.. yha have some source?
0
 

Expert Comment

by:aacrg
ID: 1353224
Well, here is some stuff. I've tested it with a 300x300 bmp under WinNt4. I'm not absolutely shure if it works under Win95. (Because Winnt supports bigger icons.) On my computer it was a bit slow with this huge bitmap.

New project, new form, imagelist, set width and height of the imagelist, then add the following events:

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  WindowHandle: THandle;
begin
  ImageList1.SetDragImage(0 {Index}, ImageList1.Width div 2, ImageList1.Height div 2);
//  WindowHandle:=GetDesktopWindow;   in this case you have to calc your mouse pos with ClientToScreen...
  WindowHandle:=Form1.Handle;
  if not ImageList1.DragLock(DeskHandle, X, Y) then
{    ShowMessage('DragLock failed')};
  ImageList1.ShowDragImage;
  if not ImageList1.BeginDrag(DeskHandle, X, Y) then
{    ShowMessage('BeginDrag failed')};
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  ImageList1.EndDrag;
  ImageList1.DragUnlock;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  ImageList1.DragMove(X,Y);
end;

end.

regards rg.
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353225
It was WAY more simple:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,  Y: Integer);
begin
ImageList1.Draw(form1.Canvas,x,y,0);
end;

BUT THE QUESTION IS NOT FINISHED ! =(
the icon remains on the form each times it's drawn..
AH DAMnnnnn...
(if I do form1.refresh it .. flikkers (i dunno how they say it in english). and it's not really centered (maybe I can change that by de/increasing X and Y a bit (the imageheight dive 2 or somthing like that

HowEver.. the imagelist method is WAY faster then moving a Timage .. so thx for the idea.. now the next problem I and I guess the question is answered.. (FiNAllY.. ! =)


SkAtAn
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353226
Adjusted points to 120
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353227
another question..
How can get the size adn height of the loaded bitmap
afther some trying I still did't found the answer to
the problem .. that imagelist draws each time a mousemove
event is triggered.. so the images is displayed 100 times
form1.refresh is to slow
form1.Canvas.Refresh; didn't removed the drawn images

AH .. and, when moving over a panel.. the images are behind
the panel.. so you can't see it .. while it's very importand
that the images are above this panel (and refresh..)

0
 

Expert Comment

by:aacrg
ID: 1353228
I think after DragLock the ParentWindow is locked that'll you can't change it using paint smth. If you like to change it you have to unlock it first. About your problem with the refresh: What's the parent window of TImageList.BeginDrag? Perhaps you can use InvalidateRect to redraw only a specified rectangle. Get the size of the loaded bitmap: Where have you loaded it? In TImageList? TImageList is a list of images with the same size. You have to set it before loading anything. e.g. load your bitmap in a TImage after check the width and height then assign it to the image list.

regards and a happy new year
rg
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353229
again.. what my current problems are..
a)I load one external file and I wan't to get the size in pixels
  and use this size for the timagelist...

b)I wan't the draw event only in one panel (panel1) and the
  imagelist.draw must be on the panel, not behind, so that it
  looks like the mouse coursor changes when in the panel...
c)And I wan't to refresh everythime the imageslist.draw is
  called.. so that I don't get a curve of the images (if onmouse
  move the loaded pictures is drawn everytime a mousemove event
  is triggered (so a lot times, I only need once a time)

and if thats not possible.. another way to load a bitmap as mouse cursor IN PANEL1 ONLY ... (the stuff above should do it)

SeeYa all NEXt YEaR :-)
SkAtAn


0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 1353230
Dear Skatan187

I can't really understand your problem. Perhaps it's because you just used the TImageList.Draw method? I modified the code of aacrg a bit and it worked wonderful with a form and a panel on it. Even if you moves outside of the form. On MouseDown I capture the cursor so I will get all mouse events. E.g. you could capture the mouse on panel1.mousemove and check if the mouse moves outside the panel (panel1.getclientrect...) and then execute the same code as in Form1.MouseUp in this example.

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  p: TPoint;
begin
  p:=ClientToScreen(Point(x,y));
  ImageList_DragMove(p.x, p.y);
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if not ImageList_EndDrag then
    MessageDlg('EndDrag error!',mtError, [mbOK],0);
  ImageList_DragLeave(0);
  SetCaptureControl(nil);
  Image1.Show;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  p: TPoint;
  HotSpotX, HotSpotY: Integer;
const
  ImageIndex=0;
begin
  GetCursorPos(p);
  SetCaptureControl(Self);
  Image1.Hide;
  Image1.Update;
  HotSpotX:=ImageList1.Height div 2;
  HotSpotY:=ImageList1.Width div 2;
  ImageList_BeginDrag(ImageList1.Handle, ImageIndex, HotSpotX, HotSpotY);
  p:=ClientToScreen(Point(x,y));
  ImageList_DragEnter(0, p.x, p.y);
end;

SeeYa next year!
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353231
I had a few errors:

ImageList_DragMove(p.x, p.y);  I changed these to
ImageList.DragMove(p.x, p.y); .. I added 2 image lists:
imagelist1 and imagelist (because the source has to different
imagelists ?!) and a timage (image1) .. I gave all of these components a little bitmap.. adjusted the size etc.. and when
tryng to drag I get the error: enddrag error... (thats all that happens)
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353232
I found it using aacrg's source  :
so.. aacrg resubmit this answer and you'll get the points
(lol) .. IF, you can also tell me how to find the with and height of a bitmap-file .. it has nothing to do with timagelist,
I just want to get the width and height of a bitmap file..
if somebody else put it in a comment.. since I cant give to persons points =) aacrg get the 170 .. :-) , but: AsAP !

SkATAn

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  WindowHandle: THandle;
begin
ImageList1.EndDrag;
ImageList1.DragUnlock;

  ImageList1.SetDragImage(0, ImageList1.Width div 2, ImageList1.Height div 2);
  WindowHandle:=Form1.Handle;
  if not ImageList1.DragLock(windowHandle, panel1.left+X, panel1.top+Y) then
  ImageList1.ShowDragImage;
  if not ImageList1.BeginDrag(windowHandle, panel1.left+X, panel1.top+Y) then
ImageList1.DragMove(panel1.left+X,panel1.top+Y);
end;
0
 

Expert Comment

by:aacrg
ID: 1353233
Get the width and the height of a BMP:

var
  BMP: TBitmap;
begin
  try
    BMP:=TBitmap.Create;
    BMP.LoadFromFile('MyBitmap.bmp');   // or load from stream, ressource ...
    ShowMessage('Width:'+IntToStr(BMP.Width)+' height:'+IntToStr(BMP.height));
  finally
    BMP.Free;
  end;
end;

Is that what you want to do??

regards, rg
0
 
LVL 1

Author Comment

by:skatan187
ID: 1353234
alright.. post an aswer and you'll yet yha points =)
0
 

Accepted Solution

by:
aacrg earned 170 total points
ID: 1353235
Hi skatan187

Here is my "answer". ;-)

rg
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now