문제

I'm trying to make screenshots of certain forms that are open in an application. These forms may be covered/obscured by other open forms. Using CopyFromScreen isn't practical. Using DrawToBitmap on the form level gets me very close to where I want to be.

One issue with using DrawToBitmap with a control is that:

Controls inside containers are rendered in reverse order.

Symptoms: Form A has Control B and Control C on it. If Control B is in front of Control C when DrawToBitmap is called on Form A, it will first draw Control B and then draw Control C. Since Control C is drawn over top of Control B, the resulting bitmap looks like Control C is in front of Control B.

My current plan is to:

  1. Call SuspendLayout
  2. Recursively reverse the Z-Order of all controls on the form
  3. Call ResumeLayout
  4. Call DrawToBitmap, which will create an image showing the correct order
  5. Execute steps 1, 2, and 3 once more to put everything back the way it was before.

Does that sound about right?

I'm pretty sure I can use ctrl.Parent.Controls.GetChildIndex(ctrl) to get the current Z-Order index and then do a similar call with SetChildIndex to set it to a new value.

Now I'm looking for code samples that might help me accomplish the re-ordering part in as efficient of a manner as possible.

도움이 되었습니까?

해결책

Try this:

For Each ctl As Control In Me.Controls.OfType(Of Control).OrderBy(Function(c) Me.Controls.GetChildIndex(c))
  ctl.BringToFront()
Next

And then run same thing again, to revert it back:

If you have nested controls on your form, you might want to linearise this tree into an array, for easier processing (i.e. no need for recursion).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top