Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Перехват закрытия приложения

Автор: Shura09
Дата сообщения: 15.09.2003 11:06
Подскажите, кто знает как перехватить закрытия Access кагда пользователь нажимает на значке Х.
Просьба Вопросов типа "а зачем?" и прочих советов не давать.
Только скажите возможно ли это и как, если да.
СПАСИБО БОЛЬШОЕ.
Автор: MetroidZ
Дата сообщения: 16.09.2003 19:23
Может не в тему но:

Можно ли отключить кнопку закрытия любого окна?
Ответ:
Да, приведенный пример отключает кнопку закрытия и пункт "закрыть" ситсемного меню заданного окна. procedure TForm1.Button1Click(Sender: TObject);
var
hwndHandle : THANDLE;
hMenuHandle : HMENU;
begin
hwndHandle := FindWindow(nil, 'Untitled - Notepad');
if (hwndHandle <> 0) then begin
hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
if (hMenuHandle <> 0) then
DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);
end;
end;
Автор: ShIvADeSt
Дата сообщения: 17.09.2003 00:12
Shura09
Да можно перехватить нажатия кнопки Х в любом приложении. Для этого ставится системный хук, который фильтрует мессаги ( в отличии от случая когда требуется перехватить нажатия клавиш). В процедуре хука ты смотришь заголовыок приложения по Хэндлу, который передается в хук и если там есть слово Access то по своему переопределяешь событие WM_CLOSE или WM_CLOSEQUERY. Извини пример проги давать не буду, так как примеров по работе с хуками в инете пруд пруди. А еще лучше почитай MSDN. На твой вопрос вроде бы ответил.
Автор: BugFixer
Дата сообщения: 17.09.2003 04:57
Сильно похоже на http://www.forum.ru-board.com/topic.cgi?forum=33&bm=1&topic=2118#1
Автор: ShIvADeSt
Дата сообщения: 17.09.2003 05:29

Цитата:
Сильно похоже на http://www.forum.ru-board.com/topic.cgi?forum=33&bm=1&topic=2118#1

Не совсем так. Тут надо перехватить в чужом окне.
Автор: BugFixer
Дата сообщения: 17.09.2003 11:19
ShIvADeSt

Цитата:
Тут надо перехватить в чужом окне.

Это да... Сложнее.
Автор: Shura09
Дата сообщения: 17.09.2003 16:41
Хотя бы заблокиновать кнопку закрытия пока пользователь на что-нить не нажмет.
Только я что-то не пойму с какого бока подойти к этому примеру:

procedure TForm1.Button1Click(Sender: TObject);
var
hwndHandle : THANDLE;
hMenuHandle : HMENU;
begin
hwndHandle := FindWindow(nil, 'Untitled - Notepad');
if (hwndHandle <> 0) then begin
hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
if (hMenuHandle <> 0) then
DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);
end;
end;

Спасибо за советы.
Автор: ShIvADeSt
Дата сообщения: 17.09.2003 23:49
Shura09
Тут же все просто.

Цитата:
hwndHandle := FindWindow(nil, 'Untitled - Notepad');
только вместо Untitled - notepad пишешь Access - тру ля ля. Только учти, что лучше всего использовать функцию перечисления всех окон в ней находишь окно в котором есть надпись Access вот пример, его надо подправить под себя. Он просто возвращает хэндл первого окна в котором есть напись Access а ты уже для этого хэндла делаешт это. Вобщем дальше дело техники.


Цитата:
hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
if (hMenuHandle <> 0) then
DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);
end;
end;



type
PFindWindowStruct = ^TFindWindowStruct;
TFindWindowStruct = record
Caption : string;
ClassName : string;
WindowHandle : THandle;
end;

function EnumWindowsProc(hWindow:hWnd; lParam:LongInt):Bool;{$IFDEF Win32} stdcall; {$ELSE} ; export; {$ENDIF}
var
lpBuffer:PChar;
WindowCaptionFound:bool;
begin
GetMem(lpBuffer,MAX_PATH+30);
Result := True;
WindowCaptionFound := False;
try
if GetWindowText(hWindow, lpBuffer, MAX_PATH+30) > 0 then
if Pos(AnsiUpperCase(PFindWindowStruct(lParam).Caption),AnsiUpperCase('Access')) > 0
then WindowCaptionFound := true;
if WindowCaptionFound then begin
PFindWindowStruct(lParam).WindowHandle := hWindow;
Result := False;
end;
finally
FreeMem(lpBuffer, sizeof(lpBuffer^));
end;
end;

function FindFWindow(FCaption:string):THandle;
var
WindowInfo : TFindWindowStruct;
begin
with WindowInfo do begin
Caption:=FCaption;
ClassName:='';
WindowHandle:=0;
EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
FindFWindow:=WindowHandle;
end;
end;


Автор: MetroidZ
Дата сообщения: 18.09.2003 00:07
Это кусок программы на Delphi.

В этом примере отключается кнопка X у приложения с заголовком "Untitled - Notepad" (хотя хэндл можно и другими путями находить).
Для того чтобы его включить та же процедура, но вместо GetSystemMenu(hwndHandle, FALSE) надо GetSystemMenu(hwndHandle, TRUE).
Автор: Shura09
Дата сообщения: 18.09.2003 13:36
Интересно, как я буду использовать программу на Delphi в VBA? Может я допустил неопределенность, но программирование ведется на VBA.
Автор: BugFixer
Дата сообщения: 18.09.2003 14:42
Shura09

Цитата:
Может я допустил неопределенность, но программирование ведется на VBA.

"Работайте только исправным инструментом!" (с) не знаю чьё
Автор: dneprcomp
Дата сообщения: 18.09.2003 19:48
BugFixer

Цитата:
"Работайте только исправным инструментом!" (с) не знаю чьё

Ну и? Опять будет разборка, что лучше?
Shura09

Цитата:
как я буду использовать программу на Delphi в VBA

Delphi программу использовать не удасться. Но можно использовать аналогичные API функции. Ну и, соответственно, ту же логику.
Автор: woffer
Дата сообщения: 18.09.2003 23:22
dneprcomp

Цитата:
можно использовать аналогичные API функции.

Что значит аналогичные ? Те же самые функции
Автор: dneprcomp
Дата сообщения: 18.09.2003 23:58
woffer
Ну, так тем лучше для Shura09
Я же названия API-ек не проверял

Автор: Shura09
Дата сообщения: 19.09.2003 10:56
Вот это да!!!
Оказалось все не так то просто.
А задача - заблокировать кнопку закрытия
Нужно знать объект и свойство или параметр. Но какой??
Автор: woffer
Дата сообщения: 19.09.2003 23:43

Цитата:
Нужно знать объект и свойство или параметр. Но какой??

В смысле ? Нужно знать хендл окна, и скормить его функции GetSystemMenu
см код ShIvADeSt

Код: hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
if (hMenuHandle <> 0) then
DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);
end;
end;
Автор: Shura09
Дата сообщения: 23.09.2003 14:29
Нужен Basic.
Автор: ShIvADeSt
Дата сообщения: 24.09.2003 02:10

Цитата:
Нужен Basic.

В смысле тебе нужен компилятор Васика или же код на нем. Если первое то ищи не здесь это программирование, если второе то извини но переводить на Ваську меня ломает. Мне было достаточно когда я тот код из С в Дельфи лопатил. Сам смотри функции как они описаны в твоем хелпе и делай соответсвующий перевод. Хотя может кто другой переведет для тебя.
Автор: dad1969
Дата сообщения: 15.08.2007 14:48
Поднимаю эту тему снова. С блокнотом все работает. А вот с outlook 2007 оказалось немного хуже. В systemmenu все прекрасно отрубается, а вот сама кнопка с крестиком там видимо по другому реализована. Короче она не отрубается. А очень надо. Ибо юзвери постоянно гасят outlook, а потом жалуются что у них почта не работает.
Автор: rain87
Дата сообщения: 15.08.2007 15:28
dad1969
хм, мне вариант в голову интересный пришёл
узнать hwnd главного окна аутлука, а затем с помощью SetWindowLong(GWL_WNDPROC) поменять этому окну WNDPROC, старую ессно запомнить. и после всего этого в своей WNDPROC ловить сообщения, если WM_CLOSE - то забивать, а если другое - то вызывать старую WNDPROC
гипотетически должно работать

ну или как вариант - стоять за спиной юзира с топором
Автор: dad1969
Дата сообщения: 15.08.2007 17:19
rain87
thnx
буду попробовать.
ну а потом, для верности, за топором...
Автор: Jj7777
Дата сообщения: 19.03.2010 20:50
Подскажите, пожалуйста, как сделать так, чтобы моя программа закрывалась вместе с другой программой, блокнотом тем же, например?

Т.е. в блокноте мы жмем на крестик и он закрывается вместе с моей программой.


procedure TForm1.Button1Click(Sender: TObject);
var
hwndHandle : THANDLE;
hMenuHandle : HMENU;
begin
hwndHandle := FindWindow(nil, 'Untitled - Notepad');
if (hwndHandle <> 0) then

А дальше не знаю как писать (( Подскажите, плиз
Автор: akaGM
Дата сообщения: 19.03.2010 21:14
Jj7777
тебе лучше здесь спросить:
http://forum.ru-board.com/topic.cgi?forum=33&topic=10477#1
Автор: Jj7777
Дата сообщения: 23.03.2010 19:12
спс =)
Автор: Jj7777
Дата сообщения: 26.10.2010 00:04

Цитата:

А дальше не знаю как писать (( П

Автор: ck80
Дата сообщения: 22.04.2011 11:01
Не знал, куда ещё обратиться.

Задача похожая, подскажите, пожалуйста решение, но не как программисту, а как эникею

Есть компьютер в магазине, без жесткого диска, без системы, загружается с CD-диска и подключается к терминальному серверу. В терминале жёстко прописана на запуск одна единственная программа (Автокаталог).
Дак вот, клиенты иногда по привычке закрывают эту программу и сессия остается висеть голая. Чтобы перезапустить её нужно на сервере выкидывать этот сеанс и подключаться по новой.
Хотелось бы как-нибудь автоматизировать процесс.
В идеале, запускать эту программу из какого-нибудь скрипта, который делал проверку и если происходит закрытие программы, тут же открывал её заново. Либо просто убрать кнопку закрытия.

UPD помог res2001 из соседней темы


Код: @echo off
:loop
set "isproc="
for /f "tokens=2" %%i in ('tasklist ^| findstr "notepad.exe" ') do set "isproc=1"
if not defined isproc start "" notepad.exe
1>nul 2>&1 ping -n 1 -w 30000 127.255.255.255
goto:loop

Страницы: 1

Предыдущая тема: DBGrid и Hint (Delphi)...


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.