虚拟字符串树单元绘制
好吧,我有以下问题:
我根据一些布尔变量将树单元绘制为不同的颜色。 示例:
- isProcessService、
- isProcessInDebugger、
- isProcessService、
- isProcessElevated、
- isProcessNet
- 、isProcessOwner、
- isProcessinJob、
- isProcessPacked、
- isProcessMarkedForDeletion、
- isProcessMarkedForCreation :布尔值;
因此,在 BeforeCellPaint 中,我将根据这些布尔值绘制单元格背景颜色,例如:
procedure TMainForm.ProcessVstBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); var NodeData: PProcessData; begin if Node = nil then Exit; NodeData := Sender.GetNodeData(Node); if NodeData = nil then Exit; if (NodeData^.isProcessOwner) then begin TargetCanvas.Brush.Color := $00AAFFFF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessInDebugger) then begin TargetCanvas.Brush.Color := $00E5A5A5; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.pProcessID = 0) or (NodeData^.pProcessID = 4) then begin TargetCanvas.Brush.Color := $00FFCCAA; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessElevated) and not(NodeData^.isProcessInDebugger) then begin TargetCanvas.Brush.Color := $0000AAFF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^isProcessService) and not (NodeData^.isProcessPacked) and not(NodeData^.isProcessNet) then begin TargetCanvas.Brush.Color := $00FFFFCC; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessMarkedForDeletion) then begin TargetCanvas.Brush.Color := $005D5DFF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessMarkedForCreation) then begin TargetCanvas.Brush.Color := $0061E15E; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessNet) then begin TargetCanvas.Brush.Color := $005CE0BF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; end;
问题是:
我如何根据要创建或删除的进程将单元格绘制为绿色或红色(让颜色停留至少一秒钟,然后切换回其原始值?)
换句话说,一个进程创建后将单元格绘制为绿色,稍等一下,然后切换回原始颜色,具体取决于:isProcessService、is ProcessOwner 等等...
最大的问题是我需要在非阻塞模式下使用它(我不能使用睡眠,否则树也会冻结,因此不会注意到颜色变化)
如果您仍然无法理解我,我正在尝试模仿 Process Explorer 或 Process Hacker 在创建或删除进程时所做的相同行为。这两个应用程序都将这些进程的单元格背景绘制为红色或绿色一秒钟,然后切换回单元格的原始颜色。
仅供参考,我将通过 wmi 收到进程创建或删除的通知。
Well, I have the following problem:
I've painted the tree cells in different colors depending on some boolean vars.
Example:
- isProcessService,
- isProcessInDebugger,
- isProcessService,
- isProcessElevated,
- isProcessNet,
- isProcessOwner,
- isProcessinJob,
- isProcessPacked,
- isProcessMarkedForDeletion,
- isProcessMarkedForCreation : Boolean;
So in BeforeCellPaint I'll paint the cells background color based on those booleans like:
procedure TMainForm.ProcessVstBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); var NodeData: PProcessData; begin if Node = nil then Exit; NodeData := Sender.GetNodeData(Node); if NodeData = nil then Exit; if (NodeData^.isProcessOwner) then begin TargetCanvas.Brush.Color := $00AAFFFF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessInDebugger) then begin TargetCanvas.Brush.Color := $00E5A5A5; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.pProcessID = 0) or (NodeData^.pProcessID = 4) then begin TargetCanvas.Brush.Color := $00FFCCAA; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessElevated) and not(NodeData^.isProcessInDebugger) then begin TargetCanvas.Brush.Color := $0000AAFF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^isProcessService) and not (NodeData^.isProcessPacked) and not(NodeData^.isProcessNet) then begin TargetCanvas.Brush.Color := $00FFFFCC; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessMarkedForDeletion) then begin TargetCanvas.Brush.Color := $005D5DFF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessMarkedForCreation) then begin TargetCanvas.Brush.Color := $0061E15E; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; if (NodeData^.isProcessNet) then begin TargetCanvas.Brush.Color := $005CE0BF; TargetCanvas.FillRect(TargetCanvas.ClipRect); end; end;
The question is:
How could I paint the cell green or red depending on a process is going to be created or deleted (let the color stay for at least one second and then switch back to its original value?)
I other words, a process is created paint the cell green wait a second and then switch back to the original color depending on: isProcessService, is ProcessOwner and so on...
The biggest Problem is I need this in a non blocking mode (I can not use sleep otherwise the tree will freeze too so the color change will not be noticed)
If you still can not follow me, I'm trying to mimic the same behavior Process Explorer or Process Hacker does when a process is created or deleted. Both applications paints the cell background for those processes red or green for a second then switching back to the original color the cell had.
Just for information, I'll get notified of process creation or deletion via wmi.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
每当创建一个进程时,都会启动一个与该进程关联的计时器,超时时间为 1 秒。
isProcessMarkedForCreation
设置为 true,因此该行被涂成绿色。当计时器触发时,处理程序将 isProcessMarkedForCreation 设置为 false 并强制重新绘制该行,从而删除绿色突出显示。现在计时器已经完成了它的工作,应该将其删除。可以使用完全相同的方法进行删除。Whenever a process is created, start a timer associated with that process with a timeout of 1s. The
isProcessMarkedForCreation
is set to true and so the row is painted green. When the timer fires the handler setsisProcessMarkedForCreation
to false and forces a repaint of that row which removes the green highlight. Now that the timer has done its work it should be deleted. The exact same approach can be used for deletion.