Я постарался убрать всё "лишнее" (не влияющее на краш) и вот что получилось:
Code: Select all
--local ok, le = pcall(require, "le"); if not ok then le = nil end
local F = far.Flags
------------------------- константы --------------------------------------------------------------------
local WhatPanelA, WhatPanelP, whatpanelA, whatpanelP = 0,1,1,0
local Exportlist_Id = win.Uuid"D144DB12-FECC-4761-BF01-B50C03799F15"
local Clearlist_Id = win.Uuid"691A7993-90AF-4DE2-8894-9D5839A0ECC2"
local RestoreList_Id = win.Uuid"2988A579-F381-4111-8701-4CA087B6523A"
local ConEmu_Id = "4B675D80-1D4A-4EA9-8436-FDC23F2FC14B"
local c_number = 'number'
--local MacroEX_Exist = nil
---------------------------
local MinFileFilterToolsVer = '1.0.7'
local MinDialogToolsVer = '1.2.4'
local MinFarMenuVers = '2.1.6'
local MinBaxGetMsgVers = '1.5.3'
local InfoFiles = table.concat({"*.hlf";
"%FARPROFILE%\\macros\\modules\\BAX\\DialogTools.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\far_Menu.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\FileFilterTools.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\FlagsTools.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\GetMsg.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\mBaseTools.lua";
"%FARPROFILE%\\macros\\modules\\execute.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\TreeTable.lua";
}, ',')
--------------------------------------------------------------------------------------------------------
local ffi = require "ffi"
local C = ffi.C
ffi.cdef [=[
wchar_t* GetEnvironmentStringsW();
void FreeEnvironmentStringsW(wchar_t*);
size_t wcslen(const wchar_t*);
int SendMessageA(HWND, UINT, WPARAM, LPARAM);
int SendMessageTimeoutA(HWND, UINT, WPARAM, LPARAM, UINT, UINT, DWORD_PTR*);
]=]
--------------------------------------------------------------------------------------------------------
-- Функция определения имени языкового файла (в зависимости от расширения)
local PathName,FarLang,HlpLang = (...):match("(.*)%.lua"),win.GetEnv("FARLANG"):sub(1,3),Far.GetConfig("Language.Help"):sub(1,3)
local function LangFileName(Ext,Lang)
local Res = PathName..Lang..Ext
local Res0 = Res -- для диагностики
if not mf.fexist(Res) then Res = PathName..FarLang..Ext end
if not mf.fexist(Res) then Res = PathName..Ext end
if not mf.fexist(Res) then
Res = far.RecursiveSearch(mf.fsplit(PathName, 3), mf.fsplit(PathName, 12) .. '*' .. Ext, function(full) return full.FileName end, F.FRS_RETUPDIR)
if Res then Res = mf.fsplit(PathName, 3) .. Res end
end
return Res or Res0
end
local HlfName = LangFileName('.hlf',HlpLang)
local BAX_GetMsg = require"BAX.GetMsg"
local FileFilterTools = require"BAX.FileFilterTools"
local mBaseTools = require"Bax.mBaseTools"
local DialogTools = require"BAX.DialogTools"
local DialogItem = DialogTools.DialogItem
local ExecProc=require"execute"
local far_Menu = require"BAX.far_Menu"
local FlagsTools = require"BAX.FlagsTools"
local TreeTable = require"BAX.TreeTable".TreeTable
--------------------------------------------------------------------------------------------------------
local aGetMsg = { {Main=Far.GetConfig("Language.Main"); Help=Far.GetConfig("Language.Help")} }
local LngName = mf.fsplit(..., 7) .. '*.lng'
local FoundFile = nil
local GetMsg
--------------------------------------------------------------------------------------------------------
GetMsg = function (Tag)
if aGetMsg[1].Main ~= Far.GetConfig("Language.Main") or
aGetMsg[1].Help ~= Far.GetConfig("Language.Help") then
aGetMsg = { {Main=Far.GetConfig("Language.Main"); Help=Far.GetConfig("Language.Help")} }
FoundFile = nil
end
if aGetMsg[Tag] == nil then
local Args={File=FoundFile or LngName, Tag=Tag, HelpLang=true} --Cfg.Language == 'help'}
aGetMsg[Tag] = BAX_GetMsg(Args)
FoundFile = Args.FoundFile or FoundFile
end
return aGetMsg[Tag]
end
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Event {
id = "A459EC76-7B68-46D4-82CC-AB221FAD6791";
group = "DialogEvent";
description = GetMsg"ExitDlg"; --"Вывод количества редакторов и вьюеров и запуск сохранения контекста (при необходимости)";
-- filemask = "*.txt,*.cpp";
priority = 80;
condition = function(Event, Param)
local id = far.SendDlgMessage(Param.hDlg, F.DM_GETDIALOGINFO)
id = id and id.Id or ""
return
id == win.Uuid(far.Guids.FarAskQuitId) and
Event == F.DE_DLGPROCINIT and
Param.Msg == F.DN_INITDIALOG
end;
action = function(Event, Param)
local aButt, Title, Txt = {GetMsg('MQuit'), GetMsg('MNo')}, GetMsg('MQuit'), GetMsg('MAskQuit')
Param.hDlg:send(F.DM_CLOSE, -2)
local viewers, editors, changed = 0,0,0
local n = far.AdvControl(F.ACTL_GETWINDOWCOUNT, 0, 0)
for i=1,n do
local info = far.AdvControl(F.ACTL_GETWINDOWINFO, i)
if info and F.WTYPE_VIEWER == info.Type then
viewers = viewers + 1
end
if info and F.WTYPE_EDITOR == info.Type then
editors = editors + 1
if band(info.Flags, F.WIF_MODIFIED) == F.WIF_MODIFIED then
changed = changed + 1
end
end
end
local InfoCount, ChangedCount = {Txt, GetMsg('ViewersCount'):format(viewers); GetMsg('EditorsCount'):format(editors)}, GetMsg('ChangedCount'):format(changed)
local w = 46 --math.max(Txt:len(), InfoCount[1]:len(), InfoCount[2]:len(), ('Открыто редакторов: %d'):format(editors):len(), 40) + 6
local aDlg = {
--[[1]]DialogItem{'DI_DOUBLEBOX',0,0,w,9,Text=Title}; --};
----[[2]]DialogItem{'DI_TEXT',x1=3,y1=1, x2=w-3, y2=3,Text=('%s\nОткрыто просмотрщиков: %d\nОткрыто редакторов: %d'):format(Txt,viewers, editors), Flags='DIF_WORDWRAP|DIF_CENTERTEXT'};
--[[2]]DialogItem{'DI_TEXT',x1=3,y1=1, x2=w-3, y2=3,Text=table.concat(InfoCount, '\n'), Flags='DIF_WORDWRAP|DIF_CENTERTEXT'};
--[[3]]DialogItem{'DI_TEXT', y1=4, Flags='DIF_CENTERTEXT|DIF_CENTERGROUP', Text=ChangedCount; Name='changed'};
--[[4]]DialogItem{'DI_TEXT', y1=5, Flags='DIF_SEPARATOR'};
----[[5]]DialogItem{'DI_CHECKBOX', x1=2, y1=6, Text="Сохранить контекст перед выходом", Checked = Cfg.FromCloseDialog and 1 or 0};
--[[5]]DialogItem{'DI_CHECKBOX', y1=6, Text=GetMsg"SaveContext_Question", Checked = 1; Flags='DIF_CENTERGROUP'};
--[[4]]DialogItem{'DI_TEXT', y1=7, Flags='DIF_SEPARATOR'};
--[[6]]DialogItem{'DI_BUTTON', y1=8, Text=aButt[1], Flags='DIF_DEFAULTBUTTON|DIF_CENTERGROUP|DIF_FOCUS'};
--[[7]]DialogItem{'DI_BUTTON', y1=8, Text=aButt[2], Flags='DIF_CENTERGROUP'};
}
local pDlg, OkBtn = nil, #aDlg-1
if changed > 0 then
pDlg = function(hDlg, Msg, Param1, Param2)
if Msg == F.DN_CTLCOLORDLGITEM and aDlg[Param1].Name == 'changed' then
Param2[1].ForegroundColor = 0xFF000000 + 0xE -- Жёлтый
Param2[1].BackgroundColor = 0xFF000000 + 0xC -- на красном
return Param2
end
end
end
local iRes =
far.Dialog(win.Uuid'6163F8A9-EF2E-48FB-9006-B2075EB30382', -1,-1,w,10,nil, aDlg, F.FDLG_SMALLDIALOG, pDlg)
if iRes == OkBtn then
-- Исправление ошибки: в базу записывались признаки, какую панель сохранять и куда её восстанавливать
local prg
prg = function() far.AdvControl(F.ACTL_QUIT) end
mf.postmacro(prg)
mf.postmacro(Keys, "CtrlR") -- Без этого панели остаются на экране до любого события (клавиша, мешь)
end
end; -- action
}
Code: Select all
--local ok, le = pcall(require, "le"); if not ok then le = nil end
local F = far.Flags
------------------------- константы --------------------------------------------------------------------
local WhatPanelA, WhatPanelP, whatpanelA, whatpanelP = 0,1,1,0
local Exportlist_Id = win.Uuid"D144DB12-FECC-4761-BF01-B50C03799F15"
local Clearlist_Id = win.Uuid"691A7993-90AF-4DE2-8894-9D5839A0ECC2"
local RestoreList_Id = win.Uuid"2988A579-F381-4111-8701-4CA087B6523A"
local ConEmu_Id = "4B675D80-1D4A-4EA9-8436-FDC23F2FC14B"
local c_number = 'number'
--local MacroEX_Exist = nil
---------------------------
local MinFileFilterToolsVer = '1.0.7'
local MinDialogToolsVer = '1.2.4'
local MinFarMenuVers = '2.1.6'
local MinBaxGetMsgVers = '1.5.3'
local InfoFiles = table.concat({"*.hlf";
"%FARPROFILE%\\macros\\modules\\BAX\\DialogTools.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\far_Menu.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\FileFilterTools.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\FlagsTools.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\GetMsg.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\mBaseTools.lua";
"%FARPROFILE%\\macros\\modules\\execute.lua";
"%FARPROFILE%\\macros\\modules\\BAX\\TreeTable.lua";
}, ',')
--------------------------------------------------------------------------------------------------------
local ffi = require "ffi"
local C = ffi.C
ffi.cdef [=[
wchar_t* GetEnvironmentStringsW();
void FreeEnvironmentStringsW(wchar_t*);
size_t wcslen(const wchar_t*);
int SendMessageA(HWND, UINT, WPARAM, LPARAM);
int SendMessageTimeoutA(HWND, UINT, WPARAM, LPARAM, UINT, UINT, DWORD_PTR*);
]=]
--------------------------------------------------------------------------------------------------------
-- Функция определения имени языкового файла (в зависимости от расширения)
local PathName,FarLang,HlpLang = (...):match("(.*)%.lua"),win.GetEnv("FARLANG"):sub(1,3),Far.GetConfig("Language.Help"):sub(1,3)
local function LangFileName(Ext,Lang)
local Res = PathName..Lang..Ext
local Res0 = Res -- для диагностики
if not mf.fexist(Res) then Res = PathName..FarLang..Ext end
if not mf.fexist(Res) then Res = PathName..Ext end
if not mf.fexist(Res) then
Res = far.RecursiveSearch(mf.fsplit(PathName, 3), mf.fsplit(PathName, 12) .. '*' .. Ext, function(full) return full.FileName end, F.FRS_RETUPDIR)
if Res then Res = mf.fsplit(PathName, 3) .. Res end
end
return Res or Res0
end
local HlfName = LangFileName('.hlf',HlpLang)
local BAX_GetMsg = require"BAX.GetMsg"
local FileFilterTools = require"BAX.FileFilterTools"
local mBaseTools = require"Bax.mBaseTools"
local DialogTools = require"BAX.DialogTools"
local DialogItem = DialogTools.DialogItem
local ExecProc=require"execute"
local far_Menu = require"BAX.far_Menu"
local FlagsTools = require"BAX.FlagsTools"
local TreeTable = require"BAX.TreeTable".TreeTable
--------------------------------------------------------------------------------------------------------
local aGetMsg = { {Main=Far.GetConfig("Language.Main"); Help=Far.GetConfig("Language.Help")} }
local LngName = mf.fsplit(..., 7) .. '*.lng'
local FoundFile = nil
local GetMsg
--------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------
local function VersCompare(Vers1, Vers2, lim)
local function VersToTable(Vers)
local Res={}
for w in Vers:gmatch"%d*" do
Res[#Res+1] = tonumber(w);
if (lim or 0) > 0 and #Res >= lim then break end
end
return Res
end -- VersToTable
lim = lim or 3
local aV1, aV2 = VersToTable(Vers1), VersToTable(Vers2)
local function _cmp(a1,a2)
return a1 < a2 and -1 or
a1 > a2 and 1 or 0
end
for i=1,lim do
local _c = _cmp(aV1[i], aV2[i])
if _c ~= 0 then return _c end
end
return 0
end -- VersCompare
--------------------------------------------------------------------------------------------------------
GetMsg = function (Tag)
if aGetMsg[1].Main ~= Far.GetConfig("Language.Main") or
aGetMsg[1].Help ~= Far.GetConfig("Language.Help") then
aGetMsg = { {Main=Far.GetConfig("Language.Main"); Help=Far.GetConfig("Language.Help")} }
FoundFile = nil
end
if aGetMsg[Tag] == nil then
local Args={File=FoundFile or LngName, Tag=Tag, HelpLang=true} --Cfg.Language == 'help'}
aGetMsg[Tag] = BAX_GetMsg(Args)
FoundFile = Args.FoundFile or FoundFile
end
return aGetMsg[Tag]
end
-------------------------------------------------------------------------
-------------------------------------------------------------------------
Event {
id = "A459EC76-7B68-46D4-82CC-AB221FAD6791";
group = "DialogEvent";
description = GetMsg"ExitDlg"; --"Вывод количества редакторов и вьюеров и запуск сохранения контекста (при необходимости)";
-- filemask = "*.txt,*.cpp";
priority = 80;
condition = function(Event, Param)
local id = far.SendDlgMessage(Param.hDlg, F.DM_GETDIALOGINFO)
id = id and id.Id or ""
return
id == win.Uuid(far.Guids.FarAskQuitId) and
Event == F.DE_DLGPROCINIT and
Param.Msg == F.DN_INITDIALOG
end;
action = function(Event, Param)
local aButt, Title, Txt = {GetMsg('MQuit'), GetMsg('MNo')}, GetMsg('MQuit'), GetMsg('MAskQuit')
Param.hDlg:send(F.DM_CLOSE, -2)
local viewers, editors, changed = 0,0,0
local n = far.AdvControl(F.ACTL_GETWINDOWCOUNT, 0, 0)
for i=1,n do
local info = far.AdvControl(F.ACTL_GETWINDOWINFO, i)
if info and F.WTYPE_VIEWER == info.Type then
viewers = viewers + 1
end
if info and F.WTYPE_EDITOR == info.Type then
editors = editors + 1
if band(info.Flags, F.WIF_MODIFIED) == F.WIF_MODIFIED then
changed = changed + 1
end
end
end
local InfoCount, ChangedCount = {Txt, GetMsg('ViewersCount'):format(viewers); GetMsg('EditorsCount'):format(editors)}, GetMsg('ChangedCount'):format(changed)
local w = 46 --math.max(Txt:len(), InfoCount[1]:len(), InfoCount[2]:len(), ('Открыто редакторов: %d'):format(editors):len(), 40) + 6
local aDlg = {
--[[1]]DialogItem{'DI_DOUBLEBOX',0,0,w,9,Text=Title}; --};
----[[2]]DialogItem{'DI_TEXT',x1=3,y1=1, x2=w-3, y2=3,Text=('%s\nОткрыто просмотрщиков: %d\nОткрыто редакторов: %d'):format(Txt,viewers, editors), Flags='DIF_WORDWRAP|DIF_CENTERTEXT'};
--[[2]]DialogItem{'DI_TEXT',x1=3,y1=1, x2=w-3, y2=3,Text=table.concat(InfoCount, '\n'), Flags='DIF_WORDWRAP|DIF_CENTERTEXT'};
--[[3]]DialogItem{'DI_TEXT', y1=4, Flags='DIF_CENTERTEXT|DIF_CENTERGROUP', Text=ChangedCount; Name='changed'};
--[[4]]DialogItem{'DI_TEXT', y1=5, Flags='DIF_SEPARATOR'};
----[[5]]DialogItem{'DI_CHECKBOX', x1=2, y1=6, Text="Сохранить контекст перед выходом", Checked = Cfg.FromCloseDialog and 1 or 0};
--[[5]]DialogItem{'DI_CHECKBOX', y1=6, Text=GetMsg"SaveContext_Question", Checked = 1; Flags='DIF_CENTERGROUP'};
--[[4]]DialogItem{'DI_TEXT', y1=7, Flags='DIF_SEPARATOR'};
--[[6]]DialogItem{'DI_BUTTON', y1=8, Text=aButt[1], Flags='DIF_DEFAULTBUTTON|DIF_CENTERGROUP|DIF_FOCUS'};
--[[7]]DialogItem{'DI_BUTTON', y1=8, Text=aButt[2], Flags='DIF_CENTERGROUP'};
}
local pDlg, OkBtn = nil, #aDlg-1
if changed > 0 then
pDlg = function(hDlg, Msg, Param1, Param2)
if Msg == F.DN_CTLCOLORDLGITEM and aDlg[Param1].Name == 'changed' then
Param2[1].ForegroundColor = 0xFF000000 + 0xE -- Жёлтый
Param2[1].BackgroundColor = 0xFF000000 + 0xC -- на красном
return Param2
end
end
end
local iRes =
far.Dialog(win.Uuid'6163F8A9-EF2E-48FB-9006-B2075EB30382', -1,-1,w,10,nil, aDlg, F.FDLG_SMALLDIALOG, pDlg)
if iRes == OkBtn then
-- Исправление ошибки: в базу записывались признаки, какую панель сохранять и куда её восстанавливать
local prg
prg = function() far.AdvControl(F.ACTL_QUIT) end
mf.postmacro(prg)
mf.postmacro(Keys, "CtrlR") -- Без этого панели остаются на экране до любого события (клавиша, мешь)
end
end; -- action
}
Разница между вариантами только в наличии функции VersCompare (которая, к слову сказать, не вызывается!). Т.к. логикой объяснить этот вылет я не могу, то не стал убирать и "мёртвые" куски кода. Во вложении - дамп.
- Crash.7z
- (110.99 KiB) Downloaded 28 times