Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Издевательства над System Tray

Оформил: DeeCo

Тема сегодняшнего издевательства - System Tray ;)). Попробуем задизейблить его! Находим окно отвечающее за таскбар и делаем ему Hide. Главное - это знать класс окна, которое ищем, он естественно нигде не описан, но я его случайно узнал! ;-).

В дельфи это выглялит так:

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 = $0001;
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

Ну, теперь уже лучше? ;)).

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay