回 帖 发 新 帖 刷新版面

主题:播放器中更改及恢复电源使用方案的代码

播放器中更改及恢复电源使用方案的代码

自编的播放器在播放视频时,都会遇到两个问题:一个是电源使用方案中关闭监视器和硬盘的时间问题,一个是屏保开启的问题,这两个问题都需要你在播放视频时不时地移动一下鼠标,很烦人。当然啰,你可以将自己电脑的电源使用方案设置为“从不”,并且关闭屏保,但如果你的播放器准备发布给大家使用,那就必须妥善解决这两个问题。
我的解决办法是:在播放器中的代码中,当需要播放视频时,把电源使用方案中的三个项目(关闭监视器时间、关闭硬盘时间、系统待机时)都设置为“从不”,并关闭屏保。当视频播放完毕时,再恢复原来的设置。
关闭屏保容易解决,调用一个API函数就行了,修改电源方案则遇到了一点麻烦。开始我在代码中使用修改注册表的办法,没有成功,后来只得使用了一个DOS命令“POWERCFG”,终于成功了!现将代码与大家共享。

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long

Dim SchemeFile As String    '电源方案文件
Dim SchemeName As String    '电源方案名称
Dim monitor_timeout As Long '关闭监视器时间
Dim disk_timeout As Long    '关闭硬盘时间
Dim standby_timeout As Long '系统待机时间
Dim BjScheme As Boolean     '电源方案更改标记

Private Sub 改变电源方案()
If Not BjScheme Then
  On Error GoTo 100
  Dim st As String
  
  SchemeFile = Environ("TEMP") & "\电源使用方案.txt"
  Shell "cmd /c POWERCFG /QUERY > " & SchemeFile   '导出原电源方案的配置
  
  Do '等待生成电源方案文件
    DoEvents
    Sleep 200
  Loop Until Len(Dir(SchemeFile))
  
  Open SchemeFile For Input As #1
  Do Until EOF(1)
    Line Input #1, st
    If InStr(st, "名称") Then SchemeName = Trim(Mid(st, 20))
    If InStr(st, "关闭监视器(AC)") Then monitor_timeout = Val(Mid(st, 20))
    If InStr(st, "关闭硬盘(AC)") Then disk_timeout = Val(Mid(st, 20))
    If InStr(st, "系统待机(AC)") Then standby_timeout = Val(Mid(st, 20)): Exit Do
  Loop
  
  Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /monitor-timeout-ac 0" '关闭监视器时间改为“从不”
  Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /disk-timeout-ac 0"    '关闭磁盘时间改为“从不”
  Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /standby-timeout-ac 0" '系统待机时间改为“从不”
  
  BjScheme = True
100
  Close
End If
SystemParametersInfo 17, False, 0, 0 '关闭屏保
End Sub

Private Sub 恢复电源方案()
If BjScheme Then
  Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /monitor-timeout-ac " & monitor_timeout '复原关闭监视器时间
  Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /disk-timeout-ac " & disk_timeout       '复原关闭磁盘时间
  Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /standby-timeout-ac " & standby_timeout '复原系统待机时间
  Kill SchemeFile
  BjScheme = False
End If
SystemParametersInfo 17, True, 0, 0 '恢复屏保
End Sub


在“改变电源方案”过程中,注意“等待生成电源方案文件”的那个 DO 循环,之所以要增加这么一个空循环,是因为 Shell 命令执行后,只要没有语法错误,它不等执行结果出来,就会越过去把执行权交给下一个语句或命令,这就会造成“导出原电源方案的配置”文件还未生成,而紧接着下一句又要打开这个配置文件,必定出错,为了防止这种情况发生,所以要增加一个空循环,让系统生成配置文件后再往下执行。

回复列表 (共10个回复)

沙发

我还很好奇一个问题,不使用wmp的dll,如何读取一个音频文件(mp3,wav,flat)的播放时间。


因为我想做一个定时播放音乐的软件,这里的定时指的是指定音乐播放完成的时间。


例如,指定一个音乐必须在中午12:00正好播放完。这样,我就必须知道这个音乐的长度,才能反算出开始播放时间应该是什么时候。


另外就是,用api播放音乐除了wav外,是不是都需要自己写解码器,或者用别人的dll?

板凳

MMC控件的Length属性就是媒体文件的播放时间长度。

还有API函数:mciSendString,获取播放时间长度的代码是:

Dim ST As String*64
mciSendString "status movie length", st, len(st), 0 '其中movie是别名
l=val(st) 'L就是所播放文件的长度

mciSendString播放wav、mp3、wma(还有别的一些媒体文件)都不需要自己写解码代码。

3 楼

加精支持

4 楼

谢谢秋水老师的文章

5 楼

秋水老弟,我有几个想法。

1、关于那个“导出”是否覆盖已有文件的问题。如果能覆盖,就不说了,要是不能覆盖,在导出电源配置文件前,可以考虑删除因为不正常关机等原因造成前次导出文件。

2、读取导出文件的数据,可以放到“恢复电源方案”过程中恢复设置前读取。

3、On Error GoTo 100,都可能处理那些问题,会不会导致更改设置失败、甚至原电源方案未能导出?这些是否应该进行标记重新尝试,或者特殊处理?

呵呵,自己瞎想的,不一定有用,仅供参考。

6 楼

赞成老大的想法1、3,想法2不行的,因为要读出方案中的SchemeName,dos命令根据这个SchemeName来修改方案。

7 楼

模拟鼠标或者键盘按一个没有啥效果的键就好了哈,或者隐藏鼠标标记,或者将鼠标移动外屏幕外再移动哈

8 楼

发现“改变电源方案”过程中的那个 DO 循环效果不好,改进如下:


Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long

Dim SchemeFile As String    '电源方案文件
Dim SchemeName As String    '电源方案名称
Dim BjScheme As Boolean     '电源方案更改标记

Private Sub 改变电源方案()
On Error GoTo 100
Dim z As String, ws

SystemParametersInfo 17, False, 0, 0 '关闭屏保
Set ws = CreateObject("wscript.shell")
z = ws.regread("HKEY_CURRENT_USER\Control Panel\PowerCfg\CurrentPowerPolicy") '获取电源方案号
SchemeName = ws.regread("HKEY_CURRENT_USER\Control Panel\PowerCfg\PowerPolicies\" & z & "\Name") '获取方案名
SchemeFile = Environ("TEMP") & "\电源使用方案.txt"
Shell "cmd /c POWERCFG /QUERY > " & SchemeFile, 0  '导出原电源方案的配置

Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /monitor-timeout-ac 0", 0 '关闭监视器时间改为“从不”
Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /disk-timeout-ac 0", 0    '关闭磁盘时间改为“从不”
Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /standby-timeout-ac 0", 0 '系统待机时间改为“从不”

BjScheme = True
ws = Nothing
100
End Sub

Private Sub 恢复电源方案()
Dim st As String
Dim monitor_timeout As Integer '关闭监视器时间
Dim disk_timeout As Integer    '关闭硬盘时间
Dim standby_timeout As Integer '系统待机时间

Open SchemeFile For Input As #1
Do Until EOF(1)
  Line Input #1, st
  If InStr(st, "关闭监视器(AC)") Then monitor_timeout = Val(Mid(st, 20))
  If InStr(st, "关闭硬盘(AC)") Then disk_timeout = Val(Mid(st, 20))
  If InStr(st, "系统待机(AC)") Then standby_timeout = Val(Mid(st, 20)): Exit Do
Loop
Close #1

Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /monitor-timeout-ac " & monitor_timeout, 0 '复原关闭监视器时间
Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /disk-timeout-ac " & disk_timeout, 0       '复原关闭磁盘时间
Shell "cmd /c POWERCFG /CHANGE " & SchemeName & " /standby-timeout-ac " & standby_timeout, 0 '复原系统待机时间
SystemParametersInfo 17, True, 0, 0 '恢复屏保
BjScheme = False
Kill SchemeFile
End Sub

9 楼

我可以将这个转到我的代码分享网站里么?征求下你的同意。

10 楼

可以

我来回复

您尚未登录,请登录后再回复。点此登录或注册