treeview控件上,在前面加勾的相关动作判断!高手请进,谢谢(50)

  • 主题发起人 主题发起人 jsw0525
  • 开始时间 开始时间
J

jsw0525

Unregistered / Unconfirmed
GUEST, unregistred user!
treeview控件上,在前面加勾。勾我是加上去了现在需要判断鼠标是点的前面的框 还是点击的是后面的内容?因为鼠标的不同操作,我进行处理的问题不同,需要加以判断。不晓得有办法可以区分不。非常急需,在线等待。。。
 
有一个checkbox的事件。你在哪个地方判断。。
 
写个函数判断,数的节点是否被选择不就行了。
 
谢谢chenzhihui不是要判断打勾了没有,打购没打购我知道判断。现在需要判断鼠标是点的前面的框 还是点击的是后面的内容?
 
to:chenzhihui你有QQ吗?我的QQ,27958870谢谢你。请加我
 
// 单击节点判断, 点的是何位置procedure TMsgShowFilterDlg.tv1Click(Sender: TObject);var Node: TTreeNode; P: TPoint;begin Node := tv1.Selected; if Node = nil then Exit; if not GetCursorPos(P) then Exit; // 得到光标的位置 P := tv1.ScreenToClient(P); // ComCtrls 单元 TTreeView的各个位置都枚举出来了 // THitTest = (htAbove, htBelow, htNowhere, htOnItem, htOnButton, htOnIcon, // htOnIndent, htOnLabel, htOnRight, htOnStateIcon, htToLeft, htToRight); if (htOnicon in tv1.GetHitTestInfoAt(P.X, P.Y)) then begin FTreeViewImp.ModifyTreeNodeState(Node); end;end;// 以下是我的辅助管理类unit Unit1;interfaceuses StdCtrls, ComCtrls;type // 出自 StdCtrls.TCheckBox 的状态// TCheckBoxState = (cbUnchecked, cbChecked, cbGrayed); // TTreeView **Click 触发的事件 TMsgSelChanged = procedure(ATreeNode: TTreeNode) of object; TTreeViewImp = class(TObject) private FTreeView: TTreeView; FOnMsgSelChanged: TMsgSelChanged; procedure DoOnMsgSelChanged(ATreeNode: TTreeNode); // 遍历 ATreeNode 的 所有子节点 (不含 ATreeNode) procedure RecursionChildNode(ATreeNode: TTreeNode; const AChkState: TCheckBoxState); // 遍历 ATreeNode 的 父节点 (不含 ATreeNode) procedure RecursionParentNode(ATreeNode: TTreeNode; const AChkState: TCheckBoxState); // 遍历 ATreeNode 的 兄弟节点 (含 ATreeNode) : 返回父节点的状态 function RecursionSiblingNode(ATreeNode: TTreeNode): TCheckBoxState; // 遍历一棵树 (只传根节点进去) procedure RefreshTreeView(ATreeNode: TTreeNode); // 单个节点的处理 procedure DealOneTreeNode(ATreeNode: TTreeNode; const AChkState: TCheckBoxState); public constructor Create(ATreeView: TTreeView; const ANetType: Integer); // 修改一个节点的状态, IsChanged: 表示是否已处理过本节点的状态了 procedure ModifyTreeNodeState(ATreeNode: TTreeNode; const IsChanged: Boolean = False); property OnMsgSelChanged: TMsgSelChanged read FOnMsgSelChanged write FOnMsgSelChanged; end;implementation// 遍历 ATreeNode 的 所有子节点 (不含 ATreeNode)constructor TTreeViewImp.Create(ATreeView: TTreeView; const ANetType: Integer);begin FTreeView := ATreeView; // .................... // 你的初始化生成树 //.....................end;procedure TTreeViewImp.DealOneTreeNode(ATreeNode: TTreeNode; const AChkState: TCheckBoxState);begin if ATreeNode.ImageIndex <> Ord(AChkState) then begin ATreeNode.ImageIndex := Ord(AChkState); ATreeNode.SelectedIndex := ATreeNode.ImageIndex; // 修改数组记录 DoOnMsgSelChanged(ATreeNode); end;end;procedure TTreeViewImp.DoOnMsgSelChanged(ATreeNode: TTreeNode);begin if Assigned(FOnMsgSelChanged) then FOnMsgSelChanged(ATreeNode);end;procedure TTreeViewImp.ModifyTreeNodeState(ATreeNode: TTreeNode; const IsChanged: Boolean = False);var Node: TTreeNode; ChkState, ModifiedState: TCheckBoxState;begin if ATreeNode = nil then Exit; Node := ATreeNode; ChkState := TCheckBoxState(Node.ImageIndex); if not IsChanged then begin // 本来未选中的, 则选中 if ChkState = cbUnchecked then ModifiedState := cbChecked else ModifiedState := cbUnchecked; end else ModifiedState := ChkState; // 修改自己状态 (选中) DealOneTreeNode(Node, ModifiedState); // 修改子节点 (递归全选) RecursionChildNode(Node, ModifiedState); // 查看所有兄弟节点状态, 于决定父节点状态// ModifiedState := RecursionSiblingNode(Node); while Node.Parent <> nil do begin ModifiedState := RecursionSiblingNode(Node); DealOneTreeNode(Node.Parent, ModifiedState); Node := Node.Parent; end; // 修改父节点 (递归) RecursionParentNode(Node, ModifiedState);end;procedure TTreeViewImp.RecursionChildNode(ATreeNode: TTreeNode; const AChkState: TCheckBoxState);var Node, SiblingNode: TTreeNode;begin if ATreeNode = nil then Exit; Node := ATreeNode.getFirstChild; while Node <> nil do begin SiblingNode := Node.getNextSibling; // ===================== // 对 Node 进行条件处理 DealOneTreeNode(Node, AChkState); // ===================== if Node.HasChildren then RecursionChildNode(Node, AChkState); // 有子节点, 再递归下去 // 转接下一个兄弟节点 Node := SiblingNode; end;end;// 遍历 ATreeNode 的 父节点 (不含 ATreeNode)procedure TTreeViewImp.RecursionParentNode(ATreeNode: TTreeNode; const AChkState: TCheckBoxState);var Node: TTreeNode;begin if ATreeNode = nil then Exit; Node := ATreeNode.Parent; while Node <> nil do begin // ===================== // 对 Node 进行条件处理 DealOneTreeNode(Node, AChkState); // ===================== // 下一个兄弟节点 Node := Node.Parent; end; end;// 遍历 ATreeNode 的 兄弟节点 (含 ATreeNode)function TTreeViewImp.RecursionSiblingNode(ATreeNode: TTreeNode): TCheckBoxState;var Node: TTreeNode; HasChecked: Boolean;begin HasChecked := False; Result := cbUnchecked; // 默认 if ATreeNode = nil then Exit; Node := ATreeNode.Parent; if Node = nil then Node := FTreeView.Items[0]; // 说明是第一层节点 if Node = nil then Exit; Result := cbChecked; // 默认选中, 再检查 Node := Node.getFirstChild; while Node <> nil do begin // ===================== // 对 Node 进行条件处理 if Node.ImageIndex = Ord(cbGrayed) then // 有灰的 begin Result := cbGrayed; Exit; end else if Node.ImageIndex = Ord(cbUnchecked) then // 有未选中的 begin if (Result <> cbGrayed) then // and Result <> cbUnChecked Result := cbUnchecked; end else if Node.ImageIndex = Ord(cbChecked) then // 有选中的 begin HasChecked := True; end; // ===================== // 下一个兄弟节点 Node := Node.getNextSibling; end; if HasChecked and (Result = cbUnchecked) then Result := cbGrayed;end;// 遍历一棵树procedure TTreeViewImp.RefreshTreeView(ATreeNode: TTreeNode);var Node, SiblingNode: TTreeNode;begin if ATreeNode = nil then Exit; Node := ATreeNode; while Node <> nil do begin SiblingNode := Node.getNextSibling; // 到叶子结点则修改状态 if not Node.HasChildren then // Node.Level = 2 then begin ModifyTreeNodeState(Node, True);// Exit; end else// if Node.HasChildren then begin Node := Node.getFirstChild; RefreshTreeView(Node); end; // 转接下一个兄弟节点 Node := SiblingNode; end;end;end.
 
用控件:Raize5 -> RzCheckTree
 
首先感谢各位的热心帮助,在此衷心的感谢!但是,你们还是没有看清楚我的问题,我的问题是:1。我用的就是DELPH自带的TTreeView控件,而不是什么第3方控件。2。delphi自带的这个TTreeView控件,本身是不带选择框的,这个框是我另外写代码加上去的。目前这个框框我也已经成功加上去了。3。最后,也就是我要解决的问题就是,需要判断鼠标是点的前面的框 还是点击的是后面的内容?也就是是不是做了打购和取消勾的动作,如果关选种这个节点而没有做打购或取消打购的动作的话,我不需要做什么事情,只有进行了打购或取消打购的动作,才需要处理某些东西。所以,我需要判断判断鼠标是点的前面的框 还是点击的是后面的内容。最后,我把加框框的代码和打购的代码附加在这里: 一。 SetWindowLong(listtree.Handle, GWL_STYLE, GetWindowLong(listtree.Handle, GWL_STYLE) or $00000100); //增加选择框二。function IsNodeChecked(Node: TTreeNode): Boolean;//判断勾是否被打上const TVIS_CHECKED = $2000;var TvItem: TTVItem;begin TvItem.Mask := TVIF_STATE; TvItem.hItem := Node.ItemId; TreeView_GetItem(Node.TreeView.Handle, TvItem); Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED;end;三。打购或取消勾,第2个参数为true则打勾,为false则取消勾。procedure SetNodeChecked(Node: TTreeNode; Checked: Boolean);var TvItem: TTVItem;begin FillChar(TvItem, SizeOf(TvItem), 0); with TvItem do begin hItem := Node.ItemId; Mask := TVIF_STATE; StateMask := TVIS_STATEIMAGEMASK; if Checked then TvItem.State := TVIS_CHECKED else TvItem.State := TVIS_CHECKED shr 1; TreeView_SetItem(Node.TreeView.Handle, TvItem); end;end;
 
请各位帮忙呀谢谢我是没有想到办法现在
 
我用Rc3控件的CheckTreeList试验是可以的呀,因为控件是在MouseUp时才Check控件的,所以很容易判断呀
 
to:清新空气你可以将这个控件给我不?谢谢我的邮箱:jsw0525@sina.comQQ:27958870
 
很急着解决这个问题呀有没有朋友可以给帮忙一下呀,本人万分感谢!
 
这里面的高手如云我不相信就没人能搞的定这东西吧?大家探讨一下落,多谢
 
//onMouseUp事件procedure TfMain.treeviewMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);var MyHitTest: THitTests; begin MyHitTest := tvGaopinci.GetHitTestInfoAt(X, Y); if htOnStateIcon in MyHitTest then begin end;end;
 
TO:japhe首先谢谢你onMouseUp事件,他怎么区分是点击的什么部位呢?能将这几句代码写出来吗多谢
 
treeview控件本身前面是没有带框框的。这个框框是用这句代码加上去的:SetWindowLong(listtree.Handle, GWL_STYLE, GetWindowLong(listtree.Handle, GWL_STYLE) or $00000100); //增加选择框现在要判断鼠标是点击的前面的这个框框?还是点击的其它地方
 
TO:japhe你的方法能够定位到哪个节点,但是他区别不了鼠标是不是点击的前面的框框。我现在是要判断鼠标是不是点击了框框,其他不管
 
这个难道不行吗 ? LZ 你有试过了吗? THitTest 中每一个枚举就代表着了一种类型区域,或者说 TTreeView 上的各个类型位置区域都在 THitTest 枚举中了。你在 OnMouseMove 里写点代码试一下撒~~~~// 单击节点判断, 点的是何位置procedure TMsgShowFilterDlg.tv1Click(Sender: TObject);var Node: TTreeNode; P: TPoint;begin Node := tv1.Selected; if Node = nil then Exit; if not GetCursorPos(P) then Exit; // 得到光标的位置 P := tv1.ScreenToClient(P); // ComCtrls 单元 TTreeView 的各个位置都枚举出来了 // THitTest = (htAbove, htBelow, htNowhere, htOnItem, htOnButton, htOnIcon, // htOnIndent, htOnLabel, htOnRight, htOnStateIcon, htToLeft, htToRight); if (htOnicon in tv1.GetHitTestInfoAt(P.X, P.Y)) then begin FTreeViewImp.ModifyTreeNodeState(Node); end;end;
 
to:liuls if (htOnicon in tv1.GetHitTestInfoAt(P.X, P.Y)) then begin FTreeViewImp.ModifyTreeNodeState(Node); end;这里的FTreeViewImp,是什么??编译不过它能判断出鼠标点击的是前面的那框框吗?万分感谢
 
其实不必要和么复杂的!使用它的items的image index;selected index这个属性即可用图片来模拟选中框
 
后退
顶部