Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
1-50024
123456
2002-05-01 15:40
2002.05.16
Графика


3-49894
KAA
2002-04-17 19:01
2002.05.16
2000 Какая разница в производительности?


3-49817
VAleksey
2002-04-18 09:24
2002.05.16
Database1.DataSets


1-49958
cranium
2002-05-04 19:27
2002.05.16
TreeView редактирование названия узла


7-50143
Coalycat
2002-02-20 13:26
2002.05.16
преобразование данных





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский