Shell_NotifyIcon的功能描述:This function sends a message to the system to add, modify, or delete an icon from the taskbar status area. 看上去应该是可以的,网上也有说有不使用Shell_NotifyIcon的实现~只是没具体
TCHAR const c_szTrayClass[] = TEXT(WNDCLASS_TRAYNOTIFY); BOOL AllowSetForegroundWindow(DWORD dwProcessId);STDAPI_(BOOL) Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA lpData) { HWND hwndTray; SetLastError(0); // Clean any previous last error (code to help catch another bug) hwndTray = FindWindow(c_szTrayClass, NULL); if (hwndTray) { COPYDATASTRUCT cds; TRAYNOTIFYDATA tnd = {0}; DWORD_PTR dwRes = FALSE; DWORD dwValidFlags; int cbSize = lpData->cbSize; if (cbSize == SIZEOF(NOTIFYICONDATA)) { dwValidFlags = NIF_VALID; } else { // This will RIP if the app was stupid and passed stack // garbage as cbSize. Apps got away with this on Win95 // and NT4 because those versions didn't validate cbSize. // So if we see a strange cbSize, assume it's the V1 size. RIP(cbSize == NOTIFYICONDATA_V1_SIZE); cbSize = NOTIFYICONDATA_V1_SIZE; dwValidFlags = NIF_VALID_V1; }#ifdef _WIN64 // Thunking NOTIFYICONDATA to NOTIFYICONDATA32 is annoying // on Win64 due to variations in the size of HWND and HICON // We have to copy each field individually. tnd.nid.dwWnd = PtrToUlong(lpData->hWnd); tnd.nid.uID = lpData->uID; tnd.nid.uFlags = lpData->uFlags; tnd.nid.uCallbackMessage = lpData->uCallbackMessage; tnd.nid.dwIcon = PtrToUlong(lpData->hIcon); // The rest of the fields don't change size between Win32 and // Win64, so just block copy them over // Toss in an assertion to make sure COMPILETIME_ASSERT( sizeof(NOTIFYICONDATA ) - FIELD_OFFSET(NOTIFYICONDATA , szTip) == sizeof(NOTIFYICONDATA32) - FIELD_OFFSET(NOTIFYICONDATA32, szTip)); memcpy(&tnd.nid.szTip, &lpData->szTip, cbSize - FIELD_OFFSET(NOTIFYICONDATA, szTip));#else // On Win32, the two structures are the same COMPILETIME_ASSERT(sizeof(NOTIFYICONDATA) == sizeof(NOTIFYICONDATA32)); memcpy(&tnd.nid, lpData, cbSize); #endif tnd.nid.cbSize = sizeof(NOTIFYICONDATA32); // This will RIP if the app was really stupid and passed stack // garbage as uFlags. RIP(!(lpData->uFlags & ~dwValidFlags)); tnd.nid.uFlags &= dwValidFlags; if (dwMessage == NIM_SETFOCUS) { DWORD dwProcId; GetWindowThreadProcessId(hwndTray, &dwProcId); AllowSetForegroundWindow(dwProcId); }
Shell_NotifyIcon的功能描述:This function sends a message to the system to add, modify, or delete an icon from the taskbar status area. 看上去应该是可以的,网上也有说有不使用Shell_NotifyIcon的实现~只是没具体
系统托盘实际上就是一个ToolBar,所以是可以用消息来控制的,就是TB_开头的消息,不过这样添加的图标不会给你的程序发消息。
TCHAR const c_szTrayClass[] = TEXT(WNDCLASS_TRAYNOTIFY);
BOOL AllowSetForegroundWindow(DWORD dwProcessId);STDAPI_(BOOL) Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA lpData)
{
HWND hwndTray; SetLastError(0); // Clean any previous last error (code to help catch another bug) hwndTray = FindWindow(c_szTrayClass, NULL);
if (hwndTray)
{
COPYDATASTRUCT cds;
TRAYNOTIFYDATA tnd = {0};
DWORD_PTR dwRes = FALSE;
DWORD dwValidFlags; int cbSize = lpData->cbSize; if (cbSize == SIZEOF(NOTIFYICONDATA))
{
dwValidFlags = NIF_VALID;
}
else
{
// This will RIP if the app was stupid and passed stack
// garbage as cbSize. Apps got away with this on Win95
// and NT4 because those versions didn't validate cbSize.
// So if we see a strange cbSize, assume it's the V1 size.
RIP(cbSize == NOTIFYICONDATA_V1_SIZE);
cbSize = NOTIFYICONDATA_V1_SIZE; dwValidFlags = NIF_VALID_V1;
}#ifdef _WIN64
// Thunking NOTIFYICONDATA to NOTIFYICONDATA32 is annoying
// on Win64 due to variations in the size of HWND and HICON
// We have to copy each field individually.
tnd.nid.dwWnd = PtrToUlong(lpData->hWnd);
tnd.nid.uID = lpData->uID;
tnd.nid.uFlags = lpData->uFlags;
tnd.nid.uCallbackMessage = lpData->uCallbackMessage;
tnd.nid.dwIcon = PtrToUlong(lpData->hIcon); // The rest of the fields don't change size between Win32 and
// Win64, so just block copy them over // Toss in an assertion to make sure
COMPILETIME_ASSERT(
sizeof(NOTIFYICONDATA ) - FIELD_OFFSET(NOTIFYICONDATA , szTip) ==
sizeof(NOTIFYICONDATA32) - FIELD_OFFSET(NOTIFYICONDATA32, szTip)); memcpy(&tnd.nid.szTip, &lpData->szTip, cbSize - FIELD_OFFSET(NOTIFYICONDATA, szTip));#else
// On Win32, the two structures are the same
COMPILETIME_ASSERT(sizeof(NOTIFYICONDATA) == sizeof(NOTIFYICONDATA32));
memcpy(&tnd.nid, lpData, cbSize);
#endif tnd.nid.cbSize = sizeof(NOTIFYICONDATA32); // This will RIP if the app was really stupid and passed stack
// garbage as uFlags.
RIP(!(lpData->uFlags & ~dwValidFlags));
tnd.nid.uFlags &= dwValidFlags; if (dwMessage == NIM_SETFOCUS)
{
DWORD dwProcId;
GetWindowThreadProcessId(hwndTray, &dwProcId);
AllowSetForegroundWindow(dwProcId);
}
tnd.dwSignature = NI_SIGNATURE;
tnd.dwMessage = dwMessage; cds.dwData = TCDM_NOTIFY;
cds.cbData = SIZEOF(tnd);
cds.lpData = &tnd; if (SendMessageTimeout(hwndTray, WM_COPYDATA, (WPARAM)lpData->hWnd, (LPARAM)&cds,
SMTO_ABORTIFHUNG | SMTO_BLOCK, 4000, &dwRes))
{
return (BOOL) dwRes;
}
} return FALSE;
}以上代码来自private\shell\shell32\shlnot.c,有这些文件的可以自己去看,都在shell32目录里面。
{
PCOPYDATASTRUCT pCDS = (PCOPYDATASTRUCT) lParam;
PNOTIFYICONDATA pNID = NULL;
NOTIFYCOPYSTRUCT *pNCS = NULL;
BOOL bRecalc = TRUE; ASSERT(pCDS);
ASSERT((sizeof(NOTIFYICONDATA) == pCDS->cbData) || (sizeof(NOTIFYCOPYSTRUCT) == pCDS->cbData));
ASSERT(pCDS->lpData); if ((pCDS->dwData >= NIM_ADD) && (pCDS->dwData <= NIM_DELETE))
{
pNID = (PNOTIFYICONDATA) pCDS->lpData;
}
else if ((pCDS->dwData >= NIM_BUBBLE_ADD) && (pCDS->dwData <= NIM_BUBBLE_DELETE))
{
pNCS = (NOTIFYCOPYSTRUCT *) pCDS->lpData;
}
else
{
return FALSE;
} switch (pCDS->dwData)
{
case NIM_ADD:
{
if ((UINT) -1 != FindNotify(m_hwndTaskBar, pNID))
{
return FALSE;
} if (!InsertNotify(m_hwndTaskBar, pNID))
{
return FALSE;
}
bRecalc = FALSE; // insert calls recalc directly break;
} case NIM_MODIFY:
{
int nIcon = FindNotify(m_hwndTaskBar, pNID);
if (nIcon < 0)
{
return FALSE;
} if (!ModifyNotify(m_hwndTaskBar, pNID, nIcon))
{
return FALSE;
}
bRecalc = FALSE;
break;
} case NIM_DELETE:
{
int nIcon = FindNotify(m_hwndTaskBar, pNID);
if (nIcon < 0)
{
return FALSE;
}
DeleteItem(m_hwndTaskBar, nIcon);
bRecalc = FALSE; // delete calls recalc directly break;
} case NIM_BUBBLE_MODIFY:
bRecalc = FALSE;
case NIM_BUBBLE_ADD:
case NIM_BUBBLE_DELETE:
if (!HandleNimBubbleMessage(pNCS, pCDS->dwData))
{
return FALSE;
}
break; default:
return FALSE;
}上面的代码也是MS实现的,我是从这里知道怎么做的