做了一个自动关机的程序,主要是创建了一个线程使预定时间与系统时间比较,相同则关机,但是当线程生成后,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();
}

解决方案 »

  1.   

    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CheckTime(setTime),NULL,0,&tid);
    这么用不对,等于把函数返回值强行转化为函数指针,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);
    ......
    }
    实际你还要添加线程同步代码才能保证程序正常运行
      

  2.   

    to goodboyws(深夜不眠者):
    添加线程同步代码?是指什么?
      

  3.   

    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);
    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();
    }
    这样应该可以
      

  4.   

    to goodboyws(深夜不眠者):
    为什么我的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");
    }