⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subject_24785.htm

📁 一些关于vc的问答
💻 HTM
字号:
<p>
序号:24785 发表者:CDMA2000 发表日期:2002-12-16 15:12:59
<br>主题:如何编写屏幕保护程序(生成.scr)文件?有无资料?还有如何在代码中执行屏幕保护文件(*.scr)
<br>内容:我记得好象是rundll32.exe来执行的,但不能确定有人帮以下吗?
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:bird 回复日期:2002-12-16 15:28:33
<br>内容:http://www.cbinews.com/developer/showcontent.php?articleid=2195<BR>http://www.vckbase.com/code/listcode.asp?mclsid=13&amp;sclsid=1329<BR>看代码:<BR>http://my.szptt.net.cn/twing/landown/exam/exam003.zip
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:bird 回复日期:2002-12-16 15:32:15
<br>内容:  VC++可谓神通广大,如果学到家了,或者就掌握了那么一点MFC,你也会感到它的方便快捷,当然最重要的是功能强大。不是吗,从最基本的应用程序.EXE到动态连接库DLL,再由风靡网上的ActiveX控件到Internet Server API,当然,还有数据库应用程序……瞧,我都用它来做屏幕保护程序了。一般的屏幕保护程序都是以SCR作为扩展名,并且要放在c:\windows 目录或 c:\windows\system 目录下,由Windows 98内部程序调用(Windows NT 是在 c:\windows\system32 目录下)。怎么调用?不用说了,这谁不知道。<BR>  好了,我们来作一个简单的。选择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()函数:<BR>  BOOL CMyScreensaverApp::InitInstance()<BR>  {<BR>   AfxEnableControlContainer();<BR>  #ifdef _AFXDLL<BR>   Enable3dControls(); // Call this when using MFC in a shared DLL<BR>  #else<BR>   Enable3dControlsStatic(); // Call this when linking to MFC statically<BR>  #endif<BR>   CMyWnd* pWnd = new CMyWnd;<BR>   pWnd-&gt;Create();<BR>   m_pMainWnd = pWnd;<BR>   return TRUE;<BR>  }<BR>  当然,再这之前得先 #include “MyWnd.h" 。后面要做的都在MyWnd.h 与 MyWnd.cpp 两文件中了。<BR>  下面给出CMyWnd 的说明:<BR>  class CMyWnd : public CWnd<BR>  {<BR>  public:<BR>   CMyWnd();<BR>   static LPCSTR lpszClassName; //注册类名<BR>  public:<BR>   BOOL Create();<BR>  public:<BR>   // ClassWizard generated virtual function overrides<BR>   //{{AFX_VIRTUAL(CMyWnd)<BR>   protected:<BR>   virtual void PostNcDestroy();<BR>   //}}AFX_VIRTUAL<BR>  public:<BR>   virtual ~CMyWnd();<BR>  protected:<BR>   CPoint m_prePoint; //检测鼠标移动<BR>   void DrawBitmap(CDC& dc, int nIndexBit);<BR>   //{{AFX_MSG(CMyWnd)<BR>   afx_msg void OnPaint();<BR>   afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);<BR>   afx_msg void OnLButtonDown(UINT nFlags, CPoint point);<BR>   afx_msg void OnMButtonDown(UINT nFlags, CPoint point);<BR>   afx_msg void OnMouseMove(UINT nFlags, CPoint point);<BR>   afx_msg void OnRButtonDown(UINT nFlags, CPoint point);<BR>   afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);<BR>   afx_msg void OnDestroy();<BR>   afx_msg void OnTimer(UINT nIDEvent);<BR>   afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);<BR>   afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);<BR>   //}}AFX_MSG<BR>   DECLARE_MESSAGE_MAP()<BR>  };<BR>  MyWnd.cpp 文件:<BR>  ……<BR>  CMyWnd::CMyWnd()<BR>  {<BR>   m_prePoint=CPoint(-1, -1);<BR>  } <BR>  LPCSTR CMyWnd::lpszClassName=NULL;<BR>  BOOL CMyWnd::Create()<BR>  {<BR>   if(lpszClassName==NULL)<BR>   {<BR>   lpszClassName=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, <BR>  ::LoadCursor(AfxGetResourceHandle(),MAKEINTRESOURCE(IDC_NOCURSOR)));<BR>  //注册类;IDC_NOCURSOR为新建光标的ID,这个光标没有任何图案<BR>   }<BR>   CRect rect(0, 0, ::GetSystemMetrics(SM_CXSCREEN),<BR>   ::GetSystemMetrics(SM_CYSCREEN));<BR>   CreateEx(WS_EX_TOPMOST, lpszClassName, _T(“”), WS_VISIBLE|WS_POPUP, <BR>   rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, <BR>   GetSafeHwnd(), NULL, NULL); //创建一个全屏窗口<BR>   SetTimer(ID_TIMER, 500, NULL);//计时器,ID_TIMER别忘了定义<BR>   return TRUE;<BR>  }<BR>  为了防止同时运行两个相同的程序,下面两个函数是必需的:<BR>  void CMyWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) <BR>  {<BR>   CWnd::OnActivate(nState,pWndOther,bMinimized);<BR>   if (nState==WA_INACTIVE)<BR>   PostMessage(WM_CLOSE);<BR>  }<BR>  void CMyWnd::OnActivateApp(BOOL bActive, HTASK hTask)<BR>  {<BR>   CWnd::OnActivateApp(bActive, hTask);<BR>   if (!bActive) //is being deactivated<BR>   PostMessage(WM_CLOSE);<BR>  }<BR>  OnPaint()函数将全屏窗口置为黑色:<BR>  void CMyWnd::OnPaint()<BR>  {<BR>   CPaintDC dc(this);<BR>   CBrush brush(RGB(0,0,0));<BR>   CRect rect;<BR>   GetClientRect(rect);<BR>   dc.FillRect(&rect, &brush);<BR>  }<BR>  由计数器调用DrawBitmap()函数,切换图片;注意,下面两个函数中的IDB_BITMAP1, dc.BitBlt(0,0,800,600……以及if(nIndexBit&gt;=5)中的有关数据依据你的bmp图片个数、尺寸、位置不同而不同,我是选择了5张800x600的bmp图片。注意,ID值是连续的,IDB_BITMAP1最小。<BR>  void CMyWnd::DrawBitmap(CDC &dc, int nIndexBit)<BR>  {<BR>   CDC dcmem;<BR>   dcmem.CreateCompatibleDC(&dc);<BR>   CBitmap m_Bitmap;<BR>   m_Bitmap.LoadBitmap(IDB_BITMAP1+nIndexBit);<BR>   dcmem.SelectObject(m_Bitmap);<BR>   dc.BitBlt(0,0,800,600,&dcmem,0,0,SRCCOPY);<BR>  }<BR>  void CMyWnd::OnTimer(UINT nIDEvent)<BR>  {<BR>   CClientDC dc(this);<BR>   static nIndexBit=0;<BR>   if(nIndexBit&gt;=5)<BR>   nIndexBit=0;<BR>   DrawBitmap(dc, nIndexBit++);<BR>   CWnd::OnTimer(nIDEvent);<BR>  }<BR> <BR>  响应键盘、鼠标是屏幕保护程序不可缺少的,在OnKeyDown()、 OnLButtonDown()、 OnMButtonDown()、OnRButtonDown()、OnSysKeyDown()函数中都加入:<BR>  PostMessage(WM_CLOSE);<BR>  OnMouseMove()函数比较特殊,它应加的代码为:<BR>   if(m_prePoint == CPoint(-1,-1))<BR>   m_prePoint = point;<BR>   else if(m_prePoint!=point)<BR>   PostMessage(WM_CLOSE); <BR>  快要完工了。在OnDestroy()函数中删掉计时器:KillTimer(ID_TIMER); <BR>  还有啦,在CMyWnd::PostNcDestroy() 中加入: delete this;<BR>  哎呀,腰酸背疼,眼球发涩,手背奇麻(不会吧)!不过,相信你一定会迫不及待地按下Ctrl+F5, 看着一幅幅图片在你面前轮番展示,啊,自己的屏幕保护程序!赶快赶快,换上自制的屏保,感觉就是不一样:图片任你挑,时间间隔任你改,鼠标?键盘?我想响应谁就响应谁……哎呀,谁扔的纸团:(。<BR>  其实,上面的程序还有很多可以改进的地方,比如图片总是单一地显示;bmp 文件太大,导致生成的屏幕保护程序也很大,远没有jpg合算;没有密码,没有可直接控制的界面。由于InitInstance()函数的简单处理(直接调用CMyWnd类),你会发现当你在桌面上右击,选择“属性”、“屏幕保护程序”页、“屏幕保护程序”下拉菜单、选中MyScreensaver时,MyScreensaver就直接预览了(或是直接运行了);假设你确定MyScreensaver作为你的屏幕保护程序,等你第二次进入“屏幕保护程序”页时,就直接预览。Why? 回头看看InitInstance()函数就明白了。为了让它更听话地工作,可修改InitInstance()函数:<BR>   LPTSTR lpszArgv = __argv[1];<BR>   if (lpszArgv[0] ==‘/’)<BR>   lpszArgv++;<BR>   if (lstrcmpi(lpszArgv, _T(“s”))==0)<BR>   {<BR>   CMyWnd* pWnd=new CMyWnd;<BR>   pWnd-&gt;Create();<BR>   m_pMainWnd=pWnd;<BR>   return TRUE;<BR>   }<BR>   return FALSE;<BR>  不过现在你要是再在VC中运行这个程序,“该程序执行了非法操作,即将关闭。如果仍有问题,请与我联系(??)”将会伴随着一超重低音供你欣赏。(啊?)原因是我们加了一句return FALSE; 还有,别忘了还有一个CMyScreensaverDlg类没有用上,用它来与你的屏保直接对话再好不过了。例如,为了方便地确定时间间隔,选取图片,加上一个编辑框和几个按钮就可以了。重申一点,由于生成文件较大,占用的内存也多,如果不能运行,很可能是开的窗口太多了。这时你可以换较小的图片。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:CDMA2000 回复日期:2002-12-16 15:35:22
<br>内容:那怎样在代码中启动*.scr文件呢?
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:bird 回复日期:2002-12-16 15:56:32
<br>内容:使用SendMessage函数向系统发送一个广播消息就可以了,具体原代码为: <BR><BR>void __fastcall TForm1::Button1Click(TObject *Sender)<BR>{<BR>SendMessage(HWND_BROADCAST,WM_SYSCOMMAND,SC_SCREENSAVE,0);<BR>} <BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -