是否可以使用 VBScript 或任何其他编程语言实现以下功能:
- 检测屏幕形状 - 或者计算机是否插接
- 更改 Windows 任务栏位置
我想要实现的目标:
我的笔记本电脑有一个 14"宽屏:很宽,但不是很高。我发现将 Windows 任务栏放在屏幕左侧最方便,因为我可以腾出宽度而不是垂直空间。
但是,在办公室时,我的电脑位于扩展坞中,并连接到一个漂亮的方形大屏幕上。在这里,我更喜欢将任务栏置于其默认位置,即底部。
当然,我知道如何在任务栏属性中手动切换两个任务栏位置。但是我每天都这样做几次,这很烦人。我的问题是:我可以让任务栏位置自动更改吗?
例如,在启动时(或从休眠中唤醒),将运行一个脚本来检测:
- 屏幕形状是否大于 4:3? (或任何数字)
- 计算机是否插在扩展坞中?
如果是,将任务栏放在底部,否则放在左边。
任何人都知道如何做到这一点或可以让我走上正轨吗?或者是否已经有可以执行此操作的实用程序?
最佳答案
//省略了为什么这在别人的机器上不是一个好主意的正常补充
脚本语言在这里可能不是一个好的选择,您需要一些东西 that pumps the message to listen to WM_DISPLAYCHANGE .
收到消息后,您需要根据显示器的分辨率计算任务栏的所需方向。然后使用 RmShutdown 关闭 Windows 资源管理器。
//未记录行为开始,随时可能中断
任务栏停靠边缘存储在字节 13 中(作为来自 APPBARDATA 的 ABE 值之一),位置存储在字节 25-40 中作为 win32 RECT .您可以在重新启动资源管理器之前修改设置。
//未记录的行为结束
示例代码(完整源代码位于 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);
关于windows - 根据屏幕形状或停靠状态自动更改 Windows 7 任务栏位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12435503/