使用未公开API ITrayNotify控制托盘图标的隐藏和显示

来源:互联网 发布:四叶草引导mac和win7 编辑:程序博客网 时间:2024/06/06 18:06
Vista开始,右下角的托盘图标默认会隐藏起来,要手动设置显示。在网上找了一圈还真发现有显示的方法,使用的是微软未公开的ITrayNotify接口。

代码1 来源 http://bbs.pediy.com/showthread.php?p=1382584
#include "stdafx.h"#include <conio.h>#include <windows.h>#include <Shlwapi.h>#pragma comment(lib, "shlwapi.lib")typedef struct tagNOTIFYITEM{    PWSTR pszExeName;    PWSTR pszTip;    HICON hIcon;    HWND hWnd;    DWORD dwPreference;    UINT uID;    GUID guidItem;} NOTIFYITEM, *PNOTIFYITEM;class __declspec(uuid("D782CCBA-AFB0-43F1-94DB-FDA3779EACCB")) INotificationCB : public IUnknown{    virtual HRESULT __stdcall Notify (ULONG, NOTIFYITEM *) = 0;};class __declspec(uuid("FB852B2C-6BAD-4605-9551-F15F87830935")) ITrayNotify : public IUnknown{public:    virtual HRESULT __stdcall RegisterCallback(INotificationCB* callback) = 0;    virtual HRESULT __stdcall SetPreference(const NOTIFYITEM* notify_item) = 0;    virtual HRESULT __stdcall EnableAutoTray(BOOL enabled) = 0;};class __declspec(uuid("D133CE13-3537-48BA-93A7-AFCD5D2053B4")) ITrayNotifyWindows8 : public IUnknown{public:    virtual HRESULT __stdcall RegisterCallback(INotificationCB* callback, unsigned long*) = 0;    virtual HRESULT __stdcall UnregisterCallback(unsigned long*) = 0;    virtual HRESULT __stdcall SetPreference(NOTIFYITEM const*) = 0;    virtual HRESULT __stdcall EnableAutoTray(BOOL) = 0;    virtual HRESULT __stdcall DoAction(BOOL) = 0;};const CLSID CLSID_TrayNotify = {0x25DEAD04, 0x1EAC, 0x4911, {0x9E, 0x3A, 0xAD, 0x0A, 0x4A, 0xB5, 0x60, 0xFD}};class NotificationMgr : public INotificationCB{public:    NotificationMgr(){        m_pTrayNotify = NULL;    }    HRESULT __stdcall QueryInterface (        REFIID riid,        PVOID *ppv)    {        if (ppv == NULL)             return E_POINTER;        if (riid == __uuidof (INotificationCB)) {            *ppv = (INotificationCB *) this;        }else if (riid == IID_IUnknown) {            *ppv = (IUnknown *) this;        }else{            return E_NOINTERFACE;        }        ((IUnknown *) *ppv) -> AddRef ();        return S_OK;    }    ULONG __stdcall AddRef (VOID)    {        return 1;    }    ULONG __stdcall Release (VOID)    {        return 1;    }    HRESULT __stdcall Notify (ULONG Event, NOTIFYITEM * NotifyItem){        printf("event:%d Preference:%d id:%d path:%ls\n", Event, NotifyItem->dwPreference, NotifyItem->uID, NotifyItem->pszExeName);        if (StrStrIW(NotifyItem->pszExeName, L"qq.exe")){            if (m_pTrayNotify){                NotifyItem->dwPreference = 2;                m_pTrayNotify->SetPreference(NotifyItem);            }        }        return S_OK;    }public:    ITrayNotify * m_pTrayNotify;};int _tmain(int argc, _TCHAR* argv[]){    ITrayNotify *pTrayNotify;    NOTIFYITEM NotifyItem = {0};    NotificationMgr NotiMgr;    CoInitialize(NULL);    //    // for win7    //        HRESULT hr = CoCreateInstance (       CLSID_TrayNotify,       NULL,       CLSCTX_LOCAL_SERVER,       __uuidof(ITrayNotify),       (PVOID *)&pTrayNotify);        if (!SUCCEEDED(hr)){        printf("create instance of ITrayNotify error\n");        return -1;    }        //    // register callback    //        NotiMgr.m_pTrayNotify = pTrayNotify;    hr = pTrayNotify->RegisterCallback(&NotiMgr);        printf("over\n");    pTrayNotify->RegisterCallback(NULL);    pTrayNotify->Release();        _getch();  return 0;}

代码2 Chromium源代码
就发个链接吧 https://chromium.googlesource.com/chromium/src.git/+/master/chrome/browser/ui/views/status_icons/
代码3 根据代码1修改来的 使用类模板可支持Win8系统
更正:居然被坑了 UnregisterCallback的参数不用传址
#include <tchar.h>#include <conio.h>#include <windows.h>// The known values for NOTIFYITEM's dwPreference member.enum NOTIFYITEM_PREFERENCE {// In Windows UI: "Only show notifications."PREFERENCE_SHOW_WHEN_ACTIVE = 0,// In Windows UI: "Hide icon and notifications."PREFERENCE_SHOW_NEVER = 1,// In Windows UI: "Show icon and notifications."PREFERENCE_SHOW_ALWAYS = 2};typedef struct tagNOTIFYITEM {PWSTR pszExeName;PWSTR pszTip;HICON hIcon;HWND hWnd;NOTIFYITEM_PREFERENCE dwPreference;UINT uID;GUID guidItem;} NOTIFYITEM, *PNOTIFYITEM;MIDL_INTERFACE("D782CCBA-AFB0-43F1-94DB-FDA3779EACCB") INotificationCB : public IUnknown{public:BEGIN_INTERFACEvirtual HRESULT STDMETHODCALLTYPE Notify(ULONG, NOTIFYITEM *) = 0;END_INTERFACE};MIDL_INTERFACE("FB852B2C-6BAD-4605-9551-F15F87830935") ITrayNotify : public IUnknown{public:BEGIN_INTERFACEvirtual HRESULT STDMETHODCALLTYPE RegisterCallback(INotificationCB* callback) = 0;virtual HRESULT STDMETHODCALLTYPE SetPreference(const NOTIFYITEM* notify_item) = 0;virtual HRESULT STDMETHODCALLTYPE EnableAutoTray(BOOL enabled) = 0;END_INTERFACE};MIDL_INTERFACE("D133CE13-3537-48BA-93A7-AFCD5D2053B4") ITrayNotifyWin8 : public IUnknown{public:BEGIN_INTERFACEvirtual HRESULT STDMETHODCALLTYPE RegisterCallback(INotificationCB* callback, unsigned long*) = 0;virtual HRESULT STDMETHODCALLTYPE UnregisterCallback(unsigned long) = 0; // 被坑了 这里的参数不用传址virtual HRESULT STDMETHODCALLTYPE SetPreference(NOTIFYITEM const*) = 0;virtual HRESULT STDMETHODCALLTYPE EnableAutoTray(BOOL) = 0;virtual HRESULT STDMETHODCALLTYPE DoAction(BOOL) = 0;END_INTERFACE};const CLSID CLSID_TrayNotify = { 0x25DEAD04, 0x1EAC, 0x4911,{ 0x9E, 0x3A, 0xAD, 0x0A, 0x4A, 0xB5, 0x60, 0xFD } };template <class type>class NotificationMgr : public INotificationCB {public:NotificationMgr(type *pTrayNotify) : m_pTrayNotify(pTrayNotify) {}IFACEMETHODIMP QueryInterface(REFIID riid, PVOID *ppv) {if (ppv == NULL)return E_POINTER;if (IsEqualIID(riid, IID_IUnknown))*ppv = static_cast<IUnknown *>(this);else if (IsEqualIID(riid, __uuidof (INotificationCB)))*ppv = static_cast<INotificationCB *>(this);elsereturn E_NOINTERFACE;reinterpret_cast<IUnknown*>(*ppv)->AddRef();return S_OK;}IFACEMETHODIMP_(ULONG) AddRef() { return 1; }IFACEMETHODIMP_(ULONG) Release() { return 1; }IFACEMETHODIMP Notify(ULONG Event, NOTIFYITEM *NotifyItem) {if (wcsstr(_wcslwr(NotifyItem->pszExeName), L"qq.exe")) {if (m_pTrayNotify) {NotifyItem->dwPreference = PREFERENCE_SHOW_ALWAYS;m_pTrayNotify->SetPreference(NotifyItem);}}return S_OK;}private:type * m_pTrayNotify;};int _tmain(int argc, _TCHAR* argv[]){CoInitialize(NULL);IUnknown *pIUnk;HRESULT hr = CoCreateInstance(CLSID_TrayNotify, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pIUnk));if (SUCCEEDED(hr)){ITrayNotifyWin8 *pTrayNotify8;hr = pIUnk->QueryInterface(&pTrayNotify8);if (SUCCEEDED(hr)) // Win8{ULONG callback_id = 0;NotificationMgr<ITrayNotifyWin8> NotiMgr8(pTrayNotify8);hr = pTrayNotify8->RegisterCallback(&NotiMgr8, &callback_id);if (SUCCEEDED(hr))pTrayNotify8->UnregisterCallback(callback_id);pTrayNotify8->Release();}else // Legacy{ITrayNotify *pTrayNotify;hr = pIUnk->QueryInterface(&pTrayNotify);if (SUCCEEDED(hr)){NotificationMgr<ITrayNotify> NotiMgr(pTrayNotify);hr = pTrayNotify->RegisterCallback(&NotiMgr);if (SUCCEEDED(hr))pTrayNotify->RegisterCallback(NULL);pTrayNotify->Release();}}pIUnk->Release();}_getch();return 0;}

如果想让图标一直显示的话就等到程序退出的时候再UnregisterCallback即可,用户隐藏后马上会显示
0 0
原创粉丝点击