首页 | 新闻资讯 | 软件应用 | 图形图像 | 网络应用 | 硬件学堂 | 程序开发 | 安全中心 | 素材下载 | 作者专区 | 学院论坛
精选专题 | 精美壁纸 | 专家答疑 | Flash剧场 | Photoshop | 名词解释 | 梦幻桌面 | PS高手进阶 | QQ区 | 图书 | 黑客教材
Flash教程| 卡通制作 | AutoCAD | 3DMax实例 | PS视频教程| 网页制作 | CorelDRAW| Firework | 滤镜与实例 | 全部视频教程
当前位置:eNet硅谷动力 > 学院频道 > VC

用VC制作图片屏幕保护程序
2004-03-15 09:07 来源:eNet论坛
【简 介】
VC++可谓神通广大,如果学到家了,或者就掌握了那么一点MFC,你也会感到它的方便快捷,当然最重要的是功能强大。不是吗,从最基本的应用程序.EXE到动态连接库DLL,再由风靡网上的ActiveX控件到Internet Server API,当然,还有数据库应用程序……瞧,我都用它来做屏幕保护程序了。一般的屏幕保护程序都是以SCR作为扩展名,并且要放在c:\windows 目录或 c:\windows\system 目录下,由Windows 98内部程序调用(Windows NT 是在 c:\windows\system32 目录下)。怎么调用?不用说了,这谁不知道。
    
加入收藏  设为首页

  VC++可谓神通广大,如果学到家了,或者就掌握了那么一点MFC,你也会感到它的方便快捷,当然最重要的是功能强大。不是吗,从最基本的应用程序.EXE到动态连接库DLL,再由风靡网上的ActiveX控件到Internet Server API,当然,还有数据库应用程序……瞧,我都用它来做屏幕保护程序了。一般的屏幕保护程序都是以SCR作为扩展名,并且要放在c:\windows 目录或 c:\windows\system 目录下,由Windows 98内部程序调用(Windows NT 是在 c:\windows\system32 目录下)。怎么调用?不用说了,这谁不知道。

    好了,我们来作一个简单的。选择MFC AppWizard(exe),Project Name 为MyScreensaver,[NEXT],对话框,再后面随你了。打开菜单Project、Settings,在Debug页、Executable for debug session项,以及Link页中Output file name项改为c:\windows\MyScreensaver.scr,这样,你可以调试完后,直接在VC中运行(Ctrl+F5),便可看到结果。当然,这样做的唯一缺点是你必须手动清除Windows 目录下的垃圾文件(当然是在看到满意结果后;还有,你可借助SafeClean 这个小东东来帮你清除,除非你的硬盘大的让你感到无所谓……快快快回来,看我跑到那里去了)。接下来用Class Wizard生成CMyWnd类,其基类为CWnd(在Base Class 中为generic CWnd)。这个类是我们所要重点研究的。创建满屏窗口、计时器,隐藏鼠标,展示图片,响应键盘、鼠标等等,这家伙全包了。至于MyScreensaverDlg.h与MyScreensaverDlg.cpp文件我们暂时不管。打开MyScreensaver.cpp,修改InitInstance()函数:

    BOOL CMyScreensaverApp::InitInstance()

    {

     AfxEnableControlContainer();

    #ifdef _AFXDLL

     Enable3dControls(); // Call this when using MFC in a shared DLL

    #else

     Enable3dControlsStatic(); // Call this when linking to MFC statically

    #endif

     CMyWnd* pWnd = new CMyWnd;

     pWnd->Create();

     m_pMainWnd = pWnd;

     return TRUE;

    }

    当然,再这之前得先 #include “MyWnd.h" 。后面要做的都在MyWnd.h 与 MyWnd.cpp 两文件中了。

    下面给出CMyWnd 的说明:

    class CMyWnd : public CWnd

    {

    public:

     CMyWnd();

     static LPCSTR lpszClassName; //注册类名

    public:

     BOOL Create();

    public:

     // ClassWizard generated virtual function overrides

     //{{AFX_VIRTUAL(CMyWnd)

     protected:

     virtual void PostNcDestroy();

     //}}AFX_VIRTUAL

    public:

     virtual ~CMyWnd();

    protected:

     CPoint m_prePoint; //检测鼠标移动

     void DrawBitmap(CDC& dc, int nIndexBit);

     //{{AFX_MSG(CMyWnd)

     afx_msg void OnPaint();

     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 OnTimer(UINT nIDEvent);

     afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);

     afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);

     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()

    };

    MyWnd.cpp 文件:

    ……

    CMyWnd::CMyWnd()

    {

     m_prePoint=CPoint(-1, -1);

    }

    LPCSTR CMyWnd::lpszClassName=NULL;

    BOOL CMyWnd::Create()

    {

     if(lpszClassName==NULL)

     {

     lpszClassName=AfxRegisterWndClass(CS_HREDRAW CS_VREDRAW,

    ::LoadCursor(AfxGetResourceHandle(),MAKEINTRESOURCE(IDC_NOCURSOR)));

    //注册类;IDC_NOCURSOR为新建光标的ID,这个光标没有任何图案

     }

     CRect rect(0, 0, ::GetSystemMetrics(SM_CXSCREEN),

     ::GetSystemMetrics(SM_CYSCREEN));

     CreateEx(WS_EX_TOPMOST, lpszClassName, _T(“”), WS_VISIBLE WS_POPUP,

     rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,

     GetSafeHwnd(), NULL, NULL); //创建一个全屏窗口

     SetTimer(ID_TIMER, 500, NULL);//计时器,ID_TIMER别忘了定义

     return TRUE;

    }

    为了防止同时运行两个相同的程序,下面两个函数是必需的:

    void CMyWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)

    {

     CWnd::OnActivate(nState,pWndOther,bMinimized);

     if (nState==WA_INACTIVE)

     PostMessage(WM_CLOSE);

    }

    void CMyWnd::OnActivateApp(BOOL bActive, HTASK hTask)

    {

     CWnd::OnActivateApp(bActive, hTask);

     if (!bActive) //is being deactivated

     PostMessage(WM_CLOSE);

    }

    OnPaint()函数将全屏窗口置为黑色:

    void CMyWnd::OnPaint()

    {

     CPaintDC dc(this);

     CBrush brush(RGB(0,0,0));

     CRect rect;

     GetClientRect(rect);

     dc.FillRect(&rect, &brush);

    }

    由计数器调用DrawBitmap()函数,切换图片;注意,下面两个函数中的IDB_BITMAP1, dc.BitBlt(0,0,800,600……以及if(nIndexBit>=5)中的有关数据依据你的bmp图片个数、尺寸、位置不同而不同,我是选择了5张800x600的bmp图片。注意,ID值是连续的,IDB_BITMAP1最小。

    void CMyWnd::DrawBitmap(CDC &dc, int nIndexBit)

    {

     CDC dcmem;

     dcmem.CreateCompatibleDC(&dc);

     CBitmap m_Bitmap;

     m_Bitmap.LoadBitmap(IDB_BITMAP1+nIndexBit);

     dcmem.SelectObject(m_Bitmap);

     dc.BitBlt(0,0,800,600,&dcmem,0,0,SRCCOPY);

    }

    void CMyWnd::OnTimer(UINT nIDEvent)

    {

     CClientDC dc(this);

     static nIndexBit=0;

     if(nIndexBit>=5)

     nIndexBit=0;

     DrawBitmap(dc, nIndexBit++);

     CWnd::OnTimer(nIDEvent);

    }

   

    响应键盘、鼠标是屏幕保护程序不可缺少的,在OnKeyDown()、 OnLButtonDown()、 OnMButtonDown()、OnRButtonDown()、OnSysKeyDown()函数中都加入:

    PostMessage(WM_CLOSE);

    OnMouseMove()函数比较特殊,它应加的代码为:

     if(m_prePoint == CPoint(-1,-1))

     m_prePoint = point;

     else if(m_prePoint!=point)

     PostMessage(WM_CLOSE);

    快要完工了。在OnDestroy()函数中删掉计时器:KillTimer(ID_TIMER);

    还有啦,在CMyWnd::PostNcDestroy() 中加入: delete this;

    哎呀,腰酸背疼,眼球发涩,手背奇麻(不会吧)!不过,相信你一定会迫不及待地按下Ctrl+F5, 看着一幅幅图片在你面前轮番展示,啊,自己的屏幕保护程序!赶快赶快,换上自制的屏保,感觉就是不一样:图片任你挑,时间间隔任你改,鼠标?键盘?我想响应谁就响应谁……哎呀,谁扔的纸团:(。

    其实,上面的程序还有很多可以改进的地方,比如图片总是单一地显示;bmp 文件太大,导致生成的屏幕保护程序也很大,远没有jpg合算;没有密码,没有可直接控制的界面。由于InitInstance()函数的简单处理(直接调用CMyWnd类),你会发现当你在桌面上右击,选择“属性”、“屏幕保护程序”页、“屏幕保护程序”下拉菜单、选中MyScreensaver时,MyScreensaver就直接预览了(或是直接运行了);假设你确定MyScreensaver作为你的屏幕保护程序,等你第二次进入“屏幕保护程序”页时,就直接预览。Why? 回头看看InitInstance()函数就明白了。为了让它更听话地工作,可修改InitInstance()函数:

     LPTSTR lpszArgv = __argv[1];

     if (lpszArgv[0] ==‘/’)

     lpszArgv++;

     if (lstrcmpi(lpszArgv, _T(“s”))==0)

     {

     CMyWnd* pWnd=new CMyWnd;

     pWnd->Create();

     m_pMainWnd=pWnd;

     return TRUE;

     }

     return FALSE;

    不过现在你要是再在VC中运行这个程序,“该程序执行了非法操作,即将关闭。如果仍有问题,请与我联系(??)”将会伴随着一超重低音供你欣赏。(啊?)原因是我们加了一句return FALSE; 还有,别忘了还有一个CMyScreensaverDlg类没有用上,用它来与你的屏保直接对话再好不过了。例如,为了方便地确定时间间隔,选取图片,加上一个编辑框和几个按钮就可以了。重申一点,由于生成文件较大,占用的内存也多,如果不能运行,很可能是开的窗口太多了。这时你可以换较小的图片。有任何问题请来信:toxyz@163.net。晚些时候我将在家门口 http://yxz.163.net 放置上述例子的整个项目,有一些新玩意和大家共同探讨。
关键字: 数据库应用 
您对这篇文章的看法是:    喜欢 反感 支持 反对 加油 鄙视 学习 打击 佩服 漂亮 路过 发表评论
视频教程】 【专题汇总】 【不懂就问我关闭窗口

360安全卫士 V5.1.1正式版发布!
Photoshop给模特美腿加上质感肤色
了解差距 国外27款创意名片设计赏
认清五种被忽视的黑客攻击方式
QQ音乐播放器2009正式版今天发布!
相关文章
 本栏目最新文章
·VC各类之间的调用函数总结
·VC中特殊字体的实现方法讲解
·VC++中进程与多进程管理的方法
·用VC 6.0实现串行通信的三种方法
·VC++实现回收站的文件存取
 精彩回放
·3DSMAX打造书本翻开效果
·共享上网技巧应用四则
·陪酒女浸泡在酒里的青春
·美女的性感靓丽婚纱设计
·妖冶身姿 死或生3壁纸
·剿灭Win XP下的29个烦恼
·黑客必备 NET命令大全
·用PS制作精致绝伦的红酒
 精彩推荐
 今日软件下载
杀毒软件免费随便用
瑞星全功能安全软件2009 基于“云安全”策略和“智能主动防御”技术开发.
www.rising.com.cn
 往日推荐
·推荐“美图秀秀”就能赚Q币
·五大搜索引擎横向评测
·防御计算机病毒十大步骤

论坛精华
·史上最强最多 photo 
·photoshop完美扣图教 
·网络学院flash教程目 
·Photoshop下载大全 
·PhotoShop实例精选电 
·打包笔刷 附图的~~ 
热点推荐
绘制逼真金蛋
浪漫婚纱照片
Flash视频编程
Ulead GIF教程
热点关注
·Flash CS4 制作经典小游戏
·C语言程序设计视频教程
·PHP+MYSQL开发视频教程
·Flash CS4从入门到精通教程
·服装设计与效果图绘制教程
·21视频之Fireworks8网页制作
·Vray高级实例应用视频教程
·CorelDRAW14入门到高级教程
·Vray高级实例应用视频教程
全国计算机等级考试二级(VB语言)
往日推荐
网站重构设计
鹏哥C#教程
服装设计教程
PS唯美风景
焦点关注