I'm trying to add the same functionality to a WPF application that allows the user to see thumbnails of static and dynamic forms when not loaded but also thumbnails of forms that are open and loaded with data.
Anyone have any ideas on achieving this functionality?
In Winforms there's a method on the form you can use to tell it to draw itself to a bitmap. Not sure if WPF has the same thing. If a form is 'not loaded', then it does not exist, you'd need to store default thumbnails to show in that instance.
Driven to the arms of OSX by Vista.
"I am new to programming world. I have been learning c# for about past four weeks. I am quite acquainted with the fundamentals of c#. Now I have to work on a project which converts given flat files to XML using the XML serialization method" - SK64 ( but the forums have stuff like this posted every day )
A similar method to the one Christian mentioned is RenderTargetBitmap.Render[^]. It doesn't work exactly the same way the Control.DrawToBitmap[^] does. I tried to draw in the constructor after initialize components while the window is minimized and they gave different results.
Also, try to bind the thumbnails viewer to the windows and use a converter to convert a window to an image. But I'm not sure if this would work specially when a window is hidden or minimized.
Thanks for the pointers ... What I've come up with is the following:
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs) _
Dim CaptureForm As New TestForm
CaptureForm.Left = -999
Image1.Source = CaptureFrameworkElement(CaptureForm)
CaptureForm = Nothing
Function CaptureFrameworkElement(ByVal fe As FrameworkElement) As BitmapSource
Dim renderBitmap As New RenderTargetBitmap(CInt(Math.Ceiling(fe.ActualWidth)), _
96, 96, PixelFormats.Pbgra32)
Dim dv As New DrawingVisual()
Using dc As DrawingContext = CType(dv.RenderOpen(), DrawingContext)
Dim visualBrush As New VisualBrush(fe)
Dim rect1 As New Rect(New System.Windows.Point(0, 0),_
dc.DrawRectangle(visualBrush, Nothing, rect1)
Return CType(renderBitmap, BitmapSource)
This will let you capture any visual element. The only issue I have now is that only the contents of the form are captured and not the non-client area.
The only issue I have now is that only the contents of the form are captured and not the non-client area.
I'm thinking about accessing the Window as a Form, and call the DrawToBitmap. But I couldn't get it to work now and I don't know if it's possible. I have an exam tomorrow so I can't investigate it further right now. Maybe if there is some Win32 API that does take a snapshot of a window by handle, since we can access the handle.
' the code is not tested
Dim hlper As New System.Windows.Interop.WindowInteropHelper(Me)
Dim windowAsForm = System.Windows.Forms.Form.FromHandle(hlper.Handle) ' returns null, don't know why
Dim w = windowAsForm.Size.Width
Dim h = windowAsForm.Size.Height
Dim bitmap As New System.Drawing.Bitmap(w, h)
windowAsForm.DrawToBitmap(bitmap, New System.Drawing.Rectangle(0, 0, w, h))
' code from <a href="http://dedjo.blogspot.com/2007/05/how-to-use-systemdrawingbitmap-hbitmap.html">here</a>[<a href="http://dedjo.blogspot.com/2007/05/how-to-use-systemdrawingbitmap-hbitmap.html" target="_blank" title="New Window">^</a>], i didn't test it
Return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), _
I couldn't get around your problem... So I tried something different but not getting an image...
Dim hlper As New System.Windows.Interop.WindowInteropHelper(Me)
Dim gr As System.Drawing.Graphics = System.Drawing.Graphics.FromHwnd(hlper.Handle)
Dim ms As New MemoryStream
Dim bmp As System.Drawing.Bitmap = New System.Drawing.Bitmap(gr.VisibleClipBounds.Width, gr.VisibleClipBounds.Height, gr)
Dim bImg As System.Windows.Media.Imaging.BitmapImage = New System.Windows.Media.Imaging.BitmapImage()
bImg.StreamSource = New MemoryStream(ms.ToArray())
PS: I'm running in fullscreen mode and want preview and open window thumbnails as navigational tools...
I tried sending WM_PAINT to the window but I only got the border without the content. Looks like WPF windows do not respond to WM_PAINT properly and there is no built-in method to draw non-client area. Try to get the non-client area and the client area and compose into a single bitmap. Or maybe you should look into this DWM Thumbnail Overview[^].
I tried sending WM_PAINT to the window but I only got the border without the content.
What I do know is that WPF & GDI+ work in two seperate worlds... WPF draws in DirectX space...
I'd be interested in looking at it. I've got the code to capture the elements and you've got the code to capture the non-client area. Tying the two techniques together is a near enough hack to solve my problem.
Private Const WM_PRINT As Integer = &H317
Private Const PRF_NON_CLIENT As Integer = &H2
Private Const PRF_CLIENT As Integer = &H4
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageW" (ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
Public Sub DrawToBitmap(ByVal hWnd As IntPtr, ByVal bitmap As System.Drawing.Bitmap, _
ByVal targetBounds As System.Drawing.Rectangle)
If (bitmap Is Nothing) Then Throw New ArgumentNullException("bitmap")
If (((targetBounds.Width <= 0) OrElse (targetBounds.Height <= 0)) _
OrElse ((targetBounds.X < 0) OrElse (targetBounds.Y < 0))) Then _
Throw New ArgumentException("targetBounds")
Using graphics = System.Drawing.Graphics.FromImage(bitmap)
Dim hDC = graphics.GetHdc()
SendMessage(hWnd, WM_PRINT, hDC.ToInt32(), PRF_CLIENT + PRF_NON_CLIENT)
But you'll have to get the exact width and height of the window in case the window is maximized.
Althought WPF uses DirectX, I think they could have made WM_Print work by composing the client and non-client bitmaps the same way you would do with the code.
Are there any issues with using a WPF Browser Application with WCF as I was reading something about issues with WSDualHttpBinding. If this is the case is the best way around it to have use BasicHttpBinding or WSHttpBinding and don't use callbacks.
Cheers for your view / help with this.
Some people are like slinky's... They're not really good for anything but they bring a smile to your face when pushed down the stairs
Hello guys! I need to have different context menus in my datagrid - one for its header and one for rows of a grid. So I'm handling MouseClick event and than I need to evaluate if the underlying object for mouse cursor is Datagrid's header. Can you explain me how can I make this? The thing that I can't understand is that neither of DataGrid's and DataGridColumn's hierarchy of objects contain DataGridColumnHeader object or any reference to it. But in virtual tree if I get textblock that is located in header and contains column header's text and then get it parent container, I'll get DatagridColumnHeader object.
You might have better luck getting a good answer over on the codeplex forum.
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
Individuality is fine, as long as we do it together - F. Burns
Help humanity, join the CodeProject grid computing team here