Remote Control of Windows Mobile

Source: Internet
Author: User

Program code

Introduction:
This is a remote desktop control program for Windows Mobile. With this program, you can remotely control your windows mobile device through the keyboard and mouse.
Background:
The code is actually mentioned in my previous articles: A Remote Windows Mobile screen capture tool. In addition to calling rapi, the software can use an rapi service stream to allow desktop programs to establish uninterrupted connections between devices. Of course, in this program. I gave up Gapi and DirectDraw's screen capture method and used a simple GDI-based screen capture method. To enhance the communication capability, the zlib compression library is used at both ends of the connection.
Desktop code:
Create a ceremoteclient directory before extracting the program to save the desktop project.
Most of the desktop program code is included in ceremoteclientview. H. In fact, the wtl 8.0 framework subwindow implements the functions of all desktop clients.
The device connection is implemented through the connect () and disconnect () methods. You can use this command in the menu and toolbar, which are included in the main frame window class (mainfrm. h ). When the desktop is successfully connected to the device, a 200 microsecond clock is created to compress the screen bitmap.
Screen devices are controlled by the getscreen () method. It first turns off the timer, and then sends information to the service device requesting the current screen image:
Killtimer (screen_timer );
HR = write (rcm_getscreen );

The service device returns a message containing the same information code, compresses the size of the screen buffer, and decompress the stream data. After reading data of three types of words, the Code determines whether the space for compression and decompression buffer is sufficient, and then reads the compressed data stream:

// Read the compressed buffer.
HR = m_pstream-> Read (m_pzipbuf, cbzipbuf, & ulread );

If everything goes well, the compression buffer will be decompressed and the result DiB is the size of the bitmap. If the size is not the same, it will be repeated again. When it is very close, the screen device will be refreshed, so that the entire window will be cleared:
ZR = uncompress (m_pscrbuf, & ndestlen, m_pzipbuf, cbzipbuf );
If (Zr = z_ OK)
{
Dibinfo * pdibinfo = (dibinfo *) m_pscrbuf;
Byte * pbmpdata = (byte *) (m_pscrbuf + sizeof (dibinfo ));
Bool berase = false;

If (m_xdevscr! = Pdibinfo-> bmiheader. biwidth |
M_ydevscr! = Pdibinfo-> bmiheader. biheight)
{
M_xdevscr = pdibinfo-> bmiheader. biwidth;
M_ydevscr = pdibinfo-> bmiheader. biheight;

Setscrollsize (m_xdevscr, m_ydevscr );

Berase = true;
}

M_dib.setbitmap (bitmapinfo *) pdibinfo, pbmpdata );

Invalidaterect (null, berase );
Updatewindow ();
}
After the force window update, the timer restarts so that we can get the next screen image.
Sending input:
The input information for sending the keyboard and mouse is very simple: process the corresponding window information, convert the data into the input structure, and send it to the server for processing. The following is the processing of wm_keydown:
Lresult onkeydown (tchar VK, uint crepeat, uint flags)
{
Hresult hr;
Input input;

If (! M_bconnected)
Return 0;

Input. type = input_keyboard;
Input. Ki. wvk = mapkey (VK );
Input. Ki. wscan = 0;
Input. Ki. dwflags = 0;
Input. Ki. Time = 0;
Input. Ki. dwextrainfo = 0;

HR = write (rcm_setinput );
If (succeeded (HR ))
{
HR = write (& input, sizeof (input ));
If (succeeded (HR ))
Getscreen ();
}

Return 0;
}
The mapkey () function performs basic security key indexes between desktop and keyboard devices. Use the F1 key to control the left, and f2 to control the right. F3 and F4.
Lresult onlbuttondown (uint flags, cpoint pt)
{
Hresult hr;
Input input;

If (! M_bconnected)
Return 0;

M_bleftbtn = true;
Input. type = input_mouse;
Input. Mi. dwflags = mouseeventf_absolute |
Mouseeventf_leftdown;
Input. Mi. dx = pt. x * 65536/m_xdevscr;
Input. Mi. DY = pt. y * 65536/m_ydevscr;
Input. Mi. mousedata = 0;
Input. Mi. Time = 0;
Input. Mi. dwextrainfo = 0;

HR = write (rcm_setinput );
If (succeeded (HR ))
{
HR = write (& input, sizeof (input ));
If (succeeded (HR ))
HR = getscreen ();
}

Return 0;
}
Note that the mouse screen coordinates can be referenced by the screen. The sendinput API is used on the server.
Now, let's take a look at the code of the server device.
Device code:
Create a ceremsrv path for the device project.
Most device code is executed in the cremotecontrol class. All information sent by the Desktop client is processed in the cyclic operation method.
The device screen can be caught by the sendscreen method. It has a structure similar to a desktop copy. Let's take a look at how screen devices are easily captured:
HDC = getwindowdc (null );

After obtaining the HDC of the device screen, you can easily copy it to a bitmap file and contact the desktop. You do not need to miss the Gapi or DirectDraw technology here:
Memcpy (m_pscrbuf + I, m_dib.getbitmapinfo (), sizeof (dibinfo ));
I + = sizeof (dibinfo );

Memcpy (m_pscrbuf + I, m_dib.getdibits (), m_dib.getimagesize ());
I + = m_dib.getimagesize ();

Ulong Len = m_cbzipbuf;
Int Zr = compress (m_pzipbuf, & Len, m_pscrbuf, cbnew );

If (Zr! = Z_ OK)
Len = 0;

HR = m_pstream-> write (& dwmsg, sizeof (DWORD), & ulwritten );
HR = m_pstream-> write (& Len, sizeof (ulong), & ulwritten );
HR = m_pstream-> write (& cbnew, sizeof (DWORD), & ulwritten );
HR = m_pstream-> write (m_pzipbuf, Len, & ulwritten );

Handling input from the desktop is even simpler:

Hresult cremotecontrol: getinput ()
{
Input input;
Hresult hr;
DWORD dwread;

HR = m_pstream-> Read (& input, sizeof (input), & dwread );
If (failed (HR ))
Return hr;

If (dwread! = Sizeof (input ))
Return e_fail;

Sendinput (1, & input, sizeof (input ));

Return s_ OK;
}

A very simple method.
Points of interest:
There are two interesting things here: simulating the double-click event of the mouse, why does the Code not work on the wm5 and wm6 devices?
Double-click to send a message to the device. This is because the window merges four mouse events (down-up-down-up) into a single message wm_lbuttondblclk. If you read my code, you will know how this failed.
On the wm5 and wm6 devices, you may have to use rapi continuity to make the service device DLL respond to the client. I wrote a simple device tool once to solve complex class problems. Copy the EXE file to the device and run it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.