skatan187
asked on
mouse cursor as file-bitmap
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
(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
ASKER
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
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
skatan187,
what about overiding the Hint component?
Regards, Zif.
what about overiding the Hint component?
Regards, Zif.
ASKER
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
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
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
rg
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.
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.
ASKER
>>
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
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
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
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]
Cursor := crMyCursor;
end;
I've got a working demo, if you need.
Hope this helps.
TC
ASKER
ow.. and the cursor may only change when in panel1
ASKER
I will test this first..
ASKER
I will test this first..
ASKER
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
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]
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]).Cu rsor := 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
Screen.Cursors[crMyCursor]
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]).Cu
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
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
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
What's about my comment (using TImageList)? Why don't you try it? I'm quite shure it works.
regards rg.
regards rg.
ASKER
nope .. it didn't worked
aacrg.. yha have some source?
aacrg.. yha have some source?
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(Sende r: 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:=GetDesktopWi ndow; in this case you have to calc your mouse pos with ClientToScreen...
WindowHandle:=Form1.Handle ;
if not ImageList1.DragLock(DeskHa ndle, X, Y) then
{ ShowMessage('DragLock failed')};
ImageList1.ShowDragImage;
if not ImageList1.BeginDrag(DeskH andle, 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(Sende r: TObject; Shift: TShiftState; X,
Y: Integer);
begin
ImageList1.DragMove(X,Y);
end;
end.
regards rg.
New project, new form, imagelist, set width and height of the imagelist, then add the following events:
procedure TForm1.FormMouseDown(Sende
Shift: TShiftState; X, Y: Integer);
var
WindowHandle: THandle;
begin
ImageList1.SetDragImage(0 {Index}, ImageList1.Width div 2, ImageList1.Height div 2);
// WindowHandle:=GetDesktopWi
WindowHandle:=Form1.Handle
if not ImageList1.DragLock(DeskHa
{ ShowMessage('DragLock failed')};
ImageList1.ShowDragImage;
if not ImageList1.BeginDrag(DeskH
{ ShowMessage('BeginDrag failed')};
end;
procedure TForm1.FormMouseUp(Sender:
Shift: TShiftState; X, Y: Integer);
begin
ImageList1.EndDrag;
ImageList1.DragUnlock;
end;
procedure TForm1.FormMouseMove(Sende
Y: Integer);
begin
ImageList1.DragMove(X,Y);
end;
end.
regards rg.
ASKER
It was WAY more simple:
procedure TForm1.FormMouseMove(Sende r: TObject; Shift: TShiftState; X, Y: Integer);
begin
ImageList1.Draw(form1.Canv as,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
procedure TForm1.FormMouseMove(Sende
begin
ImageList1.Draw(form1.Canv
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
ASKER
Adjusted points to 120
ASKER
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..)
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..)
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
regards and a happy new year
rg
ASKER
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
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
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(Sende r: 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(Sende r: 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.Heigh t div 2;
HotSpotY:=ImageList1.Width div 2;
ImageList_BeginDrag(ImageL ist1.Handl e, ImageIndex, HotSpotX, HotSpotY);
p:=ClientToScreen(Point(x, y));
ImageList_DragEnter(0, p.x, p.y);
end;
SeeYa next year!
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(Sende
Y: Integer);
var
p: TPoint;
begin
p:=ClientToScreen(Point(x,
ImageList_DragMove(p.x, p.y);
end;
procedure TForm1.FormMouseUp(Sender:
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(Sende
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.Heigh
HotSpotY:=ImageList1.Width
ImageList_BeginDrag(ImageL
p:=ClientToScreen(Point(x,
ImageList_DragEnter(0, p.x, p.y);
end;
SeeYa next year!
ASKER
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)
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)
ASKER
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(Sen der: 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(window Handle, panel1.left+X, panel1.top+Y) then
ImageList1.ShowDragImage;
if not ImageList1.BeginDrag(windo wHandle, panel1.left+X, panel1.top+Y) then
ImageList1.DragMove(panel1 .left+X,pa nel1.top+Y );
end;
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(Sen
Y: Integer);
var
WindowHandle: THandle;
begin
ImageList1.EndDrag;
ImageList1.DragUnlock;
ImageList1.SetDragImage(0,
WindowHandle:=Form1.Handle
if not ImageList1.DragLock(window
ImageList1.ShowDragImage;
if not ImageList1.BeginDrag(windo
ImageList1.DragMove(panel1
end;
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:'+IntTo Str(BMP.Wi dth)+' height:'+IntToStr(BMP.heig ht));
finally
BMP.Free;
end;
end;
Is that what you want to do??
regards, rg
var
BMP: TBitmap;
begin
try
BMP:=TBitmap.Create;
BMP.LoadFromFile('MyBitmap
ShowMessage('Width:'+IntTo
finally
BMP.Free;
end;
end;
Is that what you want to do??
regards, rg
ASKER
alright.. post an aswer and you'll yet yha points =)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Regards, Madshi.