Изменение NTShutdownSystem
Помогите, плз. Недавно столкнулся с проблемой перепрограммирования кнопки "Выключение компьютера" в меню "Пуск". Как известно, за процедуру выключения отвечает системная функция NTShutdownSystem(). Где найти в винде ее исходник и изменить его содержимое?
NtShutdownSystem() - это функция ядра WindowsNT. Не пойму смысла, зачем её менять? К тому же NtShutdownSystem() не отвечает за показ окна "выключить, презагрузить и т.д.", а всего лишь завершает работу системы. Если действительно хочешь её изменить, тогда иди на wasm.ru, там написано про перехват функций API. Можешь хотя-бы задачу свою описать, а то нифига не понятно.
Так мне окно "Выключить, перегрузить" сто лет не надо. Объясняю задачу: изменить действие системы при нажатии на кнопку "Выключить" в этом окне. Грубо говоря, чтобы я мог нажать на эту кнопку, а комп не выключался, а выдавал сообщение "Всем привет".
http://forum.codenet.ru/showthread.php?t=36270
Только сначала тебе нужно получить хэндл этой кнопки "Shut down" (в русской версии винды кажется "Выключить компьютер"). Это можно сделать с помощью FindWindow, FindWindowEx. Если не поможет, тогда копай в сторону SetWindowsHookEx.
Смысл в том, чтобы перехватить сообщение WM_LBUTTONDOWN у кнопки "Выключить компьютер" и выполнить свой код заместо виндосского
В помощь:
класс панели, на которой располагается меню "Пуск" называется "Shell_TrayWnd". Это применимо к FindWindow(). Если хочешь узнать еще, тогда запускай Spy++ (В комплекте с Visual C++) или WinSight (в комплекте с Delphi).
следует отметить что при перезвате функции NtShutdownSystem, твоё действие будет выполняться при выключении через любую программу. как я понял, тебе надо изменить действие только при нажатии кнопки "Выключить компьютер", поэтому, как уже было сказано, копай в сторону SetWindowsHookEx.
А где можно посмотреть готовый код какой-нибудь аналогичной операции?
unit Test1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
H: TFarProc;
implementation
{$R *.DFM}
function MyFunc (Code, wParam, lParam: integer): integer;
begin
if Code >= 0 then
if wParam = WM_RBUTTONDOWN then ShowMessage('Text');
end;
begin
H := SetWindowsHook(WH_MOUSE, @MyFunc);
end.
В результате вся эта хиромантия спокойно компилируется, а при выполнении выдает ошибку следующего содержания:
Exception EGPFault in module TEST.EXE at 0001:015E.
General protection fault in mouse TEST.EXE at 0001:015E,
которая размножается и в конце концов прибивает и себя, и сам TEST.EXE.
Как с этим бороться?
SetWindowsHookEx внедряет dll в адресное пространство каждого процесса (или любого указанного, точно не помню). Почитай относительно SetWindowsHookEx на wasm.ru. Или просто в гугле вбей. Ты вообще неправильно делаешь
Цитата: polaroid
SetWindowsHookEx внедряет dll в адресное пространство каждого процесса (или любого указанного, точно не помню).
dll внедряется в память всех GUI процессов и тех не GUI процессов, в которые посылают оконные сообщения.
to Alexander92, примеров хуков немерено, покопайся в гугле хорошенько. Кстати, насоклько я понял, ты хочешь отследить нажатие мышью на кнопку "Выключить" - это крайне не рациональный подход, перехват NTShutdownSystem намного лучше.
Вроде разобрался, всем большое спасибо за помощь. :)