Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26264
Рейтинг: 2140
#166: 2025-04-13 13:50:03 ЛС | профиль | цитата
sla8a писал(а):
И как насчет вынести свойства селектора из свойства Table?

Вынес и подшаманил код. А то с табуляторами бред творится -- https://forum.hiasm.com/getfile/40555
Давай в дальнейшем его редактировать, что бы я больше не шаманил.
sla8a писал(а):
Может нужно еще добавить цвет текста для селектора без фокуса?

Попробуй, но добавляй в последнюю редакцию. И про дефолтный цвет не забудь.
карма: 22

0
файлы: 1hiMTStrTbl_Change_Select_Text_Color_25_04_13_c2.zip [15.6KB] [57]
Ответов: 2370
Рейтинг: 683
#167: 2025-04-13 13:56:08 ЛС | профиль | цитата
А подскажи как унаследовать переменные чтоб функция их признала как родные:
function WndHDR(Sender: PControl; var Msg: TMsg; var Rslt: Integer): Boolean;
const
HDN_FIRST = -300; { Header }
HDN_ITEMCHANGINGA = HDN_FIRST - 0;
HDN_ITEMCHANGEDA = HDN_FIRST - 1;
HDN_DIVIDERDBLCLICKA = HDN_FIRST - 5;
HDN_BEGINTRACKA = HDN_FIRST - 6;
HDN_ENDTRACKA = HDN_FIRST - 7;
HDN_ITEMCHANGINGW = HDN_FIRST - 20;
HDN_ITEMCHANGEDW = HDN_FIRST - 21;
HDN_DIVIDERDBLCLICKW = HDN_FIRST - 25;
HDN_BEGINTRACKW = HDN_FIRST - 26;
HDN_ENDTRACKW = HDN_FIRST - 27;
type
tagNMHEADERA = packed record
Hdr: TNMHdr;
Item: Integer;
Button: Integer;
PItem: PHDItemA;
end;
HD_NOTIFY = tagNMHEADERA;
PHDNotify = ^HD_NOTIFY;
PNMHEADER = ^tagNMHEADERA;
var
fClass: ThiMTStrTbl;
ind: integer;
di, dw, dow: TData;
s: string;
FData: TData;
Color: TColor;

function getColor(index: integer; selectItem:boolean):TColor;
begin
if _prop_SelectColorMode = 2 and FColorItems then//set default color
begin
if selectItem then
Result := FSelectTextColor
else
Result := FSelectTextColorNoFocus;
if Assigned(PData(Sender.LVItemData[index])) and (Sender.Count <> 0) then
if (Sender.LVItemData[index] > 65535) then
begin
CopyData(@FData, PData(Sender.LVItemData[index]));
Color := ToInteger(FData);
ind := ($0F000000 and Color) shr 24;
FreeData(@FData);
Result := AColor[ind];//sets the text color
end;
end;
end;


begin

Редактировалось 3 раз(а), последний 2025-04-13 14:18:08
карма: 11

0
Разработчик
Ответов: 26264
Рейтинг: 2140
#168: 2025-04-13 14:15:33 ЛС | профиль | цитата
sla8a писал(а):
А подскажи как унаследовать переменные чтоб функция их признала как родные:

Ты про какие переменные?
карма: 22

0
Ответов: 2370
Рейтинг: 683
#169: 2025-04-13 14:17:01 ЛС | профиль | цитата
Ругается на это:
D:\HiAsm\HiAsm_AltBuild\Elements\delphi\code\hiMTStrTbl.pas(864) Error: Undeclared identifier: '_prop_SelectColorMode'
D:\HiAsm\HiAsm_AltBuild\Elements\delphi\code\hiMTStrTbl.pas(864) Error: Undeclared identifier: 'FColorItems'
D:\HiAsm\HiAsm_AltBuild\Elements\delphi\code\hiMTStrTbl.pas(867) Error: Undeclared identifier: 'FSelectTextColor'
D:\HiAsm\HiAsm_AltBuild\Elements\delphi\code\hiMTStrTbl.pas(869) Error: Undeclared identifier: 'FSelectTextColorNoFocus'
Хочу вынести отдельной функцией получение нужного цвета текста.

Редактировалось 2 раз(а), последний 2025-04-13 14:17:39
карма: 11

0
Разработчик
Ответов: 26264
Рейтинг: 2140
#170: 2025-04-13 14:18:40 ЛС | профиль | цитата
Эти переменные относятся к классу таблицы, а не к классу контрола. Надо получить в обработчике контрола указатель на класс таблицы.

--- Добавлено в 2025-04-13 14:20:21

См передачу указателя в обработчике WndProcTabGrid -- fClass

Редактировалось 2 раз(а), последний 2025-04-13 14:20:57
карма: 22

0
Ответов: 2370
Рейтинг: 683
#171: 2025-04-13 14:20:46 ЛС | профиль | цитата
nesco, а не проще эти данные в функцию передать:

function getColor(все переменные):TColor;
карма: 11

0
Разработчик
Ответов: 26264
Рейтинг: 2140
#172: 2025-04-13 14:22:07 ЛС | профиль | цитата
sla8a писал(а):
а не проще эти данные в функцию передать:

Эта функция относится все равно к классу таблицы и от получения указателя никуда не денешься.

--- Добавлено в 2025-04-13 14:44:44

И зачем тебе все это надо, когда в твоем обработчике уже используется fClass?

--- Добавлено в 2025-04-13 14:46:53

И чего там думать, когда можно передать класс таблицы в твою функцию

Редактировалось 3 раз(а), последний 2025-04-13 14:46:53
карма: 22

0
Ответов: 2370
Рейтинг: 683
#173: 2025-04-13 15:20:46 ЛС | профиль | цитата
nesco писал(а):
И зачем тебе все это надо, когда в твоем обработчике уже используется fClass?
Отказался от функции, сделал по другому.

-Добавил возможность чередования цвета строк. Вещь не прихотливая и работает только если не задействована поддержка цвета ячеек ColorItems=False. Свойством можно задействовать и выбрать с четной или нечетной начать окрашивать. И выбор цвета.
-Добавил цвет текста выделенной строки без фокуса. Так же работает только в режиме SelectColorMode=Custom. Может эти режимы по другому обозвать? К примеру Standart,All,OnlyBackground. All использует все цвета, OnlyBackground использует только цвет фона, цвет текста задается строкой ColorItems=true или по умолчанию.

На сегодня все, голова уже не соображает. Надо завтра на свежую голову посмотреть в код. Вот это точно надо менять:
if not _prop_FocusFrame and (((PNMLVCustomDraw(Msg.LParam)^.nmcd.uItemState shr 4) and 1) = 1) then//delete focus frame
PNMLVCustomDraw(Msg.LParam)^.nmcd.uItemState := CDIS_DEFAULT or CDIS_SELECTED;
Нужно будет "вырезать" флаг фокуса, а не полностью заменять. А то там насколько помню еще флаг CDIS_SHOWKEYBOARDCUES установлен, мало ли когда он выплывет боком его удаление. Да флаг CDIS_SELECTED тоже наверно желательно "вырезать". Надо это дело посмотреть.

Редактировалось 2 раз(а), последний 2025-04-13 23:49:17
карма: 11

0
Ответов: 2370
Рейтинг: 683
#174: 2025-04-13 23:49:01 ЛС | профиль | цитата
Скорее всего над правками все. Поправил код и сейчас он выглядит логичней. Флаги удаляются, а не подменяются и нет лишнего. Конечно нужно протестировать все.

Скачать архив


Нашел другую ошибку. Она не связана с текущими правками (можно легко проверить отключив весь код NM_CUSTOMDRAW). Ошибка в следующем:
1. Таблица в множественном режиме (MultiSelect = true)
2. Сбросить все выделенные строки (нажать на пустое поле)
3. Используя курсор мыши выделить первую строку (верхнюю), затем с зажатым Ctrl выбрать вторую строку (следующую за первой), еще раз нажать на вторую строку с зажатым Ctrl чтоб снять выделенную строку
И тут возникает вопрос. Сколько строк выделено в таблице?

На таблице отображается на данный момент 1 строка. onSelect после второго нажатия на одну и туже строку событие не выдает (о чем и сообщает в описании). Но если бы вместо второй строки снять выделение с первой, то onSelect сработал. Черт с ним с onSelect, вернемся к количеству выделенных строк.

Если спросить у MST_Selected то SelCount сообщит что выделена одна строка. Вроде все сходится. Но если задействовать doSelectInvert (инвертировать выделенные строки) у MST_SelectRow, то выделятся все строки кроме двух первых, что значит что все таки две строки выделено.

Если проделать еще один пункт:
4. Зажать Ctrl и с помощью кнопок стрелок вверх или вниз сдвинуть хоть на одну строку рамку фокуса.
Если сейчас инвертировать выбор строк, то будет все правильно (выделятся все строки кроме одной).

Пока вывод такой что что-то в таблице не обновляется. Причем при выборе разных строк (к примеру если выбрать первую и третью ошибки нет), ошибка может появиться, а может и нет. Хорошо бы найти что.

Схема для тестирования ошибки

Add(MainForm,4651952,266,217)
{
Width=683
Height=500
Position=1
link(onCreate,3556725:doEnum,[])
}
Add(StrList,6915816,315,175)
{
Strings=#33:1;test string 111;test string 12;|33:2;test string 121;test string 22;|33:3;test string 131;test string 32;|33:4;test string 141;test string 42;|33:5;test string 151;test string 52;|33:6;test string 161;test string 62;|33:7;test string 171;test string 72;|33:8;test string 181;test string 82;|
}
Add(MST_RowAction,4870764,455,224)
{
MSTControl="testTable"
}
Add(ArrayEnum,3556725,329,231)
{
link(onItem,6192416:doMT,[])
link(onEndEnum,11481923:doWork1,[(375,244)])
link(Array,6915816:Array,[])
}
Add(MTStrTbl,4186365,322,294)
{
Left=15
Top=15
Width=640
Height=355
Font=[MS Sans Serif,12,0,0,1]
Name="testTable"
Columns=#8:test1=80|9:test2=200|9:test3=200|
MultiSelect=0
Point(onSelect)
link(onSelect,11481923:doWork2,[])
}
Add(Label,14464975,448,322)
{
Left=175
Top=395
Width=290
Height=25
Font=[MS Sans Serif,12,0,0,1]
}
Add(MST_Selected,12880888,392,273)
{
MSTControl="testTable"
Point(SelCount)
}
Add(FormatStr,9258879,406,322)
{
DataCount=1
Mask="Выделенно строк: %1"
link(onFString,14464975:doText,[])
link(Str1,12880888:SelCount,[])
}
Add(HubEx,11481923,371,322)
{
link(onEvent,9258879:doString,[])
}
Add(MT_String,6192416,399,224)
{
link(onResult,4870764:doRowAction,[])
}
Add(MST_SelectRow,9185103,322,350)
{
IndexSelect=3
MSTControl="testTable"
Point(doSelectInvert)
link(onSelectRow,12417933:doWork2,[])
}
Add(Button,2053362,273,357)
{
Left=30
Top=395
Width=120
Height=25
Font=[MS Sans Serif,12,0,0,1]
Caption="InvertSelect"
link(onClick,9185103:doSelectInvert,[])
}
Add(Timer,12470391,322,406)
{
Interval=300
Enable=1
link(onTimer,12417933:doWork3,[(375,412)])
}
Add(HubEx,12417933,371,350)
{
Angle=3
link(onEvent,11481923:doWork3,[])
}
Add(CheckBox,9091168,231,399)
{
Left=170
Top=425
Width=200
Font=[MS Sans Serif,12,0,0,1]
Caption="Мониторить"
link(onCheck,6990708:doEvent,[])
}
Add(IndexToChanel,6990708,273,399)
{
link(onEvent1,12470391:doStop,[(313,405)(313,419)])
link(onEvent2,12470391:doTimer,[])
}

Редактировалось 5 раз(а), последний 2025-04-14 09:23:49
карма: 11

0
Разработчик
Ответов: 26264
Рейтинг: 2140
#175: 2025-04-14 01:44:01 ЛС | профиль | цитата
У меня голова вспухла от одного только описания ошибки и приводимых к ней действий. Я пока ни х... не понял, но очень интересно.
карма: 22

0
Ответов: 2370
Рейтинг: 683
#176: 2025-04-14 09:24:23 ЛС | профиль | цитата
Может так будет понятней:
gif


карма: 11

0
Разработчик
Ответов: 26264
Рейтинг: 2140
#177: 2025-04-14 19:18:09 ЛС | профиль | цитата
А че _OnSelState выдает? Наверное там надо сначала копать
карма: 22

0
Ответов: 2370
Рейтинг: 683
#178: 2025-04-14 22:06:40 ЛС | профиль | цитата
nesco, проблема скорее всего в MST_SelectRow в процедуре doSelectInvert. Вот смотри:

for i := 0 to sControl.Count - 1 do
if sControl.LVItemState[i] = [] then
sControl.LVItemState[i] := [lvisSelect, lvisFocus]
else
sControl.LVItemState[i] := [];
Получается что он делает выделенными все строки где вообще нет флагов, а всем остальным строкам очищает флаги. Правильнее будет убрать все флаги с строк где есть флаг lvisSelect, а все остальные выделить:

  for i := 0 to sControl.Count - 1 do
if (lvisSelect in sControl.LVItemState[i]) then
sControl.LVItemState[i] := []
else
sControl.LVItemState[i] := [lvisSelect, lvisFocus];
При такой правке начало работать правильно. Да и логичнее выглядит процедура.

nesco писал(а):
А че _OnSelState выдает?
Знать бы что означают значения OldState и newState. Не нашел описания. 0 -чистая строка, 3 -выделенная строка, 1 - фокус, а что 2?
карма: 11

0
Разработчик
Ответов: 26264
Рейтинг: 2140
#179: 2025-04-14 22:51:29 ЛС | профиль | цитата
sla8a писал(а):
Знать бы что означают значения OldState и newState. Не нашел описания. 0 -чистая строка, 3 -выделенная строка, 1 - фокус, а что 2?

Если бы еще вспомнить.

--- Добавлено в 2025-04-14 23:01:05

О! Нашел
  LVIS_FOCUSED            = $0001;
LVIS_SELECTED = $0002;
LVIS_CUT = $0004;
LVIS_DROPHILITED = $0008;
//LVIS_ACTIVATING = $0020;

LVIS_OVERLAYMASK = $0F00;
LVIS_STATEIMAGEMASK = $F000;


Описание -- https://learn.microsoft.com/en-us/windows/win32/controls/list-view-item-states

Редактировалось 3 раз(а), последний 2025-04-14 23:05:58
карма: 22

0
Ответов: 2370
Рейтинг: 683
#180: 2025-04-15 14:54:07 ЛС | профиль | цитата
Все таки проблема была в MST_SelectRow в процедуре doSelectInvert. Думаю нужно сделать так:

procedure THIMST_SelectRow._work_doSelectInvert;
var
sControl: PControl;
i: integer;
begin
if not Assigned(_prop_MSTControl) then exit;
sControl := _prop_MSTControl.ctrlpoint;
if (sControl.Count = 0) or not(lvoMultiSelect in sControl.LVOptions) then exit;
for i := 0 to sControl.Count - 1 do
if (lvisSelect in sControl.LVItemState[i]) then
sControl.LVItemState[i] := []
else
sControl.LVItemState[i] := [lvisSelect, lvisFocus];
_hi_onEvent(_event_onSelectRow);
end;
карма: 11

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)