Remote Control of writing screen transmission MFC realize screen screenshot sending BMP data display BMP Image

Source: Internet
Author: User
Tags bmp image sendmsg

Remote Control of writing screen transmission MFC realize screen transmission BMP data display BMP image:

I:

First of all to understand the structure of BMP image details please see I reprint an article http://blog.csdn.net/hnust_xiehonghao/article/details/37656281

Ii. Controlled Code

Note that the following code should be put into a thread because the while endless loop is used to indicate that the message is sent until the other party closes receiving. The message will automatically exit after the failure! Must be put into the thread

DWORD _ stdcall sendscreen (lpvoid lparam) // thread processing screen transmission {DWORD * pparam = (DWORD *) lparam; socket mainsocket = * pparam; DWORD dwlastsend; hwnd = getdomaintopwindow (); // obtain the hwnd of the screen. HDC hscreendc = getdc (hwnd); // obtain the HDC of the screen. HDC memdc = createcompatibledc (hscreendc); rect; // This function returns the size of the border rectangle of the specified window. This dimension is given relative to the screen coordinate in the upper left corner of the screen coordinate. Getwindowrect (hwnd, & rect); size screensize; screensize. cx = rect. right-rect.left; screensize. cy = rect. bottom-rect.top; // createcompatiblebitmap this function creates device-compatible bitmaps related to the specified device hscreendc environment. Hbitmap =: createcompatiblebitmap (hscreendc, screensize. CX, screensize. cy); While (1) {dwlastsend = gettickcount (); hgdiobj holdbmp =: SelectObject (memdc, hbitmap ); // This function converts the pixels in the hscreendc environment to be transmitted to the memdc environment of the target device.: Bitblt (memdc, 0, 0, screensize. CX, screensize. cy, hscreendc, rect. left, rect. top, srccopy);: SelectObject (memdc, holdbmp ); /*************************************** * ***********************/HDC =:: createdc ("display", null); int ibits =: getdevicecaps (HDC, bitspixel) *: getdevicecaps (HDC, PLANeS ); // The number of bytes occupied by each pixel in the current resolution: deletedc (HDC); Word wbitcount; // The number of bytes occupied by each pixel in the bitmap if (ibits <= 1) wbitcount = 1; else If (ibits <= 4) wbitcount = 4; else if (ibits <= 8) wbitcount = 8; else if (ibits <= 24) wbitcount = 24; elsewbitcount = ibits; DWORD dwpalettesize = 0; // color palette size, pixel byte size in the bitmap if (wbitcount <= 8) dwpalettesize = (1 <wbitcount) * sizeof (rgbquad); bitmap bm; // bitmap attribute structure: GetObject (hbitmap, sizeof (BM), (lpstr) & BM); bitmapinfoheader Bi; // bitmap information header structure bi. bisize = sizeof (bitmapinfoheader); bi. biwidth = BM. bmwidth; bi. biheight = BM. bmheight; bi. biplanes = 1; bi. bibitcount = wbitcount; bi. bicompression = bi_rgb; // bi_rgb indicates that the bitmap is not compressed. bisizeimage = 0; bi. bixpelspermeter = 0; bi. biypelspermeter = 0; bi. biclrused = 0; bi. biclrimportant = 0; DWORD dwbmbitssize = (BM. bmwidth * wbitcount + 31)/32) * 4 * BM. bmheight; handle hdib =: globalalloc (ghnd, dwbmbitssize + dwpalettesize + sizeof (bitmapinfoheader); // allocate memory for bitmap content // handle hdib =: glo Balalloc (ghnd, 3686440*3); // allocate memory for the bitmap content // lock the memory block specified in the memory and return an address value to point it to the starting position of the memory block. The address remains valid unless you use the globalunlock function to unlock the memory block. Lpbitmapinfoheader lpbi = (lpbitmapinfoheader) globallock (hdib); * lpbi = Bi; handle hpal =: getstockobject (default_palette); // process the palette handle holdpal = NULL; If (hpal) {HDC =: getdc (null); holdpal = selectpalette (HDC, (hpalette) hpal, false); realizepalette (HDC);} // Save the data in the pointer (lpstr) lpbi + sizeof (bitmapinfoheader) + dwpalettesize: getdibits (HDC, hbitmap, 0, (uint) BM. bmheight, (lpstr) lpbi + sizeof (bitmapinfo Header) + dwpalettesize, (bitmapinfo *) lpbi, dib_rgb_colors); // obtain the new pixel value under the color palette if (holdpal) // restore the color palette {selectpalette (HDC, (hpalette) holdpal, true); realizepalette (HDC);: releasedc (null, HDC);} bitmapfileheader bmfhdr; // bitmap file header structure bmfhdr. bftype = 0x4d42; // "BM" // set the bitmap file header DWORD dwdibsize = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + dwpalettesize + dwbmbitssize; bmfhdr. bfsize = dwdibsize; bmfhdr. bfreserve D1 = 0; bmfhdr. bfreserved2 = 0; bmfhdr. bfoffbits = (DWORD) sizeof (bitmapfileheader) + (DWORD) sizeof (bitmapinfoheader) + dwpalettesize; msghead msgsend; msgsend. dwcmd = cmd_screen_to_show; msgsend. dwsize = dwbmbitssize + dwpalettesize + sizeof (bitmapinfoheader); msgsend. dwextend1 = bmfhdr. bfsize; msgsend. dwextend2 = bmfhdr. bfoffbits; If (! Sendmsg (mainsocket, (char *) lpbi, & msgsend) // the User-Defined Function sends data twice. Send msghead struct once send character buffer here is lpbi {// use this code to replace sendmsg with your own sending function's own function first send a custom struct and then send lpbi the following master node receives the message twice after it is sent twice:: deleteobject (memdc);: releasedc (hwnd, hscreendc); globalunlock (hdib); // clear globalfree (hdib); //: MessageBox (null, "failed to send", "", mb_ OK); Return 0;}/* // Save the screenshot to E: // mybitmap.bmp char strfilepath [111] = "E: // mybitmap.bmp "; handle hfile = createfile (strfilepath, generic_write, 0, null, create_always, file_attribute_normal | abnormal, null); // create a bitmap file DWORD dwwritten; writefile (hfile, (lpstr) & bmfhdr, sizeof (bitmapfileheader), & dwwritten, null); // write the bitmap file header writefile (hfile, (lpstr) lpbi, dwdibsize, & dwwritten, null ); // write the remaining content of the bitmap file */globalunlock (hdib); // clear globalfree (hdib); // closehandle (hfile); If (gettickcount ()-dwlastsend) <110) sleep (100);} return 0 ;}

3.

Master Terminal code:

1. Since the main control end also needs to receive screen messages cyclically, the code of the following function must also be put into a thread! You can also let a thread call the processing function. I use the second method to call this function using a thread!


Void cscreendlg: getfirstscreen () {msghead msgsend; msgsend. dwcmd = pai_getfirst_screen; msgsend. dwsize = 0; If (! Sendmsg (m_mainsocket, null, & msgsend) // request for screen transmission {: MessageBox (null, "screen transfer request failed", "error", mb_ OK ); closesocket (m_mainsocket); return;} // The following figure shows the screen acquisition. The result is always obtained and displayed until the screen fails to be received or the DWORD dwlastsend is exited after a certain period of time is set; msghead msgrecv; while (m_mainsocket! = Invalid_socket) {If (! Recvdata (m_mainsocket, (char *) & msgrecv, sizeof (msghead) // The Recv function used in the Custom acceptance function. replace this code with the Recv function {:: MessageBox (null, "screen data receiving, command receiving failed", "error", mb_ OK); closesocket (m_mainsocket); m_mainsocket = invalid_socket; return;} bmfhdr. bftype = 0x4d42; // "BM" // set the bitmap file header member variable bmfhdr to bitmapfileheader bmfhdr. bfsize = msgrecv. dwextend1; bmfhdr. bfreserved1 = 0; bmfhdr. bfreserved2 = 0; bmfhdr. bfoffbits = msgrecv. dwexten D2; m_infosize = msgrecv. dwextend2-sizeof (bitmapfileheader); // m_infosize is the sum of info header and palette size and if (! Recvdata (m_mainsocket, (char *) pdata, msgrecv. dwsize) // you can replace the custom acceptance function with your own function or Recv function {: MessageBox (null, "screen data receiving, data receiving failed ", "error", mb_ OK); closesocket (m_mainsocket); m_mainsocket = invalid_socket; return ;}/ * // write bitmap data into the file to create a BMP image file strcpy (strfilepath, "E: // hehe.bmp"); // The strfilepath type is Char strfilepath [111]; If (hfile! = Invalid_handle_value) closehandle (hfile); // handle hfile; hfile = createfile (strfilepath, generic_write, 0, null, create_always, file_attribute_normal | null ); // create a bitmap file DWORD dwwritten; writefile (hfile, (lpstr) & bmfhdr, sizeof (bitmapfileheader), & dwwritten, null); // write the bitmap file header writefile (hfile, (lpstr) pdata, bmfhdr. bfsize, & dwwritten, null); // write the remaining contents of the bitmap file closehandle (hfile); */invalidate (true ); // send the re-painting system message sleep (10 );}}

The code above received the BMP image information and saved it to pdata!


2. Use the information in pdata to create the handle of the BMP image.

 

Hbitmap cscreendlg: getbitmapfromdata () {hbitmap; pbitmapinfo lpbmpinfo; // bitmap information lpbmpinfo = pbitmapinfo (pdata); HDC = createdc ("display", null, null, null); // create DDB bitmap hbitmap = createdibitmap (HDC, & lpbmpinfo-> bmiheader, cbm_init, pdata + m_infosize, lpbmpinfo, dib_rgb_colors); deletedc (HDC); Return hbitmap ;}

For the differences between DDB Dib, refer to my blog's "MFC" column or Baidu


3. The following is the redrawing image after invalidate is called. The following uses double buffering technology. For more information about this technology, see article 5 in the following article.

Http://blog.csdn.net/hnust_xiehonghao/article/details/37741307

The following functions are the message response functions added in the Class Wizard to erase the window.

Bool cscreendlg: onerasebkgnd (CDC * PDC) {// todo: add the message processing program code and/or call the default value // Double Cache to prevent blinking CDC dcmem; dcmem. createcompatibledc (PDC); cbitmap bitmap; // The following can also load bitmap images from a file, such as the statement bitmap in the comment. m_hobject = getbitmapfromdata (); // (hbitmap) LoadImage (bytes (), strfilepath, image_bitmap, 0, 0, rows | lr_createdibsection); crect rect; getclientrect (& rect ); cbitmap * poldbit = dcmem. selectObject (& Bitmap); // dcmem. fillsolidrect (rect, PDC-> getbkcolor (); // fill the customer area according to the original background, otherwise it will be black PDC-> bitblt (, rect. width (), rect. height (), & dcmem, 0, 0, srccopy); dcmem. deletedc (); // Delete DC bitmap. deleteobject (); // delete a bitmap // return cdialog: onerasebkgnd (PDC); Return true ;}




By hnust_xiehonghao



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.