大家在用winamp时有没有注意到当前活动窗口会出现目前播放的歌曲名字,演唱者等信息,另外还有4个按钮,单击可以实现对歌曲的控制(停止,播放,上一首,下一首),我想问一下这个效果是怎么实现的???解决后另有重谢!!!如有源代码可发到[email protected],必有重谢!!!
解决方案 »
- 新手求助,关于视频采集传送程序,指令无法识别
- 跪拜恳求!!!DELPHI中怎样调用C#作的WEB SERVICE啊!!急啊!!!
- 请教一个delphi中编译的问题:怎样才能编译一个单独的单元?
- SQLServer 数据库备份/恢复工具
- 一个公司如何保护原代码?
- Rave Reports5.0界面问题,很急!
- 在线等待--在DBgrid上我怎么对特定的某行和某列打上颜色
- 请解决我程序中出现的问题(此时我在线:2月13号7点开始)
- 有关Delphi中使用ADO的问题(急!+)
- 请教大家:文件路径的问题
- 如何实现winamp吸附当前窗口标题栏的效果?解决后另有重谢!!!
- 用什么方法可以设置Windows机器的计算机名?
谢谢各位大侠!
是不是需要钩子什么的啊?小弟菜鸟啊~~大侠们能不能写写原理和代码?我觉得这个还是挺有难度的~~大家都来讨论啊~~
我的mail:: [email protected]
Windows, Buttons, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;type
TForm1 = class(TForm)
Image1: TImage;
procedure FormResize(Sender: TObject);
private
CaptionBtn: TRect;
procedure DrawCaptButton;
procedure WMNCPaint(var Msg: TWMNCPaint); message WM_NCPaint;
procedure WMNCActivate(var Msg: TWMNCActivate); message WM_NCACTIVATE;
procedure WMSetText(var Msg: TWMSetText); message WM_SETTEXT;
procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
procedure WMNCLButtonDown(var Msg: TWMNCLButtonDown); message WM_NCLBUTTONDOWN;
public
{ Public declarations }
end;var
Form1: TForm1;implementationconst
HTCaptionBtn = HTSIZELAST + 1;
{$R *.DFM}procedure TForm1.DrawCaptButton;
var
xFrame,
yFrame,
xSize, ySize: Integer;
R: TRect;
begin
xFrame := GetSystemMetrics(SM_CXFRAME);
yFrame := GetSystemMetrics(SM_CYFRAME); xSize := GetSystemMetrics(SM_CXSIZE);
ySize := GetSystemMetrics(SM_CYSIZE); CaptionBtn := Bounds(Width - xFrame - 4 * xSize + 2,
yFrame + 2, xSize - 2, ySize - 4); Canvas.Handle := GetWindowDC(Self.Handle); Canvas.Font.Name := 'Arial';
Canvas.Font.Color := clRed;
Canvas.Font.Style := [fsBold];
Canvas.Pen.Color := clYellow;
Canvas.Brush.Color := clBtnFace; try
DrawButtonFace(Canvas, CaptionBtn, 1, bsAutoDetect, False, False, False); R := Bounds(Width - xFrame - 4 * xSize + 2,
yFrame + 3, xSize - 6, ySize - 7); with CaptionBtn do
Canvas.TextRect(R, R.Left + 2, R.Top - 1, 'o'); finally
ReleaseDC(Self.Handle, Canvas.Handle);
Canvas.Handle := 0;
end;
end;procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
begin
inherited;
DrawCaptButton;
end;procedure TForm1.WMNCActivate(var Msg: TWMNCActivate);
begin
inherited;
DrawCaptButton;
end;procedure TForm1.WMSetText(var Msg: TWMSetText);
begin
inherited;
DrawCaptButton;
end;procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
inherited;
with Msg do
if PtInRect(CaptionBtn, Point(XPos - Left, YPos - Top)) then
Result := htCaptionBtn;
end;procedure TForm1.WMNCLButtonDown(var Msg: TWMNCLButtonDown);
begin
inherited;
if (Msg.HitTest = htCaptionBtn) then
ShowMessage('Down');
end;procedure TForm1.FormResize(Sender: TObject);
begin
Perform(WM_NCACTIVATE, Word(Active), 0);
end;end.
可以实现在标题栏上画个按钮
to:questions_problems(questions_problems) ::
在标题栏画按钮的效果我已经实现了,在当前活动窗体上也能画,就是不能响应鼠标事件~~这是我最头疼的啊~~~~~~~
52768361(涵清V3.0)兄给我发了个源码,不过没有实现上面我说的效果啊~`我说的是能够自动吸附到当前活动窗体(或者是嵌入到,好像winamp是把当前窗口的标题栏给改了~~:( )然后那四个按钮还能响应鼠标事件(单击实现止,播放,上一首,下一首功能),望各位大侠不吝执教!我想这是一个高难度的问题吧!大侠们支招啊!!!
Winamp的用户都知道,Winamp的播放列表或均衡器在被移动的时候,仿佛会受到一股磁力,每当靠近主窗口时就一下子被“吸附”过去,自动沿边对齐。我想让我的Winamp插件也具备这种奇妙特性,于是琢磨出了一种“磁化”窗口的方法。该法适用于Delphi的各个版本。为了演示这种技术,请随我来制作一个会被Winamp“吸引”的样板程序。
先新建一应用程序项目,把主窗口Form1适当改小些,并将BorderStyle设为bsNone。放一个按钮元件,双击它并在OnClick事件中写“Close;”。待会儿就按它来结束程序。现在切换到代码编辑区,定义几个全局变量。
var
Form1: TForm1; //“磁性”窗口
LastX, LastY: Integer; //记录前一次的坐标
WinampRect:Trect; //保存Winamp窗口的矩形区域
hwnd_Winamp:HWND; //Winamp窗口的控制句柄
接着编写Form1的OnMouseDown和OnMouseMove事件。
procedure TForm1.FormMouseDown(Sender: Tobject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
ClassName=‘Winamp v1.x’; //Winamp主窗口的类名
//如果改成ClassName=‘TAppBuilder’,你就会发现连Delphi也有引力啦!
begin
//记录当前坐标
LastX := X;
LastY := Y;
//查找Winamp
hwnd_Winamp := FindWindow(ClassName,nil);
if hwnd_Winamp>0 then //找到的话,记录其窗口区域
GetWindowRect(hwnd_Winamp, WinampRect);
end;
procedure TForm1.FormMouseMove(Sender: Tobject; Shift: TShiftState; X,
Y: Integer);
var
nLeft,nTop:integer; //记录新位置的临时变量
begin
//检查鼠标左键是否按下
if HiWord(GetAsyncKeyState(VK_LBUTTON)) > 0 then
begin
//计算新坐标
nleft := Left + X - LastX;
nTop := Top + Y - LastY;
//如果找到Winamp,就修正以上坐标,产生“磁化”效果
if hwnd_Winamp>0 then
Magnetize(nleft,ntop);
//重设窗口位置
SetBounds(nLeft,nTop,width,height);
end;
end;
别急着,看Magnetize()过程,先来了解一下修正坐标的原理。根据对Winamp实现效果的观察,我斗胆给所谓“磁化”下一个简单的定义,就是“在原窗口与目标窗口接近到某种预定程度,通过修正原窗口的坐标,使两窗口处于同一平面且具有公共边的过程”。依此定义,我设计了以下的“磁化”步骤。第一步,判断目标窗口(即Winamp)和我们的Form1在水平及垂直方向上的投影线是否重叠。“某方向投影线有重叠”是“需要进行坐标修正”的必要非充分条件。判断依据是两投影线段最右与最左边界的差减去它们宽度和的值的正负。第二步,判断两窗口对应边界是否靠得足够近了。肯定的话就让它们合拢。
好了,下面便是“神秘”的Magnetize过程了……
procedure TForm1.Magnetize(var nl,nt:integer);
//内嵌两个比大小的函数
function Min(a,b:integer):integer;
begin
if a>b then result:=b else result:=a;
end;
function Max(a,b:integer):integer;
begin
if a end;
var
H_Overlapped,V_Overlapped:boolean; //记录投影线是否重叠
tw,ww,wh:integer; //临时变量
const
MagneticForce:integer=50; //“磁力”的大小。
//准确的说,就是控制窗口边缘至多相距多少像素时需要修正坐标
//为了演示,这里用一个比较夸张的数字――50。
//一般可以用20左右,那样比较接近Winamp的效果
begin
//判断水平方向是否有重叠投影
ww := WinampRect.Right-WinampRect.Left;
tw := Max(WinampRect.Right,nl+Width)-Min(WinampRect.Left,nl);
H_Overlapped := tw<=(Width+ww);
//再判断垂直方向
wh := WinampRect.Bottom-WinampRect.Top;
tw := Max(WinampRect.Bottom,nt+Height)-Min(WinampRect.Top,nt);
V_Overlapped := tw<=(Height+wh);
//足够接近的话就调整坐标
if H_Overlapped then
begin
if Abs(WinampRect.Bottom-nt)
else if Abs(nt+Height-WinampRect.Top)
end;
if V_Overlapped then
begin
if Abs(WinampRect.Right-nl)
else if Abs(nl+Width-WinampRect.Left)
end;
end;
怎么样?运行后效果不错吧!