2013-02-21 9 views
9

Quale sarebbe il codice più breve per impostare lo stato di un pulsante della barra delle applicazioni di Windows 7 per un handle di finestra noto?Stato della barra delle applicazioni di Windows 7 con codice minimo

L'obiettivo è scrivere un'utilità della console che modifichi l'avanzamento e lo stato (colore) della voce della barra delle applicazioni della finestra della console da uno script batch. Mentre lo script esegue attività diverse, l'elemento della barra delle applicazioni della finestra della console dovrebbe rappresentare lo stato corrente.

Ottengo l'handle di finestra con la funzione GetConsoleWindow(), ma sembra che richieda carichi di roba di API COM e Shell che non capisco. Un esempio che ho trovato utilizza un'intera applicazione GUI con MFC per dimostrare l'API, ma la maggior parte è troppo complicata per il mio piccolo strumento e non la capisco abbastanza bene da rimuovere le cose che non mi servono.

Lo strumento deve essere compilato su Windows 7 con VS2010 (C++), ma può anche essere eseguito su versioni precedenti di Windows (senza fare nulla se una funzione non è disponibile).

+0

Cosa intendi per "stato della barra delle applicazioni"? Intendi solo mostrare progressi o qualcos'altro? – sashoalm

+0

Sì, solo avanzamento e stato (indeterminato, in pausa, errore, ovvero i colori verde, giallo e rosso). Nessun jumplist, miniature o pulsanti di azione. – ygoe

risposta

11

Ho creato una classe per impostare i progressi nella barra delle applicazioni di Win7 per un progetto alla volta. Questo è il codice ho scavato:

#include <shobjidl.h> 
#include <windows.h> 
#pragma comment(lib, "Shell32.lib") 
#pragma comment(lib, "Ole32.lib") 

class Win7TaskbarProgress 
{ 
public: 
    Win7TaskbarProgress(); 
    virtual ~Win7TaskbarProgress(); 

    void SetProgressState(HWND hwnd, TBPFLAG flag); 
    void SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal); 

private: 
    bool Init(); 
    ITaskbarList3* m_pITaskBarList3; 
    bool m_bFailed; 
}; 

Win7TaskbarProgress::Win7TaskbarProgress() 
{ 
    m_pITaskBarList3 = NULL; 
    m_bFailed = false; 
} 

Win7TaskbarProgress::~Win7TaskbarProgress() 
{ 
    if (m_pITaskBarList3) 
    { 
     m_pITaskBarList3->Release(); 
     CoUninitialize(); 
    } 
} 

void Win7TaskbarProgress::SetProgressState(HWND hwnd, TBPFLAG flag) 
{ 
    if (Init()) 
     m_pITaskBarList3->SetProgressState(hwnd, flag); 
} 

void Win7TaskbarProgress::SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) 
{ 
    if (Init()) 
     m_pITaskBarList3->SetProgressValue(hwnd, ullCompleted, ullTotal); 
} 

bool Win7TaskbarProgress::Init() 
{ 
    if (m_pITaskBarList3) 
     return true; 

    if (m_bFailed) 
     return false; 

    // Initialize COM for this thread... 
    CoInitialize(NULL); 

    CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&m_pITaskBarList3); 

    if (m_pITaskBarList3) 
     return true; 

    m_bFailed = true; 
    CoUninitialize(); 
    return false; 
} 
+1

Penso di aver bisogno di questo: '#include ' Ma cosa significa 'VERIFY()'? – ygoe

+1

Niente di importante, ho rimosso modificato la mia risposta e rimosso. È come un ASSERT() ma la dichiarazione viene ancora eseguita nelle build Release. Vedi http://msdn.microsoft.com/en-us/library/fcatwy09(v=vs.80).aspx – sashoalm

+4

Ho creato un piccolo strumento utile, estendendo la mia precedente funzione solo Flash. Puoi trovarlo qui: http://dev.unclassified.de/apps/flashconsolewindow – ygoe

0

Nota è ancora necessario chiamare RegisterWindowMessage("TaskbarButtonCreated") e ChangeWindowMessageFilterEx() di impostare un filtro dei messaggi prima di SetProgressValue() può lavorare.

In base ai documenti MSDN, si suppone di dover ricreare il proprio oggetto ogni volta che si ottiene il messaggio creato, ma ho scoperto che dovevo solo eseguire lo ChangeWindowMessageFilterEx() e che funziona in circostanze normali.

+1

Ho scritto un'applicazione che utilizza 'SetProgressValue' e funziona perfettamente senza' RegisterWindowMessage' né 'ChangeWindowMessageFilterEx'. Come sempre, nella documentazione mancano molte informazioni. – v77