void Form_Load(object sender, EventArgs e)
{
m_Notepad = Process.Start("notepad");
newWndProc = new WndProcDelegate(NewWndProc);
oldWndProc = new IntPtr(GetWindowLong(m_NotepadHwnd, GWL_WNDPROC));
SetWindowLong(m_NotepadHwnd, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc).ToInt32());
}
public IntPtr NewWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg == WM_SYSCOMMAND)
{
if (wParam.ToInt32() == SC_MINIMIZE)
{
return IntPtr.Zero;
}
.......
}
return CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam);
}
SetWindowLong GWL_WNDPROC для другого процесса
передо мной стоит такая задача. сделать невозможным закрытие/сворачивание/максимизирование любого окна из управляемого кода.
Системное меню окон я поборол ровно как и Alt+F4. Получилось задисэйблить кнопку "Х", но не мин/макс. с мин макс у меня проблемы мин/макс. Я решил сделать так, чтоб когда пользователь нажимает на эти кнопки ничего не происходило. Для этого я хочу использовать функцию SetWindowLong с параметром GWL_WNDPROC. Как сказано в мсдне эта функция в комбинации с этим аргументом:
Цитата:
Sets a new address for the window procedure.
Т.е. я устанавливаю новый адрес процедуры окна и в новой процедуре проверяю пришедшее сообщение - если оно не мин и не макс вызываем старую процедуру, а если мин или макс - ничего не делаем.
Вот код (простой до безобразия), который я использую. но ничего не происходит - новая процедура окна не вызывается.
Код:
Если я пытаюсь определить новую процедуру окна для текущей формы (значит и процесса) все работает, как надо. но в случае блокнота и любого другого приложения ничего не проиходит.
Я так подозреваю это из-за вот этого примечания в мсдне:
Цитата:
GWL_WNDPROC
Sets a new address for the window procedure.
Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread.
Sets a new address for the window procedure.
Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread.
Буду очень признателен за помощь.
П.С. не спрашивайте почему я решил не дать сворачивать окно. логично было бы задисэйблить мин/макс кнопки. но, хоть про это очень много тем в форумах, полезного поста я так и не встретил. если кто-то знает 100% рабочий метод задисэйблить эти кнопки буду втройне признателен.
Тебе надо внедриться в чужой процесс и оттуда подменять оконную функцию.
1. Выделить память в чужом процессе для моей функции, которая будет заменять оконную функцию.
2. скопировать ее в это пространство.
3. создать удаленный поток (CreateRemoteThread) указав ему адрес этой же функции.
Если так, то у меня еще несколько вопросов:
а) как должна выглядеть функция, которую я собираюсь копировать в чужой процесс (которая будет менять оконную функцию)? я так понимаю, она не может быть написана на с#?
б) скопировать в чужой процесс придется не только эту функцию, но также и новую оконную функцию?
Цитата: Visitor
1. Выделить память в чужом процессе для моей функции, которая будет заменять оконную функцию.
2. скопировать ее в это пространство.
3. создать удаленный поток (CreateRemoteThread) указав ему адрес этой же функции.
правильно
Цитата: Visitor
а) как должна выглядеть функция, которую я собираюсь копировать в чужой процесс (которая будет менять оконную функцию)? я так понимаю, она не может быть написана на с#?
код в функции (как и весь внедряемый код) должен быть базонезависимым, наверно его придётся писать на асме
Цитата: Visitor
б) скопировать в чужой процесс придется не только эту функцию, но также и новую оконную функцию?
РАЗУМЕЕТСЯ!
Проще переместить код оконной функции в dll. А ещё проще поставить хук.