//////////////////////////////////////////////////////
// CAP2PRN R1.00 (WPF and .Netframework)
// ReachFramework , System.Printing
// System.Drawing , System.Windows.Forms 参照設定
// (c)inf102 S.H. 2025. All rights reserved.
//////////////////////////////////////////////////////
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace PRN01 {
public partial class MainWindow : Window {
[DllImport("User32.dll")]
private static extern bool SetCursorPos(int X, int Y);
///////////////////////////////////////////////////////////////////////////////////////////
const int WAKU=3; // 選択枠の幅
static string Desktop="";
static int x1=0,y1,x2,y2;
static bool area_select=false; // false = 選択開始前 , true = エリア選択中
static int Y=0;
///////////////////////////////////////////////////////////////////////////////////////////
public void m(string s) {
MessageBox.Show(s);
}
public MainWindow() {
InitializeComponent();
// デスクトップにND_SSフォルダ作成
Desktop=System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
Directory.CreateDirectory(Desktop+"\\ND_SS");
Desktop+="\\ND_SS";
// 画面全体のスクリーンショット保存
BitmapSource bs=FULLCopyScreen();
using (Stream stream = new FileStream (Desktop+"\\ND_SSTMP.JPG", FileMode.Create)){
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bs));
encoder.Save(stream);
}
// マウス十字型に変更
Mouse.OverrideCursor = Cursors.Cross;
// マウスカーソルをプライマリディプレイの中央に移動
SetCursorPos((int)SystemParameters.PrimaryScreenWidth/2,(int)SystemParameters.PrimaryScreenHeight/2);
}
// 選択前
public void Msg1(object sender) {
var canvas = sender as Canvas;
SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,255, 0, 0));
TextBlock text2 = new TextBlock{
Text = "[印刷] マウス左押して選択開始.\r\n何かキー押すと中止. [HOME]で全画面印刷",
FontSize = 21,
Foreground = brush,
FontWeight = FontWeights.Bold
};
// X軸設定 //////////////
bool FLG = false;
// 左端
if (x2 < 180) {
Canvas.SetLeft(text2,10);
FLG = true;
}
// 右端
if (x2>(int)SystemParameters.PrimaryScreenWidth -200) {
Canvas.SetLeft(text2,(int)SystemParameters.PrimaryScreenWidth-370);
FLG=true;
}
// 通常
if (FLG==false) Canvas.SetLeft(text2,x2-170 );
/////////////////////////////////////////////////////////////////////////
/////////////////////////
// Y軸設定 //////////////
////////////////////////
// マウスが下より上
if ( Y==0 && (y2 < (int)SystemParameters.PrimaryScreenHeight-70)) Canvas.SetTop(text2,y2+20);
// マウスが下の下 は必ず上表示
if ( y2 > (int)SystemParameters.PrimaryScreenHeight-70 ){
Canvas.SetTop(text2,y2-70);
Y=2;
}
// マウスが上より下で上に表示中
if ( Y==2 && (y2 > 70)) Canvas.SetTop(text2,y2-70);
// マウスが上の上
if ( y2 < 70 ){
Canvas.SetTop(text2,y2+20);
Y=0;
}
// 下に表示中でマウスが画面より下
if ( Y==0 && y2 > (int)SystemParameters.PrimaryScreenHeight-70 ){
Canvas.SetTop(text2,y2+20);
Y=5;
}
// 上に表示中 上より下
if (Y == 5 && y2 > 70) Canvas.SetTop(text2,y2-70);
// 文字表示
DrawCanvas.Children.Add(text2);
}
// 選択中
public void Msg2(object sender) {
if (Math.Abs(x2-x1) <380) return;
if (Math.Abs(y2-y1) <60) return;
var canvas = sender as Canvas;
DrawCanvas.Children.Clear();
SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,0, 255, 0));
TextBlock text = new TextBlock{
Text = "印刷範囲 指定中.左Upで印刷\r\n何かキー押すと中止. [HOME]で全画面印刷",
FontSize = 21,
FontWeight= FontWeights.Bold,
Foreground = brush
};
Canvas.SetLeft(text,(x2-x1)/2+x1-185);
Canvas.SetTop (text,(y2-y1)/2+y1-30 );
DrawCanvas.Children.Add(text);
}
// 選択開始
private void Window_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
var canvas = sender as Canvas;
area_select=true;
// 選択開始位置
System.Windows.Point position = e.GetPosition(canvas);
x1=(int)position.X;
y1=(int)position.Y;
Msg2(sender);
}
// 領域枠表示 マウス移動イベント
private void Window_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) {
DrawCanvas.Children.Clear();
var canvas = sender as Canvas;
System.Windows.Point position = e.GetPosition(canvas);
// MOUSE XY
x2=(int)position.X;
y2=(int)position.Y;
SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,255, 0, 0));
// 選択開始表示 左ボタン前
if (area_select==false) {
Msg1(sender);
return;
}
// 範囲選択中の説明表示
Msg2(sender);
Line Line1 = new Line();
Line Line2 = new Line();
Line Line3 = new Line();
Line Line4 = new Line();
Line1.MouseUp += Window_PreviewMouseLeftButtonUp;
Line2.MouseUp += Window_PreviewMouseLeftButtonUp;
Line3.MouseUp += Window_PreviewMouseLeftButtonUp;
Line4.MouseUp += Window_PreviewMouseLeftButtonUp;
Line1.Stroke = System.Windows.Media.Brushes.Yellow;
Line1.StrokeThickness = WAKU; // 線の太さ
Line2.Stroke = System.Windows.Media.Brushes.Yellow;
Line2.StrokeThickness = WAKU;
Line3.Stroke = System.Windows.Media.Brushes.Yellow;
Line3.StrokeThickness = WAKU;
Line4.Stroke = System.Windows.Media.Brushes.Yellow;
Line4.StrokeThickness = WAKU;
// 左上から左下
Line1.X1 = x1; // 開始点X
Line1.Y1 = y1; // 開始点Y
Line1.X2 = x1; // 終了点X
Line1.Y2 = y2; // 終了点Y
// Canvas に追加
DrawCanvas.Children.Add(Line1);
// 左上から右上
Line2.X1 = x1; // 開始点X
Line2.Y1 = y1; // 開始点Y
Line2.X2 = x2; // 終了点X
Line2.Y2 = y1; // 終了点Y
DrawCanvas.Children.Add(Line2);
//左下から右下
Line3.X1 = x1; // 開始点X
Line3.Y1 = y2; // 開始点Y
Line3.X2 = x2; // 終了点X
Line3.Y2 = y2; // 終了点Y
// Canvas に追加
DrawCanvas.Children.Add(Line3);
//右上から右下
Line4.X1 = x2; // 開始点X
Line4.Y1 = y1; // 開始点Y
Line4.X2 = x2; // 終了点X
Line4.Y2 = y2; // 終了点Y
// Canvas に追加
DrawCanvas.Children.Add(Line4);
}
// 選択完了
private void Window_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) {
int xx=x1,yy=y1,he=y2-y1,wi=x2-x1;
// FILENAME
string outfile=DateTime.Now.ToString("yyMMdd-HH-mm-ss");
// 左上から右下
if (x1 < x2 && y1 < y2) {
CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx,yy,wi,he);
}
// 右下から左上
if (x1 > x2 && y1 > y2){
xx=x2;
yy=y2;
wi=Math.Abs(wi);
he=Math.Abs(he);
CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx-10,yy-7,wi+5,he+2);
}
// 左下から右上
if (x1 < x2 && y1 > y2) {
wi=x2-x1;
he=y1-y2;
yy=y2;
CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx-10,yy-7,wi+5,he+2);
}
// 右上から左下
if (y1 < y2 && x1 > x2){
yy=y1;
wi=x2-x1;
wi=Math.Abs(wi);
he=y2-y1;
xx=x2;
CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx-10,yy-7,wi+5,he+2);
}
// 切り抜き部を横向き用紙に合わせて拡大・縮小して印刷
BitmapImage bmp = new BitmapImage(new Uri(Desktop+"\\"+outfile+".jpg"));
PrintImage(bmp);
// 一時ファイル削除
File.Delete(Desktop+"\\ND_SSTMP.JPG");
// 印刷 mspaint使用
/*
System.Threading.Thread.Sleep(500);
ProcessStartInfo psi = new ProcessStartInfo{
FileName = "mspaint.exe",
Arguments = "/p "+ Desktop+"\\"+outfile+".jpg",
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
};
Process.Start(psi);
*/
Application.Current.Shutdown();
}
// 全画面印刷 or 中止
private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
// 全画面
if (e.Key == Key.Home){
string outfile=DateTime.Now.ToString("yyMMdd-HH-mm-ss");
CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", 0,0,(int)SystemParameters.PrimaryScreenWidth-1,(int)SystemParameters.PrimaryScreenHeight-1);
BitmapImage bmp = new BitmapImage(new Uri(Desktop+"\\"+outfile+".jpg"));
PrintImage(bmp);
}
try {
File.Delete(Desktop+"\\ND_SSTMP.JPG");
}
catch{ }
Application.Current.Shutdown();
}
// 部分カット
public void CropJpeg(string inputPath, string outputPath, int x, int y, int width, int height){
BitmapImage source = new BitmapImage();
source.BeginInit();
source.UriSource = new Uri(inputPath, UriKind.Absolute);
source.CacheOption = BitmapCacheOption.OnLoad;
source.EndInit();
var rect = new System.Drawing.Rectangle((int)this.Left, (int)this.Top, (int)this.Width, (int)this.Height);
var screen = System.Windows.Forms.Screen.FromRectangle(rect);
int w = screen.Bounds.Width;
int h = screen.Bounds.Height;
if (x+width >=w) width =w-x;
if (y+height>=h) height =h-y;
if (y<0) y=0;
if (x<0) x=0;
if (width >w) width =w;
if (height >h) height=h;
Int32Rect cropArea = new Int32Rect(x, y, width, height);
CroppedBitmap cropped=null;
try{
cropped = new CroppedBitmap(source, cropArea);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(cropped));
using (FileStream fs = new FileStream(outputPath, FileMode.Create)){
encoder.Save(fs);
fs.Close();
}
}
catch {
cropped =null;
m("範囲が狭すぎます.やり直して下さい.");
Application.Current.Shutdown();
}
}
// FULLSCREEN CAPTURE
private static BitmapSource FULLCopyScreen(){
using (var screenBmp = new Bitmap((int)SystemParameters.PrimaryScreenWidth,(int)SystemParameters.PrimaryScreenHeight,System.Drawing.Imaging.PixelFormat.Format32bppArgb)){
using (var bmpGraphics = Graphics.FromImage(screenBmp)){
bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
return Imaging.CreateBitmapSourceFromHBitmap(screenBmp.GetHbitmap(),IntPtr.Zero,Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
}
}
}
// 用紙に合わせて印字
public void PrintImage(BitmapImage bitmapImage){
byte[] imageData;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
using (MemoryStream ms = new MemoryStream()){
encoder.Save(ms);
imageData = ms.ToArray();
}
System.Drawing.Image imageToPrint;
using (MemoryStream ms = new MemoryStream(imageData)){
imageToPrint = System.Drawing.Image.FromStream(ms);
}
PrintDocument printDoc = new PrintDocument();
printDoc.DefaultPageSettings.Landscape = true;
printDoc.PrintPage += (s, e) =>{
System.Drawing.Rectangle bounds = e.MarginBounds;
float scale = Math.Min((float)bounds.Width / imageToPrint.Width,(float)bounds.Height / imageToPrint.Height);
int width = (int)(imageToPrint.Width * scale);
int height = (int)(imageToPrint.Height * scale);
int left = bounds.Left + ((bounds.Width - width) / 2);
int top = bounds.Top + ((bounds.Height - height) / 2);
e.Graphics.DrawImage(imageToPrint, left, top, width, height);
};
printDoc.Print();
}
}
}