Solved

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

Posted on 2004-03-28
7
490 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Having just graduated from college and entered the workforce, I don’t find myself always using the tools and programs I grew accustomed to over the past four years. However, there is one program I continually find myself reverting back to…R.   So …
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

717 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