WindowsAPI调用和OC奇骏图片识别,窗体越界时鼠标
分类:计算机编程

对窗体加越界限制后,鼠标拖动窗体越界时,窗体不能动,鼠标位置可动,但窗体不再越界时,鼠标位置还能回到鼠标按下时相对窗体的坐标:
1、首先创建一个窗体Form1,然后在窗体上拖一个button1按钮(主要通过这个按钮来拖动窗体)

WindowsAPI调用和OCR图片识别,

傻了吧唧的装双系统.成功的干崩了原本的系统.现在重装VS.闲的没事胡扯几句.

WindowsAPI在每一台Windows系统上开放标准API供开发人员调用.功能齐全.在这里只介绍三个部分.

1.利用API控制鼠标键盘.

2.对外部程序的读写和监听

3.对外部程序窗口的改动.

外部程序的意思就是.假设我的程序是360.辣么我能控制腾讯QQ客户端啥的.

API的宏.以下任何常量和函数都可以在

const int MOUSEEVENTF_MOVE = 0x0001; // 移动鼠标 
const int MOUSEEVENTF_LEFTDOWN = 0x0002; //模仿鼠标左键按下
const int MOUSEEVENTF_LEFTUP = 0x0004; //模仿鼠标左键抬起 
const int MOUSEEVENTF_RIGHTDOWN = 0x0008; //模仿鼠标右键按下 
const int MOUSEEVENTF_RIGHTUP = 0x0010; //模仿鼠标右键抬起
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;// 模仿鼠标中键按下 
const int MOUSEEVENTF_MIDDLEUP = 0x0040;// 模仿鼠标中键抬起 
const int MOUSEEVENTF_ABSOLUTE = 0x8000; //标示是否采取绝对坐标 
private const int WM_SETTEXT = 0x000C;
const int BM_CLICK = 0xF5;//鼠标点击事件
const int WM_GETTEXT = 0xd;//获取文本
const int WM_CLOSE = 0x0010;//关闭窗口

 

调用时程序会在Bin下寻找同名DLL.如果没有会在C:WindowsSystem32中寻找同名DLL.

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool BlockInput([In, MarshalAs(UnmanagedType.Bool)] bool fBlockIt);

//BlockInput(true)锁定鼠标键盘.BlockInput(false)激活鼠标键盘.锁定时需要Thread.Sleep(500)才能生效

//如果在锁定鼠标键盘后死机..可以用CTRL ALT DELETE 激活鼠标键盘.听说用IO读出任务管理器可以使CTRL ALT DELETE 无效

 

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

//移动鼠标到指定坐标

 

[DllImport("user32")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);

//鼠标的点击事件

SetCursorPos(X, Y);//移动鼠标
mouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE), 0, 0, 0, IntPtr.Zero);//摁下
SetCursorPos(X, Y);//移动鼠标
mouse_event((int)(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE), 0, 0, 0, IntPtr.Zero);//放开

//移动鼠标到指定位置然后拖拽到指定位置

SetCursorPos(X, Y);//移动鼠标

mouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP), 0, 0, 0, IntPtr.Zero);//摁下

mouse_event((int)(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP), 0, 0, 0, IntPtr.Zero);//摁下

//移动鼠标到指定位置左键双击

c#提供封装的对象可以控制键盘

SendKeys.Send("1111高");//发送字符串
SendKeys.SendWait("{^c }");//发送键盘按键.组合键

API中有keybd_event函数.Win IO等也可以控制键盘.但是本人没有找到使用组合键的方法..

对剪切板的操作

``IDataObject iData = Clipboard.GetDataObject();

``var a = (String)iData.GetData(DataFormats.Text);

//读

``Clipboard.SetDataObject("1高G");

//写

  var g = Graphics.GetImage();

//读取剪切板里的图片

对外部程序的读写:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr Hwnd, int Msg, int wpala, string lpala);

 private const int WM_SETTEXT = 0x000C;//定义写的宏

 private  const int WM_GETTEXT = 0xd;//定义读的宏

  public static int WM_CLICK = 0x00F5;//定义点击的宏

public  const int BM_CLICK = 0xF5;//鼠标点击事件

//可以对外部程序的控件做读写.按钮点击.窗口关闭等

SendMessage(new IntPtr(“句柄”), WM_SETTEXT, 0,“数据”);

//写

StringBuilder code = new StringBuilder(1024);

SendMessage(new IntPtr(“句柄”), WM_GETTEXT, 1024, code);

//读

 SendMessage(“句柄”,WM_CLOSE,0,null);

//关闭窗口

SendMessage(new IntPtr(“句柄”), BM_CLICK, 0, 0);

//按钮的点击

 

在Windows系统下。每生成一个控件或者窗口都会出现一个句柄.是本对象的唯一标识符.可以通过坐标抓取.也可以用SPY 和INSPECT捕获句柄.稍后讲

下面是监听外部程序按钮点击的源码.是我哭着闹着求着微软的大牛给我写的一个案例.不要问我是怎么写的.我只会抄.如果有兴趣可以自行搜索全局钩子.HOOK.以下案例是微软的大臂用MSAA技术做的钩子

const uint WINEVENT_INCONTEXT = 0x0004;
const uint EVENT_MIN = 0x00000001;
const uint EVENT_MAX = 0x7FFFFFFF;
const uint EVENT_OBJECT_INVOKED = 0x8013;
const uint EVENT_OBJECT_STATECHANGE = 0x800A;
const uint ROLE_SYSTEM_PUSHBUTTON = 43;
const uint ROLE_SYSTEM_WINDOW = 10;
const int STATE_SYSTE_PRESSED = 0X00000008;
const int STATE_SYSTE_FOCUSED = 0X00000004;

 

[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(
uint eventMin,
uint eventMax,
IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc,
uint idProcess,
uint idThread,
uint dwFlags);

delegate void WinEventDelegate(
IntPtr hWinEventHook,
uint eventType,
IntPtr hwnd,
int idObject,
int idChild,
uint dwEventThread,
uint dwmsEventTime);

[DllImport("Oleacc.dll")]
static extern uint AccessibleObjectFromEvent(IntPtr hwnd, int dwObjectID, int dwChildID, out IAccessible ppacc, [MarshalAs(UnmanagedType.Struct)] out object pvarChild);

private void WinEventCallback(
IntPtr hWinEventHook,
uint eventType,
IntPtr hwnd,
int idObject,
int idChild,
uint dwEventThread,
uint dwmsEventTime)
{
if (eventType == EVENT_OBJECT_STATECHANGE)
{
IAccessible accObj = null;
object o = null;
AccessibleObjectFromEvent(hwnd, idObject, idChild, out accObj, out o);

int state;
if (accObj != null &&
accObj.accRole.ToString().Equals(ROLE_SYSTEM_PUSHBUTTON.ToString()) &&
accObj.accName == txtButtonName.Text.Trim() &&
int.TryParse(accObj.accState.ToString(), out state))
{
if ((state & STATE_SYSTE_PRESSED) == STATE_SYSTE_PRESSED &&
FindParentWindow(accObj, txtFormName.Text.Trim()))
{

txtOutput.AppendText(string.Format("{0}: {1} clicked.rn", DateTime.Now.ToShortTimeString(), accObj.accName));
}
}
}

}

bool FindParent(IAccessible acc, string parentName)
{
if (acc == null)
{
return false;
}

int maxRetry = 5;
int count = 0;
IAccessible cur = acc.accParent as IAccessible;
while (cur != null && count < maxRetry)
{
if (parentName.Equals(cur.accName.ToString())&&
cur.accRole.ToString().Equals(ROLE_SYSTEM_WINDOW.ToString()))
{
return true;
}

cur = cur.accParent as IAccessible;

count ;
}

return false;
}

bool FindParentWindow(IAccessible acc, string parentName)
{
if (acc == null)
{
return false;
}

int count = 0;
IAccessible cur = acc.accParent as IAccessible;
while (cur != null)
{
if (cur.accRole.ToString().Equals(ROLE_SYSTEM_WINDOW.ToString()))
{
if (parentName.Equals(cur.accName.ToString()))
{
return true;
}
else
{
return false;
}
}

cur = cur.accParent as IAccessible;

count ;
}

return false;
}

以上都是C底层的设计.啥都不能改.有性趣可以自行搜索IAccessible  

 

private void button1_Click(object sender, EventArgs e)
{
//先获取Process
string targetProcessName = txtProcessName.Text.Trim();
if (!string.IsNullOrEmpty(targetProcessName))
{
Process targetProcess = Process.GetProcessesByName(targetProcessName).First();

if (targetProcess != null)
{
//IAccessible acc =
IntPtr result = SetWinEventHook(EVENT_MIN, EVENT_MAX, IntPtr.Zero,
new WinEventDelegate(WinEventCallback), (uint)targetProcess.Id, 0, 0);
Console.WriteLine(result);
}
}
}

这些是我唯一看懂的源码.targetProcessName是挂钩的进程名称.targetProcessName是挂钩的程序按钮.

如果调用这个方法.就可以监听外部程序的按钮.如果目标点击.就会触发我们的事件.txtOutput文本会记录事件.

 

以下讲窗口的改动和句柄的捕获.

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

//第一个参数填NULL,第二个参数填窗口标题可以捕获该窗口的句柄

 

[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);

 

public struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}

 

//第一个参数窗口句柄.声明Rect传进去就会返回窗口的Rect

[DllImport("user32.dll", EntryPoint = "WindowFromPoint")]
public static extern int WindowFromPoint(
int xPoint,
int yPoint
);

//传递XY就会返回坐标处的句柄

 

对于窗口的改动用API很蛋疼.步骤是先正常化窗口.然后设置活动窗口.最后置顶.由于是用代码置顶.所以最后还要手动取消置顶

 

[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

//第一个填窗口句柄.后面填函数识别的整数

//     //最大化3 最小化2 正常化1

[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd);

//第一个填窗口句柄.

//设置活动窗口是必须的.不要问我为什么.

 

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);

 

SetWindowPos(“句柄”, -1, 0, 0, 0, 0, 1 | 2);

SetWindowPos(“句柄”, -2, 0, 0, 0, 0, 1 | 2);

//-1置顶.-2取消置顶

以上就是API.多了也懒得讲

public Bitmap GetScreenSnapshot(int x, int y, int wid, int hei)//截图
{
Rectangle rectangle = new Rectangle(x, y, wid, hei);
Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(rectangle.X, rectangle.Y, 0, 0, rectangle.Size, CopyPixelOperation.SourceCopy);
}
return bitmap;
}

做图片识别先做截图.传递TOP.LEFT.WIDTH.HEIGHT利用以上方法完成区域截图

当时吧.认为自己对图片识别底层有一定了解.然后自己重写了一套OCR.万万没想到在WIN 10上识别率过低.最后老老实实的用了网上的框架.

AspriseOCR.dll.

DevIL.dll

ILU.dll

private string OCRPrise(string imgfile,string width, string height)
{
String gcstr = Marshal.PtrToStringAnsi(OCRpart(@"" imgfile, -1, 0, 0,Convert.ToInt32( width),Convert.ToInt32( height)));
gcstr = gcstr.Replace('O', '0');
gcstr = gcstr.Replace('o', '0');
gcstr = gcstr.Replace('Z', '2');
gcstr = gcstr.Replace('z', '2');
gcstr = gcstr.Replace('L', '1');
gcstr = gcstr.Replace('l', '1');
gcstr = gcstr.Replace('I', '1');
gcstr = gcstr.Replace('i', '1');

gcstr = gcstr.Replace('T', '7');
gcstr = gcstr.Replace('t', '7');

gcstr = gcstr.Replace('G', '9');
gcstr = gcstr.Replace('g', '9');

gcstr = gcstr.Replace('S', '5');
gcstr = gcstr.Replace('s', '5');

gcstr = gcstr.Replace('J', '2');
gcstr = gcstr.Replace('j', '2');

gcstr = gcstr.Replace(',', '.');

gcstr = gcstr.Replace("(P1C)", "");

gcstr = gcstr.Replace("-", "");

gcstr = gcstr.Replace("'", "");
string result = null;

for (int i = 0; i < gcstr.Length; i )
{
if (!String.IsNullOrWhiteSpace(gcstr[i].ToString()))
{
result = gcstr[i];
}
}
return result;
}

以上就可以识别数字.在XP Win 7 Win10下识别率和兼容性还不错

以下讲本屌认知的OCR.在WIN7下还是很耐用的.因为WIN 10视网膜屏.所以..

比如目前要识别一张黑纸白字的图片中的数字

每一张图片都可以被解析成数据

数据中会存放图片的每一个像素和它对应的XY以及RGB

比如要识别白字.黑色像素的RGB是000.那么我们去除黑色像素的数据.保留白色像素的特征.相对坐标和像素值作为标准特征.

下一次在识别白字黑纸的图片就在轮回一边.

要注意数字的切割和与标准特征的对比.

一张图片有上千个像素.在底层进行处理时算法的工作量非常大.如果能做到快速和高效.重写的OCR就算成功.我在WIN 7上写的OCR明显很成功.

#region

int bytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];

Marshal.Copy(ptr, rgbValues, 0, bytes);

byte red = 0;
byte green = 0;
byte blue = 0;

for (int x = 0; x < bmp.Width; x )
{
for (int y = 0; y < bmp.Height; y )
{
//See the link above for an explanation
//of this calculation
int position = (y * bmpData.Stride) (x * Image.GetPixelFormatSize(bmpData.PixelFormat) / 8);
blue = rgbValues[position];
green = rgbValues[position 1];
red = rgbValues[position 2];
//Console.WriteLine("Fast: " red " "
// green " " blue);
if (red == 128 && green == 0 && blue == 0)
{
divisionx.Add(x);
divisiony.Add(y);
break;
}
}
}
bmp.UnlockBits(bmpData);

 

#endregion7

//过滤

#region 
//var ocrdata = frist[3].Split(new char[] { '|'});
//hdc = GetDC(IntPtr.Zero);
//for (int i = lpRect.Left Convert.ToInt32( ocrdata[0]); i <= lpRect.Left Convert.ToInt32(ocrdata[0]) Convert.ToInt32(ocrdata[2]); i )
//{
// for (int a1 = lpRect.Top Convert.ToInt32(ocrdata[1]); a1 < lpRect.Top Convert.ToInt32(ocrdata[1]) Convert.ToInt32(ocrdata[3]); a1 )
// {
// Color color = GetColor(i, a1);
// if (color.R == 128 && color.G == 0 && color.B == 0)
// {
// divisionx.Add(i);
// divisiony.Add(a1);
// break;
// }

// }

//}
//ReleaseDC(IntPtr.Zero, hdc);

#endregion

//获取指定像素做截图范围

 

if (divisionx.Count > 0)
{
#region 
for (int ic = 0; ic < divisionx.Count; ic )
{
if (ic <= divisionx.Count - 2)
{
if (ic == 0)
{
if (divisionx[ic] 1 != divisionx[ic 1])
{
divisionx.Remove(divisionx[ic]);
break;
}
}
else
{
if (divisionx[ic] 1 != divisionx[ic 1] && divisionx[ic] - 1 != divisionx[ic - 1])
{
divisionx.Remove(divisionx[ic]);
break;
}
}
}
}
#endregion

 

//删除小数点

 

#region 

for (int i = 0; i < divisionx.Count; i )
{
if (i <= divisionx.Count - 2)
{
if (xystate == 0 && divisionx[i] 1 == divisionx[i 1])
{
xystate = 1;
startx.Add(divisionx[i]);
//MessageBox.Show(startx.ToString());
}
if (divisionx[i] 1 != divisionx[i 1] && xystate == 1)
{
xystate = 0;
endx.Add(divisionx[i]);
// MessageBox.Show(endx.ToString());//末尾数字无法确定像素范围.单独计算
}
}
}
#endregion

//分割

#region 

int max = -1;
int test;
for (int i = 0; i < divisionx.Count; i )
{
if (i <= divisionx.Count - 2)
{
max = (divisionx[i] > divisionx[i 1] ? test = divisionx[i] : test = divisionx[i 1]) > max ?
(divisionx[i] > divisionx[i 1] ? max = divisionx[i] : max = divisionx[i 1]) : max;

}

}

#endregion

endx.Add(max);

//添加末尾指定像素

 

#region 

int maxy = -1;
int testy;
for (int i = 0; i < divisiony.Count; i )
{
if (i <= divisiony.Count - 2)
{
if (maxy == -1)
{
maxy = (divisiony[i] > divisiony[i 1] ? testy = divisiony[i 1] : testy = divisiony[i]);
}
else
{
maxy = (divisiony[i] > divisiony[i 1] ? testy = divisiony[i 1] : testy = divisiony[i]) < maxy ?
(divisiony[i] > divisiony[i 1] ? testy = divisiony[i 1] : testy = divisiony[i]) : maxy;
}

}

}

#endregion

//获取TOP像素

#region 

int buttommax = -1;
int buttomtest;
for (int i = 0; i < divisiony.Count; i )
{
if (i <= divisiony.Count - 2)
{
buttommax = (divisiony[i] > divisiony[i 1] ? buttomtest = divisiony[i] : buttomtest = divisiony[i 1]) > buttommax ?
(divisiony[i] > divisiony[i 1] ? buttomtest = divisiony[i] : buttomtest = divisiony[i 1]) : buttommax;

}

}

#endregion

//获取Buttom像素

#region 截图
int screenx;
int screeny;
int screenWidth;
int screenHeight;
if (startx.Count == endx.Count)
{
for (int i = 0; i < startx.Count; i )
{
screenx = startx[i];
screeny = maxy;
screenWidth = endx[i] - startx[i] 2;
screenHeight = buttommax - maxy 2;
//OCR.GetScreenSnapshot(screenx, screeny, screenWidth, screenHeight).Save(@"" AppDomain.CurrentDomain.SetupInformation.ApplicationBase i ".bmp", ImageFormat.Bmp);
Image img = Image.FromHbitmap(bmp.GetHbitmap());
Bitmap newbmp = new Bitmap(screenWidth, screenHeight, PixelFormat.Format32bppArgb);

using (Graphics g = Graphics.FromImage(newbmp))
{
//Rectangle origReg = new Rectangle(0, 0, bmp.Width, bmp.Height);
//Rectangle destReg = new Rectangle(screenx, screeny, screenWidth, screenHeight);
g.DrawImage(img, 0, 0, new Rectangle(screenx, screeny, screenWidth, screenHeight), GraphicsUnit.Pixel);
}

newbmp.Save(@"" AppDomain.CurrentDomain.SetupInformation.ApplicationBase i ".bmp", ImageFormat.Bmp);

}

}
else
{
MessageBox.Show("图片识别失败");
}
#endregion

 

#region 读取图片
string finallydata = null;
List<string> ocr = FileIO.BitmapSean();
List<string> value = new List<string>();
KeyValuePair<string, string> dicdata = new KeyValuePair<string, string>();

if (ocr.Count > 0)//图片
{
if (StaffData.OCRData.Count > 0)//模板
{
for (int g = 0; g < ocr.Count; g )
{

for (int i = 0; i <= 9; i )
{
value.Clear();
dicdata = StaffData.OCRData.Where(a => a.Key== i.ToString()).FirstOrDefault();//模板的数据

string[] ocrtest = dicdata.Value.Split(new char[] { '!' });

if (ocrtest.Count() > 0)
{

for (int a = 0; a < ocrtest.Count(); a )
{
value.Add(ocrtest[a]);//dic转list
}

if (value.Count > 0)//匹配
{
string resultocr = OCR.TestOCRProperty(gaulxy: value, gaulFile: ocr[g], gaulKey: StaffData.OCRData.Where(a => a.Key == i.ToString()).FirstOrDefault().Key.ToString());//图片识别
if (resultocr != "-1")
{
finallydata = resultocr;
break;

}

}
}
}
}
if (!String.IsNullOrWhiteSpace(finallydata))
{

string last1 = finallydata[finallydata.Count() - 1].ToString();
string last2 = finallydata[finallydata.Count() - 2].ToString();
finallydata = finallydata.Substring(0, finallydata.Count() - 2);
finallydata = finallydata "." last2 last1;

}
// MessageBox.Show(finallydata);
}

}
#endregion

 

#region 删除图片
//List<string> imgdata = FileIO.BitmapSean();
//if (imgdata.Count > 0)
//{
// for (int img = 0; img < imgdata.Count; img )
// {
// if (File.Exists(imgdata[img]))
// {
// File.Delete(imgdata[img]);
// }
// }
//}
#endregion

 

以上就是本屌手写的OCR.仅仅提供一个思路和经验.

<OCR>
<!--数字特征-->
<ocrdata key="0" value="1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!4|0!-4|1!4|0!-4|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-2|-7"/>
<ocrdata key="1" value="-1|1!1|0!0|1!0|1!0|1!0|1!0|1!-1|1!1|0!1|0!-1|-7"/>
<ocrdata key="2" value="1|0!1|0!-3|1!4|0!-4|1!4|0!-1|1!-1|1!-1|1!-1|1!0|1!1|0!1|0!1|0!1|0!-3|-7"/>
<ocrdata key="3" value="1|0!1|0!-3|1!4|0!0|1!-2|1!1|0!1|1!0|1!-4|1!4|0!-3|1!1|0!1|0!-2|-7"/>
<ocrdata key="4" value="-1|1!1|0!-2|1!2|0!-2|1!2|0!-3|1!3|0!-2|1!1|0!1|0!1|0!-1|1!0|1!1|0!-1|-7"/>
<ocrdata key="5" value="1|0!1|0!1|0!1|0!-4|1!0|1!0|1!1|0!1|0!1|0!1|1!0|1!-4|1!4|0!-3|1!1|0!1|0!-3|-7"/>
<ocrdata key="6" value="1|0!1|0!-3|1!3|0!-3|1!0|1!1|0!1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-2|-7"/>
<ocrdata key="7" value="1|0!1|0!1|0!1|0!-4|1!3|0!0|1!-1|1!0|1!0|1!0|1!0|1!-2|-7"/>
<ocrdata key="8" value="1|0!1|0!-3|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-2|-7"/>
<ocrdata key="9" value="1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!4|0!-3|1!1|0!1|0!1|0!0|1!-3|1!3|0!-3|1!1|0!1|0!-2|-7"/>
<!--以下为Win 10 数字特征-->
<ocrdata key="!0 " value="1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!4|0!-4|1!4|0!-4|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-2|-7"/>
<ocrdata key="!5 " value="1|0!1|0!1|0!1|0!-4|1!0|1!0|1!1|0!1|0!1|0!-3|1!4|0!0|1!-4|1!4|0!-3|1!1|0!1|0!-3|-7"/>
<ocrdata key="!6 " value="1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!3|0!1|0!-3|1!1|0!2|0!0|1!-4|1!3|0!-2|1!1|0!-1|-7"/>
<ocrdata key="!8 " value="1|0!1|0!-3|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!4|0!-3|1!1|0!1|0!-2|-7"/>
<ocrata key="!9 " value="1|0!1|0!-3|1!4|0!-4|1!4|0!-4|1!3|0!1|0!-3|1!1|0!2|0!0|1!-4|1!3|0!-2|1!1|0!-1|-7"/>
<!--截图范围-->
<!--第一组金额.第二组税额.第三组小写.第四组发票编号-->
<ocrxy key="1600*900" value="485|427|100|15!615|427|158|12!620|448|153|11!687|131|61|14"/>
</OCR>

以上是我保存的数字特征.每一个像素的间距.仅供参考

 

傻了吧唧的装双系统.成功的干崩了原本的系统.现在重装VS.闲的没事胡扯几句. WindowsAPI在每一台Windows系统上开...

声明:private Point mouseOffset;        //记录鼠标指针的坐标
        private bool isMouseDown = false; //记录鼠标按键是否按下

2、然后对按钮添加鼠标按下事件、鼠标移动事件和鼠标抬起事件,事件里面是对窗体和鼠标坐标的操作,整体代码如下:
using System.Drawing;
using System.Windows.Forms;
namespace 窗体越界鼠标还能回到初始坐标
{
    public partial class Form1 : System.Windows.Forms.Form
    {
        #region 变量定义
        public Point mainFormPosition;//主窗口左上角位置
        int workingAreaHeight = SystemInformation.WorkingArea.Height;
        int workingAreaWidth = SystemInformation.WorkingArea.Width;
        private Point relativetMousePosition;//鼠标相对窗体的相对坐标
        bool FirstLeft = false;//是否左边第一次按下时坐标
        bool FirstRight = false;//是否右边第一次按下时坐标
        bool FirstUp = false;//是否上边第一次按下时坐标
        bool FirstDown = false;//是否下边第一次按下时坐标
        bool isFirstDown = true;//是否第一次按下,鼠标越界纠正时判断是否是第一次按下,不是按下后又拖动了
        bool isMoveOut = false;//是否拖出
        //这两个变量做差,差值为拖出的距离时软件弹出侧边
        int oldMove_X = 0;//侧边停靠拖出时起始坐标
        //上一个时刻、鼠标的位置
        private Point oldMousePosition;
        //当前时刻、鼠标的位置
        private Point currentMousePosition;
        //鼠标事件
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
        //移动鼠标
        const int MOUSEEVENTF_MOVE = 0x0001;
        //模拟鼠标左键按下
        const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        //模拟鼠标左键抬起
        const int MOUSEEVENTF_LEFTUP = 0x0004;
        //模拟鼠标右键按下
        const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
        //模拟鼠标右键抬起
        const int MOUSEEVENTF_RIGHTUP = 0x0010;
        //模拟鼠标中键按下
        const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        //模拟鼠标中键抬起
        const int MOUSEEVENTF_MIDDLEUP = 0x0040;
        //标示是否采用绝对坐标
        const int MOUSEEVENTF_ABSOLUTE = 0x8000;
        #endregion

C#代码 

调用  :  BLL.BitmapRegion.CreateControlRegion(this, new Bitmap(Application.StartupPath "\pic\login.bmp"));

        #region 窗体初始化
        public Form1()
        {
            InitializeComponent();
        }
        #endregion

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.ComponentModel;  
  5. using System.Data;  
  6. using System.Drawing;  
  7. using System.Windows.Forms;  
  8.   
  9. namespace AllTest  
  10. {  
  11.     class BarcodeControl  
  12.     {  
  13.         #region private  
  14.   
  15.         private const int MIN_SIZE = 10; //对控件缩放的最小值   
  16.         private const int BOX_SIZE = 7;  //调整大小触模柄方框大小   
  17.   
  18.         public bool _IsCtrlKey = false;  
  19.         private TextBox _textbox;  
  20.         private Control _MControl = null;  
  21.         private bool _IsMouseDown = false;  
  22.         private Point _oPointClicked;  
  23.         private Color BOX_COLOR = Color.White;  
  24.         private Label[] _lbl = new Label[8];  
  25.         private int _startl, _startt, _startw, _starth;  
  26.         private bool _dragging;  
  27.         private Cursor[] _arrArrow = new Cursor[] {Cursors.SizeNWSE, Cursors.SizeNS,   
  28.                                                     Cursors.SizeNESW, Cursors.SizeWE, Cursors.SizeNWSE, Cursors.SizeNS,   
  29.                                                     Cursors.SizeNESW, Cursors.SizeWE};  
  30.  
  31.         #endregion  
  32.   
  33.         #region 构造函数  
  34.   
  35.         /// <summary>   
  36.         /// 构造控件拖动对象   
  37.         /// </summary>   
  38.         /// <param name="moveControl">需要拖动的控件 </param>   
  39.         public BarcodeControl(Control moveControl)  
  40.         {  
  41.             //   
  42.             // TODO: 在此处添加构造函数逻辑   
  43.             //   
  44.             _MControl = moveControl;  
  45.             _MControl.MouseDown  = new MouseEventHandler(this.Control_MouseDown);  
  46.             _MControl.MouseUp  = new MouseEventHandler(this.Control_MouseUp);  
  47.             _MControl.MouseMove  = new MouseEventHandler(this.Control_MouseMove);  
  48.             _MControl.Click  = new System.EventHandler(this.Control_Click);  
  49.   
  50.             //构造8个调整大小触模柄   
  51.             for (int i = 0; i < 8; i )  
  52.             {  
  53.                 _lbl[i] = new Label();  
  54.                 _lbl[i].TabIndex = i;  
  55.                 _lbl[i].FlatStyle = 0;  
  56.                 _lbl[i].BorderStyle = BorderStyle.FixedSingle;  
  57.                 _lbl[i].BackColor = BOX_COLOR;  
  58.                 _lbl[i].Cursor = _arrArrow[i];  
  59.                 _lbl[i].Text = "";  
  60.                 _lbl[i].BringToFront();  
  61.                 _lbl[i].MouseDown  = new MouseEventHandler(this.handle_MouseDown);  
  62.                 _lbl[i].MouseMove  = new MouseEventHandler(this.handle_MouseMove);  
  63.                 _lbl[i].MouseUp  = new MouseEventHandler(this.handle_MouseUp);  
  64.             }  
  65.   
  66.             CreateTextBox();  
  67.             Create();  
  68.   
  69.             //Control_Click((object)sender, (System.EventArgs)e);   
  70.         }  
  71.  
  72.         #endregion  
  73.   
  74.         #region 需拖动控件键盘事件  
  75.   
  76.         private void textBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)  
  77.         {  
  78.             if (e.KeyValue == 37 || e.KeyValue == 38 || e.KeyValue == 39 || e.KeyValue == 40)  
  79.             {  
  80.                 if (e.KeyValue == 37)  
  81.                     _MControl.Left -= 1;  
  82.                 if (e.KeyValue == 38)  
  83.                     _MControl.Top -= 1;  
  84.                 if (e.KeyValue == 39)  
  85.                     _MControl.Left  = 1;  
  86.                 if (e.KeyValue == 40)  
  87.                     _MControl.Top  = 1;  
  88.                 MoveHandles();  
  89.                 ControlLocality();  
  90.                 _MControl.Visible = true;  
  91.             }  
  92.   
  93.             if (e.KeyValue == 46)  
  94.             {  
  95.                 for (int i = 0; i < 8; i )  
  96.                 {  
  97.                     _MControl.Parent.Controls.Remove(_lbl[i]);  
  98.                 }  
  99.                 _MControl.Parent.Controls.Remove(_MControl);  
  100.                 _textbox.Parent.Controls.Remove(_textbox);  
  101.             }  
  102.   
  103.             if (e.KeyValue == 17)  
  104.             {  
  105.                 _IsCtrlKey = true;  
  106.                 //MessageBox.Show("a");   
  107.             }  
  108.         }  
  109.  
  110.         #endregion  
  111.   
  112.         #region 需拖动控件鼠标事件  
  113.   
  114.         private void Control_Click(object sender, System.EventArgs e)  
  115.         {  
  116.             _textbox.Focus();  
  117.             _MControl = (sender as Control);  
  118.             MoveHandles();  
  119.   
  120.             if (_IsCtrlKey == false)  
  121.             {  
  122.                 for (int i = 0; i < _MControl.Parent.Controls.Count; i )  
  123.                 {  
  124.                     if (_MControl.Parent.Controls[i].Text.Trim().Length == 0 && _MControl.Parent.Controls[i] is Label)  
  125.                     {  
  126.                         _MControl.Parent.Controls[i].Visible = false;  
  127.                     }  
  128.                 }  
  129.             }  
  130.         }  
  131.         private void Control_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)  
  132.         {  
  133.             _IsMouseDown = true;  
  134.             _oPointClicked = new Point(e.X, e.Y);  
  135.             for (int i = 0; i < 8; i )  
  136.             {  
  137.                 _MControl.Parent.Controls.Add(_lbl[i]);  
  138.                 _lbl[i].BringToFront();  
  139.             }  
  140.             HideHandles();  
  141.         }  
  142.   
  143.         private void Control_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)  
  144.         {  
  145.             _IsMouseDown = false;  
  146.             MoveHandles();  
  147.             ShowHandles();  
  148.             _MControl.Visible = true;  
  149.         }  
  150.   
  151.         private void Control_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)  
  152.         {  
  153.             if (_IsMouseDown)  
  154.             {  
  155.                 int l = _MControl.Left   (e.X - _oPointClicked.X);  
  156.                 int t = _MControl.Top   (e.Y - _oPointClicked.Y);  
  157.                 int w = _MControl.Width;  
  158.                 int h = _MControl.Height;  
  159.                 l = (l < 0) ? 0 : ((l   w > _MControl.Parent.ClientRectangle.Width) ?  
  160.                     _MControl.Parent.ClientRectangle.Width - w : l);  
  161.                 t = (t < 0) ? 0 : ((t   h > _MControl.Parent.ClientRectangle.Height) ?  
  162.                     _MControl.Parent.ClientRectangle.Height - h : t);  
  163.                 _MControl.Left = l;  
  164.                 _MControl.Top = t;  
  165.                 ControlLocality();  
  166.             }  
  167.             //_MControl.Cursor=Cursors.SizeAll;   
  168.         }  
  169.  
  170.         #endregion  
  171.         #region 调整大小触模柄鼠标事件  
  172.   
  173.         private void handle_MouseDown(object sender, MouseEventArgs e)  
  174.         {  
  175.             _dragging = true;  
  176.             _startl = _MControl.Left;  
  177.             _startt = _MControl.Top;  
  178.             _startw = _MControl.Width;  
  179.             _starth = _MControl.Height;  
  180.             HideHandles();  
  181.         }  
  182.         // 通过触模柄调整控件大小   
  183.         //    0  1  2   
  184.         //  7      3   
  185.         //  6  5  4   
  186.         private void handle_MouseMove(object sender, MouseEventArgs e)  
  187.         {  
  188.             int l = _MControl.Left;  
  189.             int w = _MControl.Width;  
  190.             int t = _MControl.Top;  
  191.             int h = _MControl.Height;  
  192.             if (_dragging)  
  193.             {  
  194.                 switch (((Label)sender).TabIndex)  
  195.                 {  
  196.                     //l算法:控件左边X坐标 + 鼠标在触模柄X坐标 < 控件左边X坐标 + 父控件宽度 - 控件大小 ?控件左边X坐标 + 鼠标在触模柄X坐标 :控件左边X坐标 + 父控件宽度 - 控件大小    
  197.                     //t算法:   
  198.                     //w算法:   
  199.                     //h算法:   
  200.                     case 0: // _dragging top-left sizing box   
  201.                         l = _startl   e.X < _startl   _startw - MIN_SIZE ? _startl   e.X : _startl   _startw - MIN_SIZE;  
  202.                         t = _startt   e.Y < _startt   _starth - MIN_SIZE ? _startt   e.Y : _startt   _starth - MIN_SIZE;  
  203.                         w = _startl   _startw - _MControl.Left;  
  204.                         h = _startt   _starth - _MControl.Top;  
  205.                         break;  
  206.                     case 1: // _dragging top-center sizing box   
  207.                         t = _startt   e.Y < _startt   _starth - MIN_SIZE ? _startt   e.Y : _startt   _starth - MIN_SIZE;  
  208.                         h = _startt   _starth - _MControl.Top;  
  209.                         break;  
  210.                     case 2: // _dragging top-right sizing box   
  211.                         w = _startw   e.X > MIN_SIZE ? _startw   e.X : MIN_SIZE;  
  212.                         t = _startt   e.Y < _startt   _starth - MIN_SIZE ? _startt   e.Y : _startt   _starth - MIN_SIZE;  
  213.                         h = _startt   _starth - _MControl.Top;  
  214.                         break;  
  215.                     case 3: // _dragging right-middle sizing box   
  216.                         w = _startw   e.X > MIN_SIZE ? _startw   e.X : MIN_SIZE;  
  217.                         break;  
  218.                     case 4: // _dragging right-bottom sizing box   
  219.                         w = _startw   e.X > MIN_SIZE ? _startw   e.X : MIN_SIZE;  
  220.                         h = _starth   e.Y > MIN_SIZE ? _starth   e.Y : MIN_SIZE;  
  221.                         break;  
  222.                     case 5: // _dragging center-bottom sizing box   
  223.                         h = _starth   e.Y > MIN_SIZE ? _starth   e.Y : MIN_SIZE;  
  224.                         break;  
  225.                     case 6: // _dragging left-bottom sizing box   
  226.                         l = _startl   e.X < _startl   _startw - MIN_SIZE ? _startl   e.X : _startl   _startw - MIN_SIZE;  
  227.                         w = _startl   _startw - _MControl.Left;  
  228.                         h = _starth   e.Y > MIN_SIZE ? _starth   e.Y : MIN_SIZE;  
  229.                         break;  
  230.                     case 7: // _dragging left-middle sizing box   
  231.                         l = _startl   e.X < _startl   _startw - MIN_SIZE ? _startl   e.X : _startl   _startw - MIN_SIZE;  
  232.                         w = _startl   _startw - _MControl.Left;  
  233.                         break;  
  234.                 }  
  235.                 l = (l < 0) ? 0 : l;  
  236.                 t = (t < 0) ? 0 : t;  
  237.                 _MControl.SetBounds(l, t, w, h);  
  238.             }  
  239.         }  
  240.   
  241.         private void handle_MouseUp(object sender, MouseEventArgs e)  
  242.         {  
  243.             _dragging = false;  
  244.             MoveHandles();  
  245.             ShowHandles();  
  246.         }  
  247.  
  248.         #endregion  
  249.   
  250.         #region private方法  
  251.   
  252.         private void Create()  
  253.         {  
  254.             //_IsMouseDown = true;   
  255.             //_oPointClicked = new Point(e.X,e.Y);   
  256.             for (int i = 0; i < 8; i )  
  257.             {  
  258.                 _MControl.Parent.Controls.Add(_lbl[i]);  
  259.                 _lbl[i].BringToFront();  
  260.             }  
  261.             HideHandles();  
  262.         }  
  263.   
  264.         private void CreateTextBox()  
  265.         {  
  266.             _textbox = new TextBox();  
  267.             _textbox.CreateControl();  
  268.             _textbox.Parent = _MControl.Parent;  
  269.             _textbox.Width = 0;  
  270.             _textbox.Height = 0;  
  271.             _textbox.TabStop = true;  
  272.             _textbox.KeyDown  = new System.Windows.Forms.KeyEventHandler(textBox_KeyDown);  
  273.         }  
  274.   
  275.         private void ControlLocality()  
  276.         {  
  277.             if (_MControl.Location.X < 0)  
  278.             {  
  279.                 _MControl.Visible = false;  
  280.                 _MControl.Left = 0;  
  281.             }  
  282.             if (_MControl.Location.Y < 0)  
  283.             {  
  284.                 _MControl.Visible = false;  
  285.                 _MControl.Top = 0;  
  286.             }  
  287.             if (_MControl.Location.X   _MControl.Width > _MControl.Parent.Width)  
  288.             {  
  289.                 _MControl.Visible = false;  
  290.                 _MControl.Left = _MControl.Parent.Width - _MControl.Width;  
  291.             }  
  292.             if (_MControl.Location.Y   _MControl.Height > _MControl.Parent.Height)  
  293.             {  
  294.                 _MControl.Visible = false;  
  295.                 _MControl.Top = _MControl.Parent.Height - _MControl.Height;  
  296.             }  
  297.         }  
  298.   
  299.         private void HideHandles()  
  300.         {  
  301.             for (int i = 0; i < 8; i )  
  302.             {  
  303.                 _lbl[i].Visible = false;  
  304.             }  
  305.         }  
  306.   
  307.         private void MoveHandles()  
  308.         {  
  309.             int sX = _MControl.Left - BOX_SIZE;  
  310.             int sY = _MControl.Top - BOX_SIZE;  
  311.             int sW = _MControl.Width   BOX_SIZE;  
  312.             int sH = _MControl.Height   BOX_SIZE;  
  313.             int hB = BOX_SIZE / 2;  
  314.             int[] arrPosX = new int[] {sX hB, sX   sW / 2, sX   sW-hB, sX   sW-hB,   
  315.                                           sX   sW-hB, sX   sW / 2, sX hB, sX hB};  
  316.             int[] arrPosY = new int[] {sY hB, sY hB, sY hB, sY   sH / 2, sY   sH-hB,   
  317.                                           sY   sH-hB, sY   sH-hB, sY   sH / 2};  
  318.             for (int i = 0; i < 8; i )  
  319.             {  
  320.                 _lbl[i].SetBounds(arrPosX[i], arrPosY[i], BOX_SIZE, BOX_SIZE);  
  321.             }  
  322.         }  
  323.   
  324.         private void ShowHandles()  
  325.         {  
  326.             if (_MControl != null)  
  327.             {  
  328.                 for (int i = 0; i < 8; i )  
  329.                 {  
  330.                     _lbl[i].Visible = true;  
  331.                 }  
  332.             }  
  333.         }  
  334.  
  335.         #endregion   
  336.     }  
  337. }  

 相关方法:

        //-------------------------按钮button1鼠标事件---------------------------------------------------------------
        #region 鼠标左键按下Button1按钮事件
        private void Button1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                currentMousePosition = Control.MousePosition;
                oldMousePosition = currentMousePosition;   //鼠标按下时、两个时刻的坐标变成一样,防止错误移动            
                mainFormPosition = Location;
                if (isFirstDown)//鼠标按下时,记录第一次鼠标按下相对主窗体的坐标
                {
                    relativetMousePosition.X = currentMousePosition.X - Location.X;
                    relativetMousePosition.Y = currentMousePosition.Y - Location.Y;
                    isFirstDown = false;
                }
                if (isMoveOut)//鼠标按下时,记录拖出时的初始坐标
                {
                    oldMove_X = currentMousePosition.X;
                }
            }
        }
        #endregion

接下来在一个窗体上放一个控件和按钮 
在按钮的单击事件里写 

 #region MouseDown事件
        private void form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            int xOffset;
            int yOffset;

        #region 鼠标左键按住Button1按钮移动事件
        private void Button1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                currentMousePosition = Control.MousePosition;
                if (currentMousePosition.X < relativetMousePosition.X && currentMousePosition.Y > relativetMousePosition.Y && currentMousePosition.Y < workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y)//左边窗体越界坐标纠正
                {
                    mainFormPosition.X = 0;
                    mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                    //保存上一个时刻的鼠标位置
                    oldMousePosition.Y = currentMousePosition.Y;
                    FirstLeft = true;
                }
                else if (currentMousePosition.X > workingAreaWidth - this.ClientSize.Width relativetMousePosition.X && currentMousePosition.Y > relativetMousePosition.Y && currentMousePosition.Y < workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y)//右边窗体越界坐标纠正
                {
                    mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
                    mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                    //保存上一个时刻的鼠标位置
                    oldMousePosition.Y = currentMousePosition.Y;
                    FirstRight = true;
                }
                else if (currentMousePosition.Y < relativetMousePosition.Y && currentMousePosition.X > relativetMousePosition.X && currentMousePosition.X < workingAreaWidth

C#代码 

            if (e.Button == MouseButtons.Left)
            {
                xOffset = -e.X;// -SystemInformation.FrameBorderSize.Width;
                yOffset = -e.Y;// -SystemInformation.FrameBorderSize.Height;
                mouseOffset = new Point(xOffset, yOffset);
                isMouseDown = true;              
            }
        }
        #endregion

  • this.ClientSize.Width relativetMousePosition.X)//上边窗体越界坐标纠正
                    {
                        mainFormPosition.Y = 0;
                        mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                        //保存上一个时刻的鼠标位置
                        oldMousePosition.X = currentMousePosition.X;
                        FirstUp = true;
                    }
                    else if (currentMousePosition.Y > workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y && currentMousePosition.X > relativetMousePosition.X && currentMousePosition.X < workingAreaWidth - this.ClientSize.Width relativetMousePosition.X)//下边窗体越界坐标纠正
                    {
                        mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
                        mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                        //保存上一个时刻的鼠标位置
                        oldMousePosition.X = currentMousePosition.X;
                        FirstDown = true;
                    }
                    else if (currentMousePosition.X < relativetMousePosition.X && currentMousePosition.Y < relativetMousePosition.Y)//左上角窗体越界坐标纠正
                    {
                        mainFormPosition.X = 0;
                        mainFormPosition.Y = 0;
                        mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                        mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                        //保存上一个时刻的鼠标位置
                        oldMousePosition.X = currentMousePosition.X;
                        oldMousePosition.Y = currentMousePosition.Y;
                        FirstLeft = true;
                        FirstUp = true;
                    }
                    else if (currentMousePosition.X > workingAreaWidth - this.ClientSize.Width relativetMousePosition.X && currentMousePosition.Y < relativetMousePosition.Y)//右上角窗体越界坐标纠正
                    {
                        mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
                        mainFormPosition.Y = 0;
                        mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                        mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                        //保存上一个时刻的鼠标位置
                        oldMousePosition.X = currentMousePosition.X;
                        oldMousePosition.Y = currentMousePosition.Y;
                        FirstRight = true;
                        FirstUp = true;
                    }
                    else if (currentMousePosition.X < relativetMousePosition.X && currentMousePosition.Y > workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y)//左下角窗体越界坐标纠正
                    {
                        mainFormPosition.X = 0;
                        mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
                        mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                        mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                        //保存上一个时刻的鼠标位置
                        oldMousePosition.X = currentMousePosition.X;
                        oldMousePosition.Y = currentMousePosition.Y;
                        FirstLeft = true;
                        FirstDown = true;
                    }
                    else if (currentMousePosition.X > workingAreaWidth - this.ClientSize.Width relativetMousePosition.X && currentMousePosition.Y > workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y)//右下角窗体越界坐标纠正
                    {
                        mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
                        mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
                        mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                        mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                        //保存上一个时刻的鼠标位置
                        oldMousePosition.X = currentMousePosition.X;
                        oldMousePosition.Y = currentMousePosition.Y;
                        FirstRight = true;
                        FirstDown = true;
                    }
                    if (FirstLeft)
                    {
                        currentMousePosition.X = relativetMousePosition.X;
                        FirstLeft = false;
                    }
                    if (FirstRight)
                    {
                        currentMousePosition.X = workingAreaWidth - this.ClientSize.Width relativetMousePosition.X;
                        FirstRight = false;
                    }
                    if (FirstUp)
                    {
                        currentMousePosition.Y = relativetMousePosition.Y;
                        FirstUp = false;
                    }
                    if (FirstDown)
                    {
                        currentMousePosition.Y = workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y;
                        FirstDown = false;
                    }
                    if (FirstLeft && FirstUp)
                    {
                        currentMousePosition.X = relativetMousePosition.X;
                        currentMousePosition.Y = relativetMousePosition.Y;
                        FirstLeft = false;
                        FirstUp = false;
  1. AllTest.BarcodeControl barcode = new BarcodeControl(控件); //传入控件即可看到效果  

        #region MouseMove事件
        private void form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (isMouseDown)
            {
                Point mousePos = Control.MousePosition;
                mousePos.Offset(mouseOffset.X, mouseOffset.Y);
                Location = mousePos;
            }
        }
        #endregion

                }
                if (FirstRight && FirstUp)
                {
                    currentMousePosition.X = workingAreaWidth - this.ClientSize.Width relativetMousePosition.X;
                    currentMousePosition.Y = relativetMousePosition.Y;
                    FirstUp = false;
                    FirstRight = false;
                }
                if (FirstLeft && FirstDown)
                {
                    currentMousePosition.X = relativetMousePosition.X;
                    currentMousePosition.Y = workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y;
                    FirstLeft = false;
                    FirstDown = false;
                }
                if (FirstRight && FirstDown)
                {
                    currentMousePosition.X = workingAreaWidth - this.ClientSize.Width relativetMousePosition.X;
                    currentMousePosition.Y = workingAreaHeight - this.ClientSize.Height relativetMousePosition.Y;
                    FirstRight = false;
                    FirstDown = false;
                }
                //对窗体进行移动
                mainFormPosition.X = currentMousePosition.X - oldMousePosition.X;
                mainFormPosition.Y = currentMousePosition.Y - oldMousePosition.Y;
                //保存上一个时刻的鼠标位置
                oldMousePosition = currentMousePosition;

        #region MouseUp事件
        private void form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            // 修改鼠标状态isMouseDown的值
            // 确保只有鼠标左键按下并移动时,才移动窗体
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = false;
            }
        }
        #endregion

                #region 越界处理
                if (mainFormPosition.X < 0)//左边越界
                {
                    mainFormPosition.X = 0;
                }
                else if (mainFormPosition.Y < 0)//上边越界
                {
                    mainFormPosition.Y = 0;
                }
                else if (mainFormPosition.X > workingAreaWidth - this.ClientSize.Width)//右边越界
                {
                    mainFormPosition.X = workingAreaWidth - this.ClientSize.Width;
                }
                else if (mainFormPosition.Y > workingAreaHeight - this.ClientSize.Height)//下边越界
                {
                    mainFormPosition.Y = workingAreaHeight - this.ClientSize.Height;
                }
                //更新主窗口位置
                Location = mainFormPosition;
                #endregion
            }
        }
        #endregion

 

        #region 鼠标在按钮Button1抬起事件
        private void Button1_MouseUp(object sender, MouseEventArgs e)
        {
            isFirstDown = true;
            //如果主窗体在这个位置,就判断允许主窗体在鼠标抬起后执行移动事件
            if (mainFormPosition.X == workingAreaWidth - this.ClientSize.Width)
            {
                isMoveOut = false;
            }
            if (mainFormPosition.X == 0)
            {
                isMoveOut = false;
            }
        }
        #endregion
    }
}

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

动画效果如下:

namespace BLL
{
    /// <summary>

 图片 1

    /// Summary description for BitmapRegion.
    /// </summary>
    public class BitmapRegion
    {
        public BitmapRegion()
        { }

这是本人在一个项目中遇到的问题,所以特意总结出来分享给大家。

        /// <summary>
        /// Create and apply the region on the supplied control
        /// 创建支持位图区域的控件(目前有button和form)
        /// </summary>
        /// <param name="control">The Control object to apply the region to控件</param>
        /// <param name="bitmap">The Bitmap object to create the region from位图</param>
        public static void CreateControlRegion(Control control, Bitmap bitmap)
        {
            // Return if control and bitmap are null
            //判断是否存在控件和位图
            if (control == null || bitmap == null)
                return;

            // Set our control''s size to be the same as the bitmap
            //设置控件大小为位图大小
            control.Width = bitmap.Width;
            control.Height = bitmap.Height;
            // Check if we are dealing with Form here
            //当控件是form时
            if (control is System.Windows.Forms.Form)
            {
                // Cast to a Form object
                //强制转换为FORM
                Form form = (Form)control;
                // Set our form''s size to be a little larger that the  bitmap just
                // in case the form''s border style is not set to none in the first place
                //当FORM的边界FormBorderStyle不为NONE时,应将FORM的大小设置成比位图大小稍大一点
                form.Width = control.Width;
                form.Height = control.Height;
                // No border
                //没有边界
                form.FormBorderStyle = FormBorderStyle.None;
                // Set bitmap as the background image
                //将位图设置成窗体背景图片
                form.BackgroundImage = bitmap;
                // Calculate the graphics path based on the bitmap supplied
                //计算位图中不透明部分的边界
                GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
                // Apply new region
                //应用新的区域
                form.Region = new Region(graphicsPath);
            }
            // Check if we are dealing with Button here
            //当控件是button时
            else if (control is System.Windows.Forms.Button)
            {
                // Cast to a button object
                //强制转换为 button
                Button button = (Button)control;
                // Do not show button text
                //不显示button text
                button.Text = "";

                // Change cursor to hand when over button
                //改变 cursor的style
                button.Cursor = Cursors.Hand;
                // Set background image of button
                //设置button的背景图片
                button.BackgroundImage = bitmap;

                // Calculate the graphics path based on the bitmap supplied
                //计算位图中不透明部分的边界
                GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
                // Apply new region
                //应用新的区域
                button.Region = new Region(graphicsPath);
            }
        }
        /// <summary>
        /// Calculate the graphics path that representing the figure in the bitmap
        /// excluding the transparent color which is the top left pixel.
        /// //计算位图中不透明部分的边界
        /// </summary>
        /// <param name="bitmap">The Bitmap object to calculate our graphics path from</param>
        /// <returns>Calculated graphics path</returns>
        private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
        {
            // Create GraphicsPath for our bitmap calculation
            //创建 GraphicsPath
            GraphicsPath graphicsPath = new GraphicsPath();
            // Use the top left pixel as our transparent color
            //使用左上角的一点的颜色作为我们透明色
            Color colorTransparent = bitmap.GetPixel(0, 0);
            // This is to store the column value where an opaque pixel is first found.
            // This value will determine where we start scanning for trailing opaque pixels.
            //第一个找到点的X
            int colOpaquePixel = 0;
            // Go through all rows (Y axis)
            // 偏历所有行(Y方向)
            for (int row = 0; row < bitmap.Height; row )
            {
                // Reset value
                //重设
                colOpaquePixel = 0;
                // Go through all columns (X axis)
                //偏历所有列(X方向)
                for (int col = 0; col < bitmap.Width; col )
                {
                    // If this is an opaque pixel, mark it and search for anymore trailing behind
                    //如果是不需要透明处理的点则标记,然后继续偏历
                    if (bitmap.GetPixel(col, row) != colorTransparent)
                    {
                        // Opaque pixel found, mark current position
                        //记录当前
                        colOpaquePixel = col;
                        // Create another variable to set the current pixel position
                        //建立新变量来记录当前点
                        int colNext = col;
                        // Starting from current found opaque pixel, search for anymore opaque pixels
                        // trailing behind, until a transparent   pixel is found or minimum width is reached
                        ///从找到的不透明点开始,继续寻找不透明点,一直到找到或则达到图片宽度
                        for (colNext = colOpaquePixel; colNext < bitmap.Width; colNext )
                            if (bitmap.GetPixel(colNext, row) == colorTransparent)
                                break;
                        // Form a rectangle for line of opaque   pixels found and add it to our graphics path
                        //将不透明点加到graphics path
                        graphicsPath.AddRectangle(new Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1));
                        // No need to scan the line of opaque pixels just found
                        col = colNext;
                    }
                }
            }
            // Return calculated graphics path
            return graphicsPath;
        }
    }
}

本文由pc28.am发布于计算机编程,转载请注明出处:WindowsAPI调用和OC奇骏图片识别,窗体越界时鼠标

上一篇:架构师的入门基础 下一篇:没有了
猜你喜欢
热门排行
精彩图文