http://blog.csdn.net/riklin/article/details/4417247

看好了,这是XP系统,未装.net。我的Photoshop学的不太好,把玻璃片弄的太透了些,如果你们有好的美术,再加上这种技术,肯定会如鱼得水。下面就来详细说说它的制作过程吧: 
    第 一步:在VC6中使用GDI+:你得从网上弄个GDI+ for XP的库,大约500K。如果找不到的话,找我QQ要吧,我会把这个窗口的源程序一起发给你的。把它解压后,将所有文件还包括子目录中的文件复制到你的项 目目录。在stdafx.h中加入以下代码: 
             #include "gdiplus.h"

using namespace Gdiplus; 
            #pragma comment(lib, "gdiplus.lib") ////请修改为你的.lib文件路径 
    我的项目名为Test,所以在TestApp中加入全局变量 
ULONG_PTR gdiplusToken; 
    在BOOL CTestApp::InitInstance()中加入这两行: 
       GdiplusStartupInput gdiplusStartupInput; 
       GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 
    记住在线程退出后要御掉GDI+,它很占资源的,在int CTestApp::ExitInstance() 中加入这行: 
      GdiplusShutdown(gdiplusToken); 
    一切准备工作就绪,开始制作窗口了。

二、制作PNG图像:这不是程序员的事,是美工的事,可是目前美术技术都是我一人,所以干脆连PNG一起教你们做了吧。 
    先打开Photoshop(简称PS),打开一张背景图,在背景图上使用圆角矩形工具 画个矩型,再用图层样式调出如下绿色玻璃片: 
 
    什么?怎么个调出来的?你还真以为我什么都教你?要是我连PS的过程都写上来,那我干脆写本书得了。体谅一下吧,写教程是需要大量时间的,所以能省则省。 
    将背景去掉,将玻璃保存成PNG图片,不需要设置任何参数,PNG是自动使用这种与背景溶合透明的,强大吧^_^! 
    再用同样的方法,制作绿色按钮 ,记住做界面的时候,一般要使用一种主色调,在这里我随便用了下绿色作为主色调,现在网络流行的是蓝色。文字则不能用RGB色彩,这样用户容易产生视觉疲劳。我做这个界面只是想试试绿玻璃好不好看,结果觉得不怎么好看,以后有空再弄个蓝玻璃试试吧。 
    按钮不需要保存成PNG,因为我不准备将它透明。至于这种“透明控件”的文章,你在网上一搜一大堆。 
    继续吧!还要做其它3个按钮,“确定”的按下效果,“取消”的拾起和按下效果,在这里我就不截图了。 
    美术都搞定,开始写代码。

三、写代码之前,我先说说工序:先用SetWindowLong将对话框设置成层级窗体,再使用GDI+显示图片。显示成功后再用UpdateLayeredWindow函数进行透明处理。 
    现在问题出来了,你会发现你原来在窗口上画的控件一概不显示,怎么办呢?我是在这个窗口上再盖上另一个对话框,设置成启动窗体那种样式,所有消息都在这个前景窗体上处理。 
    问题又来了,前景窗体盖上去,后面窗口又看不见了,怎么办呢?我又想了办法,在前景窗体加了透明色,在这里我是用粉红色,因为在电脑中粉红色用的最少,因为它很刺眼。用这个方法的缺点就是你的控件不能有粉红色。 
    最后将两个按钮改成位图按钮即可。

现在来看详细制作过程吧: 
    定义成员变量:在TestDlg.h中定义 
BLENDFUNCTION m_Blend; 
HDC m_hdcMemory;

改成层级窗体:在BOOL CTestDlg::OnInitDialog()函数中加入如下代码: 
//窗体样式为0x80000为层级窗体 
DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE); 
SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);

加载PNG图片: 
//绘制内存位图 
HDC hdcTemp=GetDC()->m_hDC; 
m_hdcMemory=CreateCompatibleDC(hdcTemp); 
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,500,500); 
SelectObject(m_hdcMemory,hBitMap);

//使用GDI+载入PNG图片 
HDC hdcScreen=::GetDC (m_hWnd); 
RECT rct; 
GetWindowRect(&rct); 
POINT ptWinPos={rct.left,rct.top}; 
Graphics graph(m_hdcMemory);   //GDI+中的类 
Image image(L"bk.png",TRUE);   //GDI+中的类 
graph.DrawImage(&image,0,0,267,154); //后面两个参数要设置成跟图片一样大小,否则会失真

窗口透明贴图: 
//使用UpdateLayerWindow进行窗口透明处理 
HMODULE hFuncInst=LoadLibrary("User32.DLL"); 
typedef BOOL (WINAPI *MYFUNC)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);           
MYFUNC UpdateLayeredWindow; 
UpdateLayeredWindow=(MYFUNC)GetProcAddress(hFuncInst,"UpdateLayeredWindow"); 
SIZE sizeWindow={267,154}; 
POINT ptSrc={0,0}; 
UpdateLayeredWindow( m_hWnd,hdcScreen,&ptWinPos,&sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2);

使用上述代码后,运行程序,你会发现你的窗口已经是透明的了,下面进行控件处理:

四、前景窗体 
    新建对话框,画上控件,我在这里起名为COnWindow,随便起的,不要笑我^_^。 
 
    读者奇怪的是,这上面怎么没有“用户名、密码”两个Label控件?不好意思,因为我的玻璃做的太透,这些文字在玻璃上已经很难看清楚,所以我干脆用PS描了下边,直接画到前景上去了,就成了这种效果 ,忽优了你们一下,不好意思,快去画吧^_^。 
   
    定义成员变量:在OnWindow.h中定义: 
CBrush m_brush;  //背景画刷 
CBitmapButton m_ok; 
CBitmapButton m_cancel;

设置画笔:在在BOOL COnWindow::OnInitDialog()加入一行: 
  m_brush.CreateSolidBrush(RGB(255,0,255));  //背景设置为粉红色

改为层级窗体: 
//SetWindowsLong将窗体设置为层级窗体 
DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE); 
SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle|0x80000);

设置透明色: 
//用SetLayeredWindowAttributes设置透明色为0,它比UpdateLayeredWindow的使用要简单些 
HMODULE hInst=LoadLibrary("User32.DLL"); 
typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD); 
MYFUNC SetLayeredWindowAttributes = NULL; 
SetLayeredWindowAttributes=(MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes"); 
SetLayeredWindowAttributes(this->GetSafeHwnd(),0xff00ff,0,1); 
FreeLibrary(hInst);

不要忘记把窗体前景刷成粉红色:在HBRUSH COnWindow::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 消息映射函数中加入代码: 
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 
// TODO: Change any attributes of the DC here 
if(nCtlColor=CTLCOLOR_DLG) 
  return m_brush; 
return  CDialog::OnCtlColor(pDC,   pWnd,   nCtlColor);

现在要把前景窗体和背景窗体联动,这可是关键点: 
    把 前景窗体设置成启动窗体,无标题栏,样式为Popup弹出式。写到这里,我不得不说的是:我曾想把前景窗体设置成Child,发现前景窗体又被“透明”掉 了,什么都看不见,郁闷呀,所以只好用OnMove消息来设计窗体同步了。如果有对窗体机制比较熟悉的高手朋友,希望帮助我用更好的解决方法。

组合窗口,并保持联动: 
    在TestDlg.h中加入头文件:#include "OnWindow.h",再定义变量COnWindow *pChildWnd;

在void CTestDlg::OnMove(int x, int y) 加入如下代码,看清楚了,这里是CTestDlg透明窗口。矩形的坐标运算你可以自己修改,关键要跟背景对齐: 
CDialog::OnMove(x, y); 
// TODO: Add your message handler code here 
CRect rcWindow;                  // 使用MoveWindow函数的示例 
GetWindowRect(rcWindow); 
rcWindow.bottom-=10; 
rcWindow.left+=10; 
rcWindow.right-=10; 
rcWindow.top+=20; 
pChildWnd->MoveWindow(&rcWindow);

创建窗体时:在int CTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 加入如下代码: 
//创建子窗体 
pChildWnd=new COnWindow(this); 
pChildWnd->Create(IDD_ONWINDOW_DIALOG); 
pChildWnd->ShowWindow(SW_SHOW);

你现在看到窗体上没有标题栏吧?你把鼠标移到窗口顶部,还可以照样移动窗口,知道为什么吗?因为窗口虽然透明了,但是背景窗口的任何控件都是存在的,只是不显示,它还能照样响应事件,不信你在背景窗口上放上个按钮试试。不错吧?又省掉一些代码。

五、最后,我们来处理位图按钮:VC6的CBitmapButton::LoadBitmaps方法不能直接贴上16位真彩按钮,于是我将两个真彩色按钮用Acdsee32转换成256色的,就可以直接载入了,相信你们也没看出来吧? 
    处理成256色后,再在BOOL COnWindow::OnInitDialog() 写入代码: 
//载入按钮位图 
m_ok.LoadBitmaps(IDB_OK1,IDB_OK2); 
m_cancel.LoadBitmaps(IDB_CANCEL1,IDB_CANCEL2); 
m_ok.SubclassDlgItem(IDOK, this); 
m_cancel.SubclassDlgItem(IDCANCEL, this); 
    现在按下按钮只能关闭自己,给父窗口发个消息吧:在void COnWindow::OnOK()和void COnWindow::OnCancel() 都加入代码:
HWND hWnd=GetParent()->m_hWnd;
::SendMessage(hWnd,WM_CLOSE,0,0);

http://blog.csdn.net/witch_soya/article/details/6889939

PNG透明窗体全攻略(控件不透明)的更多相关文章

  1. android屏幕适配的全攻略3-动态获取手机屏幕宽高及动态设置控件宽高

    1.获取手机屏幕宽高: DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetr ...

  2. nim_duilib(14)之xml配置半透明窗体控件不透明

    before starting note 截至目前,我只能用xml写一些简单的布局和设置控件属性,循序渐进吧. 正在学习nim_duilib的xml的一些属性. xml配置半透明 GTAV中就有很多控 ...

  3. 窗体透明,但窗体上的控件不透明(简单好用)good

    1.在Delphi中,设置窗体的AlphaBlend := true;AlphaBlendValue := 0-255; AlphaBlendValue越小窗体的透明度就越高.这种方法将会使窗体和窗体 ...

  4. delphi 窗体透明详解TransparentColorValue,窗体透明控件不透明

    关于窗体透明的做法 来自:http://blog.csdn.net/shuaihj/article/details/8610343 关于窗体透明的做法 1.在Delphi中,设置窗体的AlphaBle ...

  5. VC窗体透明而控件不透明以及Static文本背景透明方法

    出自http://my.oschina.net/ypimgt/blog/60951 优点:    1.Dialog 窗体完全透明.     2. 窗体上的控件不透明. DC 绘制的图形不透明.     ...

  6. 用C#制作PDF文件全攻略

    用C#制作PDF文件全攻略 目  录 前    言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...

  7. (转)战斗bug技巧全攻略

    原文地址:http://www.cnblogs.com/manuosex/p/3736077.html 程序员不是有一幅这样的对联吗 上联:一个项目两部电脑三餐盒饭只为四千工资搞得五脏俱损六神无主仍然 ...

  8. 用友U8客户端连接不上服务器全攻略

    用友U8客户端连接不上服务器全攻略 http://www.enet.com.cn2009年09月23日09:26 来自论坛 [导读]:如果网络不通,就让用户查找网络原因 检查步骤: 1.网络是否通? ...

  9. webBrowser中操作网页元素全攻略

    原文 webBrowser中操作网页元素全攻略 1.获取非input控件的值: webBrowser1.Document.All["控件ID"].InnerText; 或webBr ...

随机推荐

  1. sql 声明 将结果select 而混合值

    String slctpsql="select id ,"+uid+","+ddd+","+score+",'"+mar ...

  2. 4.生产者 消费者模式的RabbitMQ

    1.生产者: using RabbitMQ.Client; using System; using System.Text; namespace Publisher1 { class Program ...

  3. 微信4.5 for Android安卓内测版体验【实时对讲】杀手级应用下载

    微信4.5 for Android 安卓 内测版 体验 程序启动画面,是一支在动的烛光 主要功能更新如下 支持语音提醒,到时间后自动弹出消息框 发起语音提醒请求 成功识别语音请求,并且保存在本地,应该 ...

  4. 认识ADO.net

    这篇文章源自对刘皓的文章的学习 ADO.NET入门教程(一) 初识ADO.NET 这篇文章非常好,用一张图,以及对图的解释介绍了ado.net组件 ado.net内部主要有两个部分 dataProvi ...

  5. 努比亚Z7 mini刷机教程_recovery卡刷机教程

    之前小编分享努比亚Z7 mini电话访问Root权限.recovery刷机教程. 所以对于朋友谁搞机整机的爱,左边是写第三方手机刷包.那么下面刷的家小编与您分享努比亚Z7 mini刷机教程手机. 一. ...

  6. IME输入法编程心得

    原文:IME输入法编程心得 posted @ 2012-11-30 00:42 from [FreedomShe] 自然语言处理的输入法作业成品没有做出来,但不想再在蛋疼的Win32上面耗费时间了,整 ...

  7. Beginner’s Tutorial: 3D Line and Border Effects in XAML

    This mini-tutorial might be for you if you’re having troubles finding the right line colors to achie ...

  8. EPPlus简单使用

    在使用之前需要在项目中添加对EEPULS.dll的引用 1,创建excel 2,创建sheet 3,添加内容 4,修改 5,保存 FileInfo newFile = new FileInfo(fil ...

  9. Apache和Tomcat的整合

    1.web架构 首先上图,解释web通用架构 通常情况下分为三大块 : ★ Web server :  通常情况下由 Apache Http Server  . IBM Http Server  .I ...

  10. springboot 上传图片

    1. 创建多层目录 创建多层目录要使用File的mkdirs()方法,其他可以使用mkdir()方法. 2. 文件大小限制 配置文件中,在spring1.4以后要使用 ` spring.http.mu ...