Solved

Is there any way to create an 'image' of a website?

Posted on 2004-03-28
7
488 Views
Last Modified: 2007-12-19
Hi,
this is going in the languages section, as I'm using c# (so a solution in that would be ideal) but I think any relevant programming is more low-level so c/c++ stuff would be useful as well.
Right, I need a way to take a url and return an image - as in a Bitmap.
This is driving me crazy - is there actually any way?

I've looked into creating an instance of Internet Explorer (SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorerClass();)
and capturing the screen...

int hWindowDC, hOffscreenDC, hBMP, hBMPOld, r;
const int SRCCOPY = 13369376;
hWindowDC = GetWindowDC(hWnd);
hOffscreenDC = CreateCompatibleDC(hWindowDC);
hBMP = CreateCompatibleBitmap(hWindowDC, 800, 600);
hBMPOld = SelectObject(hOffscreenDC, hBMP);
r = BitBlt(hOffscreenDC, 0, 0, 800, 600, hWindowDC, 0, 0, SRCCOPY);
hBMP = SelectObject(hOffscreenDC, hBMPOld);
r = DeleteDC(hWindowDC);
r = DeleteDC(hOffscreenDC);
Bitmap ret = Image.FromHbitmap(new IntPtr(hBMP));
DeleteObject(hBMP);
ret.Save("C:\\capturescreentest.bmp");

but this really isn't the ideal approach - for one I don't want the explorer window on top, which is of course vital if I'm capturing the screen. Is there any way I can do it 'behind the scenes'? Is there any way to do it without opening internet explorer for that matter?

Thanks for your time.
0
Comment
Question by:shifty_mc
  • 3
  • 3
7 Comments
 
LVL 5

Accepted Solution

by:
JMoon5FTM earned 300 total points
ID: 10720684
I'd start by creating a WebBrowser control instead of an instance of Internet Explorer - it'll perform better, for one thing.

Off the top of my head, you could try sending the WebBrowser a WM_PRINTCLIENT message.  WPARAM should be the hDC you want to draw in, and LPARAM should be PRF_CLIENT + PRF_CHILDREN.

Never tried this before, and don't know if it works - but if it doesn't, you're probably stuck with capturing the screen.
0
 
LVL 5

Expert Comment

by:JMoon5FTM
ID: 10720686
If that doesn't work, the MSDN web site also mentions a WM_PRINT message that takes the same arguments.  MSDN documents it exactly the same way, so I'm not sure what the difference is.
0
 

Author Comment

by:shifty_mc
ID: 10721166
ah, ok, since I posted I have changed to using a WebBrowser control like you said.
The code I have is a Form which conatins a WebBrowser control.  The browser is navigated to a url, and when the DownloadComplete Event happens, I want to capture the screen.
This WM_PRINT stuff appears to be exactly what I'm looking for so thank you, but I'm unsure how to implement it in C#.
I've looked at http://www.fengyuan.com/article/wmprint.html and worked out the following code...

Graphics grfxScreen = Graphics.FromHwnd(hWnd);
MyBitmap = new Bitmap((int) this.Width, (int) this.Height, grfxScreen);
Graphics grfxBitmap = Graphics.FromImage(MyBitmap);
IntPtr hdcBitmap = grfxBitmap.GetHdc();
Message printClientMessage = Message.Create(hWnd, WM_PRINTCLIENT, hdcBitmap, new IntPtr(PRF_CHILDREN | PRF_CLIENT));  
DefWndProc(ref printClientMessage);

However, as the article in the link above says, this only gets a blank screen.  The article shows how to add/change code to OnPaint and LRESULT CALLBACK WndProc0, but I have no idea how to do this in C#.

Any ideas?
Cheers.

If anyone comes up with the appropriate c# code by the way (I can't imagine it'd be too hard to translate using the above link) I'd be more than happy to increase the points - I can sense the answer getting closer!
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 1

Expert Comment

by:jstiff
ID: 10723330
Take a look at the following URL.  Not sure, but it sounds like it might address some of your questions.

http://www.codeproject.com/csharp/ImageCapture.asp?target=image%7Ccapture
0
 

Author Comment

by:shifty_mc
ID: 10725050
No, this demonstrates the techniques I know about - using BitBlt to capture screen.
The WM_PRINT stuff is definitely the way to go... if I can get it working, but thanks anyway.

Incidentally, I now have...

protected override void WndProc(ref Message m)
{
      switch ((Win32.Msgs)m.Msg)
      {
            case Win32.Msgs.WM_PRINTCLIENT:
                  SendMessage(m.HWnd, m.Msg, m.WParam, m.LParam);
                  break;

            case Win32.Msgs.WM_PAINT:
// Not sure if following two commented out lines would achieve the same result or not - they'd probably be better, because they use c# graphics instead of c++ pointers, but don't know
                  //Graphics g = Graphics.FromHdc(m.WParam);
                  //OnPaint(new PaintEventArgs(g, g.ClipBounds));
                  OnPaint(m.HWnd,m.WParam);
                  break;

            default:
                  // unhandled window message
                  base.WndProc(ref m);
                  break;
      }
}

I then need to have an OnPaint method - but this is where I get stuck in the translation to C# - any ideas? The C++ version from the article on that link I mentioned in a previous comment is...

void OnPaint(HWND hWnd, WPARAM wParam)
{
    PAINTSTRUCT ps;
    HDC         hDC;
    if ( wParam==0 )
        hDC = BeginPaint(hWnd, & ps);
    else
        hDC = (HDC) wParam;
    OnDraw(hWnd, hDC);
    if ( wParam==0 )
        EndPaint(hWnd, & ps);
}

What's the C# equivalent for OnDraw? And can I rewrite this Onpaint method if it takes a PaintEventArgs such as that from my commented out code in the WndProc method?
0
 
LVL 5

Expert Comment

by:JMoon5FTM
ID: 10735911
The article you're referring to looks neat, but I think that stuff is too low-level to implement in C#.  Not knowing C# myself, though, I can't say for sure and I'm afraid I can't be a lot of help with such stuff.  Even if you do get it to work, though, the article says it doesn't work in Win95/98/ME, so that's something to beware of.

If you need more help, try posting another question, maybe in the .NET area.
0
 

Author Comment

by:shifty_mc
ID: 10736385
Hi,

I've just cracked it! I created a separate message to deal with what I thought was a separate issue, but it all ties in really, so if anyone's interested, see...
http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_20939542.html
The actual capturing of a screen hidden from view is done using WM_PRINT, and I think my code for that is on the other message thread as well. For some reason it wouldn't work when converted it to C# graphics, so I just used lots of dllimports. The only other issue (which kept me frustrated for a VERY long time) was that even when every event signified that the browser had finished downloading, painting etc, there was a slight time lag between the final events firing and the screen being suitable for capture. All this is on the other message thread.

Thanks for all the help - I don't think I would have ever found out about WM_PRINT otherwise (I'm on a steep learning curve). Cheers.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
java ^ examples 8 69
data scientists and AI 17 114
java continue statement 10 155
splitOdd10 challenge 5 115
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This article will show, step by step, how to integrate R code into a R Sweave document
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question