关于一个画边框和清除所画边框的问题!(225分)

  • 主题发起人 主题发起人 Luis Pater
  • 开始时间 开始时间
上面哪些程序当然不能在其他的窗体上画框!
procedure MakeIt(WantHandle:HWND);
var
DC:hDC;
MyRect:TRect;
begin
DC := GetWindowDC(WantHandle);
Canvas.Handle:=dc;
Canvas.Pen.Mode:=pmXor;
//Canvas.Pen.Color:=RGB(255, 100, 0);
Canvas.Pen.Color:=RGB(255, 255, 255);
Canvas.Pen.Width:=5;
Canvas.Brush.Style:=bsClear;
GetWindowRect(MyHandle,MyRect);
Canvas.Rectangle(0,0,MyRect.Right-MyRect.Left-1,MyRect.Bottom-MyRect.Top-1);
end;

这段代码只要配合一个与以下类似的过程就可以在其他窗体上画框:
var
MyHandle:HWND;
P:TPoint;
begin
GetCursorPos(P);
MyHandle:=WindowFromPoint(P);
MakeIt(MyHandle);
end;
但是以上这些代码仅仅是反色线条,并不是我要的指定的颜色的线条!
问题是画四条直线的方法我也用过了!很不理想!还有就是 beyondair 的后面的那种方法
也不可行!因为我应用这个程序的范围不单单是 Windows 9x、2000这些基本平台,还需要
考虑到 Windows XP 用了一些界面增强以后的特殊的窗体……[:(][:(][:(][:(]
 
这样不知道你是否满意? 我的意思是你既然可以画边框的话,为什么不可以用当前form的
颜色重新画一遍? 那样的话也能达到你要的效果啊!
代码如下:
var
red,blue,yellow : integer;
canshowrim : Boolean;
//自定义加边框颜色的函数
procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
var
dc : hDc;
Pen : hPen;
OldPen : hPen;
OldBrush : hBrush;
begin
inherited;
dc := GetWindowDC(Handle);
msg.Result := 1;
if canShowrim then
begin
red := 255; blue := 100;Yellow :=0;
end else
begin
red := 192; blue := 192;Yellow :=192; //本处是你自己窗体的颜色
end;
Pen := CreatePen(PS_SOLID, 1, RGB(red,blue, yellow));
OldPen := SelectObject(dc, Pen);
OldBrush := SelectObject(dc, GetStockObject(NULL_BRUSH));
Rectangle(dc, 0,0, Form1.Width, Form1.Height);
SelectObject(dc, OldBrush);
SelectObject(dc, OldPen);
DeleteObject(Pen);
ReleaseDC(Handle, Canvas.Handle);
end;

//给窗体边框加红色
procedure TForm1.Button1Click(Sender: TObject);
var
Msg : TWMNCPaint;
begin
canshowrim := True;
WMNCPaint(msg);
end;

//给窗体边框加和窗体同样的颜色。
procedure TForm1.Button2Click(Sender: TObject);
var
msg : TwmncPaint;
begin
canshowrim := False;
WMNCPaint(Msg );//
end;
 
To, Luis Pater
在winXP里更好办,因为那里窗体的四周都是蓝色的,我昨天贴的用notxor的方法就是winXP
测试的,但效果记不清了,现在用的是2000,没法测
To: xiao_wen
你的方法没有还原边框,边框不是单色的
 
var
Form1: TForm1;
hOldWnd :HWND;
implementation

{$R *.DFM}


procedure FrameWindow(Wnd: HWnd);
var
Rect: TRect;
DC: hDC;
OldPen, Pen: hPen;
OldBrush, Brush: hBrush;
X2, Y2: Integer;
begin
{ Get the target window's rect and DC }
GetWindowRect(Wnd, Rect);
DC := GetWindowDC(Wnd);
{ Set ROP appropriately for highlighting }
SetROP2(DC, R2_NOT);
{ Select brush and pen }
Pen := CreatePen(PS_InsideFrame, 4, 0);
OldPen := SelectObject(DC, Pen);
Brush := GetStockObject(Null_Brush);
OldBrush := SelectObject(DC, Brush);
{ Set dimensions of highlight }
X2 := Rect.Right - Rect.Left;
Y2 := Rect.Bottom - Rect.Top;
{ Draw highlight box }
Rectangle(DC, 0, 0, X2, Y2);
{ Clean up }
SelectObject(DC, OldBrush);
SelectObject(DC, OldPen);
ReleaseDC(Wnd, DC);
{ Do NOT delete the brush, because it was a stock object }
DeleteObject(Pen);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
hNewWnd: HWnd;
begin
hNewWnd := WindowFromPoint(Mouse.CursorPos);
{ To avoid flickering, remove the old frame ONLY if moved to new window }
if hNewWnd <> hOldWnd then
begin
if hOldWnd <> 0 then
FrameWindow(hOldWnd);
if hNewWnd <> 0 then
FrameWindow(hNewWnd);
hOldWnd := hNewWnd;
end;
end;
 
To, Luis Pater
用你的函数,我还是没能在另外的窗体上画出框来,makeit(form2.handle);
但本窗体就可以,不知是什么原因,
doll_paul说的是对的,要想解决这个问题,还得局部重画,这个是肯定可行的,因为
把窗体移出屏幕外,再移回来,只有移出去的部分才会重画,不会影响其它部分,象
form1.BorderWidth:=1; form1.BorderWidth:=0; 这样类似的语句都可以引起
局部重画,但我没有办法知道它们是怎么干的。
 
下面这个API函数可以让屏幕上任何一块矩形区域里的东西重画,可以用四个小矩形
包围框框的四条边,分别重绘就可以了

BOOL InvalidateRect(

HWND hWnd, // handle of window with changed update region
CONST RECT *lpRect, // address of rectangle coordinates
BOOL bErase // erase-background flag
);
hWnd:传0即可,即指定屏幕区域
^rect: @rc, rc--将框框的四条边,分别以四个最小矩形包围,//只重画这四条边,
以免闪烁严重
berase:true or false;
下面的例子刷新了整个屏幕,所以重画的地方都闪烁,如果只重画四边就不会了吧,试试看吧
procedure TForm1.Button1Click(Sender: TObject);
var
DC : hDc;
begin
DC := GetWindowDC(Handle);
Canvas.Handle:=dc;
Canvas.Pen.Color:=RGB(255, 100, 0);
Canvas.Pen.Width:=3;
Canvas.Brush.Style:=bsClear;
Canvas.Rectangle(0,0,Width,Height);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
rc:Trect;
begin
rc:=rect(0,0,400,400);//要重画的区域
invalidateRect(0,@rc,true);//重画
end;
 
to beyondair,QQ留言收到~我身体不太舒服,所以下班就回家了~

以上几位的代码都是了,依然没有解决问题。

peng_qs的代码好像不是指定色彩,应该也是用Xor原理吧?

而老兄你的呢,虽然用了我说的函数,但好像还是有明显的闪烁啊!

另外,关于局部更新的API好像不止一个.....大家努力吧,呵可~
 
问题远远没有大家想象得那么简单!不要以为 Windows XP 就是那种单板的蓝色,光它自
带的就有三种配色方案,何况我的界面就更加花哨了!请看截图:
http://yourweb.vicp.net/MyWindows.jpg
图片可能有点大(100K)!用猫的用户请见谅!由于使自己的机器,虽然作 FTP 服务器,
但难免有时还是要重新启动的!所以下不了请隔几个小时再试试看!谢谢!
还有我所说的那画反色边框,beyondair说用我定义的过程画不出来!我给大家完整代码,
大家自己下一下,然后编译一下!地址:
http://yourweb.vicp.net/Test.zip
编译环境:Delphi 6+SP2+Windows 2000 &amp; Windows XP

另:我免费提供大家50MB支持 PHP、PERL、MySQL、ODBC 的主页空间!100M直连中国电信
光纤骨干网![8D]不过就是机器配置有点差,使我自己的家用计算机![:)][:)]
 
呵,谁也没说简单啊,真是的~

你的代码,我测试无效果~

别外,如果支持MSSQL的话,我用~呵呵!
 
PHP、CGI 上用 MSSQL??有没有搞错啊??我可没有给你运行 ASP 的功能哦!我的机器
永远不会支持 VB 语法的应用语言的![8D][8D][8D][8D]
代码运行无效果???不会吧??按住图案鼠标左键不放,将鼠标拖曳到其他窗体上去啊!
我除了 9x 平台没试验过,其他 NT 系统运行的都很正常的啊![?][?][?][?]
 
可真的没有效果哦~

呵呵,PHP,CGI怎么不可能用MSSQL??我不要ASP,我只要一个数据库测试软件用~

别外,你就这么看不起VB吗???
 
我最最不喜欢的就是 Basic!不要意思![8D][8D]
测试数据库??你这个也太奢侈了吧……MS SQL 太费系统资源……我的机器拖不动啊!
怎么会没有效果呢……不可能啊!我测试过很多机器了……都没问题的啊!
 
呵呵,老兄,有必要对Basic这样吗?如果不是MS就没有今天,哈哈~~~

你的代码我昨天没好好看,因为身体不舒服,刚才中午测试了,没问题~

细看代码,发现用的一样是XOr。我们上面的讨论早说过了,这种办法不成的!!!!!
 
To doll_paul:
我上面给出的InvalidateRect函数是先使指定的矩形区域无效,再引起重画,应该可
以能够完成老兄说的局部重画的功能吧,我上面的代码是重画整个屏幕,闪是必然的
你试了没有只将窗体的四条边重画,效果如何
另外,我上面说过,即使是局部重画,因为色彩快速交替想一点都不闪也不大可能,你
再用别的函数也同样是重画嘛,会有区别么?
To Luis Pater
不管你用什么Windows系统,局部重画总是可以擦去你自己画的框框的,上面的函数,你
试了没有?如还不行,只有再想办法
 
to beyondair,你的意思我完全明白~但是,你要知道,我们现在说的局部涮新的闪烁,根本
不是由于色彩交替的结果。。。。。。另外,我在QQ上让你试的Rea...那个API,好像也可
以起到局部重绘的作用~但我没有试成,总是整理桌面涮新!
 
我想到一种方法:
截取四条边框的图位信息,在需要取消边框的时候将这些图位信息重新绘制到窗体上……
不过就是不知道这个方法可不可行……两位看看?[:)][:)][:)]
 
to Luis Pater,不是我打击你,你的这个想法,我当时在一个VC的朋友提醒下,就想到了~
反正我没有测试成功,你可以试试~
 
我当时也有人提醒我这样,但是我找不到一个可行的方案……
在思考思考吧……
 
xiao_wen的做法很好吗
干吗
想那么多
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
后退
顶部