高难度问题: 如何向指定颜色输出图像? 对于屏幕上显示的某个特定颜色,其显示的不是颜色,而是我输出的图象.比如有个第三方窗体,其背景色是RGB(16,0,16),我想让所有显示这个颜色的地方露出我的图象,我知道这是可行的,但是如何做?请资深图形方面朋友支援 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 问题已改变为:如何设置第三方窗体某个指定颜色透明?我们知道DELPHI中可以设置透明颜色通道,此颜色在窗体显示后将变透明,那么可否指定第三方窗体某个颜色为透明的呢? 你打算如何显示?比如别人的窗体大小是400*300,你的图片是200*100,你打算如何做?拉伸你的图像到400*300吗? 解决这个问题,接下来就是处理了。 假设你的图片大小和对方窗体的大小一致了。那么,截获对方窗体的WM_PAINT消息,在这个消息里面,先调用原来的处理过程,然后,截获它的图像,遍历所有的点,判断每一点是否和你的目标一致,如果是就把它设置成你的image上对应的点。 如果你仅仅想解决“如何设置第三方窗体某个指定颜色透明?”这个问题,很简单:就是调用SetLayeredWindowAttributes(USER32.DLL中,delphi没有封装,需要自己加载),不过这样的话,那个窗体显示该颜色的地方全部镂空,就是异形窗体了。这样就不能显示你的图片了。 需求更明确一点的话,就有更好的办法了。 1.对于第1种情况,其实要求比这更复杂:别人窗体内容也是不变更新的,我的图片(或视频)当然也可以动的,但两者又互相不干扰.我相信目前这里没人知道完美解决方案,所以算了2.第2种情况,可否说详细些?我要的就是镂空效果.至少图片我可以放在新窗体上然后"插在"那窗体底下,这个不难.那个SetLayeredWindowAttributes可否给个详细定义或用法? 谢谢! 镂空效果用SetWindowRgn,计算区域. 1.对于第1种情况,其实要求比这更复杂:别人窗体内容也是不变更新的,我的图片(或视频)当然也可以动的,但两者又互相不干扰.我相信目前这里没人知道完美解决方案,所以算了-------------------------------------------- 这个嘛,我想到一个较笨的方法,先让别人的窗体镂空,这个我已经说过了,直接用SetLayeredWindowAttributes就可以搞定。然后,创建一个窗体,跟别人的窗体大小一样,把它放到别人窗体的下面,在上面显示自己的视频或者图片。然后处理消息,当别人窗体移动的时候跟着一起移动。以前看过比人实现的Vista玻璃效果就是这么搞的。应当没问题。 很好搞定。给你一个SetLayeredWindowAttributes的例子。 TSetLayeredWindowAttributes = function (Handle: DWORD; ClrKey: COLORREF; Alpha: BYTE; Flags: DWORD ):Boolean; stdcall; FunAddr: TSetLayeredWindowAttributes;// Alpha: 窗体的透明度// ColorKey: 需要透明的颜色procedure TForm1.SetAlphaWindow(Alpha: integer; ColorKey: TColor);var NewStyle: DWORD; hLib: THandle;begin hLib:= LoadLibrary('USER32.DLL'); FunAddr:= GetProcAddress(hModel, 'SetLayeredWindowAttributes'); // 这里没有检查是否加载成功 // 自己处理一下 // 设置窗体透明属性 NewStyle:= GetWindowLong(Self.Handle, GWL_EXSTYLE) or WS_EX_LAYERED; SetWindowLong(Self.Handle, GWL_EXSTYLE, NewStyle); // 调用SetLayeredWindowAttributes FunAddr( FWinHandle, ColorKey, Alpha, LWA_COLORKEY or LWA_ALPHA); // 重绘窗体 RedrawWindow(Self.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN); // FreLibrary(hLib);end;注意: 这个函数只能用于NT系统。9X以前的不适用。 如何取消透明(LWA_ALPHA的情况)?据我所知,值为255与未使用此函数还是有差异,主频低的机器上能体现出来 用SetWindowLang把WS_EX_LAYERED位去掉.PS:但是,用SetLayeredWindowAttributes的方法只可以对"整个"窗口改变透明度,而不能实现楼主所要的"特定"区域,应该用SetWindowRgn. SetWindowRgn,如果窗体内容是不断更新变化的,那应如何用? 10楼的,谁跟你说SetLayeredWindowAttributes不能实现特定区域?你有没有试验过?翻看MSDN好好看看。你有没有研究过类似QQ音乐或酷狗音乐歌词显示的那种效果?我立即写个给你看看能不能实现。[code=Delphi(Pascal)]unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;type TSetLayeredWindowAttributes = function (Handle: DWORD; ClrKey: COLORREF; Alpha: BYTE; Flags: DWORD ):Boolean; stdcall; TForm1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); private { Private declarations } FunAddr: TSetLayeredWindowAttributes; procedure WMPaint(var Msg: TMessage); message WM_PAINT; public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);var NewStyle: DWORD; hLib: THandle;begin Self.BorderStyle:= bsNone; hLib:= LoadLibrary('USER32.DLL'); FunAddr:= GetProcAddress(hLib, 'SetLayeredWindowAttributes'); // 设置窗体透明属性 NewStyle:= GetWindowLong(Self.Handle, GWL_EXSTYLE) or WS_EX_LAYERED; SetWindowLong(Self.Handle, GWL_EXSTYLE, NewStyle); // 调用SetLayeredWindowAttributes FunAddr(Self.Handle, $C8D0D4, 255, LWA_COLORKEY); // 重绘窗体 RedrawWindow(Self.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN); // Free library FreeLibrary(hLib);end;procedure TForm1.WMPaint(var Msg: TMessage);begin Self.Canvas.Font.Color:= clRed; Self.Canvas.Font.Size := 20; Self.Canvas.Font.Style:= [bsBold]; Self.Canvas.TextOut(10, 10, '测试一下');end;end.code] TO:12楼etomahawk 他说的是改变一个窗体部分区域的透明度,不是镂空。你的代码仅是把窗体镂空了,而且太长,只须把窗体颜色改为c,SetLayeredWindowAttributes(h, c, 255, LWA_COLORKEY)一句就行。 Delphi XE如何多层开发? 用delphi开发报表,是最合适的工具吗? createoleobject对象的问题? 关于报表的备注和显示内容如何放置的问题请教 关于InHttp的问题,急急急,请各位老大帮帮在下,无胜感激! 急救!!!紧急寻觅类似与QQ的聊天源程序<包括服务端和客户端>.最好服务端的数据库也附上,谢谢!!! 关于浮点数的函数转换问题,先谢谢! 字符串问题很简单的 (高分相送100) BDE是如何访问数据库的? 如何实现一表的行列转换--在线等待 推荐unsigned 做Delphi版主 请教简单的多线程问题
如何设置第三方窗体某个指定颜色透明?我们知道DELPHI中可以设置透明颜色通道,此颜色在窗体显示后将变透明,那么可否指定第三方窗体某个颜色为透明的呢?
解决这个问题,接下来就是处理了。
假设你的图片大小和对方窗体的大小一致了。那么,截获对方窗体的WM_PAINT消息,在这个消息里面,先调用原来的处理过程,然后,截获它的图像,遍历所有的点,判断每一点是否和你的目标一致,如果是就把它设置成你的image上对应的点。 如果你仅仅想解决“如何设置第三方窗体某个指定颜色透明?”这个问题,很简单:就是调用SetLayeredWindowAttributes(USER32.DLL中,delphi没有封装,需要自己加载),不过这样的话,那个窗体显示该颜色的地方全部镂空,就是异形窗体了。这样就不能显示你的图片了。 需求更明确一点的话,就有更好的办法了。
2.第2种情况,可否说详细些?我要的就是镂空效果.至少图片我可以放在新窗体上然后"插在"那窗体底下,这个不难.
那个SetLayeredWindowAttributes可否给个详细定义或用法? 谢谢!
这个嘛,我想到一个较笨的方法,先让别人的窗体镂空,这个我已经说过了,直接用SetLayeredWindowAttributes就可以搞定。然后,创建一个窗体,跟别人的窗体大小一样,把它放到别人窗体的下面,在上面显示自己的视频或者图片。然后处理消息,当别人窗体移动的时候跟着一起移动。以前看过比人实现的Vista玻璃效果就是这么搞的。应当没问题。
很好搞定。给你一个SetLayeredWindowAttributes的例子。
TSetLayeredWindowAttributes = function (Handle: DWORD; ClrKey: COLORREF; Alpha: BYTE; Flags: DWORD ):Boolean; stdcall; FunAddr: TSetLayeredWindowAttributes;// Alpha: 窗体的透明度
// ColorKey: 需要透明的颜色
procedure TForm1.SetAlphaWindow(Alpha: integer; ColorKey: TColor);
var
NewStyle: DWORD;
hLib: THandle;
begin
hLib:= LoadLibrary('USER32.DLL');
FunAddr:= GetProcAddress(hModel, 'SetLayeredWindowAttributes');
// 这里没有检查是否加载成功
// 自己处理一下 // 设置窗体透明属性
NewStyle:= GetWindowLong(Self.Handle, GWL_EXSTYLE) or WS_EX_LAYERED; SetWindowLong(Self.Handle, GWL_EXSTYLE, NewStyle); // 调用SetLayeredWindowAttributes
FunAddr( FWinHandle, ColorKey, Alpha, LWA_COLORKEY or LWA_ALPHA); // 重绘窗体
RedrawWindow(Self.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN); //
FreLibrary(hLib);
end;注意: 这个函数只能用于NT系统。9X以前的不适用。
PS:但是,用SetLayeredWindowAttributes的方法只可以对"整个"窗口改变透明度,而不能实现楼主所要的"特定"区域,应该用SetWindowRgn.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;type
TSetLayeredWindowAttributes = function (Handle: DWORD; ClrKey: COLORREF; Alpha: BYTE; Flags: DWORD ):Boolean; stdcall; TForm1 = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FunAddr: TSetLayeredWindowAttributes; procedure WMPaint(var Msg: TMessage); message WM_PAINT; public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
var
NewStyle: DWORD;
hLib: THandle;
begin
Self.BorderStyle:= bsNone; hLib:= LoadLibrary('USER32.DLL');
FunAddr:= GetProcAddress(hLib, 'SetLayeredWindowAttributes'); // 设置窗体透明属性
NewStyle:= GetWindowLong(Self.Handle, GWL_EXSTYLE) or WS_EX_LAYERED; SetWindowLong(Self.Handle, GWL_EXSTYLE, NewStyle); // 调用SetLayeredWindowAttributes
FunAddr(Self.Handle, $C8D0D4, 255, LWA_COLORKEY); // 重绘窗体
RedrawWindow(Self.Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN); // Free library
FreeLibrary(hLib);
end;procedure TForm1.WMPaint(var Msg: TMessage);
begin
Self.Canvas.Font.Color:= clRed;
Self.Canvas.Font.Size := 20;
Self.Canvas.Font.Style:= [bsBold]; Self.Canvas.TextOut(10, 10, '测试一下');
end;end.
code]