Month
Sample Output Kill Timers

Brief Information about the January 99 CSIG Meeting

General Purpose Timer - Advanced


Last month I discussed a timer application program which replaces a small electronic kitchen timer that I use periodically to test computer programs or installation procedures.

For this month C Users Group meeting, I have added the ability to change the size of the timer window. As shown in the above image, the timer can be adjusted to be any size from very tiny to full screen and everywhere in between. In order to accomplish this, extra code has been added to dynamically determine the location of all of the controls (buttons) in the application. The windows and the digits are mathematically scaled to obtain the desired size. At the meeting, we will review the original code and then discuss the details of the new code.

The timer is based on Microsoft foundation classes (MFC) and is compiled using Microsoft Visual C++ version 5. There is a large display for numbers over an inch high. Several buttons provide start and stop functions. In addition to the new sizing feature, other extra features of this timer include the ability to start the timer from the command line such as in the middle of a batch program and to an identify the timer so that more than one event can be timed. Just for fun, I wrote a simple batch program that starts 36 timers at once.

Window Search and Destroy Utility

When the "fun.bat" program is used to create 36 timers it leaves them on the screen. The KillTimers program will remove or "kill" them. It does so by looping through all of the windows on the screen and checking the title of each window to see if it may be a timer. As it does this, it records the title in a special data file listing for later display. When it finds a timer, it sends a "WM_CLOSE" message to close it. In addition to its mentioned utility, this program uses some unusual system calls in order to find the information.

"Random Access" questions start at 7:30 Tuesday night. See you there.


You can get the source code and the executable programs from links on C User Group: The source code and executables will be available directly from the ACGNJ ftp server:

See SOURCE CODE links below.


Sample Code - Timer:


void CTimerDlg::OnSize(UINT nType, int cx, int cy) 
{
	RECT newPosDims; int fontSizeA, fontSizeB;
	CDialog::OnSize(nType, cx, cy);

	if (NULL==m_digits.m_hWnd) return;

	newPosDims.left  = MulDiv(digitRect.left,   cx, ReferenceRect.right );
	newPosDims.top   = MulDiv(digitRect.top ,   cy, ReferenceRect.bottom);
	newPosDims.right = MulDiv(digitRect.right,  cx, ReferenceRect.right);
	newPosDims.bottom= MulDiv(digitRect.bottom, cy, ReferenceRect.bottom);
	m_digits.MoveWindow(&newPosDims);

	newPosDims.left  = MulDiv(BstartRect.left,   cx, ReferenceRect.right );
	newPosDims.top   = MulDiv(BstartRect.top ,   cy, ReferenceRect.bottom);
	newPosDims.right = MulDiv(BstartRect.right,  cx, ReferenceRect.right);
	newPosDims.bottom= MulDiv(BstartRect.bottom, cy, ReferenceRect.bottom);
	m_button_start.MoveWindow(&newPosDims);

	newPosDims.left  = MulDiv(BstopRect.left,   cx, ReferenceRect.right );
	newPosDims.top   = MulDiv(BstopRect.top ,   cy, ReferenceRect.bottom);
	newPosDims.right = MulDiv(BstopRect.right,  cx, ReferenceRect.right);
	newPosDims.bottom= MulDiv(BstopRect.bottom, cy, ReferenceRect.bottom);
	m_button_stop.MoveWindow(&newPosDims);

	newPosDims.left  = MulDiv(BquitRect.left,   cx, ReferenceRect.right );
	newPosDims.top   = MulDiv(BquitRect.top ,   cy, ReferenceRect.bottom);
	newPosDims.right = MulDiv(BquitRect.right,  cx, ReferenceRect.right);
	newPosDims.bottom= MulDiv(BquitRect.bottom, cy, ReferenceRect.bottom);
	m_button_quit.MoveWindow(&newPosDims);

	delete m_CFont;
	m_CFont = new CFont;

	fontSizeA = MulDiv(DIG_HEIGHT, cx, ReferenceRect.right);
	fontSizeB = MulDiv(DIG_HEIGHT, cy, ReferenceRect.bottom);

	m_CFont->CreateFont( -(__min(fontSizeA,fontSizeB)), // int nHeight, 
			    0,			// int nWidth, 
			    0,			// int nEscapement, 
			    0,			// int nOrientation, 
			    FW_BOLD,		// int nWeight, 
			    0,			// BYTE bItalic, 
			    0,			// BYTE bUnderline, 
			    0,			// BYTE cStrikeOut, 
			    ANSI_CHARSET,	// BYTE nCharSet, 
			    OUT_DEFAULT_PRECIS,	// BYTE nOutPrecision, 
			    CLIP_DEFAULT_PRECIS,// BYTE nClipPrecision, 
			    DEFAULT_QUALITY,	// BYTE nQuality, 
			    DEFAULT_PITCH |	// BYTE nPitchAndFamily, 
			    FF_DONTCARE,
			    "SYSTEM_FONT");	// LPCTSTR lpszFacename );

	m_digits.SetFont(m_CFont);

Sample Code - KillTimer:

void CKTDlg::OnKill() 
{
	char title[100];	HWND hWnd;	int len;
        CString buff, filename;
	filename = getenv("TEMP");
	filename += "\\~Kill.txt";
	CFile mFile;
	if (!mFile.Open( filename, CFile::modeCreate | CFile::modeWrite, NULL))
	    return;  // abort.

	for (hWnd = ::GetTopWindow(NULL); hWnd; hWnd = ::GetNextWindow(hWnd,GW_HWNDNEXT))
	    {
	    len = ::GetWindowText(hWnd,title,100);
	    if (len)
		{
		buff = title;
		mFile.Write(LPCTSTR(buff), buff.GetLength() );
		mFile.Write("\r\n",2);
		if (buff.Left(3) == "00:")
		    {
		    ::PostMessage(hWnd, WM_CLOSE, NULL, NULL);
		    }
		}
	    }
        mFile.Close();
        buff = "NOTEPAD.EXE " + filename;
        WinExec(LPCTSTR(buff), SW_SHOWNORMAL);
	EndDialog(0);
}


"Random Access" questions start at 7:30 Tuesday night.

SOURCE CODE

Source Code Files

For help, email me at b a r n o l d @ b l a s t . n e t
Back to C++ Main Page