对我来说值一百分的问题,请大家帮忙(急)(100分)

  • 主题发起人 主题发起人 sycamore
  • 开始时间 开始时间
S

sycamore

Unregistered / Unconfirmed
GUEST, unregistred user!
我想做一个多媒体界面,无标题栏,我用下面的方法可以在运行情况下移动,但我想关闭点SpeedButton1却没反应,请问该如
何使界面可以移动又点击其他控件有反应呢?
interface
.....
type
TForm1 = class(TForm)
Image1: TImage;
SpeedButton1: TSpeedButton;
procedure SpeedButton1Click(Sender: TObject);
private
{ Private declarations }
procedure WMNchittest(var msg:twmnchittest);
MESSAGE WM_NCHITTEST;
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation

{$R *.dfm}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin

close;
end;

procedure TForm1.WMNChitTest(var Msg:TWMNChitTest);
begin

inherited;
if msg.Result=htclient then

msg.Result:=htcaption;
end;


end.

请问我该增加什么语句才能使我的SpeedButton1生效(急)
 
检查一下你的close事件里的代码
 
请详细点,我看过很多例子,都说对一个按扭控件来说是很简单的,却一个例子也没有,所以一直
弄不明白。希望freebit能够把代码写下来,如可行,马上送上分数,谢了[?]
 
我按着你给的代码可行呀
 
你这段代码是不是别的地方复制来得?

如果是的话,你双击一下你的speedbutton,在dfm文件里生成相关的代码.
 
{procedure TForm1.WMNChitTest(var Msg:TWMNChitTest);
begin

inherited;
if msg.Result=htclient then

msg.Result:=htcaption;
end;
}
由于以上程序你点击在程序上时都被认为是点在CAPTION 上(所以才能移动)
我想可以在此检查点击的位置,如果MOUSE的位置在SPEEDBUTTON上则不执行
msg.Result:=htcaption
 
你这可不是什么好办法,把整个窗口客户区的鼠标事件全部当成了非客户区的事件,
所以单击按钮的事件也变成了非客户区事件,而恰好 TSpeedButton 是从
TGraphicControl 继承下来的,所以就无法正确响应了。

临时解决办法:
截获消息时,如果鼠标在 SpeedButton 上,则不将其转为非客户区消息:

procedure TForm1.WMNChitTest(var Msg:TWMNChitTest);
var
pt: TPoint;
InRect: Boolean;
begin

inherited;
if msg.Result=htclient then

begin

pt := ScreenToClient(Point(msg.XPos, msg.YPos));

with SpeedButton1do

InRect := (pt.X > Left) and (pt.X < Left + Width) and
(pt.Y > Top) and (pt.Y < Top + Height);

if not InRect then

msg.Result:=htcaption;
end;

end;


不过如果你有多个 SpeedButton 在窗口上,这样就会很麻烦。


更好的解决方法:
用记录鼠标位置的方法移动窗口:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;

type
TForm1 = class(TForm)
SpeedButton1: TSpeedButton;
procedure SpeedButton1Click(Sender: TObject);
procedure FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
procedure FormMouseMove(Sender: TObject;
Shift: TShiftState;
X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Form1: TForm1;

impelmentation

var
OldXY: TPoint;

procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
begin

OldXY := Point(X, Y);
end;


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

if ssLeft in Shift then

begin

Left := Left + X - OldXY.X;
Top := Top + Y - OldXY.Y;
end;

end;


这样无论窗口上有多少 SpeedButton 都不怕。
而且,如果窗口被正幅图片沾满的话,就把 Form1 的 MouseDown 和 MouseMove 事件
改成那个图片的相应事件,就 OK 了。

 
若窗口被图片占满就改成这个:
(注意设置 Image1 的 OnMouseDown 和 OnMouseMove 事件就可以了)

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;

type
TForm1 = class(TForm)
SpeedButton1: TSpeedButton;
Image1: TImage;
procedure SpeedButton1Click(Sender: TObject);
procedure Image1MouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
procedure Image1MouseMove(Sender: TObject;
Shift: TShiftState;
X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Form1: TForm1;

implementation

var
OldXY: TPoint;

{$R *.dfm}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin

Close;
end;


procedure TForm1.Image1MouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
begin

OldXY := Point(X, Y);
end;


procedure TForm1.Image1MouseMove(Sender: TObject;
Shift: TShiftState;
X,
Y: Integer);
begin

if ssLeft in Shift then

begin

Left := Left + X - OldXY.X;
Top := Top + Y - OldXY.Y;
end;

end;


end.

 
感谢大家的帮忙,上面的代码是我看了大量资料写的,很不理想,又没解决办法,所以来这
求助,以上各位提供的方法我先试试,哪一个可行,我马上把分数奉上,但只能给我采用的那个人。
对大家的参于和帮助非常感激,我是个delphi爱好者也是个初学者,希望能够在这里和大家共同进步,
谢谢!
 
接受答案了.
 
to beta
谢了
 
后退
顶部