在屏幕上画一直线。该直线不能因为其它窗口击活而被档住。还有。。。高手来试试呀。 (200分)

  • 主题发起人 主题发起人 lncd
  • 开始时间 开始时间
L

lncd

Unregistered / Unconfirmed
GUEST, unregistred user!
接着标题说,
还有就是能够通过拖动直线的两个端点,让直线可以任意移动(两点一线嘛)。
帮忙提前的也有分。
给线索的也有分。
 
It must be a window,and seems like a line.
 
楼上的朋友已经说了,
 
做个不规则的透明Form,让它AlwaysOnTop,然后……
你想干啥就干啥。嘿嘿!
 
看看这里:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1895973
 
一个窗体,
最大化
borderStyle:=bsnone;
AlwaysOnTop。
设置两个点(控件模拟),使其可以拖动,
在两点之间画直线,注意擦除原来的。
只是只要把其他地方透明就可以了。

///////////////////////////////////////////////////
Delphi6已经封装了这个API,Delphi5的话,就要自己进行函数声明了,

function SetLayeredWindowAttributes(hwnd:HWND; crKey:Longint; bAlpha:byte; dwFlags:longint ):longint; stdcall; external ‘user32.dll';

现在从MSDN里把它的定义考出来,分析一下。

BOOL SetLayeredWindowAttributes(
HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
);
第一个参数:hwnd是指向要操作的窗口的句柄,没什么要说的,基本API都需要的.
第二个参数:crKey是指定要透明的颜色的颜色值,这个参数和第四个参数在制定
为LWA_COLORKEY时才有用,在LWA_ALPHA参数下,一般用0;当指定要透明的颜色值时,
窗口中的制定颜色就会变得‘镂空’!
第三个参数: bAlpha是透明运算的一个参数,简单地说就是透明度,0最透明,就看不到了,
255不透明,和平常的效果一样了。
第四个参数:dwFlags由两个值LWA_COLORKEY和LWA_ALPHA,用于决定用何种方式进行透明处理。
一般用LWA_ALPHA值就可以了.
好了,就这么多了,MSDN里有详细的介绍。


 
放两个shape在一个窗体上

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Shape1: TShape;
Shape2: TShape;
procedure FormCreate(Sender: TObject);
procedure Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Shape1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
OriginalPos: TPoint; // 鼠标按下的位置
CurrentPos: TPoint; // 鼠标新位置
MouseLButtonDown: Boolean; // 标记鼠标左键是否按下

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
l: LongInt;
begin
l := GetWindowLong(Handle, GWL_EXSTYLE);
l := l or WS_EX_LAYERED;
SetWindowLong(Handle, GWL_EXSTYLE, l);
SetLayeredWindowAttributes(Handle, $00C8D0D4, 125, LWA_COLORKEY);
end;

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
MouseLButtonDown := True;
OriginalPos.x := X; // 鼠标按下的位置
OriginalPos.y := Y;
end;
end;

procedure TForm1.Shape1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if MouseLButtonDown then
begin
//画线
Refresh;//这是为了删除原来的线设置的,代码很不好,你自己寻求优化吧
//我这里就不细写了
Canvas.Pen.Color := clRed;
Canvas.MoveTo(Shape1.Left, Shape1.Top);
Canvas.LineTo(Shape2.Left, Shape2.Top);


CurrentPos.x := X; // 鼠标新位置
CurrentPos.y := Y;
with (sender as TShape) do
begin
Left := Left + CurrentPos.x - OriginalPos.x;
Top := Top + CurrentPos.y - OriginalPos.y;
end;
end;
end;

procedure TForm1.Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
MouseLButtonDown := False;
end;

end.

 
谢谢ARMADA,
我以前一直搞不定,像Spy++那样指到一个窗口,画出窗口的Rect,
只好用GetDC(0),结果把桌面画得乱七八糟,现在有你的程序,就可以轻松搞定了。
 
我还是想在屏幕上直接画线,不过线的擦除还觉得有些麻烦。
处理不好就会把屏幕画得一团糟。
/////////////////////////////////////////////
ARMADA,谢谢你热心参与,
透明窗体我试过,实际应用时效果并不好。
主要是刷新不好,导致有时透明,有时又不透明。
还有就是用这种方法要击活其它窗口时显得也不太自然。
我现在正忙项目,等我一有空就测一下你的方法。不管成不成功,
你这么热心,分分时应该不会少啦。:)

/////////////////////
 
微软的动画精灵用了这种技术,既然复杂的图形都可以做到,
做一条线应该是很简单的了
这个函数恐怕是用的着的
UpdateLayeredWindow(

The UpdateLayeredWindow function updates the position, size, shape, content, and translucency of a layered window.


 
透明窗体,只在win2000下有效啊,在win98低下要自己处理
不过不会出现:导致有时透明,有时又不透明 的情况啊?
 
去找TLinLine,用大富翁全文检索:"
谁有画直线的控件呀???小弟急用!!! "
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1661776
 
楼上乱说,扣10分
 
我记得以前玩过一个在桌面上用锤子打蚊子的游戏。
它是怎么实现的。
用它的原理应该可以满足我的要求。
 
用窗体的方式并不好。
thx1180, 提供的思路应该可行。
我要去研究一下。
======================
结贴了。
 

Similar threads

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