Форум: "WinAPI";
Текущий архив: 2002.05.16;
Скачать: [xml.tar.bz2];
ВнизРабота с треем. Найти похожие ветки
← →
writer (2002-03-12 15:47) [0]Есть необходимость установки программы без эксплорера, на машине нужна только одна программа кроме винды :) . Но возник вопрос как получить список программ свернутых в трей (значок раскладки клавы, иконка запущенного принтера и т.д. ). Насколько я понял это работа с Shell`ом винды, но как это делать пока не догнал. Если кто знает, подскажите.
Заранее благодарен.
← →
Nikolay (2002-03-12 15:58) [1]просто надо получить список всех процессов
CreateWinHelp32SnapShot
FirstProcess32
NextProcess32
← →
Writer (2002-03-12 16:15) [2]Спасибо, я наверное неправильно выразился, идея в написании своего трея, с обработкой popup програм свернутых в него....
← →
paul_shmakov (2002-03-12 18:37) [3]нужно поставить глобальный хук, перехватывающий сообщения WM_COPYDATA, посланные окну с классом "Shell_TrayWnd". в качестве данных в сообщении будет структура NOTIFYICONDATA.
ну а как с ней работать, я думаю, понятно
← →
Raptor (2002-03-12 22:13) [4]2 paul_shmakov
Интересно, кто это будет эти сообщения посылать если эксплорера и трея вместе с ним нету? :-)
Прочитайте еще раз вопрос.
2 writer
Здесь придется самому написать аналог майкрософтовского трея.
← →
Writer (2002-03-12 22:46) [5]Вот в этом аналоге у меня и стал вопрос... я пока не знаю с какой стороны к нему подступиться...
← →
Raptor (2002-03-13 00:02) [6]Как говорится, задержка за малым... ;-))
MS, вроде, кодом делиться не собирается, так что сам как-то пробуй. Может что получится.
← →
Nikolay (2002-03-13 00:03) [7]Получаешь хандл трея , по нему хандл всех его чилдов, дальше дело техники...
← →
Dimaond Cat (2002-03-13 01:53) [8]2 nikolay у трея в чилдах только таймер сидит а все остальное не более чем рисунки
2 Raptor вроде как америкосовское правительство в судебном порядке обязало мелкософт раскрыть коды, так что скоро можно будет повесилиться
← →
paul_shmakov (2002-03-13 03:21) [9]2 Raptor:
хмм.. да, облажался я. тогда можно попробовать создать свое окно с классом "Shell_TrayWnd". авось в него будут сообщения WM_COPYDATA посылаться...
← →
Suntechnic (2002-03-13 04:06) [10]>paul_shmakov © (13.03.02 03:21)
>авось в него будут сообщения WM_COPYDATA посылаться...
:))) Что есть "авось"? Если это название разрабатываемой оболочки, тогда именно так и будет происходить... :)))
← →
paul_shmakov (2002-03-13 15:37) [11]2 Suntechnic:
что есть "авось"? согласен, на авось лучше не полагаться. тогда проверим догадку.
можно написать приложение, но это делать лениво. куда проще посмотреть дизассемблером,
как функция Shell_NotifyIcon работает.
итак, функция находится в shell32.dll, просматривая таблицу экспорта которой, видно,
что экспортируется целых три символа: Shell_NotifyIcon, Shell_NotifyIconA и
Shell_NotifyIconW.
последняя из них - это unicode версия (принимает unicode версию структуры NOTIFYICONDATAW).
первые две: 1) ссылаются на самом деле на один и тот же код, 2) код всего лишь конвертирует
свой параметр в unicode (MultiByteToWideChar) и вызывает Shell_NotifyIconW.
теперь самое интересное - код Shell_NotifyIconW (внизу см. аналог на паскале).
.77CB9701| push ebp
.77CB9702: mov ebp, esp
.77CB9704: sub esp, 0ACh ; место под локальные переменные в стеке
.77CB970A: push esi
.77CB970B: push edi
.77CB970C: push 000
.77CB970E: call SetLastError ; ошибок пока не было
.77CB9714: push 000 ; заголовок окна не задан
.77CB9716: push 077CC8DE0h ; класс окна. строка "Shell_TrayWnd" в unicode
.77CB971B: call FindWindowW
.77CB9721: test eax, eax
.77CB9723: jne .077CB972Fh
.77CB9725: xor eax, eax ; окно с таким классом не найдено
.77CB9727: pop edi ; возвращаем false
.77CB9728: pop esi
.77CB9729: mov esp, ebp
.77CB972B: pop ebp
.77CB972C: retn 08
.77CB972F: lea edi, [ebp-0A4h] ; var LocalNID: NOTIFYICONDATAW
.77CB9735: mov edx, [ebp+0Ch]
.77CB9738: mov esi, edx ; адрес структуры NOTIFYICONDATA
.77CB973A: mov ecx, 26h ; sizeof(NOTIFYICONDATAW) / 4 == 26h
.77CB973F: repe movsd ; копирование NOTIFYICONDATA в LocalNID
.77CB9741: and dword ptr [ebp-98h], 007 ; LocalNID.uFlags = LocalNID.uFlags and 7;
.77CB9748: mov ecx, [ebp+08] ; команда NIM_ADD или NIM_DELETE или NIM_MODIFY
.77CB974B: lea esi, [ebp-0ACh]
.77CB9751: mov [ebp-A8h], ecx ; запись команды перед структурой LocalNID
.77CB9757: mov [ebp-04], esi ; COPYDATASTRUCT.lpData = адрес магического значения
.77CB975A: mov dword ptr [ebp-0ACh], 034753423h ; магическое значение
.77CB9764: mov dword ptr [ebp-0Ch], 1 ; COPYDATASTRUCT.dwData = 1
.77CB976B: mov dword ptr [ebp-08], 0A0h ; COPYDATASTRUCT.cbData = A0
.77CB9772: lea ecx,[ebp-0Ch]
.77CB9775: push ecx ; указатель на структуру COPYDATASTRUCT
.77CB9776: push dword ptr [edx+4] ; HWND окна, посылающего сообщение
.77CB9779: push 4Ah ; WM_COPYDATA
.77CB977B: push eax ; HWND ранее найденного окна
.77CB977C: call SendMessageW
.77CB9782: jmps .077CB9727h ; на выход. true возвращается,
; если SendMessage сработала удачно
← →
paul_shmakov (2002-03-13 15:38) [12]или вот аналог на паскале
const
MagicNIDMessageValue = $34753423;
type
TNIDMessage = packed record
Magic: DWord; // всегда равно $34753423
Message: DWord; // NIM_ADD, NIM_MODIFY или NIM_DELETE
NID: TNotifyIconDataW;
end;
function Shell_NotifyIconW(dwMessage: DWORD; lpData: PNotifyIconDataW): BOOL; stdcall;
var
TrayWnd: HWND;
NIDMessage: TNIDMessage;
Cds: TCopyDataStruct;
begin
Result := false;
SetLastError(0);
TrayWnd := FindWindow("Shell_TrayWnd", nil);
if TrayWnd <> 0 then
begin
CopyMemory(@NIDMessage.NID, lpData, sizeof(TNotifyIconDataW));
NIDMessage.NID.uFlags := NIDMessage.NID.uFlags and (NIF_MESSAGE or NIF_ICON or NIF_TIP);
NIDMessage.Message := dwMessage;
Cds.lpData := Pointer(@NIDMessage);
NIDMessage.Magic := MagicNIDMessageValue;
Cds.dwData := 1;
Cds.cbData := SizeOf(TNIDMessage);
Result := SendMessage(TrayWnd, WM_COPYDATA, WPARAM(NIDMessage.NID.hWnd), LPARAM(@Cds));
end;
end;
т.о. Shell_NotifyIconW просто ищет окно с классом "Shell_TrayWnd" и посылает в него
сообщение WM_COPYDATA. в качестве данных выступает простая структура TNIDMessage.
возвращаясь к топику: если создать свое окно с классом "Shell_TrayWnd" и обрабатывать
входящие сообщения WM_COPYDATA, то можно написать полный аналог system tray!
и, заметьте, очень просто.
удачи!
p.s. если кто напишет и проверит - большое спасибо.
← →
paul_shmakov (2002-03-15 06:16) [13]ну и для полноты картины :)
в относительно новых версиях shell32.dll правилом хорошего тона является следующее соглашение: если перезапускается explorer.exe (d случае краха или еще по какой причине), то он должен оповестить об этом все работающие приложения, чтобы они, если требуется, заново добавили свои иконки в трей.
делает он это следующим образом:
procedure InformEveryoneAboutMyCrash;
var
WM_TASKBARCREATED: UINT;
begin
WM_TASKBARCREATED := RegisterWindowMessage("TaskbarCreated");
PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
end;
все остальные приложения соответственно должны обрабатывать сообщение, номер которого возвращает вызов RegisterWindowMessage("TaskbarCreated"), и заново добавлять свою иконку в трей.
2 writer:
я думаю, Вам лучше тоже добавить процедуру InformEveryoneAboutMyCrash в свой проект и вызывать ее по мере надобности :)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2002.05.16;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.005 c