一个透明时钟和工作考勤检查






3.55/5 (8投票s)
2003年12月1日
2分钟阅读

289196

2665
一个时钟演示,但它也可以用于考勤打卡。通过在小时块上点击几下,你就可以实现它。
引言
很长一段时间以来,我一直想为我的机器写一个时钟。我不喜欢数字时钟的感觉,日复一日,年复一年,工作工作,工作…… 也许,我是一个老古董!我只喜欢新鲜的蓝天里的自由!
一个透明的时钟?它应该看起来像一块玻璃吗?或者桌面上的某些像素块,以及时针和分针周围的透明度?秒针怎么绕着中心点转动,并且明显地保持周围的透明度呢?
好吧,我决定在 Windows 2000 下编写它,因为我可以使用透明图层属性。为了实现它,我必须完成这些
首先,在 OnCreate
部分,注册一个热键,用于在您双击时针或分针时将其打开,并强制它消失。接下来,将窗口样式更改为 WS_EX_TOOLWINDOW
,这样,它就会从任务栏中消失。最后,设置 WS_EX_LAYERED
属性,它会显示结果。以下是 OnCreate
部分的代码。
int CClockDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; m_bHotkeyReg=RegisterHotKey(GetSafeHwnd(), theApp.m_hatomHotKey,MOD_ALT|MOD_CONTROL|MOD_SHIFT,VK_F12); CRect rc; GetWindowRect(&rc); HDC hdc=::GetDC(GetSafeHwnd()); CSize size(GetDeviceCaps(hdc,LOGPIXELSX),GetDeviceCaps(hdc,LOGPIXELSY)); int w=(size.cx/size.cy)*rc.Height(); SetWindowPos(NULL,0,0,w,rc.Height(), SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW); ::ReleaseDC(GetSafeHwnd(),hdc); m_size=CSize(w,rc.Height()); SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,WS_EX_TOOLWINDOW); DWORD Style = ::GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE); Style |= WS_EX_LAYERED; ::SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,Style); ::SetLayeredWindowAttributes( GetSafeHwnd(), m_ColorBackground, //本颜色将删除 (BYTE)(255.f * m_fTransPercent/100.f),LWA_ALPHA|LWA_COLORKEY); return 0; }
容易吗?如果你不了解代码的注释,这是可以理解的,因为我是一个中国人,我的英语很差,但我会尽力让你清楚。
从 APP 文件中,你可以看到两个过程 SayInChinese
和 PlayWaveSound
。我在这里忽略了它们,因为我让它们在我的早期项目中工作(它可以用中文说话)。所以,你可以在下一步让它用英语说话。
第一步,在使用这些代码之前,你应该做以下事情
- 将 clock.mdb 文件复制到 ./Debug 子文件夹和 ./Release 文件夹。
- 重新构建并运行它。
使用一个名为 CClockRSet
的类。它派生自 CDaoRecordset
。我用它来记录考勤信息。使用两个过程来执行它
BOOL GetTodayID(UINT& uID) { SYSTEMTIME st; GetLocalTime(&st); CString sql; sql.Format("select * from [KaoQin] where (YEAR(RiQi)=%d and MONTH(RiQi)=%d and DAY(RiQi)=%d)", st.wYear,st.wMonth,st.wDay); CClockRSet rs; rs.Open(AFX_DB_USE_DEFAULT_TYPE,sql,CRecordset::readOnly); ASSERT(rs.IsOpen()); if(!rs.IsOpen()) return FALSE; BOOL bRet=FALSE; if(rs.GetRecordCount()>0) { rs.MoveFirst(); uID=rs.m_ID; bRet=TRUE; } if(rs.IsOpen()) rs.Close(); return bRet; }
它检查今天的第一个记录,并在今天打卡时返回 ID。失败时返回零。
if(!GetTodayID(m_uTodayID)) { if(FillClock(BAODAO,m_uTodayID)) { VERIFY(GetTodayID(m_uTodayID)); ASSERT(m_uTodayID!=0); } }
一个创建今天记录的条目
BOOL CClockDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->message==WM_KEYDOWN) { if(pMsg->wParam==VK_ESCAPE) { //SHORT stat1=GetKeyState(VK_LCONTROL); //SHORT stat2=GetKeyState(VK_LSHIFT); //if(stat1 & 0x0800 && stat2 & 0x0800) //{ ShowWindow(SW_MINIMIZE); ShowWindow(SW_HIDE); return TRUE; //} } //if(pMsg->wParam==VK_F1) //{ // theApp.ShowHelp(); // return TRUE; //} } return CDialog::PreTranslateMessage(pMsg); }
按 ESC 键执行隐藏你的时钟。
void CClockDlg::OnLButtonDown(UINT nFlags, CPoint point) { CDialog::OnLButtonDown(nFlags, point); CRect rcTest; for(int i=1;i<=12;i++) { //test if you are clicking at the right place rcTest=GetHourRect(i); if(rcTest.PtInRect(point)) { if(i==12) { if(m_uTodayID!=0) FillClock(WUFAN,m_uTodayID); } else if(i==1) { if(m_uTodayID!=0) FillClock(PMBAODAO,m_uTodayID); } else if(i==6) { if(m_uTodayID!=0) FillClock(XIABAN,m_uTodayID); } else if(i==7) { if(m_uTodayID!=0) FillClock(NIGHTBAODAO,m_uTodayID); } DWORD dwFlag=SND_RESOURCE; //Play the music ::PlaySound(MAKEINTRESOURCE(IDR_WAVE_DIDA), AfxGetResourceHandle(),dwFlag); if(m_uDiDaTimer!=0) { KillTimer(m_uDiDaTimer); m_uDiDaTimer=0; } m_uDiDaCount+=i; const int OKPASSWORD=1+2+3+4+5+6; TRACE("%d m_uDiDaCount=%d/%d\n",i,m_uDiDaCount,OKPASSWORD); // it is mystery!:) //如果密码不正确,启动Timer if(m_uDiDaCount!=OKPASSWORD) { //下面的输入必须在10秒钟内完成,否则输入将被清理 m_uDiDaTimer=SetTimer(2,1000*10,NULL); } else { ::PlaySound(MAKEINTRESOURCE(IDR_WAVE_DONE), AfxGetResourceHandle(),dwFlag); DoLoginAction(); m_uDiDaCount=0; } return; } } //Move the window while you drag it PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y)); }
在 OnTimer
过程中,它做一些事情来让它说中文。它可以说类似:“早上好,先生,现在是 XXXX 点”,但它用中文说。你可以在下一次下载中文语音 API。
CString ss; if(st.wHour>=0 && st.wHour<3) ss="凌晨"; if(st.wHour>=3 && st.wHour<6) ss="清晨"; if(st.wHour>=6 && st.wHour<9) ss="早晨"; if(st.wHour>=9 && st.wHour<12) ss="中午"; if(st.wHour>=12 && st.wHour<15) ss="下午"; if(st.wHour>=15 && st.wHour<18) ss="傍晚"; if(st.wHour>=18 && st.wHour<21) ss="晚上"; if(st.wHour>=21 && st.wHour<=23) ss="深夜"; if(st.wMinute!=m_nLastMinute) { //是否允许报时 if(st.wMinute==30) { //是否允许半小时报时 if(theApp.GetProfileInt("settings","CanAlarmHalfHour",FALSE)) { CString sFile=theApp.GetProfileString("settings", "HalfHourAlarmFile",""); if(!sFile.IsEmpty() && PathFileExists(sFile)) { CString sExt=PathFindExtension(sFile); if(sExt.CompareNoCase(".wav")==0) { theApp.PlayWaveSound(sFile); } } if(theApp.GetProfileInt("settings", "UseChineseVoiceInAlarm",TRUE)) { CString s; s.Format("%s %d点%d分", ss,st.wHour,st.wMinute); theApp.SayInChinese(s); } } } } if(m_nLastHour != st.wHour) { //是否允许报时 if(theApp.GetProfileInt("settings","CanAlarmHour",TRUE)) { CString sFile=theApp.GetProfileString("settings", "HourAlarmFile",""); if(!sFile.IsEmpty() && PathFileExists(sFile)) { CString sExt=PathFindExtension(sFile); if(sExt.CompareNoCase(".wav")==0) { theApp.PlayWaveSound(sFile); } } if(theApp.GetProfileInt("settings", "UseChineseVoiceInAlarm",TRUE)) { CString sE; sE="正"; if(st.wMinute!=0) sE.Format("%d分",st.wMinute); CString s; s.Format("%s %d点%s",ss,st.wHour,sE); theApp.SayInChinese(s); } } }
右键单击时使其更透明。
void CClockDlg::OnRButtonDown(UINT nFlags, CPoint point) { CDialog::OnRButtonDown(nFlags, point); ::SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE, (LONG)(::GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE) & ~WS_EX_LAYERED)); ::SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE, (LONG)(::GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE) | WS_EX_LAYERED)); if(m_fTransPercent>0.f) m_fTransPercent-=5.f; if(m_fTransPercent<10.f) m_fTransPercent=10.f; ::SetLayeredWindowAttributes( GetSafeHwnd(), m_ColorBackground, //本颜色将删除 (BYTE)(255.f * m_fTransPercent/100.f),LWA_ALPHA|LWA_COLORKEY); BLENDFUNCTION bl={AC_SRC_OVER,0, (BYTE)(255.f * m_fTransPercent/100.f),AC_SRC_ALPHA}; ::UpdateLayeredWindow(GetSafeHwnd(), NULL, NULL,NULL, NULL, NULL, m_ColorBackground, &bl, ULW_ALPHA|ULW_COLORKEY); theApp.WriteProfileInt("Settings","ClockTransparent",(int)m_fTransPercent); }
void CClockDlg::OnHotKey(WPARAM wParam, LPARAM lParam) { WORD wL,wH; wL=LOWORD(lParam); wH=HIWORD(lParam); if((wL & MOD_ALT) && (wL & MOD_CONTROL) && (wL & MOD_SHIFT)) { if(wH==VK_F12) { if(!::IsWindowVisible(GetSafeHwnd())) { ShowWindow(SW_RESTORE); ShowWindow(SW_SHOW); } } } }
再次显示它的热键。
我还能说些什么呢?这对你来说很明显也很清楚,我将在下周上传中文语音 API (CSAPI)。