2012-09-15 14 views
10

sono le seguenti cose possibili utilizzando VBScript o qualsiasi altro linguaggio di programmazione:Cambio di Windows posizione 7 barra delle applicazioni automaticamente in base forma schermo o su attracco stato

  • rilevare forma schermo - o se il computer è ancorato
  • cambiamento della finestre posizione barra delle applicazioni

Quello che sto cercando di realizzare:

Il mio laptop ha un widescreen da 14 ": piuttosto largo, ma non molto alto. Trovo più comodo avere la barra delle applicazioni di Windows che si trova sulla sinistra dello schermo, dal momento che posso risparmiare la larghezza ma non lo spazio verticale.

Tuttavia, quando sono in ufficio, il mio computer si trova in una docking station ed è collegato a uno schermo grande e squadrato. Qui preferisco di gran lunga avere la barra delle applicazioni nella sua posizione predefinita, cioè nella parte inferiore.

So come passare manualmente tra le due posizioni della barra delle applicazioni in Proprietà barra delle applicazioni, naturalmente. Ma lo faccio alcune volte al giorno, il che è piuttosto fastidioso. La mia domanda è: posso cambiare automaticamente la posizione della barra delle applicazioni?

Per esempio, in fase di avvio (o svegliarsi dal letargo) uno script sarebbe in grado di rilevare sia:

  • è di forma dello schermo più alta di 4: 3? (o qualsiasi numero)
  • Il computer è inserito nella docking station?

Se sì, mettere barra delle applicazioni in basso, altrimenti a sinistra.

Qualcuno sa come fare questo o può mettermi sulla strada giusta? O c'è già un'utilità là fuori che può fare questo?

+0

Una cosa certa è che VBScript non sarà in grado di modificare la posizione della barra delle applicazioni, senza alcuna strumento di terze parti. Suggerisco di usare lo script * AutoIt * (tramite le funzioni del mouse) per automatizzare la modifica della posizione della barra delle applicazioni in base alle dimensioni e all'orientamento dello schermo corrente nonché per interrogare lo stato di aggancio (tramite oggetto WMI). – Jay

+1

Jay, ho dimostrato che si può fare, vedere la mia risposta, non sottovalutare vbscript – peter

risposta

7

// augment normale sul perché questa non è una buona idea sulla macchina di qualcun altro omesso

Un linguaggio di scripting potrebbe non essere una buona scelta qui, hai bisogno di qualcosa that pumps the message to listen to WM_DISPLAYCHANGE.

Quando si riceve il messaggio è necessario calcolare l'orientamento desiderato della barra delle applicazioni sulla base delle risoluzioni del monitor. Quindi si utilizza RmShutdown per chiudere Windows Explorer.

// documentato comportamento comincia può rompere qualsiasi momento

La docking bordo barra viene memorizzato nel byte 13 (come uno dei valori ABE da APPBARDATA) e la posizione viene memorizzata nel byte 25-40 come win32 RECT. È possibile modificare le impostazioni prima di riavviare Explorer.

// comportamento non documentato finisce

codice di esempio (sorgente completo a 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); 
2

È possibile farlo in una partita semplice o da uno script. Impostare il valore del registro per posizionare la barra delle applicazioni in base alla risoluzione corrente dello schermo (se nell'alloggiamento sarà superiore) e quindi riavviare explorer.exe. Così ad esempio, un lotto per impostare la barra a sinistra dello schermo sarebbe (ammesso che abbiate il file bottom.reg nella cartella D: \ scripts)

reg add d:\scripts\Bottom.reg 
@echo off taskkill /f /IM explorer.exe 
explorer.exe 

Il contenuto di bottom.reg sono

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 

e per 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 

avrete un po 'tremolante, ma dal momento che si farà questo, quando si avvia Windows che non sarà un problema suppongo. Ho provato questo su Windows 7.

EDIT: fatto un VBScript che fa la stessa cosa in base alla risoluzione dello schermo

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