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
/// <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();
}
sinnvoller wäre wahrscheinlich diesen Namespace Print zu verwenden - oder wie der heißt
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
Hi Vertexwahn,
Geht mir wie LastGentleman:
mit WinAPI.GetDesktopWindow() kann ich leider nix anfangen - Sorry bin Anfänger...
Grüße
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
}
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);
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
Wer weiss wie man eine Suchmaschine bedient ist im Vorteil 🙂
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
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
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...
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
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...
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
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...
Oder Du machst es so: