参考文章: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 : 实现文件 // #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); }