Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Graphics
  4. Capturing Network PC`s Desktop

Capturing Network PC`s Desktop

Scheduled Pinned Locked Moved Graphics
graphicsperformancesysadminhelptutorial
11 Posts 3 Posters 22 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H HassanKU

    When performance is not an issue and when all that we want is just a snapshot of the desktop, we can consider the GDI option. This mechanism is based on the simple principle that the desktop is also a window - that is it has a window Handle (HWND) and a device context (DC). If we can get the device context of the desktop to be captured, we can just blit those contents to our application defined device context in the normal way. And getting the device context of the desktop is pretty straightforward if we know its window handle - which can be achieved through the function GetDesktopWindow(). Thus, the steps involved are: Acquire the Desktop window handle using the function GetDesktopWindow(); Get the DC of the desktop window using the function GetDC(); Create a compatible DC for the Desktop DC and a compatible bitmap to select into that compatible DC. These can be done using CreateCompatibleDC() and CreateCompatibleBitmap(); selecting the bitmap into our DC can be done with SelectObject(); Whenever you are ready to capture the screen, just blit the contents of the Desktop DC into the created compatible DC - that's all - you are done. The compatible bitmap we created now contains the contents of the screen at the moment of the capture. Do not forget to release the objects when you are done. Memory is precious (for the other applications). Void CaptureScreen() { int nScreenWidth = GetSystemMetrics(SM_CXSCREEN); int nScreenHeight = GetSystemMetrics(SM_CYSCREEN); HWND hDesktopWnd = GetDesktopWindow(); HDC hDesktopDC = GetDC(hDesktopWnd); HDC hCaptureDC = CreateCompatibleDC(hDesktopDC); HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight); SelectObject(hCaptureDC,hCaptureBitmap); BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight, hDesktopDC,0,0,SRCCOPY|CAPTUREBLT); SaveCapturedBitmap(hCaptureBitmap); //Place holder - Put your code //here to save the captured image to disk ReleaseDC(hDesktopWnd,hDesktopDC); DeleteDC(hCaptureDC); DeleteObject(hCaptureBitmap); } In the above code snippet, the function GetSystemMetrics() returns the screen width when used with SM_CXSCREEN, and returns the screen height when called with SM_CYSCREEN. Refer to the accompanying source code for details of how to save the captured bitmap to the disk and how to send it to the clipboard. Its pretty straightforward. The source code implements the above technique f

    M Offline
    M Offline
    Mark Salsbery
    wrote on last edited by
    #2

    A process running on the remote system would call CaptureScreen() at regular intervals (however many frames-per-second you want). Instead of SaveCapturedBitmap(), you would probably want to SendCapturedBitmap(...). A SendCapturedBitmap() implementaion would transfer the serialized bitmap bits over a socket to a remotely connected process. That's the basics but there's some issues... Getting the bitmap bits. I prefer using DIBSections but GetDIBits() is fine too. Bandwidth. Multiply the number of bytes per frame by the frames per second. Is it possible to send that many bytes-per-second over the network without compression? Which part is giving you trouble? What have you tried so far? Mark

    "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

    H 1 Reply Last reply
    0
    • H HassanKU

      When performance is not an issue and when all that we want is just a snapshot of the desktop, we can consider the GDI option. This mechanism is based on the simple principle that the desktop is also a window - that is it has a window Handle (HWND) and a device context (DC). If we can get the device context of the desktop to be captured, we can just blit those contents to our application defined device context in the normal way. And getting the device context of the desktop is pretty straightforward if we know its window handle - which can be achieved through the function GetDesktopWindow(). Thus, the steps involved are: Acquire the Desktop window handle using the function GetDesktopWindow(); Get the DC of the desktop window using the function GetDC(); Create a compatible DC for the Desktop DC and a compatible bitmap to select into that compatible DC. These can be done using CreateCompatibleDC() and CreateCompatibleBitmap(); selecting the bitmap into our DC can be done with SelectObject(); Whenever you are ready to capture the screen, just blit the contents of the Desktop DC into the created compatible DC - that's all - you are done. The compatible bitmap we created now contains the contents of the screen at the moment of the capture. Do not forget to release the objects when you are done. Memory is precious (for the other applications). Void CaptureScreen() { int nScreenWidth = GetSystemMetrics(SM_CXSCREEN); int nScreenHeight = GetSystemMetrics(SM_CYSCREEN); HWND hDesktopWnd = GetDesktopWindow(); HDC hDesktopDC = GetDC(hDesktopWnd); HDC hCaptureDC = CreateCompatibleDC(hDesktopDC); HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight); SelectObject(hCaptureDC,hCaptureBitmap); BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight, hDesktopDC,0,0,SRCCOPY|CAPTUREBLT); SaveCapturedBitmap(hCaptureBitmap); //Place holder - Put your code //here to save the captured image to disk ReleaseDC(hDesktopWnd,hDesktopDC); DeleteDC(hCaptureDC); DeleteObject(hCaptureBitmap); } In the above code snippet, the function GetSystemMetrics() returns the screen width when used with SM_CXSCREEN, and returns the screen height when called with SM_CYSCREEN. Refer to the accompanying source code for details of how to save the captured bitmap to the disk and how to send it to the clipboard. Its pretty straightforward. The source code implements the above technique f

      D Offline
      D Offline
      David Crow
      wrote on last edited by
      #3

      HassanKU wrote:

      In consideration to the above code please let me know how to capture the network PC`s desktop to my software..

      Do you have a process running on the remote machine that is capturing its screen and sending it back to the calling machine?


      "A good athlete is the result of a good and worthy opponent." - David Crow

      "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

      H 2 Replies Last reply
      0
      • D David Crow

        HassanKU wrote:

        In consideration to the above code please let me know how to capture the network PC`s desktop to my software..

        Do you have a process running on the remote machine that is capturing its screen and sending it back to the calling machine?


        "A good athlete is the result of a good and worthy opponent." - David Crow

        "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

        H Offline
        H Offline
        HassanKU
        wrote on last edited by
        #4

        Actually can i send u my application.... ??? Please give me ur email address...

        1 Reply Last reply
        0
        • M Mark Salsbery

          A process running on the remote system would call CaptureScreen() at regular intervals (however many frames-per-second you want). Instead of SaveCapturedBitmap(), you would probably want to SendCapturedBitmap(...). A SendCapturedBitmap() implementaion would transfer the serialized bitmap bits over a socket to a remotely connected process. That's the basics but there's some issues... Getting the bitmap bits. I prefer using DIBSections but GetDIBits() is fine too. Bandwidth. Multiply the number of bytes per frame by the frames per second. Is it possible to send that many bytes-per-second over the network without compression? Which part is giving you trouble? What have you tried so far? Mark

          "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

          H Offline
          H Offline
          HassanKU
          wrote on last edited by
          #5

          Actually i cant get the main idea how to send on sockets.. void SaveBitmap(char *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; FILE* fp=NULL; LPVOID pBuf=NULL; BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; do{ hdc=GetDC(NULL); ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); if(bmpInfo.bmiHeader.biSizeImage<=0) bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; if((pBuf=malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) { MessageBox(NULL,_T("Unable to Allocate Bitmap Memory"),_T("Error"),MB_OK|MB_ICONERROR); break; } bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf,&bmpInfo,DIB_RGB_COLORS); if((fp=fopen(szFilename,"wb"))==NULL) { MessageBox(NULL,_T("Unable to Create Bitmap File"),_T("Error"),MB_OK|MB_ICONERROR); break; } bmpFileHeader.bfReserved1=0; bmpFileHeader.bfReserved2=0; bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; bmpFileHeader.bfType='MB'; bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); }while(false); if(hdc) ReleaseDC(NULL,hdc); if(pBuf) free(pBuf); if(fp) fclose(fp); } This is the implementation of savebitmap..... and how to sendbitmap i dont know...:confused: Please help me.. I want to submit it by 3rd may... else ma 30 numbers would be ruined. :((

          M 1 Reply Last reply
          0
          • D David Crow

            HassanKU wrote:

            In consideration to the above code please let me know how to capture the network PC`s desktop to my software..

            Do you have a process running on the remote machine that is capturing its screen and sending it back to the calling machine?


            "A good athlete is the result of a good and worthy opponent." - David Crow

            "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

            H Offline
            H Offline
            HassanKU
            wrote on last edited by
            #6

            Yes server is requesting da desktop of network Pc... and the capturing method is running on network PC.

            D 1 Reply Last reply
            0
            • H HassanKU

              Yes server is requesting da desktop of network Pc... and the capturing method is running on network PC.

              D Offline
              D Offline
              David Crow
              wrote on last edited by
              #7

              HassanKU wrote:

              ...and the capturing method is running on network PC.

              Is this part working?


              "A good athlete is the result of a good and worthy opponent." - David Crow

              "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

              H 2 Replies Last reply
              0
              • D David Crow

                HassanKU wrote:

                ...and the capturing method is running on network PC.

                Is this part working?


                "A good athlete is the result of a good and worthy opponent." - David Crow

                "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                H Offline
                H Offline
                HassanKU
                wrote on last edited by
                #8

                No i have jus created sockets that sends and receives "Text messages" jus 4 ensuring that ma sockets r working... http://msdn2.microsoft.com/en-us/library/ms532314.aspx[^] http://msdn2.microsoft.com/en-us/library/ms532342.aspx[^] Go to these links 4 help... these links will tell u how to create bitmap

                D 1 Reply Last reply
                0
                • D David Crow

                  HassanKU wrote:

                  ...and the capturing method is running on network PC.

                  Is this part working?


                  "A good athlete is the result of a good and worthy opponent." - David Crow

                  "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                  H Offline
                  H Offline
                  HassanKU
                  wrote on last edited by
                  #9

                  http://msdn2.microsoft.com/en-us/library/ms532334.aspx[^] I think dis will work.... Please provide me a method how to send on sockets... and retrieve it.. we`ll copy it into buffer for sure..

                  1 Reply Last reply
                  0
                  • H HassanKU

                    Actually i cant get the main idea how to send on sockets.. void SaveBitmap(char *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; FILE* fp=NULL; LPVOID pBuf=NULL; BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; do{ hdc=GetDC(NULL); ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); if(bmpInfo.bmiHeader.biSizeImage<=0) bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; if((pBuf=malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) { MessageBox(NULL,_T("Unable to Allocate Bitmap Memory"),_T("Error"),MB_OK|MB_ICONERROR); break; } bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf,&bmpInfo,DIB_RGB_COLORS); if((fp=fopen(szFilename,"wb"))==NULL) { MessageBox(NULL,_T("Unable to Create Bitmap File"),_T("Error"),MB_OK|MB_ICONERROR); break; } bmpFileHeader.bfReserved1=0; bmpFileHeader.bfReserved2=0; bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; bmpFileHeader.bfType='MB'; bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); }while(false); if(hdc) ReleaseDC(NULL,hdc); if(pBuf) free(pBuf); if(fp) fclose(fp); } This is the implementation of savebitmap..... and how to sendbitmap i dont know...:confused: Please help me.. I want to submit it by 3rd may... else ma 30 numbers would be ruined. :((

                    M Offline
                    M Offline
                    Mark Salsbery
                    wrote on last edited by
                    #10

                    In theory, you should be able to replace the fwrite() calls with socket send() calls. In practice, you can improve your protocol by sending the headers only once. This information only changes if you change the capture rect size or the screen resolution and/or bitdepth changes so for each captured frame you only need to send the pixel data. Also, I'm not sure about this calculation: bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; The pixel data is aligned to a DWORD (4-byte) boundary for each row so maybe something like this: long lStride = ((bmpInfo.bmiHeader.biWidth * (long)bmpInfo.bmiHeader.biBitCount + 31L) & ~31L) / 8L; bmpInfo.bmiHeader.biSizeImage = lStride * abs(bmpInfo.bmiHeader.biHeight); Mark

                    "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                    1 Reply Last reply
                    0
                    • H HassanKU

                      No i have jus created sockets that sends and receives "Text messages" jus 4 ensuring that ma sockets r working... http://msdn2.microsoft.com/en-us/library/ms532314.aspx[^] http://msdn2.microsoft.com/en-us/library/ms532342.aspx[^] Go to these links 4 help... these links will tell u how to create bitmap

                      D Offline
                      D Offline
                      David Crow
                      wrote on last edited by
                      #11

                      You need to scale this large problem down into several smaller problems. I would be inclined to first get the actual communication working at a very basic level before anything else. The calling machine(s) should be able to send multiple requests to the remote machine without any of them being lost. The remote machine could simply write "Received request from xxx." to a file of some sort. Then I would have the remote machine "answer" those requests by being able to take a snapshot of its desktop. Simply send a 0 or 1 back to the calling machine to indicate success or failure. Have the calling machine display this acknowledgment. More to come...


                      "A good athlete is the result of a good and worthy opponent." - David Crow

                      "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups