Показаны сообщения с ярлыком API. Показать все сообщения
Показаны сообщения с ярлыком API. Показать все сообщения

понедельник, 20 октября 2008 г.

Кусочки: Как, зная Handle окна программы, определить имя EXE

Как, зная Handle окна программы, определить имя EXE

// Для начала определимкакому процессу принадлежит окно:

 
Var pProcID : ^DWORD;
begin
 GetMem (pProcID, SizeOf (DWORD));
 GetWindowThreadProcessId (WinHandle, pProcID);
end;

 
// а после этого используйте  TProcessEntry32 примерно так:
 
function GetExeNameByProcID (ProcID : DWord) : String;
var
 ContinueLoop : BOOL;
 FSnapshotHandle : THandle;
 FProcessEntry32 : TProcessEntry32;
begin
 FSnapshotHandle := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
 
 FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
 
 ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
 
 Result := '';
 while (Integer (ContinueLoop) <> 0) and (Result='') do
 begin
  if FProcessEntry32.th32ProcessID = ProcID then
  Result := FProcessEntry32.szExeFile;
  ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
 end;
end;

 
// Не забудьте в uses добавить Tlhelp32

Кусочки: Получение информации о выполняющихся процессах (Win2000)

Для NT-платформы (Windows NT/2000) программный код может выглядеть следующим образом: 
function GetProcessesWinNT(var Proc: TProcArray):Integer;
var
Num: Integer;
LP: Array[0..$3FFF-1] of Dword; // заведомо большой массив
CB: DWord;
CBNeeded:DWord;
ProcHndl: THandle;
ModHand: HModule;
ModName: array [0..MAX_PATH] of Char;
I: Integer;
begin
  EnumProcesses(@LP,CB,CBNeeded);
  Num:= CBNeeded div SizeOf(DWORD);
  SetLength(Proc,Num);
 For I:=0 to Num-1 do
  begin
  ProcHndl:=
  OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,LP[I]);
  If GetModuleFileNameEx(ProcHndl,ModHand,ModName,SizeOf(ModName))> 0 then
  Proc[I]:=ModName else Proc[I]:='Unknown';
  end;
IF ProcHndl > 0 then CloseHandle(ProcHndl);
Result:=Num;
end;


Здесь уже используется модуль PSAPI, который необходимо включить в раздел USES. Кому интересно разобраться в деталях данного кода отсылаю к справке по API. 

Замечу, что под управлением WINDOWS 2000, в списке процессов я наблюдал иногда "абракадабру" по путям некоторых процессов. Предлагаю в этом вопросе читателю разобраться самостоятельно, а у меня пока до этого не дошли руки. Тем не менее, считаю, что данная статья может послужить хорошим подспорьем, для всех интересующихся данным вопросом. 

В конце приведу код для определения платформы компьютера, поскольку он может понадобиться при реализации кода для вывода списка процессов. Оставляю его без комментариев. 
function GetPlatform: String;
var VI: TOSVersionInfo;
begin
VI.dwOSVersionInfoSize:=SizeOf(VI);
GetVersionEx(VI);
Case VI.dwPlatformId of
Ver_Platform_Win32s: Result:= 'Win32s';
Ver_Platform_Win32_Windows: Result:='Win95';
Ver_Platform_Win32_NT: Result:='WinNT'
else Result:='Unknown Platform'; 
end;
end;

Кусочки: Получение информации о выполняющихся процессах

Получить информацию о выполняющихся в данный момент на компьютере процессах можно на основе функций API. Для разных платформ эти функции отличаются, как и подключаемые для этих целей модули.

В Windows 95/98/2000/xp/nt код может выглядеть следующим образом: 

function GetProcessesWin95(var Proc: TProcArray):Integer;

var
FSnap: THandle;
PE: TProcessEntry32;
PPE: PProcessEntry32;
I: Integer;
begin
If FSnap > 0 then CloseHandle(FSnap);
FSnap:=CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PE.dwSize:=SizeOf(PE);
I:=0;
SetLength(Proc,1000); // заведомо большой массив
If Process32First(FSnap,PE) then
  repeat
  New(PPE);
  PPE^:=PE;
  Proc[I]:=PPE.szExeFile;
  I:=I+1;
  until not Process32Next(FSnap, PE);
Result:=I;
end;


Для работы этого кода нужно подключить в разделе USES модуль TlHelp32 (Help Tool API 32). 

Функция возвращает число процессов и записывает их пути в массив-переменную Proc. Тип переменной Proc - обычный массив строк, который нужно описать в разделе описания типов: 

type TProcArray = Array of String;

Поясню основные моменты реализации кода. Строка 
 
FSnap:=CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);

означает получение "моментального снимка всех процессов". Точнее, в результате ее выполнения мы получаем дескриптор снимка. Функции Process32First и Process32Next позволяют "пробежаться" по всем процессам. О более детальной информации отсылаю читателя к справочной литературе об API.

суббота, 18 октября 2008 г.

Кусочки: Примерная защита Shareware приложения

После добавления следующего кода в программу, она запустится только один раз за время сессии Windows. Для повторного запуска программы необходимо будет перезагрузить Windows. 

procedure TForm1.FormShow(Sender : TObject); 

var atom : integer; 

CRLF : string; 
begin 

if 
GlobalFindAtom('THIS_IS_SOME_OBSCUREE_TEXT') = 0 then 
atom := GlobalAddAtom('THIS_IS_SOME_OBSCUREE_TEXT') 
else 
begin 
  CRLF := #10 + #13; 
  ShowMessage('This programm will start only once' + CRLF + 
  for next start reboot windows please, or...' + CRLF + 
  'REGISTER PROGRAM !!'); 
  Close; 
end; 
end; 

пятница, 17 октября 2008 г.

WinAPI: Полезности в Delphi. getasynckeystate

Итак, в статье я опишу несколько маленьких, но очень полезных вещей в дельфи.
Они могут пригодиться при написании больших проектов.

О.Отлавливаем нажатие на клавиши.
Как вы знаете нажатие на клавишу мыши можно отследить при события MouseDown. Нам же нужно отследить какая клавиша нажата и вывести ее на экран. Для этого существуют 3 процедуры (аналогичные мышке) это 

KeyPress – нажатие
KeyDown – только нажатие
KeyUp – отпускание клавиши 

Создай новое приложение. Помести на форму 1 Label, и создай обработчик KeyDown для формы.

У этого события есть параметр Key сюда нужно записывать ANSII код клавиши. Все коды можно посмотреть здесь 
http://www.realcoding.net/article/view/1857.
Так, а вот и обработчик:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key=51 then
Label1.Caption:='Ты нажал клавишу "3"';
end;

Теперь если жмакнешь по клавиши 3 появиться эта надпись.
Так вот. Думаю, ты понял, что отлавливать события нажатия на клавишу тут мы можем только у нашей формы или ее компонентов.

А если хочется и во всем Windows клавиши отлавливать.
Для этого существует API функция getasynckeystate в качестве параметра ей нужно указать виртуальный код клавиши, которую хотим отлавливать.
Вот список виртуальных кодов

vk_lbutton = $01;
vk_rbutton = $02;
vk_cancel = $03;
vk_mbutton = $04;
vk_back = $08;
vk_tab = $09;
vk_clear = $0c;
vk_return = $0d;
vk_shift = $10;
vk_control = $11;
vk_menu = $12;
vk_pause = $13;
vk_capital = $14;
vk_escape = $1b;
vk_space = $20;
vk_prior = $21;
vk_next = $22;
vk_end = $23;
vk_home = $24;
vk_left = $25;
vk_up = $26;
vk_right = $27;
vk_down = $28;
vk_select = $29;
vk_print = $2a;
vk_execute = $2b;
vk_snapshot = $2c; 
vk_insert = $2d;
vk_delete = $2e;
vk_help = $2f;
>> vk_a - vk_z такие же, как и их ascii-эквиваленты: 'a' - 'z' ($41 - $5A)<< >> vk_0 - vk_9 такие же, как и их ascii-эквиваленты: '0' - '9' ($30 - $39)}
vk_numpad0 = $60;
vk_numpad1 = $61;
vk_numpad2 = $62;
vk_numpad3 = $63;
vk_numpad4 = $64;
vk_numpad5 = $65;
vk_numpad6 = $66;
vk_numpad7 = $67;
vk_numpad8 = $68;
vk_numpad9 = $69;
vk_multiply = $6a;
vk_add = $6b;
vk_separator = $6c;
vk_subtract = $6d;
vk_decimal = $6e;
vk_divide = $6f;
vk_f1 = $70;
vk_f2 = $71;
vk_f3 = $72;
vk_f4 = $73;
vk_f5 = $74;
vk_f6 = $75;
vk_f7 = $76;
vk_f8 = $77;
vk_f9 = $78;
vk_f10 = $79;
vk_f11 = $7a;
vk_f12 = $7b;
vk_f13 = $7c;
vk_f14 = $7d;
vk_f15 = $7e;
vk_f16 = $7f;
vk_f17 = $80;
vk_f18 = $81;
vk_f19 = $82;
vk_f20 = $83;
vk_f21 = $84;
vk_f22 = $85;
vk_f23 = $86;
vk_f24 = $87;
vk_numlock = $90;
vk_scroll = $91;

Теперь кинь на форму таймер и установи интервал в 500 мс. Вот обработчик

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if getasynckeystate($1b)<>0 then
Label1.Caption:='Вы нажали «ESC»';
end;

Думаю тут все понятно. Теперь при наличии мозгов можно написать простенький клавиатурный шпион.

воскресенье, 12 октября 2008 г.

WinAPI: Perform. Отправка сообщений форме.

Очень часто в программе необходимо сделать перемещение окна за её поле. Или же если вы сделали скин к приложению, натянув на него рисунок и спрятав рамку окна. Сделать это можно так:

procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
const SC_DragMove = $F012; 
begin 
ReleaseCapture; 
perform(WM_SysCommand, SC_DragMove, 0); 
end;


Этот код применим ко всем визуальным компонентам Delphi. Он позволяет перемешать НЕ ОБЪЕКТ по форме, а форму в целом по рабочему столу. Ниже ещё один способ.

Данный метод описан в технической информации (TI) Borland и бывает полезен если ваша форма не имеет области заголовка (синей полосы вверху). У такой формы свойство BorderStyle установлено равным bsNone. Самый просотой способ заключается в том, чтобы заставить Windows думать, что произошло нажатие в области заголовка окна, когда происходит нажатие в клиентской области. Это можно сделать, добавив собственный обработчик события wm_NCHitTest. Откройте модуль вашей формы и добавьте следующее описание в разделе private:

procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);


Процедура названа так в соответствии с соглашениями об именах в Windows, но вы можете изменить название, если вам захочется. Теперь в разделе implementation опишем код процедуры.

procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);
begin
inherited;
//вызываем стандартный обработчик 
if M.Result = htClient then 
M.Result := htCaption;
end;



Обратите внимание, что в начале вызывается стандартный обработчик. Кроме перемещения формы, добавьте возможность завершения программы в виде кнопки или пункта меню, так как пользователь не сможет закрыть ее при помощи заголовка окна или системного меню.

вторник, 23 сентября 2008 г.

WinAPI: Enumwindows

Представьте, что вам надо свернуть все окна на рабочем столе, или передать всем запущеным программам и открытым окнам несколько сообщений... Или просто получить список всех запущеных программ и открытых окон. Как это сделать? Самый простой способ - использовать API Enumwindows, синтаксис которой представлен ниже.

function EnumWindows(EnumFunc: TFarProc, lParam: Longint): Bool;

Значит тепеть о том, чем собственно эта функция заниматся... Она перечисляет все окна на рабочем столе(видимые и невидимые, включая системный трэй), к каждому из которых применяется функция, имя которой указывается в первом параметре. Теперь давайте рассмотрим функцию, которая будет выполнять необходимые нам операции над перечисляемыми программами и окнами. Синтаксис таков:

function EnumWindowsProc(h:hwnd): Bool; stdcall;

Вот это минимальная необходимая фунция для работы с перечисляемыми окнами. Так как функция Enumwindows перечисляет handle всех окон и приложений, то главным и необходимым входящим параметром Enumwindowsproc будет handle получаемого объекта. (Хрень какую то пишу...). Ниже приведен кусок программы, которая сворачивает все возможные (видимые и невидимые, включая системный трэй) окна и программы в пуск. Не рекомендую так делать.

function enumwindowsproc(h:hwnd):bool; stdcall;
begin
closewindow(h);
enumwindowsproc:=true
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
enumwindows(@enumwindowsproc,0);
end;


Теперь посмотрим на главные особенности использования данной функции... Первое, не забудте, что в Enumwindows, на месте первого параметра вы указываете не описанную функцию, а адрес на нее (@). Второе, чтоб enumwindowsproc выполнялась ко всем окнам, необходимо в конце её тела сделать Callback, тоесть написать enumwindowsproc:=true. И третье, enumwindowsproc - просто стандартное название, изменить его можно на любое другое.:)

воскресенье, 21 сентября 2008 г.

WinAPI: Set/get windowtext

Set/get windowtext

Как можнодогадаться из названия данных API функций, речь пойдет о работе с заголовками различных окон и программ. С ними можно сделать что угодно. При том, используя API, работать можно с заголовками "чужих" окон и программ. Дот две функции, первая из которых служит для получения заголовка окна, а вторая для установления нового.

function GetWindowText(Wnd: HWnd; Str: PChar; MaxCount: Integer): Integer;

function SetWindowText(Wnd: HWnd; Str: PChar);


Рассмотрим первую функцию. Первый параметр указывает на окно, заголовок которой будет определяться. Второй - переменную, в которую будет заноситься заголовок. Третья определяет размер буфера, выделенного под заголовок. Приведенный ниже код позволяет определить заголовок программы.

procedure TForm1.Button1Click(Sender: TObject);
var r:array[1..255]of char;
begin
getwindowtext(application.Handle,@r,255);
showmessage(r)
end;


А вот так можно получать заголовки скрытых приложений и окон (по классам):

procedure TForm1.Button1Click(Sender: TObject);
var r:array[1..255]of char;
begin
getwindowtext(findwindow('progman',nil),@r,255);
showmessage(r)
end;


С помощью второй функции можно устанавливать свои заголовки. Рассмотрим её параметры. Первый указывает на окно, заголовок которого будем менять, а второй собственно и есть новый заголовок. Вот так можно менять у своей программы..

setwindowtext(application.Handle,'Hello!!!');

Чтоб поменять заголовок у формы, пиши.....

setwindowtext(Handle,'Hello!!!');

Чтоб у других программ и окон пиши...

setwindowtext(findwindow(nil,'Мой компьютер'),'Hello!!!');

суббота, 20 сентября 2008 г.

WinAPI: Flashwindow

FlashWindow

Очень часто в программах...... нет, не так..... Во многих программах мы встречаем...... и не так...... Скажу просто.... вы устанавливаете какую нибудь игру. Включили установку, свернули её и начали юзать Winamp. Вдруг во время установки выскакивает окошко с ошибкой и начинает мигать, дабы пользователь отвлекся от прослушивания музыки и обратил внимание на это окошко. Вот как раз для такого привлечения и используется данная API. Синтаксис её таков:

function FlashWindow(Wnd: HWnd; Invert: Bool): Bool;

Функция имеет два параметра. Первый указывает на окно, которое будет мигать, а вторая на то будет ли оно мигать или нет. Возвратное значение: true - если окно было активным, false - если было неактивным. Приведенный ниже код заставит рамку окна программы мигать каждые три секунды:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
timer1.Interval:=3000;
flashwindow(handle,true)
end;


Вот и все!!! скоро выложу мигание кнопки окна в системном трэе.

WinAPI: Showwindow и Findwindow

Showwindow и Findwindow

На данной странице речь пойдет о двух API функциях, с помощью которых осуществляется показ и скрытие различных окон, программ, элементов Windows с глаз пользователя. Рассмотрим каждую из функций подробнее...

function ShowWindow(Wnd: HWnd; CmdShow: Integer); 

Первый параметр функции указывает окно, с которым будет происходить та или иная операция, а второй указывает операцию, которая требуется. Нам нужны только две основные операции, это показ окна - sw_show и его скрытие - sw_hide. Список остальных операций с окном можно узнать из Microsoft Win32 Programmer's Reference, идущей в комплекте справки с Delphi.
Если мы хотим скрыть нашу программу, то пишем:

procedure TForm1.Button1Click(Sender: TObject);
begin
showwindow(application.MainForm.Handle,sw_hide);
end;


Чтобы скрыть кнопку программы из трэя и по Alt-Tab, пишем это...

procedure TForm1.Button1Click(Sender: TObject);
begin
showwindow(application.Handle,sw_hide);
end;


Ну и чтоб это все потом, естественно показать, на месте sw_hide пишем sw_show.
Рассмотрим вторую функцию:

function FindWindow(ClassName, WindowName: PChar): HWnd;

С помощью этой функции мы находим в системе окно по заданным нами параметрам. Возвратным значением данной функции будет handle искомого нами окна, если такое существует и 0, если не существует. Первый её параметр указывает на класс объекта, по которому во всей системе можно найти сам объект, а во втором параметре указывается текст в заголовке этого объекта. Например у нас есть открытая папка под названием "Музыка". Значит в заголовке открытого окна есть надпись "Музыка". Нам необходимо скрыть данное окно с рабочего стола. Для этого пишем: 

procedure TForm1.Button1Click(Sender: TObject);
begin
showwindow(findwindow(nil,'Музыка'),sw_show);
end;


После нажатия на кнопку, наше окно исчезнет с глаз долой. Но эксмериментировать с простыми окнами не интересно. Давайте немного позабавимся с ОС. Приведенный ниже код сможет скрыть весь traybar:

procedure TForm1.Button1Click(Sender: TObject);
begin
showwindow(findwindow('shell_tray_wnd',nil),sw_show);
end;


Здесь мы делаем поиск уже не по заголовку объекта, а по его классу. Константа "Shell_traywnd" указывает как раз на наш системный трэй. Если хорошо поискать такие константы, то можно например скрыть значки рабочего стола, написав константу "progman". Также можно скрыть кнопку пуск, или системные часы...