贴图方法进行软件界面设计的疑问?

fisher_older 2009-10-04 04:40:04
不用第三方皮肤控件,单用贴图片的方法来构造软件界面,遇到几个问题,解决不了,请教高手解答。
先将Form1的borderstyle设为none,然后进行贴图,问题来了:

1、边框用画有圆角的图片来实现,而图片放在panel中,但panel的角是直角,那如何实现圆角?类似qq2008的圆角界面。
2、将边框去掉以后,如何实现窗体拉伸功能?
3、网上有没有做得比较好看一点的界面例程?最好是模仿vista风格的,满世界找都没找到。请提供线索。

当然,不能使用第三方皮肤控件。
很急!感谢!
...全文
219 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
kx11kx 2010-09-10
  • 打赏
  • 举报
回复
关注!
wxsan 2009-10-08
  • 打赏
  • 举报
回复
关注!
ahjoe 2009-10-07
  • 打赏
  • 举报
回复
1. 用圆角窗体
2. 不需要Panel, 窗体本身有canvas可以画图的
3. 鼠标在周边的事件转换成窗体边框的事件 procedure OnHitTest(var msg: TMEssage); message WM_NCHITTEST;



procedure TForm1.OnHitTest(var msg: TMEssage);
const
CORNER_WIDTH = 12;
htvalues: array [0..2, 0..2] of THitWindow =
(
(HTTOPLEFT, HTTOP, HTTOPRIGHT),
(HTLEFT, HTCLIENT, HTRIGHT),
(HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT)
);
var
P: TPoint;
ctrl: TControl;
idx: integer;
idy: integer;
begin
p.x := msg.LParamLo - Left;
p.y := msg.LParamHi - Top;
ctrl := ControlAtPos(p, True, False);
if (ctrl = nil) and (Align <> alClient) then
begin
if (p.x < CORNER_WIDTH) and (p.y < CORNER_WIDTH) then
begin
idx := 0;
idy := 0;
end
else if (p.x < CORNER_WIDTH) and (p.y > Height - CORNER_WIDTH) then
begin
idx := 0;
idy := 2;
end
else if (p.x > Width - CORNER_WIDTH) and (p.y < CORNER_WIDTH) then
begin
idx := 2;
idy := 0;
end
else if (p.x > Width - CORNER_WIDTH) and (p.y > Height - CORNER_WIDTH) then
begin
idx := 2;
idy := 2;
end
else
begin
if p.x < 4 then
idx := 0
else if p.x > Width - 4 then
idx := 2
else
idx := 1;
if p.y < 4 then
idy := 0
else if p.y > Height - 4 then
idy := 2
else
idy := 1;
end;
msg.Result := integer(htvalues[idy, idx]);
end
else
inherited;
end;

fisher_older 2009-10-06
  • 打赏
  • 举报
回复
贴图以后,在图片周围无法实现拉伸。不知道是什么原因?
fisher_older 2009-10-06
  • 打赏
  • 举报
回复
当然,我说的所谓画完圆角后拖拉窗体不正常,是因为贴图以后就不能拉伸了。
皮皮鲁,我是这样做的:在窗体下部放置一个panel,Align:=Bottom,panel里放一个image,Align:=Client。加载一张图片。然后在FormCreate事件里让窗体画成圆角,圆角实现后,鼠标移到边框处无法拉伸。当然,不贴图就没有这种情况。
请问大虾们,这是什么原因呢?
fisher_older 2009-10-05
  • 打赏
  • 举报
回复
彪窃狂,不要生气嘛,没回你的话是因为在等你的下文呢,DX组件的方法你能详细说一下吗?
皮皮鲁和小笨象,谢谢你们的回答,我基本已经搞定了。我想有很多同仁会受益于二位的无私答复的。
只爱三国,请不要抱怨,只是因为在论坛里搜索了好几天也没有满意的答案,所以只好发帖求助。
再次感谢大家的热心。
做界面应该是大多数程序员都要面临的问题,希望大家集思广益,能够多出点主意,对大家都有好处。
过两天就结贴,参与者都有分。
sanguomi 2009-10-05
  • 打赏
  • 举报
回复
一天到晚都是些老问题
wzzwwz 2009-10-05
  • 打赏
  • 举报
回复
那我坏人做到家吧,拿小象的代码改的,亲测OK

unit Unit1;

interface

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

type
TForm1 = class(TForm)
procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
OldWndProc: TWndMethod;
function CheckMouseInBorder(X, Y: Integer;
var AResult: Integer): Boolean;
procedure NewWndProc(var AMsg: TMessage);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure RoundRgn(frm: TCustomForm);
var
hRgn1: HRGN;
begin
BeginPath(frm.Canvas.Handle);
RoundRect(frm.Canvas.Handle, 1, 1, frm.Width, frm.Height, 50, 50);
EndPath(frm.Canvas.Handle);
hRgn1 := PathToRegion(frm.Canvas.Handle);
SetWindowRgn(frm.Handle, hRgn1, True);
end;

function TForm1.CheckMouseInBorder(X, Y: Integer;
var AResult: Integer): Boolean;
begin
Result := False;
//判断当前鼠标的位置,是否在边界上,以改变鼠标并进行拖拉
//并返回所处的位置。
X := X - Left;
Y := Y - Top;

//最大化时不处理。
if (WindowState = wsMaximized) then
begin
Exit;
end;

if (X<=10) and (Y<=10) then
aResult := HTTOPLEFT //左上角
else if (X<=10) and (Y>=ClientHeight-10) then
aResult := HTBOTTOMLEFT //左下角
else if (X<=2) then
aResult := HTLEFT //左边
else if(X>=ClientWidth-10) and (Y<=10) then
aResult := HTTOPRIGHT //右上角
else if(X>=ClientWidth-10) and (Y>=ClientHeight-10) then
aResult := HTBOTTOMRIGHT //右下角
else if(X>=ClientWidth-2) then
aResult := HTRIGHT //右边
else if(Y>=ClientHeight-2) then
aResult := HTBOTTOM //下边
else if(Y<=2) then
aResult := HTTOP //上边
else
Exit;

Result := True;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
RoundRgn(Self);
end;

procedure TForm1.NewWndProc(var AMsg: TMessage);
var
ret: Integer;
begin
OldWndProc(AMsg);
if (AMsg.Msg = WM_NCHITTEST) and
CheckMouseInBorder(aMsg.LParamLo, aMsg.LParamHi, ret) then
AMsg.Result := ret;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
OldWndProc := WindowProc;
WindowProc := NewWndProc;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
WindowProc := OldWndProc;
end;

end.
fhfanxin 2009-10-04
  • 打赏
  • 举报
回复
楼上的翻译成delphi语言可以吗?

做好人做到底
小笨象 2009-10-04
  • 打赏
  • 举报
回复
为何不能编辑俺自己写的东西?

这些代码,都是《资料收集库》里的代码。

void __fastcall TDocBookMainForm::WndProc(Messages::TMessage &Msg)
{
TForm::WndProc(Msg);
switch(Msg.Msg)
{
case WM_NCHITTEST:
{
Msg.Result = CheckMouseInBorder(Msg.LParamLo,Msg.LParamHi);
break;
}
}
}

小笨象 2009-10-04
  • 打赏
  • 举报
回复
皮皮鲁的方法,画圆角应该没问题。主要是画完圆角后调用拖拉程序时会不正常??
怎么不正常了?正常得很!
这个函数在Form的onmousemove中调用即可。

int __fastcall TDocBookMainForm::CheckMouseInBorder(int X,int Y)
{
//判断当前鼠标的位置,是否在边界上,以改变鼠标并进行拖拉
//并返回所处的位置。
X = X - Left;
Y = Y - Top;

//最大化时不处理。
if(WindowState == wsMaximized) return HTCLIENT;

if(X<=10 && Y<=10) return HTTOPLEFT; //左上角
if(X<=10 && Y>=ClientHeight-10) return HTBOTTOMLEFT;//左下角
if(X<=2) return HTLEFT; //左边
if(X>=ClientWidth-10 && Y<=10) return HTTOPRIGHT; //右上角
if(X>=ClientWidth-10 && Y>=ClientHeight-10)
return HTBOTTOMRIGHT;//右下角
if(X>=ClientWidth-2) return HTRIGHT; //右边
if(Y>=ClientHeight-2) return HTBOTTOM; //下边
if(Y<=2) return HTTOP; //上边
return HTCLIENT;
}
//---------------------------------------------------------------------------
fhfanxin 2009-10-04
  • 打赏
  • 举报
回复
靠,无视我的存在啊????

本来回顾一下,看问题是否结了,如果没结,那我继续给你找DX组件方面的资料。

现在没心思了,你自己去找吧
fisher_older 2009-10-04
  • 打赏
  • 举报
回复
皮皮鲁的方法,画圆角应该没问题。主要是画完圆角后调用拖拉程序时会不正常。
我相信一定有人做过,希望有经验的同仁能够不吝赐教,有代码和详细步骤那是最好了。再次感谢所有人!
mdejtod 2009-10-04
  • 打赏
  • 举报
回复
只要不是异形窗体,很简单的,使用一个带有透明度调节的panel即可

wzzwwz 2009-10-04
  • 打赏
  • 举报
回复
什么的效果不好?如果要进行复杂区域创建,需要创建多次,然后合并的。
拉伸的话,你可以在右下角可见区域放一个控件,鼠标移动到那里的时候改变鼠标样式,拖拉的效果要自己实现了
fisher_older 2009-10-04
  • 打赏
  • 举报
回复
wzzwwz你好,画圆角的方法我也试过,
比如:
var hr :thandle;
hr:=createroundrectrgn(0,0,width,height,6,6);
setwindowrgn(handle,hr,true);

窗体的确能实现圆角,但是效果并不太好,并且对窗体拉伸之类的操作有冲突。
fisher_older 2009-10-04
  • 打赏
  • 举报
回复
bdmh你好,你说的方法我试了一下,好像不太可行,因为贴图是很多块组成的。
alphablend:=true;
alphablendvalue:=0;
连贴图都看不见了。
异性窗体源码很多,但是都是使用的单张图片实现的。
iqyely 2009-10-04
  • 打赏
  • 举报
回复
这个要来关注下。
fhfanxin 2009-10-04
  • 打赏
  • 举报
回复
bdmh一直都是超速打字中………………

关于这个问题,可以使用DX组件

具体资料,我去万一的博客剽窃一下
wzzwwz 2009-10-04
  • 打赏
  • 举报
回复
bdmh 神速啊,我打字的功夫。。。
加载更多回复(2)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧