要实现对话框淡入浅出效果, 还是挺简单的, 说白了, 就是在对话框初始化时候加个定时器, 在对话框销毁前也加个定时器, 定时器的操作, 无非就是更新对话框界面的透明度, 要改变对话框的透明度, 用一个API就搞定了:SetLayeredWindowAttributes
恩, 思路就是这样, 这里上关键代码吧
typedef BOOL (__stdcall *FunSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
FunSetLayeredWindowAttributes funSetLayeredWindowAttributes;
funSetLayeredWindowAttributes = (FunSetLayeredWindowAttributes)GetProcAddress(GetModuleHandle("user32.dll"), "SetLayeredWindowAttributes");ModifyStyleEx(NULL, 0x80000/*WS_EX_LAYERED*/); //窗口要有WS_EX_LAYERED属性才能用设置透明的那个API
enum{IDT_SHOW = 100, IDT_EXIT = 101};
在OnInitDialog方法里面添加一个定时器
SetTimer(IDT_SHOW, 50, NULL);
同样, 在OnCancel方法里面添加一个定时器, 顺便把IDT_SHOW定时器给KILL掉
KillTimer(IDT_SHOW);
SetTimer(IDT_EXIT, 50, NULL);
OnTimer方法这样写:
switch(nIDEvent)
{
case IDT_SHOW:
funSetLayeredWindowAttributes(this->m_hWnd, 0, m_current % 255, 2);
m_current += 5;
if(m_current >= 255)
KillTimer(IDT_SHOW);
break;
case IDT_EXIT:
m_current -= 5;
funSetLayeredWindowAttributes(this->m_hWnd, 0, m_current % 255, 2);
if(m_current <= 5)
{
CDialog::OnCancel();
KillTimer(IDT_EXIT);
}
break;
}
很简单吧, 一个淡入浅出效果就出来了
另:
static控件背景透明
添加WM_CTLCOLOR消息映射
ON_WM_CTLCOLOR()
添加响应函数
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
实现响应函数
if(IDS_STATIC == pWnd->GetDlgCtrlID())
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)::GetStockObject(NULL_BRUSH);
}
这里, 封装了一个基类, 方便以后用
FadeIODlg.h
#pragma once
class CFadeIODlg : public CDialog
{
DECLARE_MESSAGE_MAP()
public:
CFadeIODlg(UINT uDLGID, CWnd* pParent = NULL);
virtual ~CFadeIODlg();
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual void OnCancel();
virtual void OnOK();
afx_msg BOOL OnInitDialog();
afx_msg void OnTimer(UINT nIDEvent);
private:
enum{ TIME_BEGIN = 100, TIME_END = 101};
typedef BOOL (__stdcall *FUNSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
FUNSetLayeredWindowAttributes m_funTransparent;
enum{
MAX_TRANSPARENT = 255, //最大透明度
NUM_BEGIN = 10, //开始计时器时间间隔
NUM_END = 10, //结束计时器时间间隔
NUM_CHANGE = 5, //改变透明度
};
int m_currentTransparent; //当前窗口透明度
};
FadeIODlg.cpp
#include "stdafx.h"
#include "UI.h"
#include "FadeIODlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CFadeIODlg::CFadeIODlg(UINT uDLGID, CWnd* pParent /* = NULL */)
: CDialog(uDLGID, pParent)
{}
CFadeIODlg::~CFadeIODlg()
{}
void CFadeIODlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFadeIODlg, CDialog)
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL CFadeIODlg::OnInitDialog()
{
CDialog::OnInitDialog();
ModifyStyleEx(0, 0x80000);
m_currentTransparent = 0;
m_funTransparent = (FUNSetLayeredWindowAttributes)GetProcAddress(GetModuleHandle("User32.dll"), "SetLayeredWindowAttributes");
if(m_funTransparent)
{
//m_funTransparent(this->GetSafeHwnd(), 0, 0, 2);
SetTimer(TIME_BEGIN, NUM_BEGIN, NULL);
}
return TRUE;
}
void CFadeIODlg::OnTimer(UINT nIDEvent)
{
switch(nIDEvent)
{
case TIME_BEGIN:
if(m_currentTransparent <= MAX_TRANSPARENT)
{
m_funTransparent(this->GetSafeHwnd(), 0, m_currentTransparent, 2);
m_currentTransparent += NUM_CHANGE;
}
else
KillTimer(TIME_BEGIN);
break;
case TIME_END:
if(m_currentTransparent >= 0)
{
if(m_currentTransparent > MAX_TRANSPARENT)
m_currentTransparent = MAX_TRANSPARENT;
m_funTransparent(this->GetSafeHwnd(), 0, m_currentTransparent, 2);
m_currentTransparent -= NUM_CHANGE;
}
else
{
KillTimer(TIME_END);
CDialog::OnCancel();
}
break;
}
}
void CFadeIODlg::OnOK()
{
}
void CFadeIODlg::OnCancel()
{
if(m_funTransparent)
{
KillTimer(TIME_BEGIN);
SetTimer(TIME_END, NUM_END, NULL);
}
else
CDialog::OnCancel();
}
ok, 完成, 以后直接继承这个对话框, 稍微修改一下, 效果就出来了