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.
"Random Access" questions start at 7:30 Tuesday night. See you there.
See SOURCE CODE links below.
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);
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); }