//直接贴代码:
//头文件
#include "stdafx.h"
#include <Windows.h>
#include <commctrl.h>
#pragma once
//如果工具栏要添加,删除 使用ITaskbarList接口
//改写系统的TBBUTTON结构
typedef struct tag_MyTbButton1{
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
#ifdef _WIN64
BYTE bReserved[6]; // padding for alignment
#elif defined(_WIN32)
BYTE bReserved[2]; // padding for alignment
#endif
DWORD_PTR dwData;
BYTE IsUsingString; //为1表示szText可用,为0表示index可用
union {
INT_PTR index;
WCHAR szText[MAX_PATH];//需要注意,是UNICODE版本的
}var;
}MYTBBUTTON,*PMYTBBUTTON,*LPMYTBBUTTON;
//下面的实现 可在xp下使用,未在vista及以后版本中测试
//获取“工具栏”的窗体句柄,失败返回NULL
HWND __stdcall GetToolBarWndHandle();
//获取“工具栏”存在窗体的个数
DWORD __stdcall GetToolBarCount();
class CTaskBarListEnum{
public:
CTaskBarListEnum();
virtual ~CTaskBarListEnum();
//获取“工具栏”窗体个数
int GetTaskBarCount();
//获取“工具栏”窗体的句柄
HWND GetTaskBarWndHandle();
//获取创建“工具栏”的目标进程ID
DWORD GetTaskListProcessID();
//更新
BOOL Reset();
//在一个链表中获取下一个可用的,否则返回FALSE,注意会在内部自增一个地址偏移
BOOL Next(__out LPMYTBBUTTON lpBufInfo,__out_opt int* pcurIndex);
//根据索引值获取相对应的元素
BOOL IndexOf(__in int index,__out LPMYTBBUTTON lpBufInfo);
private:
//总个数
int m_icount;
//当前索引值
int m_index;
//获取工具栏的窗体句柄
HWND m_htoolbarwnd;
//指向远程内存
TBBUTTON* m_pRmBtInfo;
//本地储存的数组
LPMYTBBUTTON m_pLmBtInfo;
HANDLE m_hProcess;
DWORD m_pid;
private:
BOOL SetMembers();
//错误初始化
VOID ErrorInitialize();
};
///////////////////////////////////////////////////////
//源文件
#include "stdafx.h"
#include "TaskbarEnum.h"
//下面的实现 可在xp下使用
//获取“工具栏”的窗体句柄,失败返回NULL
HWND __stdcall GetToolBarWndHandle()
{
HWND h1=FindWindow(_T("Shell_TrayWnd"),0);
HWND h2=FindWindowEx(h1,0,_T("ReBarWindow32"),0);
h1=FindWindowEx(h2,0,_T("MSTaskSwWClass"),0);
h2=FindWindowEx(h1,0,_T("ToolbarWindow32"),0);
return h2;
}
//获取“工具栏”存在窗体的个数
DWORD __stdcall GetToolBarCount(){
return(DWORD)SendMessage(GetToolBarWndHandle(),TB_BUTTONCOUNT,0,0);
}
CTaskBarListEnum::CTaskBarListEnum(){
this->m_icount=0;
this->m_htoolbarwnd=NULL;
this->m_index=-1;//负数表示 错误状态
this->m_pRmBtInfo=NULL;
this->m_pLmBtInfo=NULL;
this->m_hProcess=NULL;
HWND h1=FindWindow(_T("Shell_TrayWnd"),0);
HWND h2=FindWindowEx(h1,0,_T("ReBarWindow32"),0);
h1=FindWindowEx(h2,0,_T("MSTaskSwWClass"),0);
h2=FindWindowEx(h1,0,_T("ToolbarWindow32"),0);
this->m_htoolbarwnd=h2;
this->Reset();
}
VOID CTaskBarListEnum::ErrorInitialize(){
this->m_icount=0;
this->m_htoolbarwnd=NULL;
this->m_index=-1;//负数表示 错误状态
this->m_pLmBtInfo=NULL;
this->m_pRmBtInfo=NULL;
this->m_hProcess=NULL;
}
BOOL CTaskBarListEnum::SetMembers(){
if(this->m_pLmBtInfo)
HeapFree(GetProcessHeap(),0,this->m_pLmBtInfo);
__try{
this->m_icount=(int)SendMessageW(this->m_htoolbarwnd,TB_BUTTONCOUNT,0,0);
if(this->m_icount<=0) __leave;
GetWindowThreadProcessId(this->m_htoolbarwnd,&(this->m_pid));
this->m_hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE
,FALSE,this->m_pid);
if(!this->m_hProcess) __leave;
this->m_pRmBtInfo=(TBBUTTON*)VirtualAllocEx(
this->m_hProcess,
0,
sizeof(TBBUTTON),
MEM_COMMIT,
PAGE_READWRITE
);
if(!this->m_pRmBtInfo){
CloseHandle(m_hProcess);
this->ErrorInitialize();
__leave;
}
this->m_pLmBtInfo=(LPMYTBBUTTON)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(MYTBBUTTON)*this->m_icount);
if(!this->m_pLmBtInfo){
VirtualFreeEx(m_hProcess,this->m_pRmBtInfo,0,MEM_RELEASE);
CloseHandle(m_hProcess);
this->ErrorInitialize();
__leave;
}
MYTBBUTTON* pFirstAddress=this->m_pLmBtInfo;
TBBUTTON temp;
ZeroMemory(&temp,sizeof(TBBUTTON));
for(int i =0;i<this->m_icount;i++){
SendMessageW(this->m_htoolbarwnd,TB_GETBUTTON,(WPARAM)i,(LPARAM)this->m_pRmBtInfo);
ReadProcessMemory(m_hProcess,this->m_pRmBtInfo,&temp,sizeof(TBBUTTON),NULL);
if(!IS_INTRESOURCE(temp.iString)){
ReadProcessMemory(m_hProcess,(LPVOID)(DWORD)(temp.iString),this->m_pLmBtInfo->var.szText,MAX_PATH*sizeof(WCHAR),NULL);
this->m_pLmBtInfo->IsUsingString=1;
}else{
this->m_pLmBtInfo->var.index=temp.iString;
this->m_pLmBtInfo->IsUsingString=0;
}
#ifdef _WIN64
CopyMemory(this->m_pLmBtInfo->bReserved,temp.bReserved,sizeof(BYTE)*6);//6是硬编码
#elif defined(_WIN32)
CopyMemory(this->m_pLmBtInfo->bReserved,temp.bReserved,sizeof(BYTE)*2);// 2是硬编码
#endif
this->m_pLmBtInfo->dwData=temp.dwData;
this->m_pLmBtInfo->fsState=temp.fsState;
this->m_pLmBtInfo->fsStyle=temp.fsStyle;
this->m_pLmBtInfo->iBitmap=temp.iBitmap;
this->m_pLmBtInfo->idCommand=temp.idCommand;
this->m_pLmBtInfo=(LPMYTBBUTTON)((ULONG)this->m_pLmBtInfo+sizeof(MYTBBUTTON));
}
VirtualFreeEx(m_hProcess,this->m_pRmBtInfo,0,MEM_RELEASE);
CloseHandle(m_hProcess);
this->m_pLmBtInfo=pFirstAddress;
this->m_index=0;
return TRUE;
}__finally{
}
this->ErrorInitialize();
return FALSE;
}
BOOL CTaskBarListEnum::Reset(){
return this->SetMembers();
}
CTaskBarListEnum::~CTaskBarListEnum(){
HeapFree(GetProcessHeap(),0,this->m_pLmBtInfo);
}
int CTaskBarListEnum::GetTaskBarCount(){
return this->m_icount;
}
HWND CTaskBarListEnum::GetTaskBarWndHandle(){
return this->m_htoolbarwnd;
}
DWORD CTaskBarListEnum::GetTaskListProcessID(){
return this->m_pid;
}
BOOL CTaskBarListEnum::IndexOf(__in int index,__out LPMYTBBUTTON lpBufInfo){
if(!lpBufInfo) return FALSE;
ZeroMemory(lpBufInfo,sizeof(MYTBBUTTON));
if(index>this->m_icount || index<0) return FALSE;
CopyMemory(lpBufInfo,&(this->m_pLmBtInfo[index]),sizeof(MYTBBUTTON));
return TRUE;
}
BOOL CTaskBarListEnum::Next(__out LPMYTBBUTTON lpBufInfo,__out_opt int* pcurIndex){
if(!lpBufInfo) return FALSE;
ZeroMemory(lpBufInfo,sizeof(MYTBBUTTON));
if(this->m_index<0 || this->m_index>= this->m_icount) return FALSE;
CopyMemory(lpBufInfo,&(this->m_pLmBtInfo[this->m_index]),sizeof(MYTBBUTTON));
if(pcurIndex) *pcurIndex=this->m_index;
this->m_index++;
return TRUE;
}