mein RemoteDesktop prog
-
Climber schrieb:
Hi,
ich glaube im Netzwerk ist es ok, aber übers Internet wird es wohl stark
ruckeln, da ja erst das Bild runtergeladen werden muss, um es im Dialog anzuzeigen. Bei mir ist das Programm dann irgendwann abgeschmiert, weil
der Speicher zugemüllt war.Wie wirst du die Steuerung der Maus/ Tastatur umsetzen?
warum der Speicher volläuft hab ich jetz auch raus
::DeleteDC(hDesktopCompatibleDC); statt
::ReleaseDC(hWND,hDesktopCompatibleDC);
Die eingabe wird mithilfe eines Hooks und SendInput umgesetzt was über ein paralelles Socket läuft.
Hab leider immernoch keine antwort auf meine Hauptfrage gefunden,bleibe dran
-
Du könntest eine andere Library zum Erzeugen des JPEG verwenden, wie z.B. DevIL oder FreeImage oder ...
Die können üblicherweise in "memory streams speichern".
-
Ist alles sehr interessant. Halt uns mal informiert

Ich habe sowas vor ca 1 Jahr auch mal versucht (just4fun),
aber es war nur im Netzwerk zu gebrauchen, da ich nicht
genau verstanden habe, wie man nur differente Bildpunkte überträgt
(bzw. das mit den Eingaben löst).
-
hustbaer schrieb:
Du könntest eine andere Library zum Erzeugen des JPEG verwenden, wie z.B. DevIL oder FreeImage oder ...
Die können üblicherweise in "memory streams speichern".Hi! wollte nurnoch die Lösung posten die ich gefunden habe. Da die vorgeschlagenen libraries seh umfangreich sind würde es Tage dauern bis man die draufhat, also hab ich mir CImage nochma angeschaut und festgestellt, dass die wohl auch streams unterstützt!
//Bild holen und abspeichern HGLOBAL hMem = ::GlobalAlloc(GMEM_ZEROINIT,1000000); IStream* spStream; CreateStreamOnHGlobal(hMem,FALSE,&spStream); int iScreen_x=::GetSystemMetrics(SM_CXSCREEN); int iScreen_y=::GetSystemMetrics(SM_CYSCREEN); HWND hWND=::GetDesktopWindow(); HDC hDesktopDC=::GetDC(hWND); HDC hDesktopCompatibleDC=::CreateCompatibleDC(hDesktopDC); HBITMAP hDesktopBitmap=::CreateCompatibleBitmap(hDesktopDC,iScreen_x,iScreen_y); ::SelectObject(hDesktopCompatibleDC,hDesktopBitmap); BitBlt(hDesktopCompatibleDC,NULL,NULL,iScreen_x,iScreen_y,hDesktopDC,NULL,NULL,SRCCOPY); CImage MyImage; MyImage.Attach(hDesktopBitmap,CImage::DIBOR_BOTTOMUP); MyImage.Save(spStream,ImageFormatJPEG); MyImage.ReleaseGDIPlus(); ::ReleaseDC(hWND,hDesktopDC); ::DeleteObject(hDesktopBitmap); ::DeleteDC(hDesktopCompatibleDC); //Bild Laden und anzeigen CImage NewImage; RECT DlgRect; HWND hDlgWND=this->m_hWnd; HDC hDialogDC=::GetDC(hDlgWND); GetClientRect(&DlgRect); NewImage.Load(spStream); NewImage.StretchBlt(hDialogDC,NULL,NULL,DlgRect.right,DlgRect.bottom,SRCCOPY); NewImage.ReleaseGDIPlus(); ::ReleaseDC(hDlgWND,hDialogDC); GlobalFree(hMem);den buffer kann man später per spStream->Read(...) hohlen.davor sollte man den pointer mit spStream->Seek(...) zuerst zum anfang fahren!
schönen danke an den forum!MFG
-
Hi,
ich glaube dein ImageFormatJPEG ist so nicht richtig.
Bei mir stürzt die Anwendung nach dem Start auch gleich ab (m_hBitmap!=0)Mach es so:
MyImage.Save(spStream,Gdiplus::ImageFormatJPEG);Damit funktioniert es bei mir.
-
Achso, da fällt mir noch ein:
Vielleicht kannst du noch was genaueres zum Anzeigen/Laden des Bildes sagen.
Ich persönlich habe noch nie mit IStream oder GDI+ gearbeitet.
Und es wird dann ja übers Netzwerk übertragen.Also die notwendigen Vorarbeiten vor dem ->Seek und ->Read des streams
für den Client. Wäre nett.
-
Wofür ist eigentlich dieses IStream??
IStream* spStream; CreateStreamOnHGlobal(hMem,FALSE,&spStream);Ist das in der Übertragung zu einem anderen PC die schnellere Lösung?
Also schneller, als die Datei zusenden und dann wieder darzustellen?
Wird das dann irgendwie komprimiert oderso?Und wie wird überhaupt der IStream zum Empfänger gebracht?
-
Sverige schrieb:
Wofür ist eigentlich dieses IStream??
IStream* spStream; CreateStreamOnHGlobal(hMem,FALSE,&spStream);Ist das in der Übertragung zu einem anderen PC die schnellere Lösung?
Also schneller, als die Datei zusenden und dann wieder darzustellen?
Wird das dann irgendwie komprimiert oderso?Und wie wird überhaupt der IStream zum Empfänger gebracht?
HI!
ich muss sagen in diesem Beispiel hab ich Streams auch zum ersten mal verwendet.
Da CImage::Save() funktion 2 möglichkeiten hat ein Bild zu speichern 1.Datei 2.Stream!In diesem Beispiel stellt der Stream eine "virtuelle datei" oderso dar(die sich auch wie eine normale Datei auslesen lässt), die Datei wird also nicht auf der Festplatte sondern im Arbeitsspeicher angelegt was natürlich schneller und sinnvoller ist!
Streams allgemein können aber mehr,zb: Verbindung zu einem Ausgabegerät oder zu einer Datei...
aber das kann dir evtl. jemand anders besser erklären, da ich wenig davon weiß und nichts falsches erzählen will!
MFG
-
Hi,
aber wie willst es dann anstellen deinen Bildschirminhalt auf einem
anderen PC anzuzeigen? Du musst dann doch, wenn du mit dem Stream
arbeitest, diesen irgendwie transportieren. Oder nimmst du nun doch
dei Datei-Variante?Ich versteh noch nicht, wie das versendet wir (also der Inhalt des Stream-
Objektes). Zerlegt man das in einen CString und schickt das dann über Winsock?Und bringt es effektiv einen Verarbeitungsvorteil beim empfangenden PC?
Die reine Datei wäre bei mir so ca. 140KB groß, wenn ich sie direkt
senden würde.In meinem Beispiel, das ich von Codeproject habe, wird eine Datei von
der Festplatte verschickt (allerdings über CFile)./*************************** // listens for a connection from a remote client and uploads a file to it // the remote client must be running // a counterpart GetFileFromRemoteSender function // Input: CString fName = name of local file // which will be uploaded to remote client // Output: BOOL return value indicates success or failure of the upload ***************************/ // create socket and listen on pre-designated port /// AfxSocketInit(NULL); // make certain this is done somewhere in each thread // (usually in InitInstance for main thread) CSocket sockSrvr; // Creates our server socket sockSrvr.Create(PRE_AGREED_PORT); // Start listening for the client at PORT sockSrvr.Listen(); CSocket sockConnection; // Use another CSocket to accept the connection sockSrvr.Accept(sockConnection); // local variables used in file transfer (declared here // to avoid "goto skips definition"-style compiler errors) // return value BOOL bRet = TRUE; // used to monitor the progress of a sending operation int fileLength, cbLeftToSend; // pointer to buffer for sending data // (memory is allocated after sending file size) BYTE* sendData = NULL; CFile sourceFile; CFileException fe; BOOL bFileIsOpen = FALSE; if( !( bFileIsOpen = sourceFile.Open( fName, CFile::modeRead | CFile::typeBinary, &fe ) ) ) { TCHAR strCause[256]; fe.GetErrorMessage( strCause, 255 ); TRACE( "SendFileToRemoteRecipient encountered an error while opening the local file\n" "\tFile name = %s\n\tCause = %s\n\tm_cause = %d\n\tm_IOsError = %d\n", fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError ); /* you should handle the error here */ bRet = FALSE; goto PreReturnCleanup; } // first send length of file fileLength = sourceFile.GetLength(); fileLength = htonl( fileLength ); cbLeftToSend = sizeof( fileLength ); do { int cbBytesSent; BYTE* bp = (BYTE*)(&fileLength) + sizeof(fileLength) - cbLeftToSend; cbBytesSent = sockConnection.Send( bp, cbLeftToSend ); // test for errors and get out if they occurred if ( cbBytesSent == SOCKET_ERROR ) { int iErr = ::GetLastError(); TRACE( "SendFileToRemoteRecipient returned a socket error while sending file length\n" "\tNumber of Bytes sent = %d\n" "\tGetLastError = %d\n", cbBytesSent, iErr ); /* you should handle the error here */ bRet = FALSE; goto PreReturnCleanup; } // data was successfully sent, so account // for it with already-sent data cbLeftToSend -= cbBytesSent; } while ( cbLeftToSend>0 ); // now send the file's data sendData = new BYTE[SEND_BUFFER_SIZE]; cbLeftToSend = sourceFile.GetLength(); do { // read next chunk of SEND_BUFFER_SIZE bytes from file int sendThisTime, doneSoFar, buffOffset; sendThisTime = sourceFile.Read( sendData, SEND_BUFFER_SIZE ); buffOffset = 0; do { doneSoFar = sockConnection.Send( sendData + buffOffset, sendThisTime ); // test for errors and get out if they occurred if ( doneSoFar == SOCKET_ERROR ) { int iErr = ::GetLastError(); TRACE( "SendFileToRemoteRecipient returned a socket error while sending chunked file data\n" "\tNumber of Bytes sent = %d\n" "\tGetLastError = %d\n", doneSoFar, iErr ); /* you should handle the error here */ bRet = FALSE; goto PreReturnCleanup; } // data was successfully sent, // so account for it with already-sent data buffOffset += doneSoFar; sendThisTime -= doneSoFar; cbLeftToSend -= doneSoFar; } while ( sendThisTime > 0 ); } while ( cbLeftToSend > 0 ); PreReturnCleanup: // labelled goto destination // free allocated memory // if we got here from a goto that skipped allocation, // delete of NULL pointer // is permissible under C++ standard and is harmless delete[] sendData; if ( bFileIsOpen ) sourceFile.Close(); // only close file if it's open (open might have failed above) sockConnection.Close(); return bRet;
-
Der Code ist für Dateien ausgelegt. Einen stream kann man da getrost vergessen mit senden zu wollen!