对于屏幕上显示的某个特定颜色,其显示的不是颜色,而是我输出的图象.
比如有个第三方窗体,其背景色是RGB(16,0,16),我想让所有显示这个颜色的地方露出我的图象,我知道这是可行的,但是如何做?请资深图形方面朋友支援

解决方案 »

  1.   

    问题已改变为:
    如何设置第三方窗体某个指定颜色透明?我们知道DELPHI中可以设置透明颜色通道,此颜色在窗体显示后将变透明,那么可否指定第三方窗体某个颜色为透明的呢?
      

  2.   

       你打算如何显示?比如别人的窗体大小是400*300,你的图片是200*100,你打算如何做?拉伸你的图像到400*300吗?
        解决这个问题,接下来就是处理了。
        假设你的图片大小和对方窗体的大小一致了。那么,截获对方窗体的WM_PAINT消息,在这个消息里面,先调用原来的处理过程,然后,截获它的图像,遍历所有的点,判断每一点是否和你的目标一致,如果是就把它设置成你的image上对应的点。    如果你仅仅想解决“如何设置第三方窗体某个指定颜色透明?”这个问题,很简单:就是调用SetLayeredWindowAttributes(USER32.DLL中,delphi没有封装,需要自己加载),不过这样的话,那个窗体显示该颜色的地方全部镂空,就是异形窗体了。这样就不能显示你的图片了。  需求更明确一点的话,就有更好的办法了。 
      

  3.   

    1.对于第1种情况,其实要求比这更复杂:别人窗体内容也是不变更新的,我的图片(或视频)当然也可以动的,但两者又互相不干扰.我相信目前这里没人知道完美解决方案,所以算了
    2.第2种情况,可否说详细些?我要的就是镂空效果.至少图片我可以放在新窗体上然后"插在"那窗体底下,这个不难.
    那个SetLayeredWindowAttributes可否给个详细定义或用法? 谢谢!
      

  4.   

    镂空效果用SetWindowRgn,计算区域.
      

  5.   

    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以前的不适用。
      

  6.   

    如何取消透明(LWA_ALPHA的情况)?据我所知,值为255与未使用此函数还是有差异,主频低的机器上能体现出来
      

  7.   

    用SetWindowLang把WS_EX_LAYERED位去掉.
    PS:但是,用SetLayeredWindowAttributes的方法只可以对"整个"窗口改变透明度,而不能实现楼主所要的"特定"区域,应该用SetWindowRgn.
      

  8.   

    SetWindowRgn,如果窗体内容是不断更新变化的,那应如何用?
      

  9.   

    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]
      

  10.   

    TO:12楼etomahawk 他说的是改变一个窗体部分区域的透明度,不是镂空。你的代码仅是把窗体镂空了,而且太长,只须把窗体颜色改为c,SetLayeredWindowAttributes(h, c, 255, LWA_COLORKEY)一句就行。