// DynIconDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DynIcon.h"
#include "DynIconDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CDynIconDlg dialog
CDynIconDlg::CDynIconDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDynIconDlg::IDD, pParent)
,m_nValue1(-10)
,m_nValue2(-15)
,m_bActiv(FALSE)
,m_bFirstDefaultIcon(TRUE)
,m_bFirstIcon1(TRUE)
,m_bFirstIcon2(TRUE)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDynIconDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDynIconDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDOK, &CDynIconDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_START, &CDynIconDlg::OnBnClickedStart)
ON_BN_CLICKED(IDC_STOP, &CDynIconDlg::OnBnClickedStop)
ON_MESSAGE(WM_TRAY, OnTray)//own message
ON_WM_SYSCOMMAND()
END_MESSAGE_MAP()
// CDynIconDlg message handlers
BOOL CDynIconDlg::OnInitDialog()
{
CDialog::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 != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
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
//set the defaulticon in the tray
SetDefaultIconInTray();
CString strValue;
strValue.Format(_T("%3d"),m_nValue1);
SetDlgItemTextW(IDC_VALUE1, strValue);
strValue.Format(_T("%3d"),m_nValue2);
SetDlgItemTextW(IDC_VALUE2, strValue);
((CButton*)GetDlgItem(IDC_START))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDC_STOP))->EnableWindow(FALSE);
((CButton*)GetDlgItem(IDOK))->EnableWindow(TRUE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CDynIconDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
switch(nID){
case SC_MINIMIZE:
//if the dialog should be minimized, the dialog will be hidden
//without a button in the taskbar
ShowWindow(SW_HIDE);
return;
break;
case SC_CLOSE:
//before the dialog will be closed, we have to clear the icon(s)
if(m_bActiv){
//if the measurement is activ, there are two icons to delete
ClearIcon1();
ClearIcon2();
}
else{
//if the measurement is not activ, there is only one icon to delete
ClearDefaultIconInTray();
}
break;
default:
break;
}
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDynIconDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDynIconDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CDynIconDlg::SetDefaultIconInTray()
{
//create a handle for the default icon
HICON hIcon;
HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(IDI_ICON1),RT_GROUP_ICON);
hIcon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
//NOTIFYCONDATA structure
NOTIFYICONDATA tnid;
//set the values
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = m_hWnd;
tnid.uID = IDI_ICON1;//resourcename of the icon
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_TRAY;//user created message
tnid.hIcon = hIcon;
//defaultstring for the tooltip
m_strTooltip.Format(_T("Temperature-Monitor (inactiv)"));
//copy the string to the NOTIFYCONDATA structure
lstrcpyn(tnid.szTip, m_strTooltip, sizeof(tnid.szTip));
//call the Shell_NotifyIcon
//because it is the first time, we have to use NIM_ADD
Shell_NotifyIcon(NIM_ADD, &tnid);
//now the icon is shown in the tray and we can free the icon
DestroyIcon(hIcon);
}
void CDynIconDlg::ClearDefaultIconInTray()
{
NOTIFYICONDATA tnid;
tnid.hWnd = m_hWnd;
tnid.uID = IDI_ICON1;//the default icon
//Shell_NotifyIcon with NIM_DEL
Shell_NotifyIcon(NIM_DELETE, &tnid);
}
void CDynIconDlg::ChangeValues()
{
//this method is used to simulate the dynamic of the meassured values
//increment the values and display them in the dialog
CString strValue;
m_nValue1++;
if(m_nValue1 > 10) m_nValue1 = -10;
strValue.Format(_T("%3d"),m_nValue1);
SetDlgItemTextW(IDC_VALUE1, strValue);
m_nValue2++;
if(m_nValue2 > 10) m_nValue2 = -15;
strValue.Format(_T("%3d"),m_nValue2);
SetDlgItemTextW(IDC_VALUE2, strValue);
}
void CDynIconDlg::CreateIcons()
{
CreateIcon1();
CreateIcon2();
}
void CDynIconDlg::CreateIcon1()
{
using namespace Gdiplus;
//we need a widechar array for the value
wchar_t strValue[4];
int size = sizeof(strValue)/sizeof(wchar_t);// because the wchar_t requires two byte!!!
swprintf( strValue, size, L"%3d", m_nValue1 );//the prefix L means, that the string should be a widechar
//if you already have a char array including the value
//then you don't need the swprintf(), but
//you have to convert the char array to a widechar array
/*
char txt[4];
sprintf_s(txt, sizeof(txt),"%3d", m_nValue1);
MultiByteToWideChar(CP_ACP, 0, txt, -1, strValue, size);
*/
//you can change the colors depending on the value
//here it should be white only
//white pen to draw some lines in the icon
Pen whitePen(Color(255, 255, 255));
//white brush for the text
SolidBrush whiteBrush(Color(255,255,255));
//create a small font to write the values in the bitmap
Font font(L"Tahoma",8);//, FontStyleRegular,UnitPixel);
//origin for the string
PointF origin(-1, 1);
//alignment for the string
StringFormat format;
format.SetAlignment(StringAlignmentNear);
//create a new bitmap with 16x16 pixel
Bitmap bitmap(16,16);
//use the bitmap to draw
Graphics *graph = Graphics::FromImage(&bitmap);
//draw two horizontale lines
//just for the show
graph->DrawLine(&whitePen, 0, 15, 15, 15);
graph->DrawLine(&whitePen, 0, 0, 15, 0);
//draw the string including the value
//here we need the widechar-array
graph->DrawString(strValue, -1, &font, origin, &format, &whiteBrush);
//create the icon and put it to the handle (member of our class)
bitmap.GetHICON(&m_hIcon1);
}
void CDynIconDlg::CreateIcon2()
{
using namespace Gdiplus;
//we need a widechar array for the value
wchar_t strValue[4];
int size = sizeof(strValue)/sizeof(wchar_t);// because the wchar_t requires two byte!!!
swprintf( strValue, size, L"%3d", m_nValue2 );//the prefix L means, that the string should be a widechar
//if you already have a char array including the value
//then you don't need the swprintf(), but
//you have to convert the char array to a widechar array
/*
char txt[4];
sprintf_s(txt, sizeof(txt),"%3d", m_nValue2);
MultiByteToWideChar(CP_ACP, 0, txt, -1, strValue, size);
*/
//you can change the colors depending on the value
//here it should be white only
//white pen to draw some lines in the icon
Pen whitePen(Color(255, 255, 255));
//white brush for the text
SolidBrush whiteBrush(Color(255,255,255));
//create a small font to write the values in the bitmap
Font font(L"Tahoma",8);//, FontStyleRegular,UnitPixel);
//origin for the string
PointF origin(-1, 1);
//alignment for the string
StringFormat format;
format.SetAlignment(StringAlignmentNear);
//create a new bitmap with 16x16 pixel
Bitmap bitmap(16,16);
//use the bitmap to draw
Graphics *graph = Graphics::FromImage(&bitmap);
//draw two horizontale lines
//just for the show
graph->DrawLine(&whitePen, 0, 15, 15, 15);
graph->DrawLine(&whitePen, 0, 0, 15, 0);
//draw the string including the value
//here we need the widechar-array
graph->DrawString(strValue, -1, &font, origin, &format, &whiteBrush);
//create the icon and put it to the handle (member of our class)
bitmap.GetHICON(&m_hIcon2);
}
void CDynIconDlg::PushIcons()
{
//at the first time we have to clear the defaulticon
if(m_bFirstDefaultIcon){
m_bFirstDefaultIcon = FALSE;
ClearDefaultIconInTray();
}
//we change the content of the tooltip
//we use the same tooltip for the two icons
m_strTooltip.Format(_T("Value1:%3d\nValue2:%3d"),m_nValue1, m_nValue2);
//update the icons
PushIcon2();
PushIcon1();
}
void CDynIconDlg::PushIcon1()
{
// set NOTIFYCONDATA structure
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = m_hWnd;
tnid.uID = ICON_VALUE1; //Resourcename
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_TRAY;//user message
tnid.hIcon = m_hIcon1; //handle of the created icon
//copy the string to the NOTIFYCONDATA structure
lstrcpyn(tnid.szTip, m_strTooltip, sizeof(tnid.szTip));
if(m_bFirstIcon1){
//for the first time we have to use the Shell_NotifyIcon with NIM_ADD
//to add the icon to the tray
Shell_NotifyIcon(NIM_ADD, &tnid);
m_bFirstIcon1 = FALSE;
}
else{
//the icon already exists
//Shell_NotifyIcon with NIM_MODIFY
Shell_NotifyIcon(NIM_MODIFY, &tnid);
}
// free icon
DestroyIcon(m_hIcon1);
}
void CDynIconDlg::PushIcon2()
{
// set NOTIFYCONDATA structure
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = m_hWnd;
tnid.uID = ICON_VALUE2; //resourcename
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_TRAY;//user message
tnid.hIcon = m_hIcon2; //handle of the created icon
//copy the string to the NOTIFYCONDATA structure
lstrcpyn(tnid.szTip, m_strTooltip, sizeof(tnid.szTip));
if(m_bFirstIcon2){
//for the first time we have to use the Shell_NotifyIcon with NIM_ADD
//to add the icon to the tray
Shell_NotifyIcon(NIM_ADD, &tnid);
m_bFirstIcon2 = FALSE;
}
else{
//the icon already exists
//Shell_NotifyIcon with NIM_MODIFY
Shell_NotifyIcon(NIM_MODIFY, &tnid);
}
// free icon
DestroyIcon(m_hIcon2);
}
void CDynIconDlg::ClearIcon1()
{
NOTIFYICONDATA tnid;
tnid.hWnd = m_hWnd;
tnid.uID = ICON_VALUE1;
//Shell_NotifyIcon with NIM_DEL
Shell_NotifyIcon(NIM_DELETE, &tnid);
}
void CDynIconDlg::ClearIcon2()
{
NOTIFYICONDATA tnid;
tnid.hWnd = m_hWnd;
tnid.uID = ICON_VALUE2;
//Shell_NotifyIcon with NIM_DEL
Shell_NotifyIcon(NIM_DELETE, &tnid);
}
void CDynIconDlg::OnTimer(UINT_PTR nIDEvent)
{
switch(nIDEvent){
case TIMER1:
ChangeValues();
CreateIcons();
PushIcons();
break;
default: break;
}
}
void CDynIconDlg::OnBnClickedStart()
{
//start Timer1
SetTimer(TIMER1, 1000, NULL);
//set the states of the buttons
((CButton*)GetDlgItem(IDC_START))->EnableWindow(FALSE);
((CButton*)GetDlgItem(IDC_STOP))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDOK))->EnableWindow(FALSE);
m_bActiv = TRUE;
}
void CDynIconDlg::OnBnClickedStop()
{
//stop Timer1
KillTimer(TIMER1);
//clear icon1
ClearIcon1();
//clear icon2
ClearIcon2();
//set the defaulticon in the tray
SetDefaultIconInTray();
//set the states of the buttons
((CButton*)GetDlgItem(IDC_START))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDC_STOP))->EnableWindow(FALSE);
((CButton*)GetDlgItem(IDOK))->EnableWindow(TRUE);
m_bActiv = FALSE;
m_bFirstDefaultIcon = TRUE;
m_bFirstIcon1 = TRUE;
m_bFirstIcon2 = TRUE;
}
void CDynIconDlg::OnBnClickedOk()
{
//clear the Icon in the tray
ClearDefaultIconInTray();
OnOK();
}
LRESULT CDynIconDlg::OnTray(WPARAM wParam, LPARAM lParam)
{
//Messagehandler of the icons in the tray
UINT uMouseMsg = (UINT) lParam;
switch(uMouseMsg){
case WM_LBUTTONDBLCLK:
//show or hide the dialog
if(IsWindowVisible())
ShowWindow(SW_HIDE);
else
ShowWindow(SW_NORMAL);
BringWindowToTop();
break;
case WM_RBUTTONDOWN:
//here you can popup a menue
//PopupMenue();
break;
default:
break;
}
return 0;
}