批处理之家's Archiver

Batcher 发表于 2009-3-4 16:07

命令行窗口自动居中之批处理版(2009-03-17更新)

[quote]【方案一】比较原始的方法,思路比较容易理解。[/quote][code]@echo off
::Batcher@bbs.bathome.net
::2009-03-04
::命令行窗口自动居中之批处理版@CMD@XP
::http://bbs.bathome.net/thread-3582-1-1.html

setlocal enabledelayedexpansion
::指定命令行窗口字体大小(默认是8*16)
set FontWidth=8
set FontHeight=16
::指定命令行窗口大小(默认是80*25)
set WinCol=80
set WinRow=25

::ClearOldConf
for /f "tokens=3 delims=\" %%a in ('reg query HKEY_CURRENT_USER\Console^|findstr "_system32_cmd.exe"') do (
  if "%%a" neq "" (
    reg delete HKEY_CURRENT_USER\Console\%%a /va /f
  )
)

::SetFontSize
call :Dec2Hex %FontWidth% FontWidthH
call :Dec2Hex %FontHeight% FontHeightH
set FontWidthH=0000%FontWidthH%
set FontWidthH=%FontWidthH:~-4%
reg add HKEY_CURRENT_USER\Console /v FontSize /t reg_dword /d 0x%FontHeightH%%FontWidthH% /f

::SetWinSize
call :Dec2Hex %WinCol% WinColH
call :Dec2Hex %WinRow% WinRowtH
set WinColH=0000%WinColH%
set WinColH=%WinColH:~-4%
reg add HKEY_CURRENT_USER\Console /v WindowSize /t reg_dword /d 0x%WinRowtH%%WinColH% /f

::GetWinSize
set /a WinWidth=WinCol*FontWidth+33
set /a WinHeight=WinRow*FontHeight+45

::GetSrcSize
for /f "tokens=2 delims==" %%a in ('wmic desktopmonitor get screenwidth /value') do (
  set ScrWidth=%%a
  goto :GetSrcHeight
)
:GetSrcHeight
for /f "tokens=2 delims==" %%a in ('wmic desktopmonitor get screenheight /value') do (
  set ScrHeight=%%a
  goto :GetPosition
)

:GetPosition
set /a PosLeft=(ScrWidth-WinWidth)/2
set /a PosTop=(ScrHeight-WinHeight)/2
call :Dec2Hex %PosLeft% PosLeftH
call :Dec2Hex %PosTop% PosTopH
set PosLeftH=0000%PosLeftH%
set PosLeftH=%PosLeftH:~-4%
set PosTopH=0000%PosTopH%
set PosTopH=%PosTopH:~-4%
reg add HKEY_CURRENT_USER\Console /v WindowPosition /t reg_dword /d 0x%PosTopH%%PosLeftH% /f
start cmd
goto :eof

:Dec2Hex
set num=%1
set str=0123456789ABCDEF
set numDiv=%num%
set numConn=
:LoopD2H
set /a numMod=numDiv%%16
set numMod=!str:~%numMod%,1!
set /a numDiv/=16
set numConn=%numMod%%numConn%
if %numDiv% equ 0 (
  set %2=%numConn%
  goto :eof
)
goto :LoopD2H[/code][quote]【方案二】采用18楼pusofalse兄的方法:移位+或,可以缩短代码、提高执行效率。[/quote][code]@echo off
::Batcher@bbs.bathome.net
::2009-03-17
::命令行窗口自动居中之批处理版@CMD@XP
::http://bbs.bathome.net/thread-3582-1-1.html

setlocal enabledelayedexpansion
::指定命令行窗口字体大小(默认是8*16)
set FontWidth=8
set FontHeight=16
::指定命令行窗口大小(默认是80*25)
set WinCol=80
set WinRow=25

::SetFontSize
set /a "FontSizeD=FontHeight<<16|FontWidth"
call :Dec2Hex %FontSizeD% FontSizeH
reg add HKEY_CURRENT_USER\Console /v FontSize /t reg_dword /d 0x%FontSizeH% /f

::SetWinSize
set /a "WinSizeD=WinRow<<16|WinCol"
call :Dec2Hex %WinSizeD% WinSizeH
reg add HKEY_CURRENT_USER\Console /v WindowSize /t reg_dword /d 0x%WinSizeH% /f

::GetWinSize
set /a WinWidth=WinCol*FontWidth+33
set /a WinHeight=WinRow*FontHeight+45

::GetSrcSize
for /f "tokens=2 delims==" %%a in ('wmic desktopmonitor get screenwidth /value') do (
  set ScrWidth=%%a
  goto :GetSrcHeight
)
:GetSrcHeight
for /f "tokens=2 delims==" %%a in ('wmic desktopmonitor get screenheight /value') do (
  set ScrHeight=%%a
  goto :GetPosition
)

:GetPosition
set /a PosLeft=(ScrWidth-WinWidth)/2
set /a PosTop=(ScrHeight-WinHeight)/2
echo %PosLeft% %PosTop%
set /a "PosD=PosTop<<16|PosLeft"
call :Dec2Hex %PosD% PosH
reg add HKEY_CURRENT_USER\Console /v WindowPosition /t reg_dword /d 0x%PosH% /f
start cmd
goto :eof

:Dec2Hex
set num=%1
set str=0123456789ABCDEF
set numDiv=%num%
set numConn=
:LoopD2H
set /a numMod=numDiv%%16
set numMod=!str:~%numMod%,1!
set /a numDiv/=16
set numConn=%numMod%%numConn%
if %numDiv% equ 0 (
  set %2=%numConn%
  goto :eof
)
goto :LoopD2H[/code]

BBCC 发表于 2009-3-4 18:56

为了要实现这个居中...竟然要那么多的代码啊...

Batcher 发表于 2009-3-4 19:58

回复 2楼 的帖子

Just for fun : )

小勇12 发表于 2009-3-4 22:41

收下了 ,学习学习

BAT1 发表于 2009-3-5 18:23

因为搞不懂  指定命令行窗口字体大小  是指什么,所以改动了下数字,做下试验。
运行N次 出现N种不同结果:
第一次  直接执行      
在屏幕左上方回显两行操作成功结束  就停那里N久不动了(点X关掉)
第二次   改动          指定命令行窗口字体大小 8改16  16改32   
         在屏幕左上方回显两行操作成功结束   还是停那里N久不动 (点X关掉)
第三次  改动           指定命令行窗口大小   80改40  25改10
         在屏幕左上方回显操作结束   新建窗口居中
第四次   没有改动      回显两行操作成功结束   在左上角新建一个窗口
第五次   (同上次)
希望楼主能教下  指定命令行窗口字体大小  的作用是什么(是指在BAT运行时显示的字符吗)?  网上跟本论坛里都没这方面的贴子。

Batcher 发表于 2009-3-5 20:32

[quote]指定命令行窗口字体大小  的作用是什么(是指在BAT运行时显示的字符吗)?
[/quote]
是的

sjminh 发表于 2009-3-5 21:20

说实话,用处不大,还得改注册表,程序本身做不到吗?用手机上的,先收藏,有时间上网再研究吧!

Batcher 发表于 2009-3-5 21:36

[quote]说实话,用处不大[/quote]
同感,见三楼描述。
其中获取显示器分辨率的模块可能有时会用到,最近比较忙,过几天有时间再总结一下。
[quote]还得改注册表,程序本身做不到吗?[/quote]
是的。

Batcher 发表于 2009-3-7 00:56

[quote]第一次  直接执行      
在屏幕左上方回显两行操作成功结束  就停那里N久不动了(点X关掉)[/quote]
运行这个批处理之前,你是不是从来没有在本机使用过WMIC命令?
是的话,这就是原因所在了。

defanive 发表于 2009-3-7 01:02

要实现窗口居中的话,可以用CIdo,里面有/cts参数,可以使窗口居中。。。

Batcher 发表于 2009-3-7 01:29

回复 10楼 的帖子

是的,除此之外还有不少第三方命令行工具可以实现。
顶楼的代码只是为了挑战纯批处理而已。

defanive 发表于 2009-3-7 11:47

这个的原理我也明白,对每一个窗口都可以在注册表里面保存信息,通过更改这些信息再重新启动批处理即可。只是做起来太浪费时间罢了,效果也不一定好。。。

Batcher 发表于 2009-3-7 12:45

回复 12楼 的帖子

同意。
见3楼描述。

pusofalse 发表于 2009-3-7 23:02

计算字体大小那里,可以简化为:[code]set /a FontWidth=8, FontHeight=16
set /a FontSize=(FontHeight "<<" 16) + FontWidth[/code]直接对FontSize进行转16进制运算就好了,窗口大小同是。
貌似涉及到LowWord/HighWord(低位/高位?)

Batcher 发表于 2009-3-7 23:41

回复 14楼 的帖子

感谢指点,明天有时间的话,修改一下代码。
[color=Blue]=============================================

[2009-03-09]今天花时间看了一下,你给的公式是不正确的。

计算机中的8*16是十进制表示,我需要把它们转换成十六进制存放到注册表里面。高四位代表宽,低四位代表高,如果低四位转换的结果不满四位则需要在左侧补零。[/color]

[[i] 本帖最后由 Batcher 于 2009-3-9 10:44 编辑 [/i]]

wxcute 发表于 2009-3-8 19:31

要还原的话要删除相应注册表项,最好能批处理之。

Batcher 发表于 2009-3-9 10:49

回复 16楼 的帖子

删除相应注册表项是恢复的方法之一,另一个方法是手工修改命令行窗口的属性然后保存即可。

如果要用批处理来恢复,需要增加一个功能模块来保存修改前的设置,代码变得更长了,已经超出我“Just for fun”的范围,我不想写了,留个有兴趣的朋友玩吧^_^

pusofalse 发表于 2009-3-17 14:42

回复 15楼 的帖子

不好意思,现在才看到兄的回复。公式的确错了,应该是:[code]set /a FontWidth=8, FontHeight=16
set /a FontSize=(FontHeight "<<" 16) "|" FontWidth[/code]另外测试不必补零也可以啊~
是否在读取宽/高的时候写错了,测试代码:
设置.bat[code]@echo Off & setlocal EnableDelayedExpansion
Set /a FontWidth=8, FontHeight=16
Set /a FontSize=(FontHeight "<<" 16) "|" FontWidth

Call :Dec2Hex %FontSize% iFontSize
Echo 0x%iFontSize%
Reg Add hkcu\console /v FontSize /t reg_dword /d 0x%iFontSize%
Pause>nul & Exit /b



:Dec2Hex
set num=%1
set str=0123456789ABCDEF
set numDiv=%num%
set numConn=
:LoopD2H
set /a numMod=numDiv%%16
set numMod=!str:~%numMod%,1!
set /a numDiv/=16
set numConn=%numMod%%numConn%
if %numDiv% equ 0 (
  set %2=%numConn%
  goto :eof
)
goto :LoopD2H[/code]读取.bat[code]@echo Off
For /f "skip=4 tokens=3" %%a in ('reg query hkcu\console\ /v FontSize') do set /a FontSize=%%a

Set /a FontHeight=FontSize ">>" 16, FontWidth=FontSize "&" 0xffff
Echo FontWidth: %FontWidth% FontHeight: %FontHeight%
Pause>nul[/code]

Batcher 发表于 2009-3-17 22:52

回复 18楼 的帖子

我说的补零是指我原来采用的那个笨办法,你这个移位的方法是不需要补零的。
感谢分享!

zhong365 发表于 2013-11-2 16:01

实现这个功能好长啊

Hodson124 发表于 2014-3-8 18:23

不懂啊!!!

ShenMian 发表于 2016-10-12 23:03

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=22665&ptid=3582]5#[/url] [i]BAT1[/i] [/b]


    本人第一次就行了,执行速度很满意。

1139054012 发表于 2019-9-14 18:33

你好,楼主,请问删除哪个注册表项才能恢复原来,用了你1楼的代码,我所有bat和cmd都无法正常打开显示桌面了,一直闪退最小化,我真不知道该怎么办才好

LJY4.0 发表于 2022-5-2 12:49

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=223620&ptid=3582]23#[/url] [i]1139054012[/i] [/b]
这个事件就告诉我们,RUN脚本的时候,要备份注册表

sds 发表于 2023-1-15 20:28

64位系统运行后窗口消失了!怎么解决???

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.