2013-02-21 65 views
9

Mã ngắn nhất để đặt trạng thái của nút thanh tác vụ Windows 7 cho cửa sổ đã biết là gì?Trạng thái thanh tác vụ của Windows 7 với mã tối thiểu

Mục tiêu là viết tiện ích bảng điều khiển thay đổi tiến độ và trạng thái (màu) của mục thanh tác vụ của cửa sổ bảng điều khiển từ tập lệnh lô. Trong khi kịch bản thực hiện các tác vụ khác nhau, mục thanh tác vụ của cửa sổ bảng điều khiển của nó sẽ đại diện cho trạng thái hiện tại.

Tôi nhận được cửa sổ xử lý với các GetConsoleWindow() chức năng, nhưng sau đó nó có vẻ như yêu cầu tải của COM và Shell API công cụ mà tôi không hiểu. Một ví dụ tôi đã tìm thấy sử dụng một ứng dụng GUI toàn diện với MFC để chứng minh API, nhưng hầu hết nó là quá phức tạp cho công cụ nhỏ của tôi và tôi không hiểu nó đủ tốt để loại bỏ những thứ tôi không cần.

Công cụ sẽ biên dịch trên Windows 7 với VS2010 (C++) nhưng cũng chạy trên các phiên bản Windows cũ hơn (không làm gì nếu tính năng không khả dụng).

+0

Bạn có ý nghĩa gì bởi "trạng thái thanh tác vụ"? Bạn có nghĩa là chỉ hiển thị tiến trình hoặc cái gì khác? – sashoalm

+0

Có, chỉ cần tiến độ và trạng thái (không xác định, bị tạm dừng, lỗi, nghĩa là màu xanh lục, vàng và đỏ). Không có jumplists, hình thu nhỏ hoặc các nút hành động. – ygoe

Trả lời

11

Tôi đã tạo một lớp để đặt tiến trình trong thanh tác vụ Win7 cho một dự án cùng một lúc. Đây là mã tôi đào lên:

#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

Tôi nghĩ rằng tôi cần điều này: '#include ' Nhưng 'VERIFY()' làm gì? – ygoe

+1

Không có gì quan trọng, tôi đã xóa chỉnh sửa câu trả lời của mình và xóa nó đi. Nó giống như một ASSERT() nhưng câu lệnh vẫn được thực thi trong các bản dựng. Xem http://msdn.microsoft.com/en-us/library/fcatwy09(v=vs.80).aspx – sashoalm

+4

Tôi đã thực hiện một công cụ nhỏ tiện dụng trong số này, mở rộng tính năng chỉ Flash trước đó của tôi. Bạn có thể tìm thấy nó ở đây: http://dev.unclassified.de/apps/flashconsolewindow – ygoe

0

Lưu ý bạn vẫn cần phải gọi RegisterWindowMessage("TaskbarButtonCreated")ChangeWindowMessageFilterEx() để thiết lập một bộ lọc tin nhắn trước khi SetProgressValue() có thể làm việc.

Theo tài liệu MSDN bạn có nghĩa vụ tạo lại đối tượng mỗi khi bạn nhận được thư đã tạo nhưng tôi thấy mình chỉ cần thực hiện ChangeWindowMessageFilterEx() và hoạt động tốt cho các trường hợp bình thường.

+1

Tôi đã viết một ứng dụng sử dụng 'SetProgressValue' và hoạt động hoàn hảo mà không cần' RegisterWindowMessage' hoặc 'ChangeWindowMessageFilterEx'. Như mọi khi, rất nhiều thông tin bị thiếu trong tài liệu. – v77

Các vấn đề liên quan