Программно установить флажок - PullRequest
1 голос
/ 18 октября 2019

Я пытаюсь программно установить флажок в древовидной структуре. Под обычаем я подразумеваю, что я вызываю приведенный ниже код, чтобы включить эти флажки:

SetWindowLong(TreeView1.Handle, GWL_STYLE, GetWindowLong(TreeView1.Handle, GWL_STYLE) or TVS_CHECKBOXES)

Я попытался проверить приведенный ниже код, но он не сработал.

  Node := TreeView1.Selected;
  TVItem.mask := TVIF_STATE;
  TVItem.hItem := Node.ItemId;
  TreeView_GetItem(Node.TreeView.Handle, TVItem);
  TVItem.stateMask := TVIS_CHECKED;
  TVItem.mask := TVIS_CHECKED;

Заранее спасибо

Ответы [ 2 ]

4 голосов
/ 18 октября 2019

У вас неправильная маска состояния, отсутствует маска состояния TVIS_CHECKED (на самом деле TVIS_CHECKED нет, подробнее об этом позже). Флажки управляются через список изображений, это объясняется в документации .

Кроме того, конечно, вы должны позвонить TreeView_SetItem:

const
  TVIS_CHECKED = 2 shl 12;
var
  Node: TTreeNode;
  TVItem: TTVItem;
begin
  Node := TreeView1.Selected;
  if Assigned(Node) then begin
    TVItem.mask := TVIF_STATE;
    TVItem.hItem := Node.ItemId;
    TreeView_GetItem(Node.TreeView.Handle, TVItem);

    TVItem.stateMask := TVIS_STATEIMAGEMASK;
    TVItem.state := TVIS_CHECKED;
    TreeView_SetItem(Node.TreeView.Handle, TVItem);
  end;
end;

Обычно я бы посоветовал вызвать TreeView_SetCheckState, но VCL получил странную ошибку при переводе макроса.

Это макрос в заголовке:

#define TreeView_SetCheckState(hwndTV, hti, fCheck) \
  TreeView_SetItemState(hwndTV, hti, INDEXTOSTATEIMAGEMASK((fCheck)?2:1), TVIS_STATEIMAGEMASK)

, где

#define INDEXTOSTATEIMAGEMASK(i) ((i) << 12)

Вот почему верстка TVIS_CHECKED стоит 2000 долларов, определение сдвигов 212 бит осталось, когда fCheck истинно (2 - индекс проверенного изображения, 1 не проверено).

Это перевод VCL:

function TreeView_SetCheckState(hwndTV: HWND; hti: HTreeItem; fCheck: BOOL): UINT;
var
  LState: UINT;
begin
  if IndexToStateImageMask(Integer(fCheck)) = 0 then
    LState := 1
  else
    LState := 2;
  Result := TreeView_SetItemState(hwndTV, hti, LState, TVIS_STATEIMAGEMASK);

, где IndexToStateImageMask -

Result := I shl 12;

Как ни странно, VCL сдвигает fCheck 12 бит и затем вызывает TreeView_SetItemState с состоянием, которое не имеет смысла для маски изображения состояния (TVIS_FOCUSED (1), TVIS_SELECTED (2)).

Это XE2, я предлагаю сначала протестировать макрос, если вы работаете с более поздней версией.

1 голос
/ 18 октября 2019

Что вы определили как TVIS_CHECKED? Это должно быть:

const
  TVIS_CHECKED = $2000;

Тогда, предполагая, что Value является логическим значением того, проверен ли элемент:

FillChar(TVItem, SizeOf(TVItem), 0);
TVItem.hItem := Node.ItemId;
TVItem.mask := TVIF_STATE;
TVItem.stateMask := TVIS_STATEIMAGEMASK;
if Value then
  TVItem.state := TVIS_CHECKED
else
  TVItem.state := TVIS_CHECKED shr 1;
TreeView_SetItem(Node.Handle, TVItem);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...