使用VBScript或任何其他编程语言可能以下的事情:
- 检测屏幕形状 - 或计算机是否对接
- 更改Windows任务栏的位置
我想实现:
我的笔记本电脑有一个14" 宽屏:相当广泛,但不是很高,我觉得它最方便的位于屏幕左侧的Windows任务栏,因为我可以饶宽度而不是垂直空间。
然而,在办公室的时候,我的电脑坐落在一个扩展坞,并迷上了一个漂亮的大屏幕方形。 在这里,我更喜欢有即在底部的默认位置在任务栏。
我知道如何手动在任务栏属性两个任务栏的位置,当然,之间切换。 但我每天都这样做了几次,这是相当烦人。 我的问题是:我可以有自动在任务栏的位置变化?
例如,在启动时(或唤醒从休眠向上)的脚本将运行,其检测任一:
- 是屏幕形状比4高:3? (或任何数目)
- 是计算机停靠在扩展坞?
如果是的话,把任务栏在底部,否则在左边。
任何人都知道如何做到这一点还是可以把我在正确的轨道上? 或者是已经有一个实用工具,有可以做到这一点?
//为什么这是不是忽略别人的机器上的一个好主意普通扩充
脚本语言可能不是一个很好的选择在这里,你需要的东西,其泵送听WM_DISPLAYCHANGE消息 。
当你得到消息,你需要计算根据您的监视器的决议任务栏的所需方向。 然后你使用RmShutdown关闭Windows资源管理器。
// 无证行为开始,可能随时破
任务栏对接边缘被存储在字节13(如从ABE值之一APPBARDATA )和位置存储在字节25-40作为一个Win32 RECT 。 您可以重新启动Explorer之前修改设置。
//无证行为结束
示例代码(在完整的源https://github.com/jiangsheng/Samples/tree/master/AppBarTest ):
//returns the process id and create time for the oldest explorer.exe
RM_UNIQUE_PROCESS GetExplorerApplication()
{
RM_UNIQUE_PROCESS result={0};
DWORD bytesReturned=0;
DWORD processIdSize=4096;
std::vector<DWORD> processIds;
processIds.resize(1024);
EnumProcesses(processIds.data(),processIdSize,&bytesReturned);
while(bytesReturned==processIdSize)
{
processIdSize+=processIdSize;
processIds.resize(processIdSize/4);
EnumProcesses(processIds.data(),processIdSize,&bytesReturned);
}
std::for_each(processIds.begin(), processIds.end(), [&result] (DWORD processId) {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE, processId);
if (hProcess) {
std::wstring imageName;
imageName.resize(4096);
if(GetProcessImageFileName (hProcess,(LPWSTR)imageName.data(),4096)>0)
{
if(wcscmp(L"explorer.exe",PathFindFileName(imageName.data()))==0)
{
//this is assmuing the user is not running elevated and won't see explorer processes in other sessions
FILETIME ftCreate, ftExit, ftKernel, ftUser;
if (GetProcessTimes(hProcess, &ftCreate, &ftExit,&ftKernel, &ftUser))
{
if(result.dwProcessId==0)
{
result.dwProcessId=processId;
result.ProcessStartTime=ftCreate;
}
else if(CompareFileTime(&result.ProcessStartTime,&ftCreate)>0)
{
result.dwProcessId=processId;
result.ProcessStartTime=ftCreate;
}
}
}
}
CloseHandle(hProcess);
}
});
return result;
}
//taskbar position calculating code omitted
DWORD dwSession=0;
WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = { 0 };
DWORD dwError = RmStartSession(&dwSession, 0, szSessionKey);
if (dwError == ERROR_SUCCESS) {
RM_UNIQUE_PROCESS rgApplications[1]={GetExplorerApplication()};
dwError=RmRegisterResources(
dwSession,0,NULL,1,rgApplications,0,NULL);
DWORD dwReason;
UINT nProcInfoNeeded;
UINT nProcInfo = 10;
RM_PROCESS_INFO rgpi[10];
dwError = RmGetList(dwSession, &nProcInfoNeeded,
&nProcInfo, rgpi, &dwReason);
if(dwReason==RmRebootReasonNone)//now free to restart explorer
{
RmShutdown(dwSession,RmForceShutdown,NULL);//important, if we change the registry before shutting down explorer will override our change
//using undocumented setting structure, could break any time
//edge setting is stored at HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2!Settings
HKEY hKey={0};
DWORD result=0;
result=::RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects2"),
0, KEY_READ|KEY_WRITE, &hKey) ;
if (result== ERROR_SUCCESS)
{
std::vector<BYTE> data;
data.resize(256);
TCHAR settingValue[]= _T("Settings");
DWORD dwKeyDataType=0;
DWORD dwDataBufSize=data.size();
result=::RegQueryValueEx(hKey,settingValue, NULL, &dwKeyDataType,
(LPBYTE) data.data(), &dwDataBufSize);
while(ERROR_MORE_DATA==result)
{
data.resize(256+data.size());
dwDataBufSize=data.size();
result=::RegQueryValueEx(hKey,settingValue, NULL, &dwKeyDataType,
(LPBYTE) data.data(), &dwDataBufSize);
}
data.resize(dwDataBufSize);
if(result==ERROR_SUCCESS)
{
switch ( dwKeyDataType )
{
case REG_BINARY:
if(data.size()==40)
{
BYTE taskbarPosition=data[12];
taskbarPosition=edge;
data[12]=taskbarPosition;
RECT* taskbarRect=(RECT*)&data[24];
CopyRect (taskbarRect,&abd.rc);
result=::RegSetValueEx(hKey,settingValue,0,REG_BINARY,(LPBYTE) data.data(), dwDataBufSize);
}
break;
}
}
::RegCloseKey( hKey );
}
RmRestart (dwSession,0,NULL);
}
}
RmEndSession(dwSession);
您可以在一个简单的批处理或脚本做到这一点。 设置注册表值位置,并根据屏幕的当前的分辨率在任务栏(如果在对接将是更高版本),然后重新启动Explorer.exe的。 因此,如批次设置在屏幕的左侧任务栏会(假设你已经在d的bottom.reg文件:\ scripts文件夹)
reg add d:\scripts\Bottom.reg
@echo off taskkill /f /IM explorer.exe
explorer.exe
bottom.reg的内容
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2]
"Settings"=hex:28,00,00,00,ff,ff,ff,ff,02,00,00,00,03,00,00,00,3e,00,00,00,2e,\
00,00,00,00,00,00,00,82,04,00,00,80,07,00,00,b0,04,00,00
和left.reg
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2]
"Settings"=hex:28,00,00,00,ff,ff,ff,ff,02,00,00,00,00,00,00,00,3e,00,00,00,2e,\
00,00,00,00,00,00,00,00,00,00,00,3e,00,00,00,b0,04,00,00
你将有一些闪烁,但是因为你会做到这一点,当你开始不会是一个问题,我想窗口。 我测试了在Windows 7上。
编辑:做一个VBScript,做基于屏幕分辨率同样的事情
HKEY_CURRENT_USER = &H80000001
Set WshShell = CreateObject("WScript.Shell")
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set ObjRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
'Get curr. user name
Set colItems = objWMIService.ExecQuery("Select * From Win32_ComputerSystem")
For Each objItem in colItems
strCurrentUserName = objItem.UserName
Next
Set colItems = objWMIService.ExecQuery("Select * From Win32_DesktopMonitor where DeviceID = 'DesktopMonitor1'",,0)
For Each objItem in colItems
intHorizontal = objItem.ScreenWidth
intVertical = objItem.ScreenHeight
Next
bottom = Array(&H28,&H00,&H00,&H00,&Hff,&Hff,&Hff,&Hff,&H02,&H00,&H00,&H00,&H03,&H00,&H00,&H00,&H3e,&H00,&H00,&H00,&H2e,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H82,&H04,&H00,&H00,&H80,&H07,&H00,&H00,&Hb0,&H04,&H00,&H00)
left_ = Array(&H28,&H00,&H00,&H00,&Hff,&Hff,&Hff,&Hff,&H02,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H3e,&H00,&H00,&H00,&H2e,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H3e,&H00,&H00,&H00,&Hb0,&H04,&H00,&H00)
if intHorizontal >= 1920 then
regdata = bottom
else
regdata = left_
end if
ObjRegistry.SetBinaryValue HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2\", "Settings", regdata
'Restart user shell
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process Where Name = 'Explorer.exe'")
For Each objProcess in colProcessList
colProperties = objProcess.GetOwner(strNameOfUser,strUserDomain)
wscript.echo colProperties
If strUserDomain & "\" & strNameOfUser = strCurrentUserName then
wscript.echo "restarting"
objProcess.Terminate()
end if
Next
文章来源: Change Windows 7 taskbar location automatically based on screen shape or on docking status