MFC System Tray(Windows notification area) problems.(Probly message handling)

Started by
1 comment, last by Bandwidth 18 years, 6 months ago
I am trying to make an application to run in the system tray.. I have followed a lot of tutorials and finally got it to work. But the problem is that when I mouse over the tray icon.. it disapears.. I think it have something to do with the way I handle the callback message. I got the feeling that I am not doing it right. Please take a look at the code

// Agent.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "Agent.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_NOTIFYICON WM_APP + 0x100
/////////////////////////////////////////////////////////////////////////////
// CAgentApp

BEGIN_MESSAGE_MAP(CAgentApp, CWinApp)
	//{{AFX_MSG_MAP(CAgentApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_NOTIFYICON,OnNotifyIcon)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAgentApp construction

CAgentApp::CAgentApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CAgentApp object

CAgentApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CAgentApp initialization

BOOL CAgentApp::InitInstance()
{
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Change the registry key under which our settings are stored.
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization.
	SetRegistryKey(_T("Local AppWizard-Generated Applications"));


	// To create the main window, this code creates a new frame window
	// object and then sets it as the application's main window object.

	CMainFrame* pFrame = new CMainFrame;
	m_pMainWnd = pFrame;

	// create and load the frame with its resources

	pFrame->LoadFrame(IDR_MAINFRAME,
		WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
		NULL);




	// The one and only window has been initialized, so show and update it.
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();


	HICON hTrayIcon = LoadIcon((LPCTSTR)MAKEINTRESOURCE(IDR_MAINFRAME));

	
	
	NOTIFYICONDATA IconData;
	IconData.cbSize=sizeof(NOTIFYICONDATA);
	IconData.hIcon=hTrayIcon;//IDI_APPLICATION;
	IconData.hWnd=(HWND)m_pMainWnd;
	strcpy(IconData.szTip,"Click Here");
	IconData.uCallbackMessage=WM_NOTIFYICON;
	IconData.uFlags= NIF_ICON | NIF_MESSAGE | NIF_TIP;
	IconData.uID=IDR_MAINFRAME;

	Shell_NotifyIcon(NIM_ADD,&IconData);
	


	//m_TrayIcon.Create(pFrame,WM_NOTIFY,"Click Here",IDI_APPLICATION,IDR_MAINFRAME);

	return TRUE;
}

LRESULT CAgentApp::OnNotifyIcon(WPARAM wParam, LPARAM lParam){
	int x=MessageBox((HWND)m_pMainWnd,_T("ASd"),"asd",0);
	return true;
}
/////////////////////////////////////////////////////////////////////////////
// CAgentApp message handlers
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
		// No message handlers
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CAgentApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CAgentApp message handlers

Advertisement
Hi there!
You should apply the following changes to your code :
Move the #define WM_NOTIFYICON ... to Agent.h (header file for the app class) ;
Delete the ON_MESSSAGE line from the message map in agent.cpp (you need to handle the message differently) ; move the code that sets up the NOTIFYICONDATA structure, togheter with the hTrayIcon loading line all the way to the end of CMainFrame::OnCreate(...) ( or whatever name you gave it - it must be the main frame class - OnCreate event), just before the return.
Also, delete the member function OnNotifyIcon from CAgentApp(the app class) header and implementation file(you won't need it, as i said).
Now, you need to add the WindowProc virtual function to CMainFrame( right click on the CMainFrame class in ClassView...) and add the following code :
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {	// TODO: Add your specialized code here and/or call the base class	switch(message) {	case WM_NOTIFYICON:		{			if(lParam == WM_LBUTTONDBLCLK) AfxMessageBox("asd");			break;		}	}	return CFrameWnd::WindowProc(message, wParam, lParam);}

Also, the LoadIcon code won't work, so try this line for a temporary fix :
HICON hTrayIcon = LoadIcon(NULL, IDI_APPLICATION);

And for the IconData.hwnd :
IconData.hWnd=(HWND)GetSafeHwnd();

MainFrm.cpp should include Agent.h(app class header) by default, but please check it.
You need to check for a mouse message(ever WM_MOUSEMOVE) inside the case of WM_NOTIFYICON, cause you'll get strange behaviour with your previous code.

That's all! Hope it helps!
-= wolfwood :: rpg =-
I solved it by using wrapper code from other people...
but I prefere to have known what I did wrong..
So I will go back and try what you said...

Seems about right though.. because it seems that it is not receiving mouse message from the tray..

Will report back on the result soon...

This topic is closed to new replies.

Advertisement