让你的软件界面更漂亮(一)
我们使用过很多的软件, 给我们留下印象很深的是那些界面漂亮且迷人的软件, 国外的软件象QuickTime,国产的象金山词霸等,它们的软件界面设计风格都有独特之处。本人跟据自已的经验和大家探讨一下软件的漂亮界面实现的原理并提供DEMO程序。本人经验不多,经常从VCKBASE.COM吸取知识,共同学习,如有不足之处,请指正!也欢迎和我联系。下面就开始吧!
一、漂亮界面实现的原理
用图象元素自绘窗口标题样栏,边框,系统按钮(最大化、最小化、关闭按钮)还有按窗口中的控件。图象当然是美工画的,但要你教美工怎么去画,是不是不能理解? ,呆会我会告诉你你如何去教美工画.请先仔细看下图。
明白了吧,被红线包括的部分都是要画的图象。画得好不好会直接影响你的软件界面。
二、原理说玩了,来说一下实现的基本知识
1、VC软件绘图技术:
01.
CBitmap* pBitmap =
new
CBitmap;
02.
BITMAP BmpInfo;
03.
CBitmap* pOldBitmap;
04.
CDC* pDisplayMemDC=
new
CDC;
05.
pDisplayMemDC->CreateCompatibleDC(pDC);
06.
07.
pBitmap->LoadBitmap(IDB_TITLE_LEFT);
08.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
09.
pBitmap->GetBitmap(&BmpInfo);
10.
11.
// x,y为绘图位置 ,必要时此语句要有For(..;..;..)控制
12.
pDC->BitBlt(x,y, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY);
13.
14.
pDisplayMemDC->SelectObject(pOldBitmap);
15.
pBitmap->DeleteObject();
16.
17.
ReleaseDC(pDisplayMemDC);
//记得执行以下的语句
18.
delete
pDisplayMemDC;
19.
delete
pBitmap;
2、坐标的概念:点、窗口坐标和屏幕坐标及转换,很重要!如不清楚请先复习相关知识。
下图是我写在一个界面,就是基于上述原理实现的:
下面介绍软件如何实现的:
①、重载对话框的消息函数:
1.
void
OnNcLButtonDown(
UINT
nHitTest, CPoint point);
//单击标题栏时是响应
1.
void
OnNcMouseMove(
UINT
nHitTest, CPoint point);
//Mous 在标题移动时响应
1.
LRESULT
DefWindowProc(
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
②、添加关键成员函数为:BOOL DrawTitleBar(CDC *pDC)
③、添加完消息涵数后,在.cpp中实现它们的代码:
001.
void
CTitleBarDlg::OnNcMouseMove(
UINT
nHitTest, CPoint point)
002.
{
003.
CDC* pDC = GetWindowDC();
004.
CDC* pDisplayMemDC=
new
CDC;
005.
pDisplayMemDC->CreateCompatibleDC(pDC);
006.
CBitmap* pBitmap =
new
CBitmap;
007.
CBitmap* pOldBitmap;
008.
CRect rtWnd, rtButton;
009.
010.
if
(pDC)
011.
{
012.
CString StrTemp =
""
;
013.
GetWindowRect(&rtWnd);
014.
//mouse坐标转化为本窗口坐标 重要
015.
point.x = point.x - rtWnd.left;
016.
point.y = point.y - rtWnd.top;
017.
//判断mouse是否移到系统按钮上
018.
if
(m_rtButtExit.PtInRect(point))
019.
{
020.
pBitmap->LoadBitmap(IDB_EXIT_FOCUS);
021.
StrTemp = _T(
"关闭"
);
022.
}
023.
else
024.
{
025.
if
(m_rtButtMin.PtInRect(point))
026.
{
027.
pBitmap->LoadBitmap(IDB_MIN_FOCUS);
028.
StrTemp = _T(
"最小化窗口"
);
029.
}
030.
else
031.
{
032.
if
(m_rtButtMax.PtInRect(point))
033.
{
034.
pBitmap->LoadBitmap(IDB_MAX_FOCUS);
035.
if
(IsZoomed())
036.
{
037.
StrTemp = _T(
"还原窗口"
);
038.
}
039.
else
040.
{
041.
StrTemp = _T(
"最化大窗口"
);
042.
}
043.
}
044.
else
045.
{
046.
pBitmap->LoadBitmap(IDB_NORMAL);
047.
}
048.
}
049.
}
050.
051.
rtButton = m_rtButtMin;
052.
BITMAP BmpInfo;
053.
pBitmap->GetBitmap(&BmpInfo);
054.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
055.
pDC->BitBlt(rtButton.left-6,
056.
rtButton.top-2,
057.
BmpInfo.bmWidth,
058.
BmpInfo.bmHeight,
059.
pDisplayMemDC,
060.
0,
061.
0,
062.
SRCCOPY);
063.
pDisplayMemDC->SelectObject(pOldBitmap);
064.
pBitmap->DeleteObject();
065.
CRect ShowTipRec;
066.
ShowTipRec = m_rtButtMin;
067.
if
(!StrTemp.IsEmpty())
068.
{
069.
// ScreenToClient(&ShowTipRec);
070.
// m_ToolTip.AddToolTip(IDD_TITLEBAR_DIALOG,&ShowTipRec,StrTemp);
071.
// m_ToolTip.SetDelayTime(200);
072.
}
073.
}
074.
075.
ReleaseDC(pDisplayMemDC);
076.
ReleaseDC(pDC);
077.
delete
pDisplayMemDC;
078.
delete
pBitmap;
079.
080.
CDialog::OnNcMouseMove(nHitTest, point);
081.
}
082.
083.
//此为关键函数
084.
void
CTitleBarDlg::DrawTitleBar(CDC *pDC)
085.
{
086.
if
(m_hWnd)
087.
{
088.
CBrush Brush(RGB(0,100,255));
089.
CBrush* pOldBrush = pDC->SelectObject(&Brush);
090.
091.
CRect rtWnd, rtTitle, rtButtons;
092.
GetWindowRect(&rtWnd);
093.
//取得标题栏的位置
094.
rtTitle.left = GetSystemMetrics(SM_CXFRAME);
095.
rtTitle.top = GetSystemMetrics(SM_CYFRAME);
096.
rtTitle.right = rtWnd.right - rtWnd.left - GetSystemMetrics(SM_CXFRAME);
097.
rtTitle.bottom = rtTitle.top + GetSystemMetrics(SM_CYSIZE);
098.
099.
//计算最小化按钮的位置,位图大小为15X15
100.
rtButtons.left = rtTitle.right-60;
101.
rtButtons.top= rtTitle.top+2;
102.
rtButtons.right = rtTitle.right-42;
103.
rtButtons.bottom = rtTitle.top+20;
104.
m_rtButtMin = rtButtons;
105.
//计算最大化按钮的位置,位图大小为15X15
106.
m_rtButtMax.left = m_rtButtMin.left + 18;
107.
m_rtButtMax.top = m_rtButtMin.top;
108.
m_rtButtMax.right = m_rtButtMin.right + 16;
109.
m_rtButtMax.bottom = m_rtButtMin.bottom;
110.
111.
m_rtButtExit.left = m_rtButtMax.left + 18;
112.
m_rtButtExit.top = m_rtButtMax.top;
113.
m_rtButtExit.right = m_rtButtMax.right + 16;
114.
m_rtButtExit.bottom = m_rtButtMax.bottom;
115.
116.
//准备
117.
CBitmap* pBitmap =
new
CBitmap;
118.
BITMAP BmpInfo;
119.
CBitmap* pOldBitmap;
120.
CDC* pDisplayMemDC=
new
CDC;
121.
pDisplayMemDC->CreateCompatibleDC(pDC);
122.
123.
//重画Caption
124.
POINT DrawPonit;
125.
DrawPonit.x = rtTitle.left-4;
126.
DrawPonit.y = rtTitle.top-4;
127.
pBitmap->LoadBitmap(IDB_TITLE_LEFT);
128.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
129.
pBitmap->GetBitmap(&BmpInfo);
130.
pDC->BitBlt(rtTitle.left-4,
131.
rtTitle.top-4,
132.
BmpInfo.bmWidth,
133.
BmpInfo.bmHeight,
134.
pDisplayMemDC,
135.
0,
136.
0,
137.
SRCCOPY);
138.
DrawPonit.x = DrawPonit.x + BmpInfo.bmWidth;
139.
pDisplayMemDC->SelectObject(pOldBitmap);
140.
pBitmap->DeleteObject();
141.
142.
pBitmap->LoadBitmap(IDB_TOP);
143.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
144.
pBitmap->GetBitmap(&BmpInfo);
145.
while
(DrawPonit.x<= m_rtButtMin.left-66)
146.
{
147.
pDC->BitBlt(DrawPonit.x,
148.
DrawPonit.y,
149.
BmpInfo.bmWidth,
150.
BmpInfo.bmHeight,
151.
pDisplayMemDC,
152.
0,
153.
0,
154.
SRCCOPY);
155.
DrawPonit.x = DrawPonit.x + BmpInfo.bmWidth;
156.
}
157.
pDisplayMemDC->SelectObject(pOldBitmap);
158.
pBitmap->DeleteObject();
159.
160.
pBitmap->LoadBitmap(IDB_TITLE_RIGHT);
161.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
162.
pBitmap->GetBitmap(&BmpInfo);
163.
pDC->BitBlt(DrawPonit.x,
164.
DrawPonit.y,
165.
BmpInfo.bmWidth,
166.
BmpInfo.bmHeight,
167.
pDisplayMemDC,
168.
0,
169.
0,
170.
SRCCOPY);
171.
172.
pDisplayMemDC->SelectObject(pOldBitmap);
173.
pBitmap->DeleteObject();
174.
175.
176.
177.
//重画最小化button
178.
rtButtons = m_rtButtMin;
179.
pBitmap->LoadBitmap(IDB_NORMAL);
180.
pBitmap->GetBitmap(&BmpInfo);
181.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
182.
pDC->BitBlt(rtButtons.left-6,
183.
rtButtons.top-2,
184.
BmpInfo.bmWidth,
185.
BmpInfo.bmHeight,
186.
pDisplayMemDC,
187.
0,
188.
0,
189.
SRCCOPY);
190.
pDisplayMemDC->SelectObject(pOldBitmap);
191.
pBitmap->DeleteObject();
192.
193.
int
nOldMode = pDC->SetBkMode(TRANSPARENT);
194.
COLORREF
clOldText=pDC->GetTextColor();
195.
CFont titleFont;
196.
titleFont.CreateFont( 12,
// nHeight
197.
8,
// nWidth
198.
0,
// nEscapement文本行逆时针旋转角度
199.
0,
// nOrientation字体角度
200.
FW_BOLD,
// nWeight字体粗细程度
201.
FALSE,
// bItalic
202.
FALSE,
// bUnderline
203.
0,
// cStrikeOut 删除线
204.
ANSI_CHARSET,
// nCharSet
205.
OUT_DEFAULT_PRECIS,
// nOutPrecision
206.
CLIP_DEFAULT_PRECIS,
// nClipPrecision
207.
DEFAULT_QUALITY,
// nQuality
208.
DEFAULT_PITCH | FF_SWISS,
// nPitchAndFamily
209.
_T(
"隶书"
));
// lpszFac pDC->SelectStockObject(SYSTEM_FIXED_FONT);
210.
CFont *OldFont;
211.
OldFont = pDC->SelectObject(&titleFont);
212.
CString m_StrTitle;
213.
GetWindowText(m_StrTitle);
214.
pDC->SetTextColor(RGB(80,255,25));
215.
if
(m_ShowTitle)
216.
{
217.
pDC->TextOut(65,10,m_StrTitle);
218.
}
219.
else
220.
{
221.
m_StrTitle = m_StrTitle.Left(6);
222.
m_StrTitle +=
"..."
;
223.
pDC->TextOut(30,10,m_StrTitle);
224.
}
225.
pDC->SetBkMode(nOldMode);
226.
pDC->SetTextColor(clOldText);
227.
pDC->SelectObject(OldFont);
228.
//pDC->TextOut(60,60,m_StrTitle);
229.
//重画左边框
230.
pBitmap->LoadBitmap(IDB_LEFTDOWN);
231.
pBitmap->GetBitmap(&BmpInfo);
232.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
233.
int
i ;
234.
for
(i= 20;i<=rtWnd.bottom;i=i+BmpInfo.bmHeight-3)
235.
{
236.
pDC->BitBlt(0, rtButtons.top+i,
237.
BmpInfo.bmWidth,
238.
BmpInfo.bmHeight,
239.
pDisplayMemDC,
240.
0,
241.
0,
242.
SRCCOPY);
243.
}
244.
pDisplayMemDC->SelectObject(pOldBitmap);
245.
pBitmap->DeleteObject();
246.
247.
//重画右边框
248.
pBitmap->LoadBitmap(IDB_RIGHTDOWN);
249.
pBitmap->GetBitmap(&BmpInfo);
250.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
251.
GetClientRect(&rtWnd);
252.
for
(i= 25;i<=rtWnd.bottom+27;i=i+BmpInfo.bmHeight-3)
253.
{
254.
pDC->BitBlt(rtWnd.right, i,
255.
BmpInfo.bmWidth,
256.
BmpInfo.bmHeight,
257.
pDisplayMemDC,
258.
0,
259.
0,
260.
SRCCOPY);
261.
}
262.
pDisplayMemDC->SelectObject(pOldBitmap);
263.
pBitmap->DeleteObject();
264.
265.
//重画底边框
266.
pBitmap->LoadBitmap(IDB_DOWN);
267.
pBitmap->GetBitmap(&BmpInfo);
268.
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
269.
GetClientRect(&rtWnd);
270.
for
(i= 9; i<=rtWnd.right; i=i+2)
271.
{
272.
GetClientRect(&rtWnd);
273.
pDC->BitBlt(i,rtWnd.bottom+26,
274.
BmpInfo.bmWidth,
275.
BmpInfo.bmHeight,
276.
pDisplayMemDC,
277.
0,
278.
0,
279.
SRCCOPY);
280.
}
281.
pDisplayMemDC->SelectObject(pOldBitmap);
282.
pBitmap->DeleteObject();
283.
284.
285.
ReleaseDC(pDisplayMemDC);
286.
delete
pDisplayMemDC;
287.
delete
pBitmap;
288.
}
289.
}
290.
291.
void
CTitleBarDlg::OnNcLButtonDown(
UINT
nHitTest, CPoint point)
292.
{
293.
294.
CRect rtWnd;
295.
GetWindowRect(&rtWnd);
296.
297.
//mouse坐标转化为本窗口坐标 重要
298.
point.x = point.x - rtWnd.left;
299.
point.y = point.y - rtWnd.top;
300.
//检测各按钮是否按到
301.
if
(m_rtIcon.PtInRect(point))
302.
AfxMessageBox(
"界面软件设计者:朱一松 EMail:Song_0962@sina.com"
);
303.
else
304.
{
305.
if
(m_rtButtHelp.PtInRect(point))
306.
{
307.
SendMessage(WM_HELP);
308.
}
309.
else
310.
{
311.
if
(m_rtButtExit.PtInRect(point))
312.
{
313.
SendMessage(WM_CLOSE);
314.
}
315.
else
316.
{
317.
if
(m_rtButtMin.PtInRect(point))
318.
{
319.
m_ShowTitle = FALSE;
320.
SendMessage(WM_SYSCOMMAND,
321.
SC_MINIMIZE,
322.
MAKELPARAM(point.x, point.y));
323.
}
324.
else
325.
{
326.
if
(m_rtButtMax.PtInRect(point))
327.
{
328.
m_ShowTitle = TRUE;
329.
if
(IsZoomed())
330.
SendMessage(WM_SYSCOMMAND,
331.
SC_RESTORE,
332.
MAKELPARAM(point.x, point.y));
333.
else
334.
{
335.
SendMessage(WM_SYSCOMMAND,
336.
SC_MAXIMIZE,
337.
MAKELPARAM(point.x, point.y));
338.
Invalidate();
339.
}
340.
}
341.
else
342.
{
343.
if
(!IsZoomed())
344.
{
345.
Default();
346.
}
347.
}
348.
}
349.
}
350.
}
351.
}
352.
}
353.
354.
//******************************************************
355.
LRESULT
CTitleBarDlg::DefWindowProc(
UINT
message,
WPARAM
wParam,
LPARAM
lParam)
356.
{
357.
LRESULT
lrst=CDialog::DefWindowProc(message, wParam, lParam);
358.
359.
if
(!::IsWindow(m_hWnd))
360.
return
lrst;
361.
362.
if
(message==WM_MOVE||
363.
message==WM_PAINT||
364.
message==WM_NCPAINT||
365.
message==WM_NCACTIVATE||
366.
message == WM_NOTIFY)
367.
{
368.
CDC* pWinDC = GetWindowDC();
369.
if
(pWinDC)
370.
DrawTitleBar(pWinDC);
371.
ReleaseDC(pWinDC);
372.
}
373.
return
lrst;
374.
}
好了运行你的程序,即可出现漂亮的界面。说明在设计对话框时最好只选上Title Bars,其它不要.消息函数要手动添加。只本程序是在VC++6.0 +WinXP环境下完成的。
经过实践证明,仅仅画一个窗口很容易,多窗口程序软件实现统一风格很难。如若有机会的话,我会和大家继续探讨如何将设计好的漂亮窗口子类化,让程序所有的窗口有统一风格,美化窗口的其它控件并可自动随窗口改变而调整大小。我想那才是我们大家关心的。对不?
原文地址:http://www.vckbase.com/index.php/wv/1240
代码下载:http://download.csdn.net/detail/ylo523/8153689
让你的软件界面更漂亮(一)相关推荐
- 三星s9更新android9.0 体验,国行三星Galaxy S9系列更新Android 9.0 界面更漂亮
原标题:国行三星Galaxy S9系列更新Android 9.0 界面更漂亮 [手机中国新闻]时间已到2月份,三星Galaxy S9系列的Android 9.0系统升级终于来了.但是该系统更新仍在内测 ...
- 三星s9更新android9.0,国行三星Galaxy S9系列更新Android 9.0 界面更漂亮
时间已到2月份,三星Galaxy S9系列的Android 9.0系统升级终于来了.但是该系统更新仍在内测阶段,只有三星Galaxy S9/S9+的内测用户能收到推送,三星Android 9.0正式版 ...
- python优秀界面demo_python漂亮界面demo-女性时尚流行美容健康娱乐mv-ida网
女性时尚流行美容健康娱乐mv-ida网 mvida时尚娱乐网 首页 美容 护肤 化妆技巧 发型 服饰 健康 情感 美体 美食 娱乐 明星八卦 首页 > 高级搜索 python 读写/追加exc ...
- MySkin仿QQ皮肤,零基础拥有漂亮的软件界面
MySkin仿QQ皮肤,零基础拥有漂亮的软件界面.支持透明效果,阴影边框,任意颜色更换,自定义背景,完美支持原生winform全套控件. QQ2013/2014 皮肤同时也是MySkin默认皮肤,无需 ...
- android平板电脑汉语字体,动动手换字体:让Android平板电脑更漂亮
作为下一代移动商务PC代表,平板电脑以出色的便携性.出众的操控性,成为时下商务白领.潮男潮女们的随身"冲浪"伴侣.不管你在何处,通过平板电脑上网后,可以随时看在线视频.阅读网络小说 ...
- 麦芒8升级鸿蒙,华为畅享10 Plus、麦芒8等7款机型EMUI10正式版升级 界面更美运行更快...
在今年8月的华为开发者大会上,华为消费者业务软件部总裁王成录为我们介绍了EMUI10的众多亮点特性,不管是焕彩的UX设计.GPU Turbo再升级还是新增的强大功能,都让关注EMUI10的" ...
- MacType 文字之美 – 让 Windows 字体更漂亮
官网地址 MacType 文字之美 – 让 Windows 字体更漂亮 苹果的Mac系统总能让人眼前一亮,除了其精美的软件界面设计外,最重要是其文字显示效果(渲染方式)比 Windows 更加清晰锐利 ...
- 一种全新的软件界面设计方法
一种全新的软件界面设计方法 撰文:Aweay 你可转载,拷贝,但必须加入作者署名Aweay,如果用于商业目的,必须经过作者同意. 下载实例代码 关键字:COM MySpy IE SetUIHanlde ...
- android学习笔记---51_编码实现软件界面,把固定不变的界面写到xml中,逻辑改变的写到程序中,
2013/5/12 51_编码实现软件界面 -------------------------- 1.Android除了可以使用xml实现软件界面,还可以通过编码方式实现软件的界面,而且在某种情况下只 ...
最新文章
- Android Studio 3.5 Canary 12 发布
- Kubernetes的十大使用技巧
- 【 FPGA 】FIR滤波器之 Hilbert 变换的实现
- Valid Sudoku
- arcgis导出shp文件_地理工具学习--arcgis篇(15):CAD和SHP的简单转换
- DP(优化) UVALive 6073 Math Magic
- 什么是简单的分析SQL注入漏洞
- 《飞鸽传书2007怎么用》这种即时通讯技术已开始普及
- leetcode —— 面试题 16.19. 水域大小
- 在java程序中怎么造成死锁_java – 了解为什么在此实现中发生死锁
- tkmybatis 子查询_你的名字是爆款吗?一键查询!看看在杭州、全国多少人和你同名!...
- k8s核心技术-Helm(概述)---K8S_Google工作笔记0044
- 男人在35岁之前最好的投资
- EntityFramework6.X 之 Operation
- javascript 的线程问题
- GB2312、BIG5、GBK、GB18030简介
- 激励机制:区块链的幕后英雄
- SQLite读写同步之WAL机制
- Combining Label Propagation and Simple Models Out-performs Graph Neural Networks 论文理解
- Win10将绿色软件添加到开始菜单
热门文章
- 广州Java培训哪里好?课程特色如何?
- Linux Shell编程学习笔记(3)
- 软件工程导论第一次作业
- ERROR: Could not build wheels for pycocotools, which is required to install pyproject.toml-based pro
- SpinalHDL资料汇总
- 二十、接口的应用示例(便于理解使用场景)
- c语言 出局者 算法,下一个出局者是谁
- Python设置画布大小_Python绘图库Turtle详细分析
- Centos7添加项目启动脚步到systemctl
- godot 角色脚步声代码