не дать закрыться окну листера

Форум о самом популярном файловом менеджере Total Commander

Сообщение Sep. » Чт июл 06, 2006 6:18 am

Хочется реализовать возможность отказа при закрытии окна листера если файл был модифицирован. Собственно как перехватить событие закрытия листера получается через подмену оконной процедуры:
Код: выделить все
procedure TfmMain.HookLister;
begin
ListerWndProc:=Pointer(GetWindowLong(hLister,GWL_WNDPROC));
SetWindowLong(hLister, GWL_WNDPROC, Longint(@HookWndProc));
end;

function HookWndProc(Handle: hWnd; Msg, wParam, lParam: Longint): Longint; stdcall;
var
 fmMain: TfmMain;
begin
 if (msg = WM_CLOSE) then begin
   fmMain := TfmMain(FindControl(fmMain.hOwn));
   if(not fmMain.AskSave) then exit;
 end;
 Result:=CallWindowProc(fmMain.ListerWndProc, Handle, Msg , WParam, LParam);
end;

Но как передать HWND окна плагина в хук функцию не через глобальную переменную? Интересует решал ли кто данную задачу, и какой был вообще подход к решению?
Sep.
Рядовой
 
Сообщений: 7
Зарегистрирован: Ср авг 25, 2004 9:55 am
Пункты репутации: 0

Сообщение SCHMaster » Пт июл 07, 2006 11:00 pm

Во-первых мой тебе совет, хоть ты и перехватываешь процедуру окна листера, это еще не значит, что можно (вообще-то можно, но не нужно <!--emo&:)-->[img]style_emoticons/<#EMO_DIR#>/smile.gif[/img]<!--endemo-->) "забивать" на нее. А отмена закрытия окна и есть такой "забой". Будут глюки, поверь <!--emo&:)-->[img]style_emoticons/<#EMO_DIR#>/smile.gif[/img]<!--endemo-->. В SynPlus если ты что-то изменил (обрати внимание) в файле и нажал Esc, тебе будет предложено чохранить или отменить выход. Но тут перехватывается не команда на закрытие, а нажатие клавишь. И соответственно в зависимости от выбора - сообщение передается дальше или нет. А вот если в аналогичной ситуевине нажать кнопку "закрыть", то тебе будет только предложено мохранить файл. И незвисимо от того, сохрагишь ты его или нет - окно в любом случае закроется. Почему? Да по-тому, что каждый экземпляр листера идет в отдельном потоке. И ХЕЗ, как дядя Гистлер там организовал все это хозяйство. Но, насколько я помню, когда я эксперементировал с процедурой окна и пытался отменить DESTROY, что-то сильно ругалось и валилось <!--emo&:)-->[img]style_emoticons/<#EMO_DIR#>/smile.gif[/img]<!--endemo-->
А по твоему вопросу, как пердать, точнее где сохранить эту переменную... В хелпе по листер-плагинописательству есть рекомендации дяди Г. Ищи все тот-же SetWindowLong, GetWindowLong, но только параметр там будет малость другой. Или ищи свое окно сам - FindWindowEx и передавай полученный результат
<span style='color:red'>"Хороший юзер - мертвый юзер"</span>
SCHMaster
Майор
 
Сообщений: 478
Зарегистрирован: Пн фев 03, 2003 12:04 am
Пункты репутации: 0

Сообщение Sep. » Сб июл 08, 2006 9:59 am

Спасибо большое!
Про хелп то я совсем забыл. Действительно там так и сказано:
"you cannot save settings in global variables. You can call RegisterClass with the parameter cbWndExtra to reserve extra space for your data, which you can then access via GetWindowLong(). Or use an internal list, and store the list parameter via SetWindowLong(hwnd,GWL_ID,...)."
Попробовал так:
Код: выделить все
function HookWndProc(Handle: hWnd; Msg, wParam, lParam: Longint): Longint; stdcall;
var
 fmMain: TfmMain;
 hOwn: HWND;
begin
 hown:=FindWindowEx(Handle,0,'TfmMain',nil);
 fmMain := TfmMain(FindControl( hOwn ));
 if (msg = WM_CLOSE) then begin
   if(not fmMain.AskSave) then exit;
 end;
 Result:=CallWindowProc(fmMain.ListerWndProc, Handle, Msg , WParam, LParam);
end;

работает, но багает как то странно. Прийдется разбираться с SetWindowLong ...
Sep.
Рядовой
 
Сообщений: 7
Зарегистрирован: Ср авг 25, 2004 9:55 am
Пункты репутации: 0


Вернуться в Total Commander

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron