日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

制作类似QQ截图软件

發(fā)布時間:2024/4/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 制作类似QQ截图软件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

??? 最近在學習GDI,發(fā)現(xiàn)網(wǎng)上幾篇文章在講截圖軟件制作方法,學習了一點知識,在這里分享一下. ?

??? 主要是調(diào)用WinAPI中的函數(shù)來完成主要功能.關鍵的函數(shù)有2個,一個是CreateDC,利用這個函數(shù)來創(chuàng)建一個顯示器屏幕的DC(設備環(huán)境),作為源DC,再創(chuàng)建一個Image圖像,通過這個圖像的Graphics.GetHdc()方法來獲取另一個DC,作為目標DC,這2個DC主要是留給第二個函數(shù)用的;第二個函數(shù)是BitBlt,這個函數(shù)將源DC上的像素掃描到目標DC中,在這里就是將顯示器屏幕的像素掃描到我們創(chuàng)建的Image圖片上.

??? 掃描完成之后得到的Image圖像就是現(xiàn)在的全屏圖,可以將圖片保存或者拷貝待用.這就實現(xiàn)了全屏截圖的功能.

??? 接下來是實現(xiàn)局部截圖.首先將全屏截圖Image通過畫圖畫在Winform窗體上,這個可以用窗體的Paint事件來實現(xiàn),當窗體改變的時候,Paint事件就會被觸發(fā).局部截圖就是在已經(jīng)畫上了全屏圖片的Winform窗體上面再畫矩形,然后調(diào)用Graphics的方法DrawImage,將矩形區(qū)域的截圖保存在開始創(chuàng)建的Image中,這樣就得到了局部截圖,可以將圖片保存或者拷貝待用.

??? 功能基本上就實現(xiàn)了.需要注意的是,在窗體中畫的矩形是可反轉矩形,調(diào)用的是ControlPaint.DrawReversibleFrame()方法,這個方法需要執(zhí)行2次才能畫出矩形.

??? 主窗口代碼:

public partial class Form1 : Form
{
//*******************Global Varibles******************
private Bitmap MyImage = null;
private bool StartedCrop = false;

Point StartPoint = new Point(0, 0);
Rectangle SelectRect = new Rectangle();
int DeltaX = 0;
int DeltaY = 0;
//****************************************************

[DllImport("gdi32.dll", EntryPoint = "BitBlt")]
public static extern int BitBlt(
IntPtr hDestDC,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hSrcDC,
int xSrc,
int ySrc,
System.Int32 dwRop
);
[DllImport("gdi32.dll", EntryPoint = "CreateDC")]
public static extern IntPtr CreateDC(
string lpDriverName,
string lpDeviceName,
string lpOutput,
IntPtr lpInitData
);

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
this.Visible = false;
Thread.Sleep(100);
IntPtr dc1 = CreateDC("DISPLAY", null, null, (IntPtr)null);
Graphics g1 = Graphics.FromHdc(dc1);
MyImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);
Graphics g2 = Graphics.FromImage(MyImage);
//Visible = false;
dc1 = g1.GetHdc();
IntPtr dc2 = g2.GetHdc();
BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height,
dc1, 0, 0, 13369376);

g1.ReleaseHdc(dc1);
g2.ReleaseHdc(dc2);
this.Visible = true;
this.SetBounds(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
this.Cursor = Cursors.Cross;
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (StartedCrop == false)
{
DeltaX = 0;
DeltaY = 0;
}
StartedCrop = true;
StartPoint = new Point(e.X,e.Y);
SelectRect.Width = 0;
SelectRect.Height = 0;
SelectRect.X = e.X;
SelectRect.Y = e.Y;
Invalidate();
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Form thisform = (Form)sender;
if (StartedCrop)
{
DeltaX = e.X - StartPoint.X;
if (DeltaX < 0)
DeltaX = 0;
DeltaY = e.Y - StartPoint.Y;
if (DeltaY < 0)
DeltaY = 0;
ControlPaint.DrawReversibleFrame(thisform.RectangleToScreen(SelectRect), Color.Black, FrameStyle.Dashed);
SelectRect.Width = e.X - SelectRect.X;
SelectRect.Height = e.Y - SelectRect.Y;
ControlPaint.DrawReversibleFrame(thisform.RectangleToScreen(SelectRect), Color.Black, FrameStyle.Dashed);
}
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (DeltaX == 0 || DeltaY == 0)
{
return;
}

StartedCrop = false;
SelectRect.X = e.X - StartPoint.X;
SelectRect.Y = e.Y - StartPoint.Y;
this.Cursor = Cursors.Cross;


Bitmap theImage = new Bitmap(DeltaX, DeltaY);
Graphics g = Graphics.FromImage(theImage);
Rectangle destRect = new Rectangle(0, 0, DeltaX, DeltaY);
g.DrawImage(MyImage, destRect, StartPoint.X, StartPoint.Y, theImage.Width, theImage.Height, GraphicsUnit.Pixel);
MyImage = (Bitmap)theImage.Clone();
this.SetBounds(0, 0, MyImage.Width, MyImage.Height);
this.Visible = false;

frmOptions optionsForm = new frmOptions();
optionsForm.imageToSaveOrCopy = MyImage;
optionsForm.ShowDialog();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
if (MyImage != null)
e.Graphics.DrawImage(MyImage, ClientRectangle, 0, 0, MyImage.Width, MyImage.Height, GraphicsUnit.Pixel);
}

private void Form1_Resize(object sender, EventArgs e)
{
Invalidate();
}

private void Form1_DoubleClick(object sender, EventArgs e)
{
Application.Exit();
}
}

??? 選項窗口代碼(frmOptions)主要有2個按鈕,用來保存或者拷貝截取的圖片:

public partial class frmOptions : Form
{
public Image imageToSaveOrCopy;

public frmOptions()
{
InitializeComponent();
}

private void frmOptions_Load(object sender, EventArgs e)
{

}

private void btnSave_Click(object sender, EventArgs e)
{
if (imageToSaveOrCopy == null) {
MessageBox.Show("You have not choose the image! Please restart this program!");
Application.Exit();
}

SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "*.jpg|*.jpg";
sfd.AddExtension = true;
sfd.FileName = "1.jpg";
if (sfd.ShowDialog() == DialogResult.OK)
{
imageToSaveOrCopy.Save(sfd.FileName);
}
Application.Exit();
}

private void btnCopy_Click(object sender, EventArgs e)
{
if (imageToSaveOrCopy == null)
{
MessageBox.Show("You have not choose the image! Please restart this program!");
Application.Exit();
}
try
{
Clipboard.SetImage(imageToSaveOrCopy);
}
catch (Exception ex)
{
MessageBox.Show("Copy to clipboard error:\r\n"+ex.Message);
}
Application.Exit();
}
}

??? 由于局部截圖的時候需要在屏幕上面畫圖,而要想屏幕位置(Point)和我們主窗體的位置一一對應起來,就需要將主窗體最大化到全屏幕,為了效果好點,可以將
窗體的BorderStyle屬性設置為None.這樣整個工作就完成了.

轉載于:https://www.cnblogs.com/johnsmith/archive/2012/01/02/2309775.html

總結

以上是生活随笔為你收集整理的制作类似QQ截图软件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。