385上位机VC MFC编写透明不规则窗口动态时钟
385上位机VC MFC编写透明不规则窗口动态时钟
功能展示
WIN7等系统都有很炫很酷的时钟挂件,放在桌面很方面时间管理,我们当前例程也实现炫酷时钟功能,效果如图,程序运行后会加载目录内PNG图片显示出来,通过设置一个定时器可以轮流切换显示的图片,起到动态效果;
要点提示
功能实现的关键是设置窗口的属性为无标题栏及透明属性,窗口的无标题栏及透明属性可通过下面两行代码实现
SetWindowLong(m_hWnd,GWL_STYLE, GetWindowLong(m_hWnd,GWL_STYLE)&~(WS_CAPTION));//去除边框属性
SetWindowLong(m_hWnd,GWL_EXSTYLE,GetWindowLong(m_hWnd,GWL_EXSTYLE)^0x80000);//设置透明属性
透明度的设置得调用外部库的函数UpdateLayeredWindow ()实现;
函数原型LONG?SetWindowLong(HWND?hWnd,???int?nlndex,?LONG?dwNewLong??);
hWnd 窗口句柄及间接给出的窗口所属的类。Nlndex 指定将设定的大于等于0的偏移值可以为GWL_EXSTYLE
\-20设定一个新的扩展风格;GWL_HINSTANCE \-6设置一个新的应用程序实例句柄; GWL_ID
\-12设置一个新的窗口标识符;GWL_STYLE、-16设定一个新的窗口风格;
GWL_USERDATA\-21设置与窗口有关的32位值。每个窗口均有一个由创建该窗口的应用程序使用的32位值。
GWL_WNDPROC\-4为窗口过程设定一个新的地址;
GWL_HWNDPARENT\-8改变子窗口的父窗口,应使用SetParent函数;
dwNewLong 指定的替换值;
实现功能
1.新建基于对话框的应用程序,复制例程根目录GDI+文件夹Include及目录RES中图片文件到自己工程中,三步取初始化GDI+:在stdafx.h包含GDI+头文件
//使用GDI+第一步
#define UNICODE
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include "Include/gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "Include/gdiplus.lib")
在APP类的InitInstance()中初始化GDI+环境,及程序退出时清理GDI+环境
//使用GDI+第二步
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
//使用GDI+第三步
GdiplusShutdown(gdiplusToken); //关闭gdiplus的环境
2.将刚才复制的6幅PNG图片加载到工程中修改ID,方便识别图片;
3. 在主对话框类头文件添加自定义变量及函数
Image *m_pImageClock; //两交替背景图
Image *m_pImageClock1;//两背景图1
Image *m_pImageHHour;
Image *m_pImageHMinu;
Image *m_pImageHSec;
Image *m_pImageNum;
int m_BakWidth , m_BakHeight ;
int m_HourWidth, m_HourHeight;
int m_MinuWidth , m_MinuHeight;
int m_SecWidth , m_SecHeight ;
BOOL ImageFromIDResource(UINT nID,LPCTSTR sTR,Image * &pImg);
BOOL UpdateClockDisplay(int Transparent=99);//1-99
typedef BOOL (WINAPI *MYFUNC)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
MYFUNC UpdateLayeredWindow; //设置窗口透明的外部函数
4.在初始化函数OnInitDialog()中初始化变量及窗口属性设置
//<>
HINSTANCE hFuncInst = LoadLibrary("User32.DLL");
if(hFuncInst)
UpdateLayeredWindow=(MYFUNC)GetProcAddress(hFuncInst, "UpdateLayeredWindow");
else
{
AfxMessageBox("User32.dll ERROR!");
exit(0);
}
FreeLibrary(hFuncInst);
//<>
ImageFromIDResource(IDR_PNGNUM,"PNG",m_pImageNum);
ImageFromIDResource(IDR_PNGBAK1,"PNG",m_pImageClock1);
ImageFromIDResource(IDR_PNGBAK,"PNG",m_pImageClock);
ImageFromIDResource(IDR_PNGHOUR,"PNG",m_pImageHHour);
ImageFromIDResource(IDR_PNGMIN,"PNG",m_pImageHMinu);
ImageFromIDResource(IDR_PNGSEC,"PNG",m_pImageHSec);
m_BakWidth =m_pImageClock->GetWidth();
m_BakHeight =m_pImageClock->GetHeight();
m_HourWidth =m_pImageHHour->GetWidth();
m_HourHeight=m_pImageHHour->GetHeight();
m_MinuWidth =m_pImageHMinu->GetWidth();
m_MinuHeight=m_pImageHMinu->GetHeight();
m_SecWidth =m_pImageHSec->GetWidth();
m_SecHeight =m_pImageHSec->GetHeight();
::SetWindowPos(m_hWnd, HWND_TOPMOST,0,0,m_BakWidth,m_BakHeight,SWP_NOSIZE|SWP_NOMOVE);
//<>
SetWindowLong(m_hWnd,GWL_STYLE, GetWindowLong(m_hWnd,GWL_STYLE)&~(WS_CAPTION));//去除边框属性
SetWindowLong(m_hWnd,GWL_EXSTYLE,GetWindowLong(m_hWnd,GWL_EXSTYLE)^0x80000);//设置透明属性
UpdateClockDisplay(90);
SetTimer(1,200,NULL);//让时钟动态显示
5.添加OnTimer()定时器函数实现时钟动态显示;
void CGkbc8Dlg::OnTimer(UINT nIDEvent)
{
if(nIDEvent == 1)
UpdateClockDisplay(90);
CDialog::OnTimer(nIDEvent);
}
6.添加OnDestroy()函数释放变量
void CGkbc8Dlg::OnDestroy()
{
CDialog::OnDestroy();
delete m_pImageClock;
delete m_pImageHHour;
delete m_pImageHMinu;
delete m_pImageHSec;
}
7.添加鼠标点击函数OnLButtonDown()实现窗口可拖动功能
void CGkbc8Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
SendMessage(WM_SYSCOMMAND,0xF012,0);//非标题栏移动整个窗口
CDialog::OnLButtonDown(nFlags, point);
}
我们来演示下功能实现的整个过程
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|