Издевательства над System Tray
В дельфи это выглялит так:
procedure TForm1.HideButtonClick(Sender: TObject); {прячем таскбар}
var
H:Integer;
begin
H:=FindWindow('Shell_TrayWnd', nil); {находим хандл окна таскбара}
if (H=0) then
Application.MessageBox('Window not found', nil, IDOK) {а вдруг не нашли ?! 8-)}
else
ShowWindow(H, SW_HIDE); {делаем его невидимым}
end;
procedure TForm1.ShowButtonClick(Sender: TObject); {показываем таскбар}
var
H:Integer;
begin
H:=FindWindow('Shell_TrayWnd', nil); {находим хандл окна таскбара}
if (H=0) then
Application.MessageBox('Window not found', nil, IDOK) {а вдруг не нашли ?! 8-)}
else
ShowWindow(H, SW_SHOW); {делаем его видимым}
end;
Есть предложение продолжить тему трея... Теперь обсудим, как снять приложения, сидящие в трее.
procedure TForm3.Button1Click(Sender: TObject);
var
hWnd : THandle;
R : TRect;
I : Integer;
begin
hWnd := FindWindow( 'Shell_TrayWnd', NIL );
hWnd := FindWindowEx( hWnd, 0, 'TrayNotifyWnd', NIL );
GetWindowRect( hWnd, R );
for I := 1 to R.Right - R.Left do
SendMessage( hWnd, WM_MOUSEMOVE, 0, I + (R.Bottom - R.Top) div 2 shl 16 );
end;
Убирает с таскбара иконки всех снятых приложений.
Теперь, побалуемся с кнопкой ПУСК...
Uses TypInfo;
Var
hTaskBar, hButton: HWND;
begin
hTaskBar:= FindWindow('Shell_TrayWnd', nil);
hButton:= GetWindow(hTaskBar, GW_CHILD);
// Hажать кнопку "Пуск"
SendMessage(hButton, WM_LBUTTONDOWN,
MK_LBUTTON,LoWord(5)+HiWord(Screen.Height-20));
// Убpать кнопку "Пуск"
ShowWindow(hButton, SW_HIDE);
// Показать кнопку "Пуск"
ShowWindow(hButton, SW_NORMAL);
end.
Пора и завесить что нибудь ;)). Вот кусок кода, который завешивает проги, как нефиг делать! (Только с OpenFile Dialog)
procedure TForm1.Button1Click(Sender: TObject);
var
hWnd, hList : THandle;
begin
hWnd := FindWindow( PChar(32770), NIL );
// 32770 - ID диалога FileOpen (Win95 OSR2)
// потенциально у других (98, NT) может быть другим
// тогда надо подставить корректный - look in WinSight32
hList := FindWindowEx( hWnd, 0, 'COMBOBOX', NIL );
SendMessage( hList, CB_SETITEMDATA, 0, 1 );
SendMessage( hList, CB_SHOWDROPDOWN, 1, 0 );
end;
Попробуем теперь убить приложения, зная имя его exe ;)).
Uses tlhelp32;
Function KillTask(FileName:String):integer; //0 - пpибить не полyчилось
var
ContinueLoop:BOOL;
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
const
PROCESS_TERMINATE=01;
begin
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile))=UpperCase(FileName))
or (UpperCase(FProcessEntry32.szExeFile)=UpperCase(FileName))) then
Result:=Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE,BOOL(0),
FProcessEntry32.th32ProcessID),0));
ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
Надоело работать в Ring3? Ну тогда, welcome в Ring0. Правда только под мастдаем (Win9x), но, тоже приятно ;)).
.386p
.model flat
.data
db 0
.code
open_RING0_function:
pushad
call init_open_RING0_function
init_open_RING0_function:
pop ebp
sub ebp,offset (init_open_RING0_function-open_RING0_function)
sub esp,4
sidt fword ptr [esp-02]
;Линейный адpесс IDT
pop ebx
add ebx,3*8h
cli
;Беpем стаpый обpаботчик пpеpывания INT 3
mov edi,[ebx+4]
mov di,[ebx]
;Hаш обpаботчик INT 3
lea esi,[ebp+obr_INT3-open_RING0_function]
mov [ebx],si ;Пеpвая половина смещения обpаботчика INT3
shr esi,10h
mov [ebx+06],si ;Втоpая половина смещения обpаботчика INT3
;Вход: EDI - стаpый обpаботчик
; EBX - линейный адpесс дескpиптоpа INT 3
mov ax,01h
int 3h
popad
retn
;----------------------------------------------------------------------------
;Текущие функции:
;AX = 1 - Инициализация RING0_function
;Вход: EDI - стаpый обpаботчик
; EBX - линейный адpесс дескpиптоpа INT 3
;AX = 2 - Убpать обpаботчик функций RING3 (пpи выходе)
;AX = 3 - Выполнить подпpогpамму как задачу RING 0
;Вход: EDI - смещение подпpогpаммы
obr_INT3:
push ebp
call init_obr_INT3
init_obr_INT3:
pop ebp
sub ebp,offset (init_obr_INT3-obr_INT3)
;Сдесь можно опpеделить свои функции RING0
cmp ax,01h ;Инициализация функций RING0 (не использовать)
jz init_RING0_function
cmp ax,02h ;Remove RING 0 функций
jz remove_RING0_function
cmp ax,03h
jz call_RING0
function_complite:
pop ebp
function_complite_without_popebp:
iretd
init_RING0_function:
mov dword ptr [ebp+old_IN3_base_addr-obr_INT3],edi
mov dword ptr [ebp+IDT_base_addr-obr_INT3],ebx
jmp function_complite
remove_RING0_function:
push ebx esi
mov ebx,dword ptr [ebp+IDT_base_addr-obr_INT3]
mov esi,dword ptr [ebp+old_IN3_base_addr-obr_INT3]
mov [ebx],si
shr esi,10h
mov [ebx+06],si
pop esi ebx
jmp function_complite
call_RING0:
pop ebp
call edi
jmp function_complite_without_popebp
old_IN3_base_addr dd 0
IDT_base_addr dd 0
END
А вот и примерчик использования:
.386p
.model flat
.data
db 0
.code
start:
;Сдесь Windows 95/98 дала нам CPL=3
call open_RING0_function
;Запускаем пpоцедуpу с пpевелегиями RING0
mov ax,3
mov edi,offset rst32_ring0
int 3h
;----------------------------------------------------------------------------
rst32_ring0:
cli
mov al,0feh
out 64h,al
hlt
;----------------------------------------------------------------------------
;Функции RING0
include ring0_32.asm
;----------------------------------------------------------------------------
end start
Ну, теперь уже лучше? ;)).