新闻中心

EEPW首页>嵌入式系统>设计应用> 软硬结合——酷我音乐盒的逆天玩法

软硬结合——酷我音乐盒的逆天玩法

作者: 时间:2017-01-18 来源:网络 收藏

  22 int width = rect.Right - rect.Left; //窗口的宽度

本文引用地址://m.amcfsurvey.com/article/201701/343047.htm

  23 int height = rect.Bottom - rect.Top; //窗口的高度

  24 int x = rect.Right; //窗口的位置

  25 int y = rect.Top;

  26

  27 int X=0,Y=0;

  28 if(n_control_type==0)//坐标[-20,200]:第3列表 [-120,200]:第2列表 [-220,200]第1列表

  29 { //坐标[-200,100]:上一曲 [-170,100]暂停 [-145,100]下一曲

  30 X = x - 200;

  31 Y = y + 100;

  32 }

  33 else if (n_control_type == 1)

  34 {

  35 X = x - 170;

  36 Y = y + 100;

  37 }

  38 else

  39 {

  40 X = x - 145;

  41 Y = y + 100;

  42 }

  43

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

  45 mouse_event(MOUSEEVENTF_LEFTDOWN, X * 65536 / 1024, X * 65536 / 768, 0, 0); //发送鼠标信息

  46 mouse_event(MOUSEEVENTF_LEFTUP, Y * 65536 / 1024, Y * 65536 / 768, 0, 0);

  47 SetCursorPos(pt.X, pt.Y); //移动鼠标回到原位置

  48

  49 //if (isVisabled == 24) ShowWindow(hMusic, SW_HIDE);

  50 //SetParent(hMusic, this.Handle);

  51 //EnableWindow((IntPtr)this.Handle, true);

  52 SetWindowPos(hMusic, (IntPtr)this.Handle, x, y, width, height, SWP_NOMOVE); //使能窗口聚焦原窗口

  53 SetForegroundWindow(hCurWin); //将原来窗口放在最上层

  54 }

  PS:这个函数负责找到酷我音乐盒的窗口(第10行)、顶层窗口切换(第18行、第52行、第53行)、鼠标位置设置(第16行、第44行、第47行)、鼠标点击消息的生成(第45行、第46行)、点击区域计算(第27~42行)

  GetForegroundWindow(); 获取当前顶层窗口句柄,不懂百度一下,就windows API介绍很多,初学者知道怎么用就行啦![在调用它之前要写这些代码,下面说的调用API都要这样的!]

  1 [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]

  2 public static extern IntPtr GetForegroundWindow();

  FindWindow("kwmusicmaindlg", null);根据窗口类名或者窗口名获得窗口句柄。PS:该如何知道某个窗口的类名或者窗口名呢?一般是用VC6.0或者是VS系列软件的Tool-->Spy++,具体请见我写的一篇博文,里面有详细介绍:http://www.cnblogs.com/zjutlitao/p/3889900.html

  1 [DllImport("user32.dll", EntryPoint = "FindWindow")]

  2 public static extern IntPtr FindWindow(

  3 string lpClassName,

  4 string lpWindowName

  5 );

  GetCursorPos(out pt);获取当前鼠标的位置,保存在Point结构体内,这里因为我们想让鼠标点击一下按钮然后回到原来的位置,所以要保存原来的位置!

  1 [DllImport("user32.dll")]

  2 public static extern bool GetCursorPos(out Point pt);

  ShowWindow(hMusic,SW_SHOWNORMAL);根据句柄显示窗口,这里第二个参数是设定窗口以哪种方式显示的,主要有以最小化显示、最大化显示、正常显示.....具体参见度娘~我们这里是为了避免有时候音乐盒最小化,我们得把它打开才能触发点击事件有效。(我本来想用个标记来标记它原来的状态然后在处理之后恢复音乐盒自身的状态,但是觉得还得写些代码,没时间啦,调试这个浪费了很长时间~)

  1 //private readonly int SW_HIDE = 0; //隐藏

  2 private readonly int SW_SHOWNORMAL = 1; //还原

  3 [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]

  4 private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

  SetForegroundWindow(hMusic); 将活动窗口切换到句柄所指窗口,这样鼠标点击对应区域窗口才能接收到鼠标点击消息!

  1 [DllImport("user32.dll")]

  2 private static extern bool SetForegroundWindow(IntPtr hWnd);

  GetWindowRect(hMusic, ref rect); 获取指定窗口的在桌面上的矩形坐标(这样就能根据这个值计算目标窗口的大小和位置啦:20~25行就是干这个的)

  1 [DllImport("user32.dll")]

  2 [return: MarshalAs(UnmanagedType.Bool)]

  3 static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

  4

  5 [StructLayout(LayoutKind.Sequential)]

  6 public struct RECT

  7 {

  8 public int Left; //最左坐标

  9 public int Top; //最上坐标

  10 public int Right; //最右坐标

  11 public int Bottom; //最下坐标

  12 }

  SetCursorPos(X, Y); 设置鼠标光标位置(X,Y)

  1 [DllImport("user32.dll", EntryPoint = "SetCursorPos")]

  2 private static extern int SetCursorPos(int x, int y);

  mouse_event(MOUSEEVENTF_LEFTDOWN, X * 65536 / 1024, X * 65536 / 768, 0, 0); 发送消息函数,我们知道windows是消息机制的,你点一下鼠标其实就是光标移到指定位置,然后向系统发送一个鼠标按动消息,这里我仿制一个鼠标左击时间,第45行负责在指定位置发送个鼠标左键按下的消息,第46行发送个对应的鼠标左键抬起的消息,这样一按一抬就组成了一个点击事件。

  1 private readonly int MOUSEEVENTF_LEFTDOWN = 0x2;

  2 private readonly int MOUSEEVENTF_LEFTUP = 0x4;

  3 [DllImport("user32")]

  4 public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

  SetWindowPos(hMusic, (IntPtr)this.Handle, x, y, width, height, SWP_NOMOVE); 这个函数和ShowWindow有点像,只是这个可以设置窗口的三维显示,为什么是三维?平面窗口还有一维是窗口的叠放顺序,具体可以问度娘~(这里删了这句好像也没啥影响,当初因为没有下面那句,所以需要这个函数将焦点放到软件窗口)

  1 static readonly IntPtr HWND_TOP = new IntPtr(0);

  2 const UInt32 SWP_NOMOVE = 0x0002;

  3 [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowPos", SetLastError = true)]

  4 private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);

  5.1.4、时间函数TImer

  往窗口里加一个Timer控件:[长下面那个模样,属性设置为Interval:100,然后给它一个消息函数,属性中的那个闪电的标志],比MFC要方便的多,MFC要自己写这货,有点麻烦,但是对于打基础的童鞋还是建议从win32学起,然后再学MFC这样你对windows消息机制会有比较清晰的理解!嘿嘿,撤远啦!其实这个Timer对应的消息函数就像一个会定时执行的函数一样,你只要在里面写些逻辑,它会每隔一定的时间执行的。比如你想做动画效果,让一个小球移动,那么小球的坐标的改变的计算可以放在这里面写。下面看一下我的这个函数中写了什么:

  1 private string Status, ReceivedData;

  2 private void timer1_Tick(object sender, EventArgs e)

  3 {

  4 StatusMessage.Text = Status;

  5 StatusMessage.Text = ReceivedData;

  6 //当有有效信号过来触发控制

  7 if (signal == 1) func(2);//下一曲

  8 if (signal == 2) func(0);//上一曲

  9 if (signal == 3) func(1);//暂 停

  10 signal = 0;

  11 }

  PS:其实就是更新那个文本显示区的内容和根据上面收来的数据进行处理然后产生的3种不同的控制命令,来调用func函数执行不同的点击命令!

  >_<:好啦,软件部分终于说完啦(那其它3个功能按钮直接调用func函数就行啦),其实硬件部分更多,刚才一直没有说那个滤波算法,及对应的命令信号signal是如何产生的....下面就要介绍啦!

  6、硬件部分及滤波、信号产生算法详解:

  其实硬件部分就是CPU采集超声波测距仪采集的距离的信息通过发送给电脑,电脑再对发送过来的数据进行分析,来看看是要切歌还是暂停还是一些干扰(这里在硬件和图像处理中经常会谈到的名词:滤波)。这里只贴一下硬件部分的代码(难点是滤波,硬件是基于stc80c52的程序,包括与测距模块的通信程序、通信程序两大部分,具体细节里面有很详细的注释,建议如果是新手最好看看《新概念51单片机C语言教程》不错的哦~)



关键词:C#串口

评论


相关推荐

技术专区

关闭