| Visual C++ / FAQ Part 4 | |||||
|
|
|||||
|
С помощью Win32 API это можно сделать следующими способами: 1) Создать окно не имеющее владельца (unowned), указав расширенный стиль WS_EX_TOOLWINDOW. Недостаток: данный способ изменит вид заголовка окна. 2) С помощью интерфейса ITaskbarList. MSDN: The ITaskbarList interface is used to control the taskbar.
It allows you to dynamically add items to the taskbar,
remove items from the taskbar, and activate items on the taskbar.
Пример использования:
#include <windows.h>
#include <tchar.h>
#include <shobjidl.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR IpszCmdParam,int nCmdShow)
{
//инициализируем библиотеку COM
CoInitialize(0);
//регестрируем класс окна
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon (NULL,IDI_WARNING);
WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+11);
WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
WndClass.lpszClassName = _T("ITaskBarList");
if(!RegisterClass(&WndClass))
return 0;
//создаём окно
HWND hWnd = CreateWindow(WndClass.lpszClassName, _T("ITaskBarList"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
GetDesktopWindow(), NULL,
hInstance, NULL);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
::CoUninitialize();
return (int)Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
//обработчик кнопки delete меню окна
if(LOWORD(wParam)==IDM_DELETETAB)
{
ITaskbarList* pTaskbarList;
//создаём объект
HRESULT hRes=::CoCreateInstance(CLSID_TaskbarList,NULL,
CLSCTX_INPROC_SERVER,IID_ITaskbarList,(LPVOID*)&pTaskbarList);
if(hRes==S_OK)
//инициализируем объект
if(pTaskbarList->HrInit()==S_OK)
//удаляем кнопку. Здесь идентификатором кнопки является хендл окна-владельца
if(pTaskbarList->DeleteTab(hWnd)!=S_OK)
break;
::MessageBox(hWnd,_T("Ошибка удаления"),0,0);
}
break;
case WM_DESTROY:
::PostQuitMessage(0);
break;
}
return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
}
///////////фаил ресурсов//////////////////////////////////////////////////////
#define IDR_MENU1 101
#define IDM_DELETETAB 40001
//
// Menu
//
IDR_MENU1 MENU
BEGIN
POPUP "menu"
BEGIN
MENUITEM "deletetab", 40001
END
END
Недостаток: при перезапуске эксплорера кнопка вернётся на таскбар.
3) Пожалуй самый верный способ скрытия кнопки, при котором окно приложения не изменит вид: MSDN: As an alternative, you can create a hidden window
and make this hidden window the owner of your visible window.
То есть необходимо создать скрытое unowned окно,
которое будет владельцем для остальных окон приложения.
Это вытекает из того, что кнопка на TaskBar'е соответствует только видимому unowned окну приложения. Недостаток: необходимость дополнительного окна. CONSOLE_SCREEN_BUFFER_INFO bi; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), bi); // bi.dwCursorPosition - кооpдинаты куpсоpа Можно использовать функцию ScrollConsoleScreenBuffer или следующий код: COORD c; c.X = 0; c.Y = 0; CONSOLE_SCREEN_BUFFER_INFO bi; DWORD written; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), bi); FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ' ', bi.dwSize.X*bi.dwSize.Y, c, written); FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGRUND_BLUE /*цвет*/, bi.dwSize.X*bi.dwSize.Y, c,written);
//Очищает корзину на указанном диске
SHSTDAPI SHEmptyRecycleBin(
HWND hwnd,
LPCTSTR pszRootPath,
DWORD dwFlags);
//Получает размер и количество элементов в корзине
SHSTDAPI SHQueryRecycleBin(
LPCTSTR pszRootPath,
LPSHQUERYRBINFO pSHQueryRBInfo);
Для Windows 9x используйте CreateToolhelp32Snapsot/ Process32First(Process32Next)/ Thread32First(Thread32Next). Для WinNT NTQuerySystemInformation. А можно так: получаете список окон в системе (каким угодно способом, если нужны только процессы - можно ограничиться top-level), далее - GetWindowTreadProcessID - получаете ID процесса (и нити). OpenProcess - дает handle процесса. Посмотрите функции: BuildCommDCB BuildCommDCBAndTimeouts ClearCommBreak ClearCommError CommConfigDialog EscapeCommFunction GetCommConfig GetCommMask GetCommModemStatus GetCommProperties GetCommState GetCommTimeouts GetDefaultCommConfig PurgeComm SetCommBreak SetCommConfig SetCommMask SetCommState SetCommTimeouts SetDefaultCommConfig SetupComm TransmitCommChar WaitCommEvent 1. Сделать файл system.ini больше, чем 64К. Вешается при загрузке. 2. Вызвать код: cli jmp $ GetModuleHandle(NULL) ; PID - уникальный идентификатор объекта ядра - процесса Inst - (упрощенно) указатель на область памяти, куда загружен экземпляр модуля (экзешника, dll-ки) SystemParametrsInfo(SPI_SETDESKWALLPAPER,0,'обои.bmp',SPIF_UPDATEINIFILE); |
|||||
|