狠狠爱成人网_日韩一级在线_国产综合自拍_亚洲精品韩国_亚洲视频导航_麻豆成人在线播放_欧美jjzz_一区在线视频观看_美脚丝袜一区二区三区在线观看_欧美91视频

當前位置:系統之家 > 技術開發教程 > 詳細頁面

從任務通知區打開屏幕保護程序

從任務通知區打開屏幕保護程序

更新時間:2024-04-10 文章作者:未知 信息來源:網絡 閱讀次數:

作者:朱志強

本文通過一個快速啟動屏幕保護程序的小程序SSLaunch,來介紹應用程序如何向任務欄通知區加入圖標、如何禁止多個Win32實例以及屏幕保護程序的有關內容。

  SSLaunch用C語言編寫,用Visual C++ 5.0編譯,是一個基于無模式對話框的程序,同時禁止多個實例,即一次只能有一個實例運行。任務欄通知區圖標在對話框初始化時加入,對話框響應程序定義的回調消息,當鼠標左鍵按下時,彈出一由屏幕保護程序名填充的上下文菜單。對話框關閉(即程序退出)時刪除任務欄通知區圖標。如果讀者有興趣可以很容易地把它移植成基于 MFC 的程序。

  1、任務欄通知區

  Windows 95的任務欄中有一個通知區, 應用程序可以把一個圖標放入其中,以表示操作狀態,并可以有與之相關聯的工具用作說明控制。當鼠標出現在此圖標的矩形邊界內時,向相應的應用程序發送應用程序定義的回調消息。應用程序通過發送消息增加、修改、刪除任務欄圖標。消息的發送通過調用函數Shell_NotifyIcon來完成,如果調用成功,則返回TRUE;否則,返回FALSE。Shell_NotifyIcon函數原形如下:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
  DWORD dwMessage, // 消息標識符
  PNOTIFYICONDATA pnid // NOTIFYICONDATA 結構
  );
     消息標識符可以是 :
  NIM_ADD 向任務欄通知區加入圖標
  NIM_DELETE 從任務欄通知區刪除圖標
  NIM_MODIFY 改變任務欄通知區圖標
     NOTIFYICONDATA 結構:
  typedef struct _NOTIFYICONDATA {
   DWORD cbSize;
   HWND hWnd;
   UINT uID;
   UINT uFlags;
  UINT uCallbackMessage;
  HICON hIcon;
  char szTip[64];
  } NOTIFYICONDATA, *PNOTIFYICONDATA;
     其中:
  cbSize NOTIFYICONDATA 結構大小
  hWnd 接收回調消息窗口句柄
  uID 任務欄通知區圖標標識
  uFlags 指定該結構中那些成員有效
  uCallbackMessage 應用程序定義的回調消息
  hIcon 任務欄通知區圖標句柄
  szTip 任務欄通知區提示字符串
     參數uFlags可以是下列值的組合:
  NIF_ICON 任務欄通知區圖標有效
  NIF_MESSAGE 應用程序定義的回調消息有效
  NIF_TIP 任務欄通知區提示字符串有效
  a.任務欄通知區圖標的加入
  BOOL SSLaunch_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)

  {

   // Add an notification icon to the taskbar

   NOTIFYCONDATA nid;

   NOTIFYICONDATA nid;

  
   nid.cbSize = sizeof(nid);

   nid.hWnd = hwnd;

   nid.uID = IDI_SSLAUNCH;

   nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;

   nid.uCallbackMessage = WM_SSLAUNCHICONNOTIFY;

   nid.hIcon=LoadIcon(GetWindowInstance(hwnd),

  KEINTRESOURCE(IDI_SSLAUNCH));

   lstrcpyn(nid.szTip,g_szAppName,sizeof(nid.szTip) /sizeof(nid.szTip[0]));

  
   return(Shell_NotifyIcon(NIM_ADD, &nid))

  }

  b.任務欄通知區圖標的刪除

   應用程序退出時,應該刪除任務通知區上相應的圖標:
  void SSLaunch_OnDestroy(HWND hwnd)

  {

   // Remove the notification icon from the taskbar

  
   NOTIFYICONDATA nid;

   nid.cbSize = sizeof(nid);

   nid.hWnd = hwnd;

   nid.uID = IDI_SSLAUNCH;

  
   Shell_NotifyIcon(NIM_DELETE, &nid);

  }

  c.應用程序定義回調消息的接收

  若為任務欄通知區指定了回調消息,則系統會于鼠標事件在此區域發生時

  向應用程序發送此消息,其中wParam是任務欄通知區圖標標識,lParam

  是鼠標事件發生后的鼠標信息。

  
  void SSLaunch_OnIconNotify(WPARAM wParam, LPARAM lParam)

  {

   UINT uID = (UINT)wParam;

   UINT uMsg = (UINT)lParam;

  
   if(uID == IDI_SSLAUNCH){

   switch(uMsg){

   case WM_LBUTTONDOWN :

   //Do something

   break;

  
   case WM_LBUTTONUP :

   //Do something

   break;

  
   default :

   break;

   }

   }

  }

  
  2.禁止多個Win32實例

  在討論禁止多個Win32實例之前,我們先討論一下WinMain函數。我們知道,任何一個基于GDI的Windows程序以WinMain函數作為入口被系統調用。在Win16中,hPrevInstance指向前一個實例的句柄,但在Win32中,每一個進程都有一個獨立的4G地址空間,從0到2G屬于進程私有,對其他進程來說是不可見的。所以,在Win32中,hPrevInstance總是為NULL。

  
  int WINAPI WinMain(

  HINSTANCE hInstance, // handle to current instance

  HINSTANCE hPrevInstance, // handle to previous instance

  LPSTR lpCmdLine, // pointer to command line

  int nCmdShow // show state of window

  );

  
  因而,在Win32下不能通過判斷hPrevInstance是否為NULL來判斷一個程序的另一個實例是否存在,要用其他的方法來判斷。

  
  方法一

  用FindWindow 函數查找指定窗口,如果成功,則返回要找的窗口的句柄,否則返回NULL,由此可判斷是否有程序的另一個實例存在。

  
  下圖的代碼片段演示如何使用FindWindow函數:

  
  TCHAR szClassName[] = _TEXT("My Wnd Class");

  TCHAR szWndName[] = _TEXT("My Wnd");

  HWND hWnd = FindWindow(szClassName,szWndName);

  
  if(hWnd){

  MessageBox(NULL, _TEXT("Another Instance is already running."), _TEXT("Information"),

   MB_OK | MB_ICONINFORMATION);

  }

  
  需要注意的是,很可能程序的各個實例有不同的窗口名,如果象下面這樣調用FindWindow

   HWND hWnd = FindWindow(szClassName,NULL);

  則查找所有的窗口并匹配窗口類名,如果你能保證你的窗口類名是唯一的,那么你可以信賴FindWindow,否則,你需要用更好的方法。

  
  方法二

  
  通過在EXE之間共享數據段從而共享數據來判斷是否有程序的另一個實例存在。

  每個EXE或DLL都是由段的集合組成,在Win32程序中,每個段以點(.)開頭。例如,當編譯程序是編譯器時,則將所有代碼放入一個叫.text的段、將所有未初始化的數據放入.bss段、將所有初始化的數據放入.data段。

  
  可以給每個段賦予一個或多個屬性(以下為常用的一些段屬性):

  
  READ 段中的數據可讀

  WRITE 段中的數據可寫

  SHARED 段中的數據可被多個實例共享

  EXECUTE 段中的數據可被執行

  
  可以用以下指令生成段:

  #pragma data_seg("Shared")

  static LONG g_lInstanceCount = -1;

  #pragma data_seg()

  
  編譯器生成這段代碼時,產生一個新段,并把它所在#pragma data_seg("Shared")指令后的初始化數據放入新段Shared,未初始化的數據放入.bss段。#pragma data_seg()以后的數據放回缺省數據段。

  
  僅告訴編譯器把特定數據放入自己的段內還不足以共享它們,還要告訴鏈接器在某一特定段內變量要共享。可以在鏈接時指定這個段的屬性。

  /section:Shared,rws

   段名 屬性

  
  程序初始化時,例如調用WinMain函數時,調用InterlockedIncrement函數使共享段內變量加1,就可以通過判斷共享段內變量的值來判斷一個程序有幾個實例在運行。以下代碼演示了如何判斷一個正在運行的程序實例是這個程序的第一個實例。

  
  BOOL bIsFirstInstance = (InterlockedIncrement(&g_lInstanceCount) == 0);

   if(!bIsFirstInstance){

   MessageBox(NULL, _TEXT("Screen Saver Launcher is already running."), g_szAppName,

   MB_OK | MB_ICONINFORMATION);

   }

  
  使共享段內變量加1,沒使用 g_lInstanceCount ++,而是使用InterlockedIncrement(&g_lInstanceCount),因為InterlockedIncrement函數對變量的訪問進行同步(Synchronize),阻止多個線程同時訪問同一個變量。有關線程同步的內容請參閱有關Win32 SDK的文檔。

  禁止多個Win32實例的方法很多,如Win32核心對象(Mutex, Semaphore)、全局原子等都可以用來禁止多個Win32實例,在這里我們只簡單地介紹以上兩種方法。

  
  3.Screen Saver Launch:

  屏幕保護程序是以scr為擴展名的標準Windows可執行程序。當編輯可用屏幕保護程序的列表時,Control Panel Desktop Applet在Windows啟動目錄(Windows目錄和系統目錄)下查找擴展名是scr的基于Windows的可執行程序,如果Windows目錄和系統目錄下同時存在相同文件名的屏幕保護程序,則忽略Windows目錄下的那一個。任何蓄意的搗亂(如將文本文件或是基于DOS的可執行文件擴展名改為scr)Window95都不予理睬,但是將標準Windows可執行程序的擴展名改為scr時,Windows95及NT將不會察覺。這只是很極端的情況,相信用戶不會采用這種做法來"測試"你的Windows.

  標準的基于Win32的屏幕保護程序必須按照嚴格的標準編寫,有關詳細介紹請參閱有關Win32 SDK文檔。這里需要提到的一點是所有的基于Win32的屏幕保護程序都要求有一個不超過25個字符的說明字符串。在屏幕保護程序的資源字符串表中,這個說明字符串的標識必須是1。

  但我們發現在Windows 95下的屏幕保護程序不完全是嚴格按照標準編寫的,當編輯可用屏幕保護程序的列表時,Control Panel Desktop Applet只是簡單地把屏幕保護程序的文件名加入列表,而不是加入上面提及的說明字符串。而在Windows NT下,系統嚴格區分標準的和非標準的屏幕保護程序。對于標準的屏幕保護程序,系統取得它的說明字符串并將其顯示在屏幕保護程序的列表中;對于非標準的屏幕保護程序,系統只把它的文件名加入列表。

  由于Windows 95和Windows NT下屏幕保護程序的列表顯示略有不同,所以這里分別加以說明。為區別起見,Windows 95下的SSLaunch用SSLaunch95表示,Windows NT下的SSLaunch用SSLaunchNT表示。

  SSLaunch95 采用Window 95調用屏幕保護程序的方法,在Windows95的啟動目錄下搜索屏幕保護程序,把文件名加到任務欄通知區圖標上下文菜單中,單擊鼠標即可啟動相應的屏幕保護程序。Windows 95把用戶選中的屏幕保護程序名保存在 System.ini文件中\boot\SCRNSAVE.EXE 下。SSLaunch95比較系統保存的用戶選中的屏幕保護程序名和搜索到的屏幕保護程序名,如果相同,則在任務欄通知區圖標上下文菜單的相應菜單項設置檢查標志,以表示這個屏幕保護程序是否是當前用戶選中的。SSLaunch95沒有判斷Windows啟動目錄下的屏幕保護程序是否是真正的屏幕保護程序,因為Windows 95下的Win32不能輕易地判斷一個scr文件是否是基于GDI的Windows可執行文件(NE 或PE格式)。作者找到了兩個可用于判斷文件類型的函數:SHGetFileInfo,GetBinaryType。SHGetFileInfo可以判斷出.exe、.com、.bat幾種文件類型,但認為.scr文件不是可執行文件;GetBinaryType可以輕易地判斷出文件類型,但Windows 95不支持,只是簡單地返回ERROR_NOT_IMPLEMENT,而Win32卻支持它。

  點擊示意圖

  SSLaunch95也可以在Windows NT 下運行,不過彈出的上下文菜單不能用屏幕保護程序說明字符串填充,并且不能判斷scr是否是基于GDI的Windows可執行程序。

  下面介紹SSLaunchNT在Windows NT下對scr文件的判別,以及從scr文件資源中取得屏幕保護程序描述字符串的方法。

  a.對scr文件的判別

  Windows NT提供了對GetBinaryType函數的支持,因此,可用此函數判斷一個scr文件是否是Windows可執行程序,并判斷出它是基于Win16還是 Win32的可執行程序。這一點很重要,因為,對基于Win32的scr文件,我們在后面要取得它的字符串資源中的一個重要信息,及對屏幕保護程序的描述字符串。還應注意的是,lpApplicationName應給出全路徑,否則,它只在進程所在的路徑下尋找文件,這樣會導致錯誤,從而不能返回在Windows啟動目錄下的.scr文件的信息。


  BOOL GetBinaryType(

  LPCTSTR lpApplicationName,

  LPDWORD lpBinaryType

  );

  GetBinaryType調用成功后,lpBinaryType指向的DWORD返回以下值:

  SCS_32BIT_BINARY 基于Win32的應用程序

  SCS_DOS_BINARY 基于MS-DOS的應用程序

  SCS_OS216_BINARY 基于16位OS/2的應用程序

  SCS_PIF_BINARY MS-DOS應用程序的PIF 文件

  SCS_POSIX_BINARY 基于POSIX的應用程序

  SCS_WOW_BINARY 基于16位Windows的應用程序

  b.從scr文件字符串資源中取得屏幕保護文件描述字符串

  當我們判斷出了一個基于Win32的scr文件后,就可以著手取得它的字符串。在Win32中,有一種簡單有效的方法:把一個EXE或DLL文件以數據文件方式加載,調用LoadLibraryEx函數。

  HINSTANCE LoadLibraryEx(

  LPCTSTR lpLibFileName, // EXE或DLL文件名

  HANDLE hFile, // 保留參數,必須為NULL

  DWORD dwFlags // 函數入口標志

  );

  dwFlags可以是0或以下標志的組合:

  DON'T_RESOLVE_DLL_REFERENCES 系統將DLL映射到進程的地址空間而不調用DllMain函數。

  LOAD_LIBRARY_AS_DATAFILE 系統將DLL象一個數據文件那樣映射到進程的地址空間,而不調用DllMain函數。如果要取得EXE中的資源,也可調用LoadLibraryEx函數把EXE映射到進程地址空間。

  LOAD_WITH_ALTERED_SEARCH_PATH 將改變LoadLibraryEx在定位DLL文件時所采用的方法。

  
  當以LOAD_LIBRARY_AS_DATAFILE的方式調用LoadLibraryEx時,系統只是簡單地創建一個文件映象對象,把DLL(EXE)映射到本進程的地址空間,并不調用DllMain(WinMain)。如果調用成功,則函數返回一個HINSTANCE,即被映射到本進程地址空間的DLL(EXE)的裝入地址,這樣,就可以調用LoadString函數,從DLL(EXE)文件的字符串資源表中取得指定的字符串。

  點擊示意圖

  這里仍需指出的是,必須判斷LoadString函數調用是否成功,因為有些scr文件(即使是基于Win32的)也有可能是非標準的(如Windows 95下的大多數scr文件),如果LoadString調用失敗,則SSLaunchNT用文件名取代scr的描述字符串填入SSLaunchNT上下文菜單的菜單項。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

狠狠爱成人网_日韩一级在线_国产综合自拍_亚洲精品韩国_亚洲视频导航_麻豆成人在线播放_欧美jjzz_一区在线视频观看_美脚丝袜一区二区三区在线观看_欧美91视频
九九精品一区二区| 亚洲专区一二三| 国产精品a级| 专区另类欧美日韩| 狠狠88综合久久久久综合网| 一区二区理论电影在线观看| 91福利视频在线| 成人性生交大片免费看视频在线| 欧美mv日韩mv国产网站app| 欧美精品国产一区| jlzzjlzz欧美大全| 丝袜a∨在线一区二区三区不卡| 欧美视频精品在线| 国产欧美大片| 欧美99在线视频观看| 奇米精品一区二区三区在线观看一| 91精品国产综合久久久久久 | 亚洲国产综合91精品麻豆| 欧美性感一类影片在线播放| 99re这里只有精品视频首页| 日精品一区二区三区| 国产精品久久久久精k8 | 91在线视频在线| 18涩涩午夜精品.www| 国产午夜精品在线观看| 欧美日韩久久久一区| 99综合在线| 91在线丨porny丨国产| 久久久夜精品| 亚洲欧美在线另类| 国产在线一区二区综合免费视频| 91在线一区二区三区| 欧洲精品中文字幕| 天天综合网 天天综合色| 99热99精品| 欧美日韩午夜影院| 日本亚洲天堂网| 亚洲日本欧美| 国产精品美女视频| 懂色av一区二区三区免费看| 欧美专区一区二区三区| 国产欧美综合色| 国产精品正在播放| 精品污污网站免费看| 无码av免费一区二区三区试看 | 欧美日韩在线不卡| 成人影视亚洲图片在线| 久久精品一二三| 一本大道av伊人久久综合| 亚洲123区在线观看| 久久久亚洲精华液精华液精华液| 99日韩精品| 91影院在线免费观看| 亚洲成人免费电影| 国产欧美日韩麻豆91| 91麻豆精品久久久久蜜臀| 欧美另类一区| 岛国av在线一区| 美女国产一区二区三区| 亚洲特级片在线| 久久久五月婷婷| 日韩视频在线一区二区| 嫩草成人www欧美| 国语对白精品一区二区| 豆国产96在线|亚洲| 亚洲免费资源在线播放| 国产成人免费视频| 日韩午夜在线播放| 国语精品中文字幕| 精品综合免费视频观看| 国产精品日韩精品欧美在线| 鲁大师影院一区二区三区| 成人性生交大片免费| 亚洲精品乱码久久久久久久久| 欧洲精品一区二区| 欧美黄在线观看| 婷婷丁香久久五月婷婷| 久久婷婷久久一区二区三区| 久久亚洲欧美| 亚洲天堂黄色| 99精品一区二区三区| 久久99最新地址| 亚洲国产精品一区二区久久| 久久亚洲私人国产精品va媚药| 欧美三级视频在线| 久久精品成人| 久久精品二区三区| 国产一区二区黄色| 999亚洲国产精| 国模大胆一区二区三区| 成人免费看视频| 成人黄色在线视频| 成人深夜视频在线观看| 国产一区二区精品久久99| 免费欧美在线视频| 久久丁香综合五月国产三级网站| 亚洲动漫第一页| 日韩成人精品在线观看| 九九久久精品视频| 国产一区二区三区综合| 粉嫩欧美一区二区三区高清影视 | 婷婷丁香激情综合| 久久中文字幕电影| 一区二区91| 国产一区二区三区四区五区入口| 91精品国产综合久久精品 | www.66久久| 另类综合日韩欧美亚洲| 青娱乐精品在线视频| 国产拍揄自揄精品视频麻豆| 久久国产66| 91免费版pro下载短视频| 一区二区成人在线观看| 一区二区三区四区蜜桃| 国产精品麻豆99久久久久久| 色综合久久九月婷婷色综合| 一区在线观看| 久久久www| 91麻豆精品国产91久久久久久久久| 欧美电影在线免费观看| 久久免费视频色| 亚洲美女视频在线| 毛片av一区二区| 欧美日韩在线不卡一区| 国产欧美一区二区三区另类精品 | 香蕉成人伊视频在线观看| 国产美女精品人人做人人爽| 91视频在线观看免费| 午夜一级在线看亚洲| 精品成人免费观看| 首页国产欧美日韩丝袜| 成人国产精品免费网站| 午夜在线视频一区二区区别| 欧美大片在线观看一区二区| 一区二区三区产品免费精品久久75| 久久成人综合网| 国产精品一区二区三区免费观看| 欧美日韩五月天| 亚洲精品日日夜夜| aaa亚洲精品| 欧美日韩国产综合一区二区三区 | 韩日av一区二区| 亚洲人成毛片在线播放女女| 91精品国产一区二区三区| 亚洲va韩国va欧美va| 午夜精品电影| 久久久综合激的五月天| 国产盗摄视频一区二区三区| 91精品办公室少妇高潮对白| 亚洲精品国久久99热| 狠狠色噜噜狠狠色综合久| 欧美精品一区二区三区很污很色的 | 欧美日韩1234| 国产中文字幕一区| 欧美日韩精品一区二区在线播放| 亚洲福利一二三区| 久久一综合视频| 免费在线成人网| 欧美老女人在线| 处破女av一区二区| 久久精品水蜜桃av综合天堂| www.久久久久久久久| 26uuu亚洲综合色欧美| 欧美精品一区二区三区久久久竹菊| 精品国产91洋老外米糕| 国产精品国产三级国产专区53| 欧美韩国日本一区| 国产精品乱看| 九九视频精品免费| 国产亚洲成aⅴ人片在线观看 | 一区二区三区中文字幕精品精品| 国产精品制服诱惑| 激情久久久久久久久久久久久久久久 | 91精品国产综合久久久久久久久久 | 精品国产乱码久久久久久牛牛| 91啪亚洲精品| 免费成人美女在线观看| 精品国产凹凸成av人网站| 91久久国产自产拍夜夜嗨| 欧美aⅴ一区二区三区视频| 日韩一级高清毛片| aa国产精品| 经典三级视频一区| 亚洲精品精品亚洲| 欧美一级二级三级乱码| 亚洲国产精选| 不卡一区二区在线| 日日夜夜精品视频免费| 国产精品污污网站在线观看| 校园激情久久| 国产精品第十页| www.99精品| 成人高清视频在线| 日本大胆欧美人术艺术动态| 久久综合九色欧美综合狠狠| 欧美日韩国产成人在线91| 国产区日韩欧美| 激情欧美日韩一区| 午夜精品短视频| 91在线无精精品入口|