参考文章:http://hi.baidu.com/daigongrei/item/529f0118c9827c426826bb48
开发工具:VS2012
系统环境:Win7
步骤:
1、新建一个MFC对话框程序。
2、导入bmp图片,作为屏保显示图。
3、丰富代码,设置定时器,移动图片。
4、修改exe后缀为.scr。
5、复制该scr文件到C:\Windows\System32。
6、设置屏保为该文件即可。
代码如下。
QMProtectDlg.h
// QMProtectDlg.h : 头文件
//
#pragma once
// CQMProtectDlg 对话框
class CQMProtectDlg : public CDialogEx
{
// 构造
public:
CQMProtectDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_QMPROTECT_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
private:
UINT s_showH;//这是显示屏的高度
UINT s_showW;//这是显示屏的宽度度
UINT w_showX;//图像要显示的位置(从左到右的坐标)
CDC* w_pdcmem;//位图内存,也就是和清明上河图关联的内存,
CBitmap w_bitmap;//清明上河图位图
CPoint w_point; //记录鼠标的位置
void DrawBitmap();//画图的函数,这里手动添加了。这样方便快捷
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnDestroy();
afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID);
};
QMProtectDlg.cpp
// QMProtectDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "QMProtect.h"
#include "QMProtectDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define BITMAP_HEIGHT 469 //原图像高度
#define BITMAP_WEIGHT 1024 //原图像宽度
// CQMProtectDlg 对话框
CQMProtectDlg::CQMProtectDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CQMProtectDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CQMProtectDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CQMProtectDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_MBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_WM_SYSKEYDOWN()
ON_WM_DESTROY()
ON_WM_ACTIVATEAPP()
END_MESSAGE_MAP()
// CQMProtectDlg 消息处理程序
BOOL CQMProtectDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
//设置全屏窗口
CRect m_rcMain;
GetWindowRect(&m_rcMain);//restore the src screen's size;
//删除窗口的标题栏
LONG style = GetWindowLong(m_hWnd,GWL_STYLE);
style &= ~WS_CAPTION;
SetWindowLong(m_hWnd,GWL_STYLE,style); //设置显示窗口状态
//获得显示器屏幕的宽度
s_showW = GetSystemMetrics(SM_CXSCREEN);
s_showH = GetSystemMetrics(SM_CYSCREEN);
//show window
SetWindowPos(NULL,-23,-3,s_showW+27,s_showH+6,SWP_NOZORDER);
//获得鼠标的位置
::GetCursorPos(&w_point);
//隐藏鼠标
ShowCursor(FALSE);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CQMProtectDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CPaintDC dc(this);
w_pdcmem = new CDC;
w_bitmap.LoadBitmap(IDB_BITMAP1);
w_pdcmem->CreateCompatibleDC(&dc); //建立与dc兼容的
w_pdcmem->SelectObject(&w_bitmap);
//sndPlaySound( "清明上河图屏保音乐.wav" , SND_ASYNC | SND_LOOP );
w_showX = 0;
DrawBitmap();
SetTimer(1,1,NULL);
CDialogEx::OnPaint();
}
}
void CQMProtectDlg::DrawBitmap()
{
CClientDC dc(this);
CDC dcmem;
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc,s_showW,s_showH);
dcmem.CreateCompatibleDC(&dc);
dcmem.SelectObject(&bitmap);
dcmem.SetBkMode(0);
dcmem.FillRect(&CRect(0,0,s_showW,s_showH),
&CBrush(RGB(0,0,0))
);
UINT y = (s_showH-BITMAP_HEIGHT)/2;
dcmem.StretchBlt(
0,y,s_showW, BITMAP_HEIGHT,
w_pdcmem,
w_showX,0,s_showW,BITMAP_HEIGHT-12,
SRCCOPY);
dc.BitBlt(20,0,s_showW,s_showH,&dcmem,0,0,SRCCOPY);//显示在屏幕上
bitmap.DeleteObject();
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CQMProtectDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CQMProtectDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
w_showX += 1;
if(w_showX>=BITMAP_WEIGHT){
w_showX = 0;
}
DrawBitmap();
CDialogEx::OnTimer(nIDEvent);
}
void CQMProtectDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
PostMessage(WM_CLOSE);
CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CQMProtectDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
PostMessage(WM_CLOSE);
CDialogEx::OnLButtonDown(nFlags, point);
}
void CQMProtectDlg::OnMButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
PostMessage(WM_CLOSE);
CDialogEx::OnMButtonDown(nFlags, point);
}
void CQMProtectDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
// TODO: Add your message handler code here and/or call default
if( abs(point.x-w_point.x)>=200 ||
abs(point.y-w_point.y)>=200)
{
PostMessage(WM_CLOSE);
}
CDialogEx::OnMouseMove(nFlags, point);
}
void CQMProtectDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
PostMessage(WM_CLOSE);
CDialogEx::OnRButtonDown(nFlags, point);
}
void CQMProtectDlg::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
PostMessage(WM_CLOSE);
CDialogEx::OnSysKeyDown(nChar, nRepCnt, nFlags);
}
void CQMProtectDlg::OnDestroy()
{
CDialogEx::OnDestroy();
// TODO: 在此处添加消息处理程序代码
// TODO: Add your message handler code here
delete w_pdcmem;
KillTimer(1);//程序中用到了计时器。这里关掉计时器
}
void CQMProtectDlg::OnActivateApp(BOOL bActive, DWORD dwThreadID)
{
CDialogEx::OnActivateApp(bActive, dwThreadID);
// TODO: 在此处添加消息处理程序代码
// TODO: Add your message handler code here
if (!bActive) //is being deactivated
PostMessage(WM_CLOSE);
}