thomas10001 Posted December 6, 2005 Posted December 6, 2005 I need to capture the image of a hidden window. Can this be done without making it the top level window? (I have already code to capture an image of the top level window. But that involves a lot of hiding and showing windows and creates problem with flickering and that the whole area is not redrawn and I do not always capture what I want.) Quote
Leaders snarfblam Posted December 6, 2005 Leaders Posted December 6, 2005 I'll tell you what I know, which isn't much. In Windows generally the image for a window is only that which is stored on the screen, which means that if all or part of a window isn't visible, the image for the concealed portion does not exist. There must be a way, however, to have a form draw itself somewhere other than the screen because Microsoft offers an alt-tab replacement program which shows the image of the window you are tabbing to, even if it isn't visible (or completely visible). Quote [sIGPIC]e[/sIGPIC]
jo0ls Posted December 7, 2005 Posted December 7, 2005 (edited) Everyone uses bitblt, but there is the printWindow API too (which works for off-screen and hidden forms). One thing that you can't do though is create a form that is bigger than the available working screen space. Private Declare Function PrintWindow Lib "user32.dll" (ByVal _ hwnd As IntPtr, ByVal hdcBlt As IntPtr, ByVal nFlags As _ UInt32) As Boolean Dim WithEvents t As New Timer Dim screenCapture As Bitmap Dim otherForm As New Form Private Sub CaptureScreen() Me.Text = "capturing, " & Me.Location.X & "," & Me.Location.Y screenCapture = New Bitmap(Me.Width, Me.Height) Dim g As Graphics = Graphics.FromImage(screenCapture) Dim hdc As IntPtr = g.GetHdc Form1.PrintWindow(Me.Handle, hdc, Nothing) g.ReleaseHdc(hdc) g.Flush() g.Dispose() End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' uncomment to test capturing various hidden forms: '1- hidden off screen -> works! 'Me.Location = New Point(-500, -500) '2- Minimizes - works but just takes a capture of the small minimized form... 'Me.WindowState = FormWindowState.Minimized '3- big form laid over the top otherForm.Size = New Size(4000, 4000) otherForm.Show() t.Interval = 1000 t.Start() End Sub Private Sub t_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles t.Tick CaptureScreen() If IO.File.Exists("C:\\ScreenCapBlah.bmp") Then IO.File.Delete("C:\\ScreenCapBlah.bmp") End If screenCapture.Save("c:\\ScreenCapBlah.bmp") Me.Text = "" '1 - move the form back ' Me.Location = New Point(0, 0) '2- maximize again ' Me.WindowState = FormWindowState.Maximized '3 - hide otherForm otherForm.Hide() t.Stop() End Sub Edited December 7, 2005 by jo0ls Quote
thomas10001 Posted December 7, 2005 Author Posted December 7, 2005 PrintWindow It seems that I should use PrintWindow I found the following code that I modified a bit. public static Bitmap captureHiddenWindow(IntPtr hwnd) { Bitmap bitmap = null; // Takes a snapshot of the window hwnd, stored in the memory device context hdcMem IntPtr hdc = PlatformInvokeGDI32.GetWindowDC(hwnd); if (hdc != IntPtr.Zero) { IntPtr hdcMem = PlatformInvokeGDI32.CreateCompatibleDC(hdc); if (hdcMem != IntPtr.Zero) { Rectangle rc; PlatformInvokeGDI32.GetWindowRect(hwnd,out rc); IntPtr hbitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hdc, rc.Width, rc.Height); if (hbitmap != IntPtr.Zero) { PlatformInvokeGDI32.SelectObject(hdcMem, hbitmap); Win32.PrintWindow(hwnd, hdcMem, 0); bitmap = System.Drawing.Image.FromHbitmap(hdcMem); PlatformInvokeGDI32.DeleteObject(hbitmap); } PlatformInvokeGDI32.DeleteObject(hdcMem); } PlatformInvokeGDI32.ReleaseDC(hwnd, hdc); } return bitmap; } I added the bitmap = System.Drawing.Image.FromHbitmap(hdcMem); because I need a bitmap returned. I got an exception when I tried it due to (I guess) hdcMem was negative. What do I do wrong here? Is there another way to use the dc that I am not aware of? Quote
thomas10001 Posted December 7, 2005 Author Posted December 7, 2005 I just found out that I did mix up the parameters FromHbitmap(hdcMem); should've been FromHbitmap(hbitmap); and it works fine! Thanks all! Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.