托盘图标添加通用解决方案

xingyun86 2023-11-16 800

托盘图标添加通用解决方案

#define	WM_SYSTEMTRAY	(WM_USER + WM_COMMAND + 1)
const UINT WMEX_TASKBARCREATED = ::RegisterWindowMessage(TEXT("TaskbarCreated"));
afx_msg LRESULT OnSystemtray(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnRestartExplorer(WPARAM wParam, LPARAM lParam);
ON_MESSAGE(WM_SYSTEMTRAY, &CMySqlMgrDlg::OnSystemtray)
ON_REGISTERED_MESSAGE(WMEX_TASKBARCREATED, &CMySqlMgrDlg::OnRestartExplorer)
BOOL CMySqlMgrDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	// Add "About..." menu item to system menu.
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	// TODO: Add extra initialization here
	{
		m_nidNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
		m_nidNotifyIcon.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
		m_nidNotifyIcon.hIcon = m_hIcon;
		m_nidNotifyIcon.hWnd = m_hWnd;
		wcscpy(m_nidNotifyIcon.szTip, L"托盘显示");
		m_nidNotifyIcon.uCallbackMessage = WM_SYSTEMTRAY;
		m_nidNotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
		Shell_NotifyIcon(NIM_ADD, &m_nidNotifyIcon);
	}
	return TRUE;  // return TRUE  unless you set the focus to a control
}
afx_msg LRESULT CMySqlMgrDlg::OnSystemtray(WPARAM wParam, LPARAM lParam)
{
	switch (lParam)
	{
	case  WM_RBUTTONDOWN:
	{
		enum MenuEnumType {
			METYPE_SHOWHIDE = 10001,
			METYPE_EXIT,
		};
		CMenu menu = {};
		CPoint pt = { 0 };
		GetCursorPos(&pt);
		SetForegroundWindow();
		if (menu.CreatePopupMenu() == TRUE)
		{
			menu.AppendMenu(MF_STRING, METYPE_SHOWHIDE, (IsWindowVisible() == TRUE) ? TEXT("后台运行") : TEXT("前台运行"));
			menu.AppendMenu(MF_STRING, METYPE_EXIT, TEXT("退出软件"));
			switch ((enum MenuEnumType)menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RETURNCMD, pt.x, pt.y, this))
			{
			case METYPE_SHOWHIDE:
			{
				if (((::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) & (WS_EX_TOOLWINDOW)) == WS_EX_TOOLWINDOW) == TRUE)
				{
					::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, (::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | (WS_EX_APPWINDOW)) & (~WS_EX_TOOLWINDOW));
					::ShowWindow(m_hWnd, SW_SHOWNORMAL);
					::SetForegroundWindow(m_hWnd);
				}
				else
				{
					::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, (::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | (WS_EX_TOOLWINDOW)) & (~WS_EX_APPWINDOW));
					::ShowWindow(m_hWnd, SW_HIDE);
				}
			}
			break;
			case METYPE_EXIT:
			{
				PostQuitMessage(IDCLOSE);
			}
			break;
			default:
				break;
			};
			menu.DestroyMenu();
		}
	}
	break;
	case WM_LBUTTONDBLCLK:
	{
		if (((::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) & (WS_EX_TOOLWINDOW)) == WS_EX_TOOLWINDOW) == TRUE)
		{
			::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, (::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | (WS_EX_APPWINDOW)) & (~WS_EX_TOOLWINDOW));
			::ShowWindow(m_hWnd, SW_SHOWNORMAL);
			::SetForegroundWindow(m_hWnd);
		}
		else
		{
			::SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, (::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE) | (WS_EX_TOOLWINDOW)) & (~WS_EX_APPWINDOW));
			::ShowWindow(m_hWnd, SW_HIDE);
		}
	}
	break;
	case  WM_LBUTTONDOWN:
	{
	}
	break;
	}
	return 0;
}
LRESULT CMySqlMgrDlg::OnRestartExplorer(WPARAM wParam, LPARAM lParam)
{
	Shell_NotifyIcon(NIM_ADD, &m_nidNotifyIcon);
	return TRUE;
}
void CMySqlMgrDlg::OnCancel()
{
	// TODO: Add your specialized code here and/or call the base class
	Shell_NotifyIcon(NIM_DELETE, &m_nidNotifyIcon)
	CDialogEx::OnCancel();
}

关闭进程

__inline static
HANDLE GetCurrentProcessReal()
{
    HANDLE RealProcessHandle = NULL;
    HANDLE PseudoProcessHandle = ::GetCurrentProcess();  //获得一个伪句柄
    ::DuplicateHandle(
        ::GetCurrentProcess(),   //源进程内核句柄(即负责传递内核对象句柄的进程句柄)
        PseudoProcessHandle,   //进程伪句柄 GetCurrentProcess()
        ::GetCurrentProcess(),   //目标进程内核句柄
        &RealProcessHandle,    //接受新的,真实句柄!
        0,                     //TargetHandle句柄使用何种访问掩码,这个参数将被忽略,因为DUPLICATE_SAME_ACCESS
        FALSE,                 //新的句柄不可继承
        DUPLICATE_SAME_ACCESS);
    return(RealProcessHandle);
}
__inline static
DWORD GetCurrentProcessIdReal()
{
    return ::GetProcessId(GetCurrentProcessReal());
}
__inline static
void TerminateProcesses(LPCWSTR lpcwProcessName)
{
    BOOL bResult = FALSE;
    HANDLE hSnapShot = NULL;
    PROCESSENTRY32W PE32W = { 0 };
    hSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapShot != NULL)
    {
        for (BOOL bOk = (PE32W.dwSize = sizeof(PE32W), ::Process32FirstW(hSnapShot, &PE32W)); bOk == TRUE; PE32W.dwSize = sizeof(PE32W), bOk = ::Process32NextW(hSnapShot, &PE32W))
        {
            if (PE32W.th32ProcessID != GetCurrentProcessIdReal()
                && ::_wcsicmp(PE32W.szExeFile, lpcwProcessName) == 0)
            {
                HANDLE hP = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, PE32W.th32ProcessID);
                if (hP != NULL)
                {
                    ::TerminateProcess(hP, (0));
                    ::CloseHandle(hP);
                }
            }
        }
        ::CloseHandle(hSnapShot);
    }
}
class IniMgr
{
    std::wstring m_wIniFilePath = std::wstring();
public:
    std::wstring ReadPass(const std::wstring& wAppName)
    {
        {WCHAR wPass[4096] = { 0 }; return(GetPrivateProfileStringW(wAppName.c_str(), L"PASS", L"", wPass, 4096, m_wIniFilePath.c_str()) > 0) ? wPass : L""; }
    }
    std::wstring ReadPort(const std::wstring& wAppName)
    {
        {WCHAR wPort[4096] = { 0 }; return(GetPrivateProfileStringW(wAppName.c_str(), L"PORT", L"", wPort, 4096, m_wIniFilePath.c_str()) > 0) ? wPort : L""; }
    }
    BOOL WritePass(const std::wstring& wAppName, const std::wstring& wPass)
    {
        return WritePrivateProfileStringW(wAppName.c_str(), L"PASS", wPass.c_str(), m_wIniFilePath.c_str());
    }
    BOOL WritePort(const std::wstring& wAppName, const std::wstring& wPort)
    {
        return WritePrivateProfileStringW(wAppName.c_str(), L"PORT", wPort.c_str(), m_wIniFilePath.c_str());
    }
public:
    static IniMgr& Inst()
    {
        static IniMgr IniMgrInstance = {};
        if (IniMgrInstance.m_wIniFilePath.empty() == true)
        {
            IniMgrInstance.m_wIniFilePath = (std::wstring(*__wargv).substr(0, std::wstring(*__wargv).rfind(L'.')).append(L".conf"));
        }
        return(IniMgrInstance);
    }
};


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回