[C #] the combination of hardware and software-the reverse gameplay of cool music box
5.1. C # serial port communication 5.1.1. Obtain the list of currently available serial ports. Copy code 1 // Get all port list for selection 2 // obtain the list of all ports, and displayed in the List 3 PortList. items. clear (); 4 string [] Ports = SerialPort. getPortNames (); 5 6 for (int I = 0; I <Ports. length; I ++) 7 {8 string s = Ports [I]. toUpper (); 9 Regex reg = new Regex ("[^ COM \ d]", RegexOptions. ignoreCase | RegexOptions. multiline); // Regular Expression 10 s = reg. replace (s, ""); 11 12 PortList. items. add (s); 13} 14 if (Ports. length> 1) PortList. selectedIndex = 1; copy the code to call the serial port to reference using System. IO. ports; the regular expression of row 9th references using System. text. regularExpressions; The PortList of row 3rd is the drop-down box; the overall function is to obtain all available serial ports through the function of row 4th, and then add the drop-down box to display. If available, select the first one; 5.1.2 serial port connection button event copy code 1 private void btn_link_Click (object sender, EventArgs e) 2 {3 if (! Connection. isOpen) 4 {5 // Start 6 Status = "Connecting... "; 7 Connection = new SerialPort (); 8 btn_link.Enabled = false; 9 Connection. portName = PortList. selectedItem. toString (); 10 Connection. open (); 11 Connection. readTimeout = 10000; 12 Connection. dataReceived + = new SerialDataReceivedEventHandler (PortDataReceived); 13 Status = "connection successful"; 14} 15} copy the code. PS: the entire process is to connect the serial port number selected in the drop-down box, the first line is important. It calls SerialDataReceivedEv. EntHandler (Func Name) is used to define the handle of a data receiving function. You can write PortDataReceived at will, but then you need to write the corresponding implementation function: (it is hard to understand the handle here, you can understand it as a function and bind it to the serial port. Once the serial port has data, execute this function ....) copy code 1 // receive serial data 2 private int num = 0; // The time when the obstacle enters the range 3 private bool enter = false; // whether there are obstacles entering 4 private int signal = 0; // control signal 5 private void PortDataReceived (object o, SerialDataReceivedEventArgs e) is formed for each time segment that enters the range) 6 {7 int length = 1; 8 byte [] data = new byte [length]; 9 Conn Ection. read (data, 0, length); 10 for (int I = 0; I <length; I ++) 11 {12 bytes eddata = string. format ("{0}", data [I]); 13} 14 15 // convert data filter to control signal 16 if (data [0]! = 136 &&! Enter) {// when there is an obstacle, the passed data is not 136 and the first 17 enter = true; 18 num = 1; 19} else if (data [0] = 136 & enter) {// when the obstacle leaves, the data transferred is 136 and the first 20 enter = false; 21 if (num> 1 & num <6) {22 signal = 1; 23} else if (num> 5 & num <10) {24 signal = 2; 25} else if (num> 9) {26 signal = 3; 27} 28 num = 0; 29} else if (data [0]! = 136 & data [0] >=0 & enter) {30 num ++; 31} 32} copy the code PS: This is the implementation of the serial port data receiving function, first, let's look at the other content, because it involves the filtering algorithm and the algorithm generated by the control signal ~ The core part of the 13 lines of code is that 9th lines read the serial port data from the buffer and put it in the data [] array, so that the serial port data will be placed in the data! What should I do ~ 5.1.3 important functions: copy code 1 // <summary> 2 // simulate the mouse clicking function 3 /// </summary> 4 // <param name = "n_control_type"> 0 is the previous qu, 1 is paused, 2 is the next song </param> 5 public void func (int n_control_type) 6 {7 // bool isVisabled; // The original window status, hide or show 8 IntPtr hCurWin = GetForegroundWindow (); // obtain the current activation Window 9 10 IntPtr hMusic = FindWindow ("kwmusicmaindlg", null ); // locate the window handle 11 if (hMusic = null) 12 {13 return; 14} 15 Point pt; // obtain the current mouse position 16 GetCurso RPos (out pt); 17 ShowWindow (hMusic, SW_SHOWNORMAL); // If hidden, display it normally 18 SetForegroundWindow (hMusic ); // place the music box window in the top 19 20 RECT rect = new RECT (); // obtain the window rectangle 21 GetWindowRect (hMusic, ref rect); 22 int width = rect. right-rect. left; // The window width is 23 int height = rect. bottom-rect. top; // The window height is 24 int x = rect. right; // The Position of the window is 25 int y = rect. top; 26 27 int X = 0, Y = 0; 28 if (n_control_type = 0) // coordinates [-20,200]: 3rd list [-120,200]: 2nd list [-220,200] 1st list 29 {// coordinate [-200,100]: The last [-170,100] pause [-145,100] Next song 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 else39 {40 X = x-145; 41 Y = y + 100; 42} 43 44 SetCursorPos (X, Y); // move the mouse 45 mouse_event (MOUSEEVENTF_LEFTDOWN, X * 65536/1024, X * 65536/768, 0, 0); // send the mouse information 46 mouse_event (MOUSEEVENTF_LEFTUP, Y * 65536/1024, Y * 65536 /768, 0, 0); 47 SetCursorPos (pt. x, pt. y); // move the mouse back to the original position 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); // enables the window to focus on the original window 53 SetForegroundWindow (hCurWin ); // place the original window on the top 54} copy the code PS: this function is responsible for finding the window (10th rows) of the cool music box, top-level window switching (18th rows, 52nd rows, 53rd rows), mouse position settings (16th rows 44 rows and 47th rows), generate a message by clicking the mouse (45th rows and 46th rows), and calculate the click area (27th ~ 42 rows) GetForegroundWindow (); get the current top-level window handle, do not understand Baidu, windows API Introduction A lot, beginners know how to use it! [Write the code before calling it. The following describes how to call an API.] 1 [DllImport ("user32.dll", CharSet = CharSet. auto, ExactSpelling = true)] 2 public static extern IntPtr GetForegroundWindow (); FindWindow ("kwmusicmaindlg", null); obtain the window Handle Based on the window class name or window name. PS: How do I know the class name or window name of a window? Generally used VC6.0 or VS series software Tool --> Spy ++, please refer to a blog I wrote, which has a detailed introduction: 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 lp1_wname5); GetCursorPos (out pt); get the current cursor position, saved in the Point structure. We want to save the original location because we want to click the button and return to the original location! 1 [DllImport ("user32.dll")] 2 public static extern bool GetCursorPos (out Point pt); ShowWindow (hMusic, SW_SHOWNORMAL); display window according to handle, here, the second parameter is used to set the display mode of the window, which can be minimized, maximized, and displayed normally ..... for more information, see du Niang ~ To avoid the minimization of the music box, we need to enable it to trigger the click event. (I wanted to use a flag to mark its original status and restore the status of the music box after processing, but I felt that I had to write some code and it was no longer necessary, debugging is a waste of time ~) 1 // private readonly int SW_HIDE = 0; // hide 2 private readonly int SW_SHOWNORMAL = 1; // restore 3 [DllImport ("user32.dll", EntryPoint = "ShowWindow ", setLastError = true)] 4 private static extern bool ShowWindow (IntPtr hWnd, int nCmdShow); SetForegroundWindow (hMusic); Switch the activity window to the window indicated by the handle, in this way, you can click the corresponding area window to receive the mouse click message! 1 [DllImport ("user32.dll")] 2 private static extern bool SetForegroundWindow (IntPtr hWnd); GetWindowRect (hMusic, ref rect ); obtains the rectangular coordinates of the specified window on the desktop (so that the size and position of the target window can be calculated based on this value: 20 ~ 25 rows are doing this.) Copy code 1 [DllImport ("user32.dll")] 2 [return: financialas (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; // The leftmost coordinate 9 public int Top; // The leftmost coordinate 10 public int Right; // rightmost coordinate 11 public int Bottom; // Bottom coordinate 12} copy the code SetCursorPos (X, Y); set the cursor position (X, Y) 1 [DllImport ("user32.dll", EntryPoi Nt = "SetCursorPos")] 2 private static extern int SetCursorPos (int x, int y); mouse_event (MOUSEEVENTF_LEFTDOWN, X * 65536/1024, x * 65536/768, 0, 0 ); message sending function. We know that windows is a message mechanism. You can click the mouse to move the cursor to a specified position, and then send a mouse-clicked message to the system, here, I copy a left-click Time for the mouse. Row 45th is responsible for sending a message with the left mouse button pressed at the specified position, and row 46th sends a message with the corresponding left mouse button lifted, this constitutes a click event. 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); this function is a bit like ShowWindow, but it can be set to three-dimensional display of the window. Why is it three-dimensional? A plane window also has a one-dimensional stacked sequence of windows. For details, see du Niang ~ (If this sentence is deleted here, it does not seem to have any impact. because there was no such sentence, the function needs to focus on the C # software window) 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. Time Function TImer adds a Timer control to the window:, Set the attribute to Interval: 100, and then give it a message function, the lightning flag in the attribute], C # is much more convenient than MFC, MFC needs to write the goods by themselves, it is a little troublesome, but it is recommended to start learning from win32 for basic shoes, and then to learn MFC so that you will have a clear understanding of the windows messaging mechanism! Hey, withdraw! In fact, the message function corresponding to this Timer is like a function that will be periodically executed. You only need to write some logic in it and it will be executed at a certain time. For example, if you want to make the animation effect move a ball, you can write the calculation of the changed coordinates of the ball here. Next let's take a look at what I wrote in this function: copy the Code 1 private string Status, ReceivedData; 2 private void timerreceivtick (object sender, EventArgs e) 3 {4 StatusMessage. text = Status; 5 StatusMessage. text = ReceivedData; 6 // when there is a valid signal to trigger control 7 if (signal = 1) func (2); // next song 8 if (signal = 2) func (0); // previous 9 if (signal = 3) func (1); // temporarily stop 10 signal = 0; 11} copy code PS: in fact, it is to update the content of the text display area and process the data received by the above serial port and then generate three different control commands to call the func function to execute different click commands! >_<: Well, the software is finished. (The other three function buttons call the func function directly.) In fact, there are more hardware parts, I haven't talked about the filter algorithm and how the corresponding command signal is generated just now .... the following is an introduction!