请问如何动态生成一个彩色鼠标指针??(200分)

  • 主题发起人 主题发起人 -=Jujus=-
  • 开始时间 开始时间
J

-=Jujus=-

Unregistered / Unconfirmed
GUEST, unregistred user!
CreateCursor只能生成黑白指针
 
各位老大,帮帮忙吧!!
 
你自己做过资源档,在程序中自己从资源档中获得鼠标如何呢?<br>贴一贴,<br>&nbsp; 在Delphi中用Loadcursor()得到的光标只有黑白两色,怎样在程序中得到彩色光标呢?笔者尝试制作了以下程序:<br>  方法一 用Loadcursorfromfile()从外部调入图标作为光标<br>  Loadcursorfromfile()函数可以读*?CUR,*?ICO,*?ANI为后缀的文件作为光标,其中ICO为彩色图标格式(可用Image Editor制作),ANI为动画光标格式。以下为打开一图标作为光标的演示程序段,当光标移动到测试区域内光标会变成选定的图案;<br>  {设:opendialog1:Topendialog;Bitbtn1:Tbitbtn}<br>  procedure TForm1.BitBtn1Click(Sender:TObject);<br><br>  var tt:pchar;size:integer;s:string;<br>  begin<br>  if opendialog1.Execute then<br>  begin<br>  size:=length(opendialog1.filename);<br>  getmem(tt,size);<br>  s:=opendialog1.filename;<br>  strpcopy(tt,s);<br>  screen.cursors[2]:=loadcursorfromfile(tt);<br>  bf.cursor:=2;<br>  freemem(tt,size);<br>  end;<br>  end;<br>  方法二 从资源文件加载彩色光标<br>  用方法一发送程序时必须包含*?CUR文件,因而从资源文件中加载彩色光标是更可行的方法。用图标存放彩色光标,使用时把图标存入临时文件,用Loadcursorfromfile()从临时文件读出彩色光标。<br><br>  程序段:<br>  procedure ZloadfromResourse(screenindex:integer;name:Pchar);<br>  var td:ticon;<br>  begin<br>  try<br>  td:=ticon.Create;<br>  td.Handle:=LoadIcon(Hinstance,name);<br>  td.SaveToFile(′temp.cur′);<br>  screen.Cursors[screenindex]:=loadcursorfromfile(′temp.cur′);<br>  deletefile(′temp.cur′);<br>  finally<br>  td.free;<br>  end;<br>  end;<br>  此程序把名字为name的图标变为序号为screenindex的光标;<br>  例:<br>  ZloadfromResourse(2,′myicon′);<br>  Form1.cursor:=2;
 
zhangkan:这种方法我知道,可是对我现在需要的功能不适用。<br>比如,我需要拖动一个ListItem,指针需要显示出ListItem的内容,<br>就像是Windows的资源管理器一样。所以我需要在程序中动态生成指针资源。
 
先看看CreateCursor的定义,如果需要彩色的话,需要设置*pvANDPlane和*pvXORPlane这<br>两个参数<br>HCURSOR CreateCursor(<br>&nbsp; HINSTANCE hInst, &nbsp; &nbsp; &nbsp; &nbsp; // handle to application instance<br>&nbsp; int xHotSpot, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// x coordinate of hot spot<br>&nbsp; int yHotSpot, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// y coordinate of hot spot<br>&nbsp; int nWidth, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// cursor width<br>&nbsp; int nHeight, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // cursor height<br>&nbsp; CONST VOID *pvANDPlane, &nbsp;// AND mask array<br>&nbsp; CONST VOID *pvXORPlane &nbsp; // XOR mask array<br>);<br>下面一段是摘自MSDN的一个应用实例<br><br>&nbsp; &nbsp;// Get only the bitmap's bits, and load into a BYTE array of<br>&nbsp; &nbsp;// correct size.<br>&nbsp; &nbsp;// In this example, the bitmap created happens to have the<br>&nbsp; &nbsp;// dimensions needed for a cursor or icon. This may not always be<br>&nbsp; &nbsp;// the case. It may be necessary to "stretch" or "compress" the<br>&nbsp; &nbsp;// bitmap to the correct size, using StretchDIBits or StretchBlt<br>&nbsp; &nbsp;// (depending at what point the change in size is done).<br><br>&nbsp; &nbsp;xsize = GetSystemMetrics(SM_CXCURSOR);<br>&nbsp; &nbsp;ysize = GetSystemMetrics(SM_CYCURSOR);<br>&nbsp; &nbsp;GetObject(hbmMono, sizeof(BITMAP), (LPSTR)&amp;bm);<br>&nbsp; &nbsp;GetBitmapBits(hbmMono, (bm.bmWidthBytes * bm.bmHeight),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (LPSTR)XORbitPlane);<br><br>&nbsp; &nbsp;// The call above uses bm.bmWidthBytes instead of planes and<br>&nbsp; &nbsp;// bitsPixel because the former takes into account the fact that<br>&nbsp; &nbsp;// some drivers might pad scan lines for speed reasons.<br><br>&nbsp; &nbsp;hBitCursor = CreateCursor(ghInstance, 0, 0, xsize, ysize,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ANDbitPlane, XORbitPlane); <br>
 
To lww:<br>MSDN中的这篇文章我看了,但是好像不是说这样就可以生成一个彩色的指针。<br>在这段代码之前有这样一句话:<br>An application can create a cursor [red]from the monochrome bitmap [/red]produced by ColorDDBToMonoDDB. <br>The application can use the bitmap as either the ANDbitPlane or the XORbitPlane parameter to CreateCursor. <br>而且在Creating a cursor文档中对这两个参数的说明中说<br>AND mask &nbsp; XOR mask &nbsp; &nbsp;Display <br>0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Black &nbsp;<br>0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; White &nbsp;<br>1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Screen &nbsp;<br>1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Reverse screen &nbsp;<br>这不就是一个单色的指针吗
 
没有必要动态创建一个彩色指针吧? 所有指针你都可以以资源的形式装载<br>如果你的目的是要在拖动的时候显示彩色的拖动信息,你不是说动态创建指针,而是以下的方法:<br>//在Form1上放一个Panel,DragMode设为自动即可:<br><br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, ExtCtrls;<br><br>type<br>&nbsp; TControlDragObject = class(TDragControlObject)<br>&nbsp; private<br>&nbsp; &nbsp; FDragImages: TDragImageList;<br>&nbsp; &nbsp; FX, FY: Integer;<br>&nbsp; protected<br>&nbsp; &nbsp; function GetDragImages: TDragImageList; override;<br>&nbsp; public<br>&nbsp; &nbsp; constructor CreateWithHotSpot(Control: TWinControl; X, Y: Integer);<br>&nbsp; &nbsp; destructor Destroy; override;<br>&nbsp; end;<br><br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Panel1: TPanel;<br>&nbsp; &nbsp; procedure Panel1StartDrag(Sender: TObject;<br>&nbsp; &nbsp; &nbsp; var DragObject: TDragObject);<br>&nbsp; &nbsp; procedure Panel1EndDrag(Sender, Target: TObject; X, Y: Integer);<br>&nbsp; private<br>&nbsp; &nbsp; FDragObject: TControlDragObject;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>constructor TControlDragObject.CreateWithHotSpot(Control: TWinControl; X, Y: Integer);<br>begin<br>&nbsp; inherited Create(Control);<br>&nbsp; FX := X;<br>&nbsp; FY := Y;<br>end;<br><br>destructor TControlDragObject.Destroy;<br>begin<br>&nbsp; FDragImages.Free;<br>&nbsp; inherited;<br>end;<br><br>function TControlDragObject.GetDragImages: TDragImageList;<br>var<br>&nbsp; Bmp: TBitmap;<br>&nbsp; Idx: Integer;<br>begin<br>&nbsp; if not Assigned(FDragImages) then<br>&nbsp; &nbsp; FDragImages := TDragImageList.Create(nil);<br>&nbsp; Result := FDragImages;<br>&nbsp; Result.Clear;<br>&nbsp; Bmp := TBitmap.Create;<br>&nbsp; try<br>&nbsp; &nbsp; Bmp.Width := Control.Width;<br>&nbsp; &nbsp; Bmp.Height := Control.Height;<br>&nbsp; &nbsp; Bmp.Canvas.Lock;<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; (Control as TWinControl).PaintTo(Bmp.Canvas.Handle, 0, 0);<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; Bmp.Canvas.UnLock;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; FDragImages.Width := Control.Width;<br>&nbsp; &nbsp; FDragImages.Height := Control.Height;<br>&nbsp; &nbsp; Idx := FDragImages.AddMasked(Bmp, clBtnFace);<br>&nbsp; &nbsp; FDragImages.SetDragImage(Idx, FX, FY);<br>&nbsp; finally<br>&nbsp; &nbsp; Bmp.Free<br>&nbsp; end<br>end;<br><br>procedure TForm1.Panel1StartDrag(Sender: TObject;<br>&nbsp; var DragObject: TDragObject);<br>var<br>&nbsp; pt: TPoint;<br>begin<br>&nbsp; GetCursorPos(pt);<br>&nbsp; pt := Panel1.ScreenToClient(pt);<br>&nbsp; FDragObject := TControlDragObject.CreateWithHotSpot(Panel1, pt.X, pt.Y);<br>&nbsp; DragObject := FDragObject;<br>end;<br><br>procedure TForm1.Panel1EndDrag(Sender, Target: TObject; X, Y: Integer);<br>begin<br>&nbsp; FDragObject.Free;<br>&nbsp; FDragObject := nil;<br>end;<br><br>end.<br><br>对于其他的你可以自由发挥啦。[:)]
 
To xianjun:<br>不好意思,这段代码我没看大明白,不过你把Panel1的DragMode设为自动时StartDrag根本就不响应,<br>不知道你能不能给我详细地说明一下<br>
 
你要把Panel1的OnStartDrag和OnEndDrag事件指向那两段代码, 在Inspector中双击即可<br>这样,你拖动Panel1时会触发StartDrag,结束时调用EndDrag.
 
可我还是没有看出效果
 
或者这样做,用一个随着鼠标移动的小窗体来做,在这个窗体里显示你需要的内容<br>,没有试过。其实不用改变鼠标。^_^<br>
 
不会吧??? <br>我把DFM也发给你吧<br>object Form1: TForm1<br>&nbsp; Left = 191<br>&nbsp; Top = 107<br>&nbsp; Width = 696<br>&nbsp; Height = 480<br>&nbsp; Caption = 'Form1'<br>&nbsp; Color = clBtnFace<br>&nbsp; Font.Charset = DEFAULT_CHARSET<br>&nbsp; Font.Color = clWindowText<br>&nbsp; Font.Height = -12<br>&nbsp; Font.Name = '宋体'<br>&nbsp; Font.Style = []<br>&nbsp; OldCreateOrder = False<br>&nbsp; PixelsPerInch = 96<br>&nbsp; TextHeight = 12<br>&nbsp; object Panel1: TPanel<br>&nbsp; &nbsp; Left = 160<br>&nbsp; &nbsp; Top = 100<br>&nbsp; &nbsp; Width = 185<br>&nbsp; &nbsp; Height = 41<br>&nbsp; &nbsp; Caption = 'Panel1'<br>&nbsp; &nbsp; Color = clLime<br>&nbsp; &nbsp; DragMode = dmAutomatic<br>&nbsp; &nbsp; TabOrder = 0<br>&nbsp; &nbsp; OnEndDrag = Panel1EndDrag<br>&nbsp; &nbsp; OnStartDrag = Panel1StartDrag<br>&nbsp; end<br>end
 
对了,我这段代码的效果是鼠标指针拖动Panel1离开FORM1才能看出效果来的。<br>你稍微改改就行了。
 
thank you xianjun!!!
 
可怎么改??
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部