Laden...

Screenshot vom aktuellen Formular für einfaches Drucken?

Erstellt von MillionsterNutzer vor 18 Jahren Letzter Beitrag vor 18 Jahren 8.180 Views
M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 18 Jahren
Screenshot vom aktuellen Formular für einfaches Drucken?

Hi,

ich sollte einige Daten aus einem Formular heraus drucken können. Um dies möglichst einfach zu erledigen dachte ich mir ich könnte einfach ein Screenshot von dem Form machen und diesen dann drucken.
Wie ich eine einfache Bilddatei an den Drucker schicke weiß ich von einem anderen Problem, jetzt sollte ich nur noch wissen wie ich einen Screenshot von einem Formular mache und diesen dann als image in den Code bekomme.

Kann mir da jemand kurz auf die sprünge helfen...

Grüße

V
179 Beiträge seit 2005
vor 18 Jahren

        /// <summary>
        /// Holt einen aktuellen Bildausschnitt in das angegebene Bitmap
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="rect"></param>
		void CaptureScreen(ref Bitmap bmp, Rectangle rect)
		{
			Graphics Graphic = Graphics.FromHwnd(WinAPI.GetDesktopWindow());
						
			Graphics ReferenceGraphic = Graphics.FromImage(bmp);

			IntPtr dc1 = Graphic.GetHdc();
			IntPtr dc2 = ReferenceGraphic.GetHdc();
	
			WinAPI.BitBlt(dc2, rect.Left, rect.Top, rect.Width, rect.Height, 
				dc1, rect.Left, rect.Top, WinAPI.SRCCOPY);

			Graphic.ReleaseHdc(dc1);
			ReferenceGraphic.ReleaseHdc(dc2);
			
			Graphic.Dispose();
		}


V
179 Beiträge seit 2005
vor 18 Jahren

sinnvoller wäre wahrscheinlich diesen Namespace Print zu verwenden - oder wie der heißt

1.274 Beiträge seit 2005
vor 18 Jahren

Cool, kanst du bitte auch den Code für WinAPI.GetDesktopWindow()); posten

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 18 Jahren

Hi Vertexwahn,

Geht mir wie LastGentleman:

mit WinAPI.GetDesktopWindow() kann ich leider nix anfangen - Sorry bin Anfänger...

Grüße

V
179 Beiträge seit 2005
vor 18 Jahren

immer diese Leute, die nie mit dem Platform SDK und C++ programmiert haben 8)

WinAPI ist einfach ein import von Funktionen aus dem Platform SDK

zu faul jetzt nur die Funktionen rauszusuchen, die du benötigst:


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Xml;
using System.Threading;
using System.Text;
using System.IO;
using Microsoft.Win32;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;


 public class WinAPI
    {
        #region DLL_Imports_WinAPI
        [DllImport("User32.dll")]
        public static extern IntPtr
            SetClipboardViewer(IntPtr hWndNewViewer);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern bool
            ChangeClipboardChain(IntPtr hWndRemove,
            IntPtr hWndNewNext);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hwnd, int wMsg,
            IntPtr wParam,
            IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();

        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(
            IntPtr hdcDest, // handle to destination DC
            int nXDest, // x-coord of destination upper-left corner
            int nYDest, // y-coord of destination upper-left corner
            int nWidth, // width of destination rectangle
            int nHeight, // height of destination rectangle
            IntPtr hdcSrc, // handle to source DC
            int nXSrc, // x-coordinate of source upper-left corner
            int nYSrc, // y-coordinate of source upper-left corner
            System.Int32 dwRop // raster operation code
            );

        public const Int32 SRCCOPY = 0xCC0020;

        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        public static extern int GetSystemMetrics(int nIndex);

        public const Int32 SM_CXVIRTUALSCREEN = 78; // from <winuser.h>
        public const Int32 SM_CYVIRTUALSCREEN = 79;

        [DllImport("user32.dll")]
        public static extern void SetCursorPos(int x, int y);

        public const uint MOUSEEVENTF_MOVE = 0x0001; /* mouse move */
        public const uint MOUSEEVENTF_LEFTDOWN = 0x0002; /* left button down */
        public const uint MOUSEEVENTF_LEFTUP = 0x0004; /* left button up */
        public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008; /* right button down */
        public const uint MOUSEEVENTF_RIGHTUP = 0x0010; /* right button up */
        public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020; /* middle button down */
        public const uint MOUSEEVENTF_MIDDLEUP = 0x0040; /* middle button up */
        public const uint MOUSEEVENTF_WHEEL = 0x0800; /* wheel button rolled */
        public const uint MOUSEEVENTF_ABSOLUTE = 0x8000; /* absolute move */

        public const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
        public const uint KEYEVENTF_KEYUP = 0x0002;

        public const uint INPUT_MOUSE = 0;
        public const uint INPUT_KEYBOARD = 1;

        public struct MOUSE_INPUT
        {
            public uint dx;
            public uint dy;
            public uint mouseData;
            public uint dwFlags;
            public uint time;
            public uint dwExtraInfo;
        }

        public struct KEYBD_INPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public uint dwExtraInfo;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct INPUT
        {
            [FieldOffset(0)]
            public uint type;

            // union
            [FieldOffset(4)]
            public MOUSE_INPUT mi;

            [FieldOffset(4)]
            public KEYBD_INPUT ki;
        }

        [DllImport("user32.dll")]
        public static extern uint SendInput(
            uint nInputs,     // count of input events
            ref INPUT input,
            int cbSize        // size of structure
            );

        [DllImport("user32.dll")]
        public static extern uint MapVirtualKey(
            uint uCode,     // virtual-key code or scan code
            uint uMapType   // translation to perform
            );


        [DllImport("user32.dll")]
        public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
            UIntPtr dwExtraInfo);

        [DllImport("user32.dll")]
        public static extern short VkKeyScan(char ch);

        public enum VirtualKeyStates : int
        {
            VK_LBUTTON = 0x01,
            VK_RBUTTON = 0x02,
            VK_CANCEL = 0x03,
            VK_MBUTTON = 0x04,
            //
            VK_XBUTTON1 = 0x05,
            VK_XBUTTON2 = 0x06,
            //
            VK_BACK = 0x08,
            VK_TAB = 0x09,
            //
            VK_CLEAR = 0x0C,
            VK_RETURN = 0x0D,
            //
            VK_SHIFT = 0x10,
            VK_CONTROL = 0x11,
            VK_MENU = 0x12,
            VK_PAUSE = 0x13,
            VK_CAPITAL = 0x14,
            //
            VK_KANA = 0x15,
            VK_HANGEUL = 0x15,  /* old name - should be here for compatibility */
            VK_HANGUL = 0x15,
            VK_JUNJA = 0x17,
            VK_FINAL = 0x18,
            VK_HANJA = 0x19,
            VK_KANJI = 0x19,
            //
            VK_ESCAPE = 0x1B,
            //
            VK_CONVERT = 0x1C,
            VK_NONCONVERT = 0x1D,
            VK_ACCEPT = 0x1E,
            VK_MODECHANGE = 0x1F,
            //
            VK_SPACE = 0x20,
            VK_PRIOR = 0x21,
            VK_NEXT = 0x22,
            VK_END = 0x23,
            VK_HOME = 0x24,
            VK_LEFT = 0x25,
            VK_UP = 0x26,
            VK_RIGHT = 0x27,
            VK_DOWN = 0x28,
            VK_SELECT = 0x29,
            VK_PRINT = 0x2A,
            VK_EXECUTE = 0x2B,
            VK_SNAPSHOT = 0x2C,
            VK_INSERT = 0x2D,
            VK_DELETE = 0x2E,
            VK_HELP = 0x2F,
            //
            VK_LWIN = 0x5B,
            VK_RWIN = 0x5C,
            VK_APPS = 0x5D,
            //
            VK_SLEEP = 0x5F,
            //
            VK_NUMPAD0 = 0x60,
            VK_NUMPAD1 = 0x61,
            VK_NUMPAD2 = 0x62,
            VK_NUMPAD3 = 0x63,
            VK_NUMPAD4 = 0x64,
            VK_NUMPAD5 = 0x65,
            VK_NUMPAD6 = 0x66,
            VK_NUMPAD7 = 0x67,
            VK_NUMPAD8 = 0x68,
            VK_NUMPAD9 = 0x69,
            VK_MULTIPLY = 0x6A,
            VK_ADD = 0x6B,
            VK_SEPARATOR = 0x6C,
            VK_SUBTRACT = 0x6D,
            VK_DECIMAL = 0x6E,
            VK_DIVIDE = 0x6F,
            VK_F1 = 0x70,
            VK_F2 = 0x71,
            VK_F3 = 0x72,
            VK_F4 = 0x73,
            VK_F5 = 0x74,
            VK_F6 = 0x75,
            VK_F7 = 0x76,
            VK_F8 = 0x77,
            VK_F9 = 0x78,
            VK_F10 = 0x79,
            VK_F11 = 0x7A,
            VK_F12 = 0x7B,
            VK_F13 = 0x7C,
            VK_F14 = 0x7D,
            VK_F15 = 0x7E,
            VK_F16 = 0x7F,
            VK_F17 = 0x80,
            VK_F18 = 0x81,
            VK_F19 = 0x82,
            VK_F20 = 0x83,
            VK_F21 = 0x84,
            VK_F22 = 0x85,
            VK_F23 = 0x86,
            VK_F24 = 0x87,
            //
            VK_NUMLOCK = 0x90,
            VK_SCROLL = 0x91,
            //
            VK_OEM_NEC_EQUAL = 0x92,   // '=' key on numpad
            //
            VK_OEM_FJ_JISHO = 0x92,   // 'Dictionary' key
            VK_OEM_FJ_MASSHOU = 0x93,   // 'Unregister word' key
            VK_OEM_FJ_TOUROKU = 0x94,   // 'Register word' key
            VK_OEM_FJ_LOYA = 0x95,   // 'Left OYAYUBI' key
            VK_OEM_FJ_ROYA = 0x96,   // 'Right OYAYUBI' key
            //
            VK_LSHIFT = 0xA0,
            VK_RSHIFT = 0xA1,
            VK_LCONTROL = 0xA2,
            VK_RCONTROL = 0xA3,
            VK_LMENU = 0xA4,
            VK_RMENU = 0xA5,
            //
            VK_BROWSER_BACK = 0xA6,
            VK_BROWSER_FORWARD = 0xA7,
            VK_BROWSER_REFRESH = 0xA8,
            VK_BROWSER_STOP = 0xA9,
            VK_BROWSER_SEARCH = 0xAA,
            VK_BROWSER_FAVORITES = 0xAB,
            VK_BROWSER_HOME = 0xAC,
            //
            VK_VOLUME_MUTE = 0xAD,
            VK_VOLUME_DOWN = 0xAE,
            VK_VOLUME_UP = 0xAF,
            VK_MEDIA_NEXT_TRACK = 0xB0,
            VK_MEDIA_PREV_TRACK = 0xB1,
            VK_MEDIA_STOP = 0xB2,
            VK_MEDIA_PLAY_PAUSE = 0xB3,
            VK_LAUNCH_MAIL = 0xB4,
            VK_LAUNCH_MEDIA_SELECT = 0xB5,
            VK_LAUNCH_APP1 = 0xB6,
            VK_LAUNCH_APP2 = 0xB7,
            //
            VK_OEM_1 = 0xBA,   // ';:' for US
            VK_OEM_PLUS = 0xBB,   // '+' any country
            VK_OEM_COMMA = 0xBC,   // ',' any country
            VK_OEM_MINUS = 0xBD,   // '-' any country
            VK_OEM_PERIOD = 0xBE,   // '.' any country
            VK_OEM_2 = 0xBF,   // '/?' for US
            VK_OEM_3 = 0xC0,   // '`~' for US
            //
            VK_OEM_4 = 0xDB,  //  '[{' for US
            VK_OEM_5 = 0xDC,  //  '\|' for US
            VK_OEM_6 = 0xDD,  //  ']}' for US
            VK_OEM_7 = 0xDE,  //  ''"' for US
            VK_OEM_8 = 0xDF,
            //
            VK_OEM_AX = 0xE1,  //  'AX' key on Japanese AX kbd
            VK_OEM_102 = 0xE2,  //  "<>" or "\|" on RT 102-key kbd.
            VK_ICO_HELP = 0xE3,  //  Help key on ICO
            VK_ICO_00 = 0xE4,  //  00 key on ICO
            //
            VK_PROCESSKEY = 0xE5,
            //
            VK_ICO_CLEAR = 0xE6,
            //
            VK_PACKET = 0xE7,
            //
            VK_OEM_RESET = 0xE9,
            VK_OEM_JUMP = 0xEA,
            VK_OEM_PA1 = 0xEB,
            VK_OEM_PA2 = 0xEC,
            VK_OEM_PA3 = 0xED,
            VK_OEM_WSCTRL = 0xEE,
            VK_OEM_CUSEL = 0xEF,
            VK_OEM_ATTN = 0xF0,
            VK_OEM_FINISH = 0xF1,
            VK_OEM_COPY = 0xF2,
            VK_OEM_AUTO = 0xF3,
            VK_OEM_ENLW = 0xF4,
            VK_OEM_BACKTAB = 0xF5,
            //
            VK_ATTN = 0xF6,
            VK_CRSEL = 0xF7,
            VK_EXSEL = 0xF8,
            VK_EREOF = 0xF9,
            VK_PLAY = 0xFA,
            VK_ZOOM = 0xFB,
            VK_NONAME = 0xFC,
            VK_PA1 = 0xFD,
            VK_OEM_CLEAR = 0xFE
        }

        [DllImport("user32.dll")]
        public static extern short GetKeyState(VirtualKeyStates nVirtKey);


        //	[DllImport("user32.dll")]
        //	public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags,
        //		UIntPtr dwExtraInfo);

        //	[DllImport("user32.dll")]
        //	static extern short VkKeyScan(char ch);


        [StructLayout(LayoutKind.Explicit)]
        public struct Rect
        {
            [FieldOffset(0)]
            public int left;
            [FieldOffset(4)]
            public int top;
            [FieldOffset(8)]
            public int right;
            [FieldOffset(12)]
            public int bottom;
        }

        [DllImport("gdi32")]
        public static extern int GetClipBox(System.IntPtr hDC, ref Rect r);

        // WinAPI funktionen um Caret Position zu ermitteln
        [DllImport("user32")]
        public static extern int GetForegroundWindow();

        [DllImport("user32")]
        public static extern uint GetWindowThreadProcessId(int hWnd, out uint lpdwProcessId);

        [DllImport("user32")]
        public static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO lpgui);

        [StructLayout(LayoutKind.Sequential)]
        public struct GUITHREADINFO
        {
            public uint cbSize;
            public uint flags;
            public IntPtr hwndActive;
            public IntPtr hwndFocus;
            public IntPtr hwndCapture;
            public IntPtr hwndMenuOwner;
            public IntPtr hwndMoveSize;
            public IntPtr hwndCaret;
            public RECT rcCaret;
        }

        [Serializable, StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;

            public RECT(int left_, int top_, int right_, int bottom_)
            {
                Left = left_;
                Top = top_;
                Right = right_;
                Bottom = bottom_;
            }

            public int Height { get { return Bottom - Top + 1; } }
            public int Width { get { return Right - Left + 1; } }
            public Size Size { get { return new Size(Width, Height); } }

            public Point Location { get { return new Point(Left, Top); } }

            // Handy method for converting to a System.Drawing.Rectangle
            public Rectangle ToRectangle()
            { return Rectangle.FromLTRB(Left, Top, Right, Bottom); }

            public static RECT FromRectangle(Rectangle rectangle)
            {
                return new RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
            }

            public override int GetHashCode()
            {
                return Left ^ ((Top << 13) | (Top >> 0x13))
                    ^ ((Width << 0x1a) | (Width >> 6))
                    ^ ((Height << 7) | (Height >> 0x19));
            }

            #region Operator overloads

            public static implicit operator Rectangle(RECT rect)
            {
                return Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
            }

            public static implicit operator RECT(Rectangle rect)
            {
                return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom);
            }

            #endregion
        }

        /// <summary>
        /// The Point structure defines the x- and y-coordinates of a point. 
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            #region Fields

            /// <summary>
            /// The x value of the point's coordinates.
            /// </summary>
            public int X;

            /// <summary>
            /// The y value of the point's coordinates.
            /// </summary>
            public int Y;

            #endregion

            #region Lifecycle

            /// <summary>
            /// Initializes a new instance of the <c>POINT</c> structure.
            /// </summary>
            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }

            #endregion

            #region Operator overloads

            /// <summary>Implicitly casts a <c>POINT</c> to a <see cref="Point"/>.</summary>
            /// <param name="p">The <c>POINT</c> instance to cast to a <c>Point</c> instance.</param>
            /// <returns>The casted <c>Point</c> structure.</returns>
            public static implicit operator Point(POINT p)
            {
                return new Point(p.X, p.Y);
            }

            /// <summary>Implicitly casts a <see cref="Point"/> to a <c>POINT</c>.</summary>
            /// <param name="p">The <c>Point</c> instance to cast to a <c>POINT</c> instance.</param>
            /// <returns>The casted <c>POINT</c> structure.</returns>
            public static implicit operator POINT(Point p)
            {
                return new POINT(p.X, p.Y);
            }

            #endregion
        }

        [DllImport("user32")]
        public static extern bool ClientToScreen(int hWnd, ref POINT lpPoint);

        #endregion
    }

V
179 Beiträge seit 2005
vor 18 Jahren

Die Zeile muss ersetzt werden:

Graphics Graphic = Graphics.FromHwnd(WinAPI.GetDesktopWindow());

hier muss der handle der Form angegeben werden die man "capturen" will
z. B.:

Graphics Graphic = Graphics.FromHwnd(MyForm.Handle);
M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 18 Jahren
Erst mal ausprobieren..

Wow,

von wegen "einfach mal nen Screenshot machen"! Ich muß mir das alles erst nochmal genauer ansehen...

Komm gerade einfach nicht auf anhieb darauf wie das funktionieren soll.

Grüße

4.221 Beiträge seit 2005
vor 18 Jahren

Wer weiss wie man eine Suchmaschine bedient ist im Vorteil 🙂

Drucken eines Controls????

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans,

tja, ich hab mir deinen Link mal angesehen und mal ein wenig weitergebastelt, aber mit der Lösung die ich nutze bekomme ich nur ein leeres Bild! Wäre nett wenn du meinen code mal ansiehst:
Grundlage ist ein einfaches From mit einem Drucken-Button, einem PrintDialog-Element und einem Print-PageElement. Bei drücken des Buttons wird folgender Event ausgelöst:

private void btn_Click(object sender, System.EventArgs e)
{
this.printDialog1.Document = this.printDocument1;
if (this.printDialog1.ShowDialog() == DialogResult.OK)
   printDocument1.Print();
}

Zusätzlich kommt noch der folgende Event hinzu der eigentlich den Screenshot erledigen sollte:

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = Graphics.FromHwnd(this.Handle);
Rectangle cr = this.ClientRectangle;
Image img = new Bitmap(cr.Width,cr.Height,g);
e.Graphics.DrawImage(img, cr.Width, cr.Height, img.Width, img.Height);
}

Wie schon gesagt bekomme ich nur eine leere Seite. Was mach ich denn falsch?

Grüße

4.221 Beiträge seit 2005
vor 18 Jahren

Hast Du den printDocument1_PrintPage angehängt ?

Was sollte Deiner Ansicht nach gedruckt werden wenn Du ein leeres Image druckst ????? Weisser Adler auf weissem Grund ?

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 18 Jahren

Hi Programmierhans!

Ich hoffe du hast meine beiden Events mit Code gesehen, da ich beim einstellen meiner Antwort zuerst keinen Code darin hatte (evtl. jetzt nochmal angucken).

Zu: Hast Du den printDocument1_PrintPage angehängt ?
=> Bin mir jetzt nicht sicher was du meinst, aber beide der gezeigten Events werden ausgeführt. Daruter eben auch der printDocument1_PrintPage-Event

Zu: Was sollte Deiner Ansicht nach gedruckt werden wenn Du ein leeres Image druckst ?
Warum soll ich ein leeres Image Drucken? Ich bearbeite doch das e.Graphics aus dem printDocument1_PrintPage-Event indem ich einen ein Bitmap aus dem Handle auf mein Formular generiere und dieses wiederrum in das e.Graphics schreibe. Oder seh ich das falsch?
Sorry, bin Anfänger...

Grüße

4.221 Beiträge seit 2005
vor 18 Jahren

Image img = new Bitmap(cr.Width,cr.Height,g);

Initialisiert eine neue Instanz der Bitmap-Klasse mit der angegebenen Größe und der Auflösung des angegebenen Graphics-Objekts. (jedoch nicht mit dem Inhalt von G)

Oder eben weisser Adler auf weissem Grund.

Zudem hinterlässt dein Code ein MemoryLeak weil Du das Graphics-Objekt nicht disposed.

So zu diesem Thread habe ich nun genug geschrieben. Die Lösung (Link) habe ich Dir bereits früher gepostet.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

M
MillionsterNutzer Themenstarter:in
235 Beiträge seit 2005
vor 18 Jahren
Danke!

Hi Programmierhans,

endlich funktioniert es annähernd, jetzt muß ich nur noch das image so resizen, das es auf DinA4 passt un gut ist.

Man ist das ganze Grafik- und Druck-Zeug kompliziert. Echt nicht meine Welt...

Grüße

4.221 Beiträge seit 2005
vor 18 Jahren

Original von MillionsterNutzer
Man ist das ganze Grafik- und Druck-Zeug kompliziert. Echt nicht meine Welt...

Also ich find's nicht kompliziert... vorallem habe ich Dir ja ein lauffähiges Sample aufgezeigt.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

F
10.010 Beiträge seit 2004
vor 18 Jahren