PNG透明窗体全攻略(控件不透明)
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透明窗体全攻略(控件不透明)的更多相关文章
- android屏幕适配的全攻略3-动态获取手机屏幕宽高及动态设置控件宽高
1.获取手机屏幕宽高: DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetr ...
- nim_duilib(14)之xml配置半透明窗体控件不透明
before starting note 截至目前,我只能用xml写一些简单的布局和设置控件属性,循序渐进吧. 正在学习nim_duilib的xml的一些属性. xml配置半透明 GTAV中就有很多控 ...
- 窗体透明,但窗体上的控件不透明(简单好用)good
1.在Delphi中,设置窗体的AlphaBlend := true;AlphaBlendValue := 0-255; AlphaBlendValue越小窗体的透明度就越高.这种方法将会使窗体和窗体 ...
- delphi 窗体透明详解TransparentColorValue,窗体透明控件不透明
关于窗体透明的做法 来自:http://blog.csdn.net/shuaihj/article/details/8610343 关于窗体透明的做法 1.在Delphi中,设置窗体的AlphaBle ...
- VC窗体透明而控件不透明以及Static文本背景透明方法
出自http://my.oschina.net/ypimgt/blog/60951 优点: 1.Dialog 窗体完全透明. 2. 窗体上的控件不透明. DC 绘制的图形不透明. ...
- 用C#制作PDF文件全攻略
用C#制作PDF文件全攻略 目 录 前 言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...
- (转)战斗bug技巧全攻略
原文地址:http://www.cnblogs.com/manuosex/p/3736077.html 程序员不是有一幅这样的对联吗 上联:一个项目两部电脑三餐盒饭只为四千工资搞得五脏俱损六神无主仍然 ...
- 用友U8客户端连接不上服务器全攻略
用友U8客户端连接不上服务器全攻略 http://www.enet.com.cn2009年09月23日09:26 来自论坛 [导读]:如果网络不通,就让用户查找网络原因 检查步骤: 1.网络是否通? ...
- webBrowser中操作网页元素全攻略
原文 webBrowser中操作网页元素全攻略 1.获取非input控件的值: webBrowser1.Document.All["控件ID"].InnerText; 或webBr ...
随机推荐
- 微信小程序实例:实现tabs选项卡效果
最近微信应用号是炒的如火如荼,热门满满,但是也可以发现搜索关键词出来,各类网站出现的还都是微信的官方文档解释.正好赶上这个热潮,这几天先把小程序技术文档看了个遍,就直接着手写案例了.很多组件微信内部已 ...
- 改变浏览器中默认的ctrl+s方法
在一般的情况下,我们在浏览网页的时候按下ctrl+s,浏览器会弹出一个保存网页的框. 但是在一些特定的网页中,我们希望ctrl+s不是弹出默认的保存窗口,而是进行一下别的操作. 比如在我们使用简书的时 ...
- 【20.69%】【codeforces 732E】Sockets
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- parfor —— matlab 下的并行循环
parfor:parallel for 循环 我们知道,matlab 更适合的处理对象是矩阵,而不是大规模的循环运算.当有时不得不使用 for 循环时,如果提高 for 循环的执行效率呢.这就是 pa ...
- javascript学习-创建json对象数据,遍历
之前我已经有讲过后台返回json数据到前台,并在前台遍历json数据. 这里讲下直接在JS里创建JSON数据,然后遍历使用~ 创建代码例如以下:(创建的是JSON对象) var YearSelect ...
- win7 64位系统下进入debug
win7 64位无法直接通过命名行输入debug命令的方式进入到debug,好在我们可是使用一个工具DOSbox来进入debug.操作步骤如下:1.下载DOSbox进行安装.下载地址:点击打开链接.如 ...
- Android 4.0新增Space及GridLayout初谈
Android 4.0的SDK已经发布,在众多的新增特性中,其中对开发者来说比较重要的特性之一,是新增的两种界面布局方式:Space和Gridlayout,它们跟以往Android版本的sdk有什么不 ...
- 《The Economist》的阅读
cover story(封面故事): Clean energy's dirty secret:清洁能源的肮脏幕后: 0. 词汇 respite:n. 缓解:暂缓:暂时的休息:缓期执行:也作及物动词(v ...
- 面向对象举例(一) —— 顶点(vertex)、边(edge)与图(graph)
Graph: class Graph(dict): def __init__(self, vs=[], es=[]): for v in vs: self.add_vertex(v) for e in ...
- 从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller
原文:从零开始学习 asp.net core 2.1 web api 后端api基础框架(四)-创建Controller 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...