做了一个自动关机的程序,主要是创建了一个线程使预定时间与系统时间比较,相同则关机,但是当线程生成后,UI界面就不能操作了,资源都被该线程占用,不知道怎么改,大家帮忙看看,谢谢了!相关程序如下:
unsigned long CheckTime(CString setTime)
{
char tbuffer [9];
CString sysTime;
_strtime(tbuffer);
sysTime = tbuffer;
while(sysTime != setTime) {
_strtime( tbuffer );
sysTime = tbuffer;
}
return 0;
}
void CAutoCloseWinDlg::OnOK()
{
CString setTime;
CWnd * pWnd;
GetDlgItemText(IDC_TIMEEDIT,setTime);
pWnd = GetDlgItem(IDOK);
pWnd->EnableWindow(FALSE);
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CheckTime(setTime),NULL,0,&tid);
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
LPTSTR MachineName=NULL;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken ))
{
// PERR("OpenProcessToken",GetLastError());
return ;
}
if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid))
{
// PERR("LookupPrivilegeValue", GetLastError());
return ;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL, NULL ); //到这里,是取得权限///
ExitWindowsEx(EWX_POWEROFF,EWX_FORCE);
if (CanExit())
CDialog::OnOK();
}
unsigned long CheckTime(CString setTime)
{
char tbuffer [9];
CString sysTime;
_strtime(tbuffer);
sysTime = tbuffer;
while(sysTime != setTime) {
_strtime( tbuffer );
sysTime = tbuffer;
}
return 0;
}
void CAutoCloseWinDlg::OnOK()
{
CString setTime;
CWnd * pWnd;
GetDlgItemText(IDC_TIMEEDIT,setTime);
pWnd = GetDlgItem(IDOK);
pWnd->EnableWindow(FALSE);
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CheckTime(setTime),NULL,0,&tid);
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
LPTSTR MachineName=NULL;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken ))
{
// PERR("OpenProcessToken",GetLastError());
return ;
}
if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid))
{
// PERR("LookupPrivilegeValue", GetLastError());
return ;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL, NULL ); //到这里,是取得权限///
ExitWindowsEx(EWX_POWEROFF,EWX_FORCE);
if (CanExit())
CDialog::OnOK();
}
解决方案 »
- 真心:2个星期没弄清楚MSG msg 是什么意思?它和消息循环有关系吗
- Debug下可以打印出当前指针所属的类名吗?
- 如何在FlexGrid中画圆形位图
- ListCtrl的刷新问题
- 读写者的问题?
- consol application with mfc to solve the problem of CSocket?
- 怎样实现两个不同程序间的通讯?高分求!!!
- 关于 SOCKET 的高难度编程问题
- 如何用mfc实现对注册表的查询?急!!
- DCOM在客户端的配置问题 -- 分不在高,重在参与!
- 高分请教:有关编译错误的难题!
- 大智慧的界面做得巨猛,我服了。各位大虾,对此有研究的请赐教!!!!!!!!!!!!!!!!!!
这么用不对,等于把函数返回值强行转化为函数指针,CheckTime实际是在主线程中调用的。
应该改为
DWORD WINAPI CheckTime(
LPVOID szTime // thread data
)
{
CString setTime;
setTime = (LPCTSTR)szTime;
char tbuffer [9];
CString sysTime;
_strtime(tbuffer);
sysTime = tbuffer;
while(sysTime != setTime) {
_strtime( tbuffer );
sysTime = tbuffer;
}
deletep[] szTime;
return 0;
}
void CAutoCloseWinDlg::OnOK()
{
CString setTime;
CWnd * pWnd;
GetDlgItemText(IDC_TIMEEDIT,setTime);
pWnd = GetDlgItem(IDOK);
pWnd->EnableWindow(FALSE);
LPSTR szTime = new CHAR[setTime.GetLength()+1];
strcpy(szTime, setTime);
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CheckTime,szTime,0,&tid);
......
}
实际你还要添加线程同步代码才能保证程序正常运行
添加线程同步代码?是指什么?
{
CString setTime;
CWnd * pWnd;
GetDlgItemText(IDC_TIMEEDIT,setTime);
pWnd = GetDlgItem(IDOK);
pWnd->EnableWindow(FALSE);
LPSTR szTime = new CHAR[setTime.GetLength()+1];
strcpy(szTime, setTime);
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CheckTime,szTime,0,&tid);
BOOL bWait = TRUE;
while (bWait)
{
DWORD result ;
MSG msg ;
// Wait for update message sent to this queue
// or for one of the passed handles be set to signaled.
result = MsgWaitForMultipleObjects(1, (void**)(&hThread), FALSE, INFINITE, QS_ALLINPUT); // The result tells us the type of event we have.
if (result != (WAIT_OBJECT_0))
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// If it's a quit message, we're out of here.
if (msg.message == WM_QUIT)
return 1;
// Otherwise, dispatch the message.
DispatchMessage(&msg);
}
}
else
bWait = FALSE;
} // End of the always while loop.
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
LPTSTR MachineName=NULL;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken ))
{
// PERR("OpenProcessToken",GetLastError());
return ;
}
if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid))
{
// PERR("LookupPrivilegeValue", GetLastError());
return ;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL, NULL ); //到这里,是取得权限///
ExitWindowsEx(EWX_POWEROFF,EWX_FORCE);
if (CanExit())
CDialog::OnOK();
}
这样应该可以
为什么我的text框(IDC_TIMEEDIT)在停止thread后无法输入了?我并没有对其设置呀,只是对ok按钮的设置.我添加了下面的代码也不行:
void CAutoCloseWinDlg::OnReset()
{
// TODO: Add your control notification handler code here
CWnd * pWnd,*pText;
pWnd = GetDlgItem(IDOK);
pText = GetDlgItem(IDC_TIMEEDIT);
pWnd->EnableWindow(TRUE);
pText->EnableWindow(TRUE);
SetDlgItemText(IDC_TIMEEDIT,"00:00:00");
}