C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Таймеры в приложениях MFC / MFC / Visual C++

Таймеры в приложениях MFC

Хотя таймер и не оперирует такими понятиями, как потоки, среда, создаваемая с помощью сообщений WM_TIMER, весьма напоминает многозадачную среду.

Вся работа с таймером в MFC основана на двух методах: SetTimer и KillTimer класса CWnd.

UINT_PTR SetTimer
(
    UINT_PTR nIDEvent, 
    UINT nELAPSE, 
    void (CALLBACK* lpfnTimer)
)

Метод, при успешном завершении возвращает номер создаваемого таймера. Первый параметр - номер создаваемого таймера. Второй параметр - количество миллисекунд, через которое срабатывает таймер. Третий параметр может быть либо равен NULL, либо указывать на некоторую функцию. В первом случае сообщение WM_TIMER посылает на функцию окна и, следовательно, обработчик должен быть включён в карту сообщений.
Если третий параметр отличен от NULL, то он должен указывать на некоторую функцию.

Вот её структура:

void CALLBACK EXPORT TimerProc
(
   HWND hWnd,
   UINT nMsg,
   UINT nIDEvent,
   DWORD dwTime
)
  • hWnd - дескриптор окна
  • nMsg - сообщение WM_TIMER
  • nIDEvent - индификатор таймера
  • dwTime - системное время

Уничтожить таймер можно с помощью метода KillTimer(UINT_PTR nIDEvent), аргументом которого является идентификатор таймера.

Следует заметить что точность таймера не слишком велика. При задержке сообщения в очереди новые сообщения таймера не накапливаются, а аннулируются.

Далее я приведу простую программу с двумя таймерами. Её смысл очень прост. В диалоговом окне имеется дополнительная кнопка, с помощью которой можно либо создать, либо уничтожить таймеры. Первый таймер каждую секунду формирует заголовок окна, увеличивая его длину на один символ. Второй таймер раз в 25 секунд очищает строку заголовка и посылает звуковой сигнал.

Вот файл Timer1Dlg.cpp:

#include "stdafx.h"
#include "Timer1.h"
#include "Timer1Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


extern CTimer1Dlg * dlg;

void CALLBACK EXPORT OnTimer1(HWND, UINT, UINT, DWORD);

CTimer1Dlg::CTimer1Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTimer1Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_timer=0;
	s="";
}

void CTimer1Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON1, m_button);
}

BEGIN_MESSAGE_MAP(CTimer1Dlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
	ON_WM_TIMER()
END_MESSAGE_MAP()

BOOL CTimer1Dlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, TRUE);	
	SetIcon(m_hIcon, FALSE);
	
	return TRUE;
}

void CTimer1Dlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this);

		SendMessage(WM_ICONERASEBKGND, 
		     reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		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;

		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CTimer1Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CTimer1Dlg::OnBnClickedButton1()
{
	if(!m_timer)
	{
		SetTimer(1,1000,NULL);
		SetTimer(2,25000,OnTimer1);
		m_button.SetWindowText("Удалить");
		m_timer=1;
	}else
	{
		KillTimer(1);
		KillTimer(2);
		m_button.SetWindowText("Таймеры");
		m_timer=0;
	}
}

void CTimer1Dlg::OnTimer(UINT nIDEvent)
{
	CDialog::OnTimer(nIDEvent);
	s=s+"*";
	SetWindowText(s);
}

void CALLBACK EXPORT OnTimer1(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
	dlg->s="";
	dlg->SetWindowText(dlg->s);
	::MessageBeep(0xFFFFFFFF);
}

Вот файл Timer1Dlg.h

#pragma once


class CTimer1Dlg : public CDialog
{

public:
	CTimer1Dlg(CWnd* pParent = NULL);	

	enum { IDD = IDD_TIMER1_DIALOG };
    

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	



protected:
	HICON m_hIcon;


	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
    CButton m_button;
	int m_timer;
	CString s;
	afx_msg void OnBnClickedButton1();
	afx_msg void OnTimer(UINT nIDEvent);
};

Файл Timer1.cpp:

#include "stdafx.h"
#include "Timer1.h"
#include "Timer1Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CTimer1Dlg * dlg;

BEGIN_MESSAGE_MAP(CTimer1App, CWinApp)
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()


CTimer1App::CTimer1App()
{

}


CTimer1App theApp;


BOOL CTimer1App::InitInstance()
{

	InitCommonControls();

	CWinApp::InitInstance();


	dlg = new CTimer1Dlg;
	m_pMainWnd = dlg;
	INT_PTR nResponse = dlg->DoModal();
	if (nResponse == IDOK)
	{

	}
	else if (nResponse == IDCANCEL)
	{

	}

	return FALSE;
}

Модуль Timer1.cpp содержит запускающую часть проекта. Обратите внимание на способ задания диалогового окна. Объявление указателя на диалоговое окно позволяет упростить глобальный доступ из других модулей.