windows關機小程式

pengfoo發表於2012-01-04
 

#include <Windows.h>
#include <tchar.h>
#include <assert.h>

TCHAR* szQuestion=TEXT("1000*10等於多少?");
TCHAR* szAnswer=TEXT("10000");
WNDPROC oldEditProc=NULL;
WNDPROC oldButtonProc=NULL;
HFONT hFont=NULL;
HWND hTestDlgWnd=NULL,hEditWnd=NULL,hButtonWnd=NULL;
LRESULT CALLBACK TestDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK MyEditProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK MyButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
BOOL SystemReboot();

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
 WNDCLASS wndclass={0};
 TCHAR* szClassName=TEXT("TestDlg");
 MSG msg={0};

 COLORREF color=GetSysColor(COLOR_ACTIVEBORDER);
 HBRUSH hBrush=CreateSolidBrush(color);
 assert(hBrush);

 hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
 LOGFONT logfont={0};
 GetObject(hFont,sizeof(LOGFONT),&logfont);
 DeleteObject(hFont);
 hFont=NULL;
 logfont.lfHeight=12;
 _tcscpy(logfont.lfFaceName,TEXT("宋體"));
 hFont=CreateFontIndirect(&logfont);
 assert(hFont);

 wndclass.style=CS_NOCLOSE;
 wndclass.hInstance=hInstance;
 wndclass.hbrBackground=hBrush;
 wndclass.hCursor=LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW));
 wndclass.hIcon=LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION));
 wndclass.cbWndExtra=0;
 wndclass.cbClsExtra=0;
 wndclass.lpfnWndProc=TestDlgProc;
 wndclass.lpszMenuName=NULL;
 wndclass.lpszClassName=szClassName;
 
 if (!RegisterClass(&wndclass))
 {
  MessageBox(NULL,TEXT("視窗註冊失敗!"),TEXT("警告"),MB_OK);
  return S_FALSE;
 }

 DWORD style=WS_OVERLAPPEDWINDOW &~ (WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME);
 int cx=GetSystemMetrics(SM_CXFULLSCREEN);
 int cy=GetSystemMetrics(SM_CYFULLSCREEN);
 int iTestDlgWidth=500;
 int iTestDlgHeight=230;
 hTestDlgWnd=CreateWindowEx(WS_EX_TOOLWINDOW,
    szClassName,
    TEXT("請回答題目:"),
  style,
   cx/2-iTestDlgWidth/2,
   cy/2-iTestDlgHeight/2,
   iTestDlgWidth,
   iTestDlgHeight,
  NULL,
  NULL,
  hInstance,
  NULL);
 assert(hTestDlgWnd); 
 ::SendMessage(hTestDlgWnd,WM_SETFONT,(WPARAM)hFont,1);

 style=WS_CHILD | ES_MULTILINE | ES_LEFT | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
 hEditWnd=CreateWindow(
     TEXT("Edit"),
     TEXT(""),
     style,
     10,
     40,
     iTestDlgWidth-20,
     100,
     hTestDlgWnd,
     NULL,
     hInstance,
     0
     );
 assert(hEditWnd);
 oldEditProc=(WNDPROC)SetWindowLong(hEditWnd,GWL_WNDPROC,(LONG)MyEditProc);
 assert(oldEditProc);
 ::SendMessage(hEditWnd,WM_SETFONT,(WPARAM)hFont,1);

 style=WS_CHILD;
 hButtonWnd=CreateWindow(TEXT("Button"),
       TEXT("確定"),
       style,
       10,
       150,
       60,
       20,
       hTestDlgWnd,
       NULL,
       hInstance,
       0
       );
 assert(hButtonWnd);
 oldButtonProc=(WNDPROC)SetWindowLong(hButtonWnd,GWL_WNDPROC,(LONG)MyButtonProc);
 assert(oldButtonProc);
 ::SendMessage(hButtonWnd,WM_SETFONT,(WPARAM)hFont,1);

 ShowWindow(hTestDlgWnd,SW_SHOW);
  ShowWindow(hEditWnd,SW_SHOW);
  ShowWindow(hButtonWnd,SW_SHOW);
  UpdateWindow(hTestDlgWnd);

 ::SetFocus(hEditWnd);
 while (GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 if(hBrush)
  DeleteObject(hBrush);
 if(hFont)
  DeleteObject(hFont);
 return msg.wParam;
}

LRESULT CALLBACK TestDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 switch(message)
 {
  case WM_CLOSE:
  {
   DestroyWindow(hWnd);
  }
  break;
  case WM_DESTROY:
   {
    PostQuitMessage(0);
   }
  break;
  case WM_PAINT:
  {
     PAINTSTRUCT ps={0};
     HDC hDC=NULL;
     hDC=BeginPaint(hWnd,&ps);
     HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);
     int oldMode=SetBkMode(hDC,TRANSPARENT);
     TextOut(hDC,10,5,szQuestion,_tcslen(szQuestion));
     SelectObject(hDC,hOldFont);
     SetBkMode(hDC,oldMode);
     EndPaint(hWnd,&ps);
  }
  break;
   }
  return DefWindowProc(hWnd,message,wParam,lParam);
}

LRESULT CALLBACK MyEditProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 return (*oldEditProc)(hWnd,message,wParam,lParam);
}

LRESULT CALLBACK MyButtonProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 switch(message)
 {
   case WM_LBUTTONDOWN:
  {
    TCHAR buf[512]={0};
    GetWindowText(hEditWnd,buf,512);

   if (!_tcscmp(buf,szAnswer))
   {
     MessageBox(hWnd,TEXT("你回答正確了!"),TEXT("提示"),MB_OK);
    ::SendMessage(hTestDlgWnd,WM_CLOSE,0,0);
   }
   else
   {
    MessageBox(hWnd,TEXT("你回答錯誤!請做好接受懲罰準備!!"),TEXT("提示"),MB_OK);
    SystemReboot();
   }
  }
  break;
 }
 return (*oldButtonProc)(hWnd,message,wParam,lParam);
}

BOOL SystemReboot()
{
 HANDLE hToken;
 TOKEN_PRIVILEGES tkp;
 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
 {
  return(FALSE);
 }
 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
 tkp.PrivilegeCount = 1;   
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

 if (GetLastError() != ERROR_SUCCESS)
 {
  return FALSE;
 }

 if (!ExitWindowsEx(EWX_REBOOT, 0))
 {
  return FALSE;
 }
 return TRUE;
}

//shutdown程式

HANDLE             hToken;     
     TOKEN_PRIVILEGES   tkp;     

     OpenProcessToken(
                        GetCurrentProcess(),                 //獲得當前程式的控制程式碼
                        TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, //可查詢並修改許可權
                        &hToken                //程式訪問令牌的控制程式碼傳遞給hToken
                        );    

        //先檢視系統上SE_SHUTDOWN_NAME許可權名的識別符號(LUID),返回一個唯一的LUID識別符號。
       
          LookupPrivilegeValue(
                            NULL,                     //計算機名,NULL表示指定本地系統
                            SE_SHUTDOWN_NAME,         //許可權名稱,表示允許關機
                            &tkp.Privileges[0].Luid   //給函式傳遞LUID結構指標,給LUID傳
                                                     
                            );
   
        tkp.PrivilegeCount = 1;     //設定一個許可權,只訪問修改一個許可權       
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //說明許可權是啟用的
   
        //令牌hToken的許可權修改為可以關機(SE_SHUTDOWN_NAME)。 

相關文章