色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 軟硬結(jié)合——酷我音樂盒的逆天玩法

          軟硬結(jié)合——酷我音樂盒的逆天玩法

          作者: 時(shí)間:2017-01-18 來(lái)源:網(wǎng)絡(luò) 收藏

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

          本文引用地址:http://cafeforensic.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)//坐標(biāo)[-20,200]:第3列表 [-120,200]:第2列表 [-220,200]第1列表

            29 { //坐標(biāo)[-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); //移動(dòng)鼠標(biāo)

            45 mouse_event(MOUSEEVENTF_LEFTDOWN, X * 65536 / 1024, X * 65536 / 768, 0, 0); //發(fā)送鼠標(biāo)信息

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

            47 SetCursorPos(pt.X, pt.Y); //移動(dòng)鼠標(biāo)回到原位置

            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); //將原來(lái)窗口放在最上層

            54 }

            PS:這個(gè)函數(shù)負(fù)責(zé)找到酷我音樂盒的窗口(第10行)、頂層窗口切換(第18行、第52行、第53行)、鼠標(biāo)位置設(shè)置(第16行、第44行、第47行)、鼠標(biāo)點(diǎn)擊消息的生成(第45行、第46行)、點(diǎn)擊區(qū)域計(jì)算(第27~42行)

            GetForegroundWindow(); 獲取當(dāng)前頂層窗口句柄,不懂百度一下,就windows API介紹很多,初學(xué)者知道怎么用就行啦![在調(diào)用它之前要寫這些代碼,下面說(shuō)的調(diào)用API都要這樣的!]

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

            2 public static extern IntPtr GetForegroundWindow();

            FindWindow("kwmusicmaindlg", null);根據(jù)窗口類名或者窗口名獲得窗口句柄。PS:該如何知道某個(gè)窗口的類名或者窗口名呢?一般是用VC6.0或者是VS系列軟件的Tool-->Spy++,具體請(qǐng)見我寫的一篇博文,里面有詳細(xì)介紹: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);獲取當(dāng)前鼠標(biāo)的位置,保存在Point結(jié)構(gòu)體內(nèi),這里因?yàn)槲覀兿胱屖髽?biāo)點(diǎn)擊一下按鈕然后回到原來(lái)的位置,所以要保存原來(lái)的位置!

            1 [DllImport("user32.dll")]

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

            ShowWindow(hMusic,SW_SHOWNORMAL);根據(jù)句柄顯示窗口,這里第二個(gè)參數(shù)是設(shè)定窗口以哪種方式顯示的,主要有以最小化顯示、最大化顯示、正常顯示.....具體參見度娘~我們這里是為了避免有時(shí)候音樂盒最小化,我們得把它打開才能觸發(fā)點(diǎn)擊事件有效。(我本來(lái)想用個(gè)標(biāo)記來(lái)標(biāo)記它原來(lái)的狀態(tài)然后在處理之后恢復(fù)音樂盒自身的狀態(tài),但是覺得還得寫些代碼,沒時(shí)間啦,調(diào)試這個(gè)浪費(fèi)了很長(zhǎng)時(shí)間~)

            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); 將活動(dòng)窗口切換到句柄所指窗口,這樣鼠標(biāo)點(diǎn)擊對(duì)應(yīng)區(qū)域窗口才能接收到鼠標(biāo)點(diǎn)擊消息!

            1 [DllImport("user32.dll")]

            2 private static extern bool SetForegroundWindow(IntPtr hWnd);

            GetWindowRect(hMusic, ref rect); 獲取指定窗口的在桌面上的矩形坐標(biāo)(這樣就能根據(jù)這個(gè)值計(jì)算目標(biāo)窗口的大小和位置啦:20~25行就是干這個(gè)的)

            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; //最左坐標(biāo)

            9 public int Top; //最上坐標(biāo)

            10 public int Right; //最右坐標(biāo)

            11 public int Bottom; //最下坐標(biāo)

            12 }

            SetCursorPos(X, Y); 設(shè)置鼠標(biāo)光標(biāo)位置(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); 發(fā)送消息函數(shù),我們知道windows是消息機(jī)制的,你點(diǎn)一下鼠標(biāo)其實(shí)就是光標(biāo)移到指定位置,然后向系統(tǒng)發(fā)送一個(gè)鼠標(biāo)按動(dòng)消息,這里我仿制一個(gè)鼠標(biāo)左擊時(shí)間,第45行負(fù)責(zé)在指定位置發(fā)送個(gè)鼠標(biāo)左鍵按下的消息,第46行發(fā)送個(gè)對(duì)應(yīng)的鼠標(biāo)左鍵抬起的消息,這樣一按一抬就組成了一個(gè)點(diǎn)擊事件。

            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); 這個(gè)函數(shù)和ShowWindow有點(diǎn)像,只是這個(gè)可以設(shè)置窗口的三維顯示,為什么是三維?平面窗口還有一維是窗口的疊放順序,具體可以問(wèn)度娘~(這里刪了這句好像也沒啥影響,當(dāng)初因?yàn)闆]有下面那句,所以需要這個(gè)函數(shù)將焦點(diǎn)放到軟件窗口)

            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、時(shí)間函數(shù)TImer

            往窗口里加一個(gè)Timer控件:[長(zhǎng)下面那個(gè)模樣,屬性設(shè)置為Interval:100,然后給它一個(gè)消息函數(shù),屬性中的那個(gè)閃電的標(biāo)志],比MFC要方便的多,MFC要自己寫這貨,有點(diǎn)麻煩,但是對(duì)于打基礎(chǔ)的童鞋還是建議從win32學(xué)起,然后再學(xué)MFC這樣你對(duì)windows消息機(jī)制會(huì)有比較清晰的理解!嘿嘿,撤遠(yuǎn)啦!其實(shí)這個(gè)Timer對(duì)應(yīng)的消息函數(shù)就像一個(gè)會(huì)定時(shí)執(zhí)行的函數(shù)一樣,你只要在里面寫些邏輯,它會(huì)每隔一定的時(shí)間執(zhí)行的。比如你想做動(dòng)畫效果,讓一個(gè)小球移動(dòng),那么小球的坐標(biāo)的改變的計(jì)算可以放在這里面寫。下面看一下我的這個(gè)函數(shù)中寫了什么:

            1 private string Status, ReceivedData;

            2 private void timer1_Tick(object sender, EventArgs e)

            3 {

            4 StatusMessage.Text = Status;

            5 StatusMessage.Text = ReceivedData;

            6 //當(dāng)有有效信號(hào)過(guò)來(lái)觸發(fā)控制

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

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

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

            10 signal = 0;

            11 }

            PS:其實(shí)就是更新那個(gè)文本顯示區(qū)的內(nèi)容和根據(jù)上面收來(lái)的數(shù)據(jù)進(jìn)行處理然后產(chǎn)生的3種不同的控制命令,來(lái)調(diào)用func函數(shù)執(zhí)行不同的點(diǎn)擊命令!

            >_<:好啦,軟件部分終于說(shuō)完啦(那其它3個(gè)功能按鈕直接調(diào)用func函數(shù)就行啦),其實(shí)硬件部分更多,剛才一直沒有說(shuō)那個(gè)濾波算法,及對(duì)應(yīng)的命令信號(hào)signal是如何產(chǎn)生的....下面就要介紹啦!

            6、硬件部分及濾波、信號(hào)產(chǎn)生算法詳解:

            其實(shí)硬件部分就是CPU采集超聲波測(cè)距儀采集的距離的信息通過(guò)發(fā)送給電腦,電腦再對(duì)發(fā)送過(guò)來(lái)的數(shù)據(jù)進(jìn)行分析,來(lái)看看是要切歌還是暫停還是一些干擾(這里在硬件和圖像處理中經(jīng)常會(huì)談到的名詞:濾波)。這里只貼一下硬件部分的代碼(難點(diǎn)是濾波,硬件是基于stc80c52的程序,包括與測(cè)距模塊的通信程序、通信程序兩大部分,具體細(xì)節(jié)里面有很詳細(xì)的注釋,建議如果是新手最好看看《新概念51單片機(jī)C語(yǔ)言教程》不錯(cuò)的哦~)



          關(guān)鍵詞: C# 串口

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉