Есть более свободное решение. Даже без хука --- вообще без изменения стандартных модулей.
Просто пишется произвольный модуль, который по экшену раз в несколько секунд обходит все окна и перевычисляет их заголовки. Такой модуль является приложением к конкретной сборке, поэтому без проблем может позволить себе любые "вольности". Импорт же специфических модулей в HostWindows всегда проблематичен.
Ниже пример, который
1) отмечает документы из подсистем (
viewtopic.php?p=33418#p33418)
2) добавляет путь документов, открытых по абсолютному пути. Эту штуку придумал Иван Горячев в 1.6 сборке сообщества (
http://oberoncore.ru/projects/bb16ce).
ipuiK46 и ipuiK401 см. в архиве
http://oberoncore.ru/bbcc/subs/ipui/Код:
MODULE ipuiK401;
IMPORT
Log,
Services, Windows, Strings, Files, Converters, Views,
HostFiles, ipuiK46;
TYPE
Action = POINTER TO RECORD (Services.Action) END;
VAR
a: Action;
baseLoc: HostFiles.Locator;
PROCEDURE Append (VAR s: ARRAY OF CHAR; t: ARRAY OF CHAR);
VAR len: INTEGER; i, j: INTEGER; ch: CHAR;
BEGIN
len := LEN(s);
i := 0; WHILE s[i] # 0X DO INC(i) END;
j := 0; REPEAT ch := t[j]; s[i] := ch; INC(j); INC(i) UNTIL (ch = 0X) OR (i = len);
s[len - 1] := 0X;
IF (ch # 0X) & (i = len) THEN s[len - 2] := "…" END
END Append;
PROCEDURE CheckMod (w: Windows.Window; OUT title: Views.Title; OUT done: BOOLEAN);
VAR
loc: Files.Locator; ch: CHAR; s1, s2: HostFiles.FullName; i, j: INTEGER;
name: Files.Name; pos: INTEGER;
BEGIN
done := FALSE;
IF (w.loc # NIL) & (w.conv = Converters.list) THEN
loc := w.loc; ipuiK46.GetName(w.name, Files.docType, name);
WITH loc: HostFiles.Locator DO
i := 0; ch := loc.path[0]; j := 0; s2 := "";
WHILE ch # 0X DO
IF (ch = "\") OR (ch = "/") THEN
s1[j] := 0X; s2 := s1$; j := 0
ELSE
s1[j] := ch; INC(j)
END;
INC(i); ch := loc.path[i]
END;
s1[j] := 0X;
title := ""; done := TRUE;
IF s2 # "" THEN
IF (CAP(s1[0]) = "M") & (CAP(s1[1]) = "O") & (CAP(s1[2]) = "D") & (s1[3] = 0X) THEN
title := "("+s2+"/Mod)"
ELSIF (CAP(s1[0]) = "D") & (CAP(s1[1]) = "O") & (CAP(s1[2]) = "C") & (CAP(s1[3]) = "U") & (s1[4] = 0X) THEN
title := "("+s2+"/Docu)";
ELSIF (CAP(s1[0]) = "R") & (CAP(s1[1]) = "S") & (CAP(s1[2]) = "R") & (CAP(s1[3]) = "C") & (s1[4] = 0X) THEN
title := "("+s2+"/Rsrc)"
END
END;
Append(title, name);
IF baseLoc # NIL THEN
Strings.Find(loc.path, baseLoc.path, 0, pos);
IF pos # 0 THEN
Append(title, " | " + loc.path)
END
END
ELSE
END
END
END CheckMod;
PROCEDURE UpdateWindowTitles*;
VAR
w: Windows.Window; title: Views.Title; done: BOOLEAN;
BEGIN
IF Windows.dir # NIL THEN w := Windows.dir.First() ELSE w := NIL END;
WHILE w # NIL DO
(* Log.String(w.name); Log.Ln; *)
CheckMod(w, title, done);
IF done THEN
(* Log.Tab; Log.String(title); Log.Ln; *)
w.SetTitle(title)
END;
w := Windows.dir.Next(w)
END
END UpdateWindowTitles;
PROCEDURE (a: Action) Do;
BEGIN
UpdateWindowTitles;
Services.DoLater(a, Services.Ticks() + 3 * Services.resolution)
END Do;
PROCEDURE GetBaseLoc;
VAR
loc: Files.Locator;
BEGIN
loc := Files.stdDir.This("");
IF loc IS HostFiles.Locator THEN
baseLoc := loc(HostFiles.Locator)
ELSE
baseLoc := NIL
END
END GetBaseLoc;
BEGIN
GetBaseLoc;
NEW(a);
Services.DoLater(a, Services.now);
Log.String("ipuiK401.UpdateWindowTitles включён"); Log.Ln
CLOSE
Services.RemoveAction(a);
Log.String("ipuiK401.UpdateWindowTitles выключен"); Log.Ln
END ipuiK401.