请指点
解决方案 »
- ImageMagick的静态编译,静态链接问题
- 关于VC鼠标事件的问题
- 向网页post数据的问题
- free出现异常,大牛们快来看下
- 完成端口,程序出了问题
- 请问如何实现公交线路快速查询!!!
- 为什么sockClient.Create(); <-放到线程函数中就会出现内存错误?
- 怎么用自做的浏览器打开网页,是说点QQ邮箱马上打开
- 请问,CPaintDC和CClientDC有什么区别,它们分别使用哪些场合?
- 怎么样用自定义的CListCtrl的派生类来替换CListView中内置的CListCtrl类
- CSDN的各位大虾进来帮小弟一把,问题比较棘手,新手勿进。
- 如何解决对FD_READ响应的函数的重入问题?
int SetPower(BOOL bSuspend,BOOL bForce) //主要功能函数
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
LPTSTR MachineName=NULL; if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken ))
{
return RTN_ERROR;
}
if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid))
{
return RTN_ERROR;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),NULL, NULL );
SetSystemPowerState(bSuspend,bForce);
return 0;
}其中,SetSystemPowerState是调用睡眠或休眠的函数,第一个参数bSuspend为TRUE时,执行睡眠,为FALSE时执行休眠;第二个参数bForce是决定是否强制执行。在NT中直接调用SetSystemPowerState函数是不起作用的,要先取得权限,所以在SetSystemPowerState之前的代码是取得权限之用。
HANDLE hTimer=NULL;
LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch(message)
{
case WM_POWERBROADCAST:
switch(wParam)
{
case PBT_APMSUSPEND:
hTimer=::CreateWaitableTimer(NULL,TRUE,"WaitForResume");
if(!hTimer)
{
MessageBox("Fail to create waitable timer!");
//break;
}
hTimer=OpenWaitableTimer(TIMER_ALL_ACCESS,TRUE,"WaitForResume");
LARGE_INTEGER liDueTime;
liDueTime.QuadPart=nCounter*1000*1000*(-10);
if(!::SetWaitableTimer(hTimer,&liDueTime,0,NULL,NULL,TRUE))
{
MessageBox("Fail to set waitable timer!");
break;
} if(SetPower(TRUE,TRUE)==RTN_ERROR)
{
DWORD Er=GetLastError();
CString bfr;
bfr.Format("%d",Er);
MessageBox("Can not suspend!"+bfr);
}
break;
default:
break;
}
break;
}
default:
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}其中,nCounter是你想让系统唤醒的时间。
关键字 休眠
实现休眠功能很简单,只要在任意想要执行的地方执行如下给出的休眠函数SetPower()就行,其实休眠很简单,只需要API:SetSystemPowerState()就行,就如关机/注销/重启一样,只需要ExitWindowEx(),但这些API可以直接用在98下,却不能用在2000/XP中,因为这里牵涉到了用户权限,没有权限是不能进行这些操作的,所以,首先要取得权限,下面给出代码:#define RTN_ERROR 13void PERR(LPTSTR szAPI, DWORD dwLastError) //休眠时调用到的一个函数,用来 ////记录休眠中遇到的错误{
LPTSTR MessageBuffer;
DWORD dwBufferLength;
fprintf(stderr,"%s error! (rc=%lu)\n", szAPI, dwLastError); if(dwBufferLength=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwLastError,
LANG_NEUTRAL,
(LPTSTR) &MessageBuffer,
0,
NULL))
{ DWORD dwBytesWritten; WriteFile(GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL);
LocalFree(MessageBuffer);
}
}
INT SetPower()有 //主要功能函数
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid; LPTSTR MachineName=NULL; if(!OpenProcessToken(GetCurrentProcess(), ////////从这里////////////////////////////
TOKEN_ADJUST_PRIVILEGES,
&hToken ))
{
PERR("OpenProcessToken", GetLastError() );
return RTN_ERROR;
} if(!LookupPrivilegeValue(MachineName, SE_SHUTDOWN_NAME, &luid)) {
PERR("LookupPrivilegeValue", GetLastError() );
return RTN_ERROR;
} tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
NULL, NULL ); ////////////////到这里,是取得权限////////////////////// SetSystemPowerState(FALSE,TRUE);
return 0;} 这样,在任意需要休眠的时候调用SetPower();即可休眠,但是有一点要注意:必须打开了高级电源管理的休眠支持。
WIN2K关机时有5个选项:注销、关机、重启、等待、休眠。zkaz兄所言S3,是等待状态,或称之待机状态,是最低功耗的开电状态,动动鼠标键盘就会唤醒,S3状态不能掉电。休眠是S4状态,WINDOWS将内存的东东都写入硬盘然后关机,重上电时将硬盘数据恢复至内存,所以启动快能恢复至休眠时的工作状态,S4是可以掉电的。S5就不用说了。
但是,但是,但是楼上的各位大大啊,为什么不能理解我的问题的真正含义啊,是我的表达太有问题?
我说的是硬盘休眠,一般指非主硬盘停止转动。而主硬盘可能仍在工作。zkxz兄所言“只要操作系统在工作时,硬盘就不可能停止转动。”其实是不对的。
请大大们注意,我的问题与操作系统的休眠无关!!!
在WIN2K中不允许直接使用中断,使用DeviceIoControl也是不能实现的。谢谢楼上各位,请明白我问题者继续,分不够再加,呵呵。