SendMessage(... WM_PRINT ...) isn't working

Hi, I've put the below code into a .net 2 c# app as a test and the file it is producing is just a black rectange. The exact same code works with the XP+ PrintWindow() in place of "SendMessage".

Sorry the code isn't commented, i've just been building it as a test in another temporary project.

The hardcoded handle in this example is just one I randomly grabbed using Spy++ - you have to get a new one each time tho :)

public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        private static extern bool SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, int lParam);

        public const int WM_PRINT = 0x0317;
       

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            panel1.Height = 1000;
            panel1.Width = 1000;
            SetParent(new IntPtr(2820832), panel1.Handle);
            MoveWindow(new IntPtr(2820832), 0, 0, panel1.Width, panel1.Height, true);
           
        }

        private void button2_Click(object sender, EventArgs e)
        {
            System.Drawing.Imaging.PixelFormat pf = PixelFormat.Format24bppRgb;

            Bitmap bm = new Bitmap(panel1.Width, panel1.Height, pf);

            Bitmap bm2 = new Bitmap(panel1.Width, panel1.Height, pf);
            Graphics g2 = Graphics.FromImage(bm2);

            Graphics g = null;
            IntPtr hdc;
            Image screenfrag = null;

            IntPtr hwnd = (IntPtr)panel1.Handle;
           
            g = Graphics.FromImage(bm);
            hdc = g.GetHdc();
            SendMessage(hwnd, WM_PRINT, hdc, 0);
            g.ReleaseHdc(hdc);
            g.Flush();
            screenfrag = Image.FromHbitmap(bm.GetHbitmap());
            g2.DrawImage(screenfrag, 0, 0);

            Bitmap finalImage = new Bitmap(panel1.Width, panel1.Height, pf); //Format16bppRgb555
            Graphics gFinal = Graphics.FromImage((Image)finalImage);
            gFinal.DrawImage(bm2, 0, 0, panel1.Width, panel1.Height);

            finalImage.Save(@"C:\test.png", System.Drawing.Imaging.ImageFormat.Png);
        }

    }
saltedAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
What is this code doing?

Bob
0
saltedAuthor Commented:
Hi Bob,

It takes a screen shot of the window specified. In the example above I was using a the MozillaBrowserClass window from Firefox. But it could be anything. If you use the API function PrintWindow it works, but sendmessage...wm_print doesn't. And i need this to work on win 2000 (where PrintWindow doesn't exist).

This is what it does:            

            // Set the panel size to 1000,1000
            panel1.Height = 1000;
            panel1.Width = 1000;
            // Grab the window owned by the other process and move it into our own "panel1"
            SetParent(new IntPtr(2820832), panel1.Handle);
            // Move the window to be at 0,0 of the panel, and to be the size of the panel...
            MoveWindow(new IntPtr(2820832), 0, 0, panel1.Width, panel1.Height, true);

...

            // Create the pixel format to use
            System.Drawing.Imaging.PixelFormat pf = PixelFormat.Format24bppRgb;

            // Create the new bitmap object to draw onto later
            Bitmap bm = new Bitmap(panel1.Width, panel1.Height, pf);

            // Create a secondary bitmap object to create the graphics object from
            Bitmap bm2 = new Bitmap(panel1.Width, panel1.Height, pf);
           
            // Create the graphics object
            Graphics g2 = Graphics.FromImage(bm2);

            Graphics g = null;
            // Create the handle to the device context to print to
            IntPtr hdc;
            // Create the image to draw to
            Image screenfrag = null;

            Grab the handle of panel1 (which is what we want to print to an image).
            IntPtr hwnd = (IntPtr)panel1.Handle;
           
            g = Graphics.FromImage(bm);
            // Get the device context from the graphics object
            hdc = g.GetHdc();
            // print the window to the device context
            SendMessage(hwnd, WM_PRINT, hdc, 0);
            g.ReleaseHdc(hdc);
            g.Flush();
            screenfrag = Image.FromHbitmap(bm.GetHbitmap());
            g2.DrawImage(screenfrag, 0, 0);

            Bitmap finalImage = new Bitmap(panel1.Width, panel1.Height, pf); //Format16bppRgb555
            Graphics gFinal = Graphics.FromImage((Image)finalImage);
            gFinal.DrawImage(bm2, 0, 0, panel1.Width, panel1.Height);

            finalImage.Save(@"C:\test.png", System.Drawing.Imaging.ImageFormat.Png);


The code is really messy, but i'm really just interested in how SendMessage... WM_Print works.

Although if there is a way of getting PrintWindow to work on Win 2000 (it's only going to be installed on machines i have complete control over - the only thing i can't change is the fact it has to be 2000, but i can add/remove anything else).


0
Bob LearnedCommented:
I have no idea.  :(

Bob
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.