wildcmp nutzen.
-
Jochen Kalmbach schrieb:
Erster Treffer in google:
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus_Builder/Q_21733408.htmlund gleichzeitig auch der unbrauchbarste.

-
Dank dir, Badestrand, oh Menschenfreund.
Bis jetzt läuft alles dank deines codes prächtig.
Doch leider sind alle abgespeicherten bilder nur schwarz.#define _WIN32_WINNT 0x0501 #include <windows.h> #include <iostream> using namespace std; HWND wnd; // "wildcmp" wie gehabt, aber bitte true und false zurückgeben. bool wildcmp(const char *wild, const char *string); // Muss noch verbessert werden, funktioniert evtl aber erstmal (hab's nicht getestet). bool SaveAsBitmap( HWND wnd, const char *path ); // Der Parameter LPARAM lParam beinhaltet hier das, was wir bei EnumWindows als zweiten Parameter übergeben BOOL CALLBACK MyEnumProc( HWND wnd, LPARAM par ) { // Ein Buffer für den Fenstertitel TCHAR title[500]; ZeroMemory( title, sizeof(title) ); // Hier holen wir uns mittels des Handles den Fenster-Titel mit GetWindowText if ( GetWindowText( wnd, title, sizeof(title)/sizeof(title[0]) ) == 0 ) return TRUE; if ( wildcmp("Eimer", title) ) { HANDLE* h = reinterpret_cast<HANDLE*>( par ); *h = wnd; return FALSE; } cout << title <<endl; // "TRUE" zurückgeben, damit diese Callback-Funktion weiter aufgerufen wird return TRUE; } int main() { // Fenster, dessen Inhalt gespeichert werden soll // HANDLE wnd = NULL; // Das Fenster raussuchen lassen if (EnumWindows( MyEnumProc, reinterpret_cast<LPARAM>(&wnd) ) ) { std::cout << "EnumWindows ist fehlgeschlagen: " << GetLastError() << std::endl; return 0; } if ( wnd == NULL ) { std::cout << "Fenster nicht gefunden!" << std::endl; return 0; } // ..als Bitmap speichern if(!SaveAsBitmap( wnd, "C:\\bildsch.bmp" )) { cout << "Abspeichern fehlgeschlagen" <<endl; } } bool SaveAsBitmap( HWND wnd, const char *path ) { HDC hdcScreen; HBITMAP hbmScreen; //---------------Bitmap Informationen BITMAPINFO infobmp; infobmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); infobmp.bmiHeader.biWidth = 1024; infobmp.bmiHeader.biHeight = 768; infobmp.bmiHeader.biPlanes = 1; infobmp.bmiHeader.biBitCount = 24; infobmp.bmiHeader.biCompression = 0; infobmp.bmiHeader.biSizeImage = 0; infobmp.bmiHeader.biXPelsPerMeter = 0; infobmp.bmiHeader.biYPelsPerMeter = 0; infobmp.bmiHeader.biClrUsed = 0; infobmp.bmiHeader.biClrImportant = 0; int* bitmap = new int[1024*768*3]; BITMAPFILEHEADER bfheader; bfheader.bfType = 19778; bfheader.bfSize = sizeof(BITMAPFILEHEADER) + 1024*768*3 + sizeof(BITMAPINFOHEADER); bfheader.bfReserved1 = 0; bfheader.bfReserved2 = 0; bfheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //Bitmap Informationen hdcScreen = GetWindowDC(wnd); hbmScreen = CreateCompatibleBitmap(hdcScreen,1024,768); // temporärer DC HDC hdcTemp = CreateCompatibleDC( hdcScreen ); // Bitmap reinselektieren HBITMAP hbmOld = (HBITMAP)SelectObject( hdcTemp, hbmScreen ); // Inhalt von BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY ); GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS); // aufräumen SelectObject( hdcTemp, hbmOld ); DeleteObject( hbmScreen ); DeleteDC( hdcTemp ); HANDLE hfile = CreateFile(path,GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0); //Datei Schreiben DWORD word; WriteFile(hfile,&bfheader,14,&word,NULL); WriteFile(hfile,&infobmp,40,&word,NULL); WriteFile(hfile,bitmap,1024*768*3,&word,NULL); ReleaseDC(wnd,hdcScreen); CloseHandle(hfile); delete[] bitmap; } bool wildcmp(const char *wild, const char *string) { // Written by Jack Handy - jakkhandy@hotmail.com const char *cp = NULL, *mp = NULL; while ((*string) && (*wild != '*')) { if ((*wild != *string) && (*wild != '?')) { return 0; } wild++; string++; } while (*string) { if (*wild == '*') { if (!*++wild) { return 1; } mp = wild; cp = string+1; } else if ((*wild == *string) || (*wild == '?')) { wild++; string++; } else { wild = mp; string = cp++; } } while (*wild == '*') { wild++; } return !*wild; }
-
wildcmp schrieb:
Bis jetzt läuft alles dank deines codes prächtig.
Doch leider sind alle abgespeicherten bilder nur schwarz.Mensch Badestrand! Was hast Du denn da wieder gemacht?
-
Mensch Badestrand! Was hast Du denn da wieder gemacht?
Mein code optimiert, was ja nicht verwerflich ist, oder?

-
Jochen Kalmbach schrieb:
Mensch Badestrand! Was hast Du denn da wieder gemacht?
In die Hölle mit mir

edit: @wildcmp: Ich denke da war Ironie im Spiel..
-
Warum hast du eigentlich die Variable HWND wnd aus der main-Funktion global gemacht? Und such doch mal bei Google, ob du nicht eine andere/funktionierende DC-nach-Bitmap Funktion findest.
-
`wnd' was not declared in this scope
Daher global.
DC-nach-Bitmap
Naja, die chancen stehen wohl eher schlecht noch eine funktion inder msdn zu finden

So weit hast du mich schon gebracht. Schade, dass es doch nicht klappt. Dennoch vielen dank.
-
wildcmp schrieb:
`wnd' was not declared in this scope
In welcher Funktion kommt die Meldung denn? Sowohl in main, als auch in MyEnumProc und SaveAsBitmap sollte die Variable doch bekannt sein?
wildcmp schrieb:
Naja, die chancen stehen wohl eher schlecht noch eine funktion inder msdn zu finden

Ach, wer wird denn gleich aufgeben?
Such mal bei Google nach "device context to bitmap c++" oder "winapi save dc to file" oder so (aber ohne Anführungsstriche).
Vielleicht schreib ich auch noch was zusammen, oder die Forum-Suche könnte helfen
-
Danke für dein Mut, Badestrand.
Zwar habe ich ein paar funktionen gefunden, doch ist anzumerken, dass ich die meisten nicht verstehe :D. Naja, 2 varianten:
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, "Unable to Allocate Bitmap Memory", "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, "Unable to Create Bitmap File", "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); }BOOL WriteDIB(LPCTSTR szFileName, LPBITMAPINFO pBm, LPVOID pBits) { HFILE hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // make sure pBm->bmiHeader.biSizeImage is computed int ls = (pBm->bmiHeader.biWidth + 3) & (~3); pBm->bmiHeader.biSizeImage = ls * pBm->bmiHeader.biHeight * pBm->bmiHeader.biBitCount / 8; // if we are writing a 8 bit bitmap we must remember of the palette // - 256 RGBQUAD that are stored after pBm->bmiHeader. We are not handling // them in this code BITMAPFILEHEADER hdr; hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM" hdr.bfSize = sizeof(hdr) + sizeof(BITMAPINFOHEADER); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; hdr.bfOffBits = hdr.bfSize; DWORD dwByteCount; WriteFile(hFile, &hdr, sizeof(hdr), &dwByteCount, NULL); WriteFile(hFile, pBm, pBm->bmiheader.biSize, &dwByteCount, NULL); WriteFile(hFile, pBits, pBm->bmiheader.biSizeImage, &dwByteCount, NULL); CloseHandle(hFile); return TRUE; }
-
Ich habe gerade versucht beide funktionen zu probieren.
Es war mehr schlecht als recht. Mein Versuch war eher lächerlich
-
Badestrand,
ich habe zwar nun ein bild (immerhin) nur willkürliche teile vom desktop.
Da scheint etwas nur nicht zu passen und nicht komplett falsch zu sein.
-
Ich hab gerade mal die obere probiert, also bei funktionierts. Jedenfalls halbwegs, es wird immer das komplette Bild vom Bildschirm und nicht der Inhalt des angegebenen Fensters gespeichert. Das Bild hat bei mir auch die richtigen Farben und Proportionen usw. Rufst du die Funktion auch richtig auf? Also etwa so:
// In der Main-Funktion: HBITMAP hbmp = static_cast<HBITMAP>( GetCurrentObject( GetDC(wnd), OBJ_BITMAP ) ); if ( hbmp ) SaveBitmap( "C:\\bildsch.bmp", hbmp );
-
Ich habe nochmal den komplett alten code genommen.
Jetzt sehe ich da ein teil des desktops, nur leider ist der anfangstpunkt total falsch und auch die größe, wobei diese ja falsch sein muss, da:infobmp.bmiHeader.biWidth = 1024; infobmp.bmiHeader.biHeight = 768;Vielleicht liegt der willkürliche bereich des bildes hierran:
// Inhalt von BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY ); GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS);
-
Trotz meiner versuche gelang es mir nicht das problem zu beheben. Hat wer von euch eine idee?
-
Zeig doch noch mal den kompletten aktuellen Code, dann kömma ja noch mal gucken.
-
Ich bekomme weder eine fehlermeldung noch eine ausgabe vom programm (trotz der fehlerabfragen per if).
#define _WIN32_WINNT 0x0501 #include <windows.h> #include <iostream> using namespace std; HWND wnd; // "wildcmp" wie gehabt, aber bitte true und false zurückgeben. bool wildcmp(const char *wild, const char *string); // Muss noch verbessert werden, funktioniert evtl aber erstmal (hab's nicht getestet). bool SaveAsBitmap( HWND wnd, const char *path ); // Der Parameter LPARAM lParam beinhaltet hier das, was wir bei EnumWindows als zweiten Parameter übergeben BOOL CALLBACK MyEnumProc( HWND wnd, LPARAM par ) { // Ein Buffer für den Fenstertitel TCHAR title[500]; ZeroMemory( title, sizeof(title) ); // Hier holen wir uns mittels des Handles den Fenster-Titel mit GetWindowText if ( GetWindowText( wnd, title, sizeof(title)/sizeof(title[0]) ) == 0 ) return TRUE; if ( wildcmp("*Firefox*", title) ) { HANDLE* h = reinterpret_cast<HANDLE*>( par ); *h = wnd; return FALSE; } cout << title <<endl; // "TRUE" zurückgeben, damit diese Callback-Funktion weiter aufgerufen wird return TRUE; } int main() { // Fenster, dessen Inhalt gespeichert werden soll // HANDLE wnd = NULL; // Das Fenster raussuchen lassen if (EnumWindows( MyEnumProc, reinterpret_cast<LPARAM>(&wnd) ) ) { std::cout << "EnumWindows ist fehlgeschlagen: " << GetLastError() << std::endl; return 0; } if ( wnd == NULL ) { std::cout << "Fenster nicht gefunden!" << std::endl; return 0; } // ..als Bitmap speichern if(!SaveAsBitmap( wnd, "C:\\bildsch.bmp" )) { cout << "Abspeichern fehlgeschlagen" <<endl; } } bool SaveAsBitmap( HWND wnd, const char *path ) { HDC hdcScreen; HBITMAP hbmScreen; //---------------Bitmap Informationen BITMAPINFO infobmp; infobmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // infobmp.bmiHeader.biWidth = 1024; // infobmp.bmiHeader.biHeight = 768; infobmp.bmiHeader.biPlanes = 1; infobmp.bmiHeader.biBitCount = 24; infobmp.bmiHeader.biCompression = 0; infobmp.bmiHeader.biSizeImage = 0; infobmp.bmiHeader.biXPelsPerMeter = 0; infobmp.bmiHeader.biYPelsPerMeter = 0; infobmp.bmiHeader.biClrUsed = 0; infobmp.bmiHeader.biClrImportant = 0; int* bitmap = new int[1024*768*3]; BITMAPFILEHEADER bfheader; bfheader.bfType = 19778; bfheader.bfSize = sizeof(BITMAPFILEHEADER) + 1024*768*3 + sizeof(BITMAPINFOHEADER); bfheader.bfReserved1 = 0; bfheader.bfReserved2 = 0; bfheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); //Bitmap Informationen hdcScreen = GetWindowDC(wnd); hbmScreen = CreateCompatibleBitmap(hdcScreen,1024,768); // temporärer DC HDC hdcTemp = CreateCompatibleDC( hdcScreen ); // Bitmap reinselektieren HBITMAP hbmOld = (HBITMAP)SelectObject( hdcTemp, hbmScreen ); // Inhalt von BitBlt( hdcTemp, 0, 0, 1024, 768, hdcScreen, 0, 0, SRCCOPY ); GetDIBits(hdcTemp,hbmScreen,0,768,bitmap,&infobmp,DIB_RGB_COLORS); // aufräumen SelectObject( hdcTemp, hbmOld ); DeleteObject( hbmScreen ); DeleteDC( hdcTemp ); HANDLE hfile = CreateFile(path,GENERIC_WRITE,0,0,OPEN_ALWAYS,0,0); //Datei Schreiben DWORD word; WriteFile(hfile,&bfheader,14,&word,NULL); WriteFile(hfile,&infobmp,40,&word,NULL); WriteFile(hfile,bitmap,1024*768*3,&word,NULL); ReleaseDC(wnd,hdcScreen); CloseHandle(hfile); delete[] bitmap; } bool wildcmp(const char *wild, const char *string) { // Written by Jack Handy - jakkhandy@hotmail.com const char *cp = NULL, *mp = NULL; while ((*string) && (*wild != '*')) { if ((*wild != *string) && (*wild != '?')) { return 0; } wild++; string++; } while (*string) { if (*wild == '*') { if (!*++wild) { return 1; } mp = wild; cp = string+1; } else if ((*wild == *string) || (*wild == '?')) { wild++; string++; } else { wild = mp; string = cp++; } } while (*wild == '*') { wild++; } return !*wild; }
-
wildcmp schrieb:
Ein Fenster muss den Handle so aufgebaut haben:
x Tisch y - Limit i:eSag' was hast du denn damit vor?
-
@wildcmp: Tut mir Leid, ich weiß auch nicht, bekomme es bei Tests auch nicht hin
