Screenshot von dem laufenden Programm



  • Hallo!

    Habe leider immer noch keine Lösung auf mein Problem bekommen, aber vielleicht kann mir hier jemand nen Tipp geben?

    Gibt es eine Möglichkeit einen Screeshot von meinem in VC60-ATL/WTL programmierten Programm während des Programmablaufs zu machen. Aber so, dass ich auf jeden Fall ein Screenshot von dem gesamten Programm habe und nicht nur wie z.B. mit der ALT+drucktaste, wo man überlappende oder außerhalb des Bildschirms liegende Teile nicht sieht.

    Bin für jeden Tipp dankbar!



  • Ich mache es so,
    Alt + druck
    dann einfügen im ms_paint.
    mit ms_Paint kann man das Bild wie er will schneiden.
    dann einfügen in meinem Manuell



  • Danke, aber das Problem ist, dass ich das Bild per Knopfdruck in der Zwischenablage brauche (weil ich die Zwischenablage dann ausdrucken will). Und mit Alt+drucken wird ja auch nur das gespeichert, was man auf dem Bildschirm sieht.



  • Wenn du mit dem Maus auf dem Dialog des Tooles erst klickest dann alt+ druck,
    bekommst du den Screenshot sauper.



  • Aber wenn das Fester nur zur Hälfte zu sehen ist, wird auch (bei mir zumindestens) nur der sichtbare Teil in den Screenshot gepackt, bzw. noch die Elemente die im sichtbaren Bereich darvorliegen. Ich will aber ganz unabhängig davon, was man von meinem Programm sieht einen Screenshot machen (per Knopfdruck im Programm und es dann auch automatisch ausdrucken).


  • Mod

    plizer schrieb:

    Aber wenn das Fester nur zur Hälfte zu sehen ist, wird auch (bei mir zumindestens) nur der sichtbare Teil in den Screenshot gepackt, bzw. noch die Elemente die im sichtbaren Bereich darvorliegen. Ich will aber ganz unabhängig davon, was man von meinem Programm sieht einen Screenshot machen (per Knopfdruck im Programm und es dann auch automatisch ausdrucken).

    Das ist aber was anderes als ein Screenshot!
    http://www.codeproject.com/info/search.aspx?artkw=screen+clipboard&sbo=kw

    Aber etwas bei Codeproject gesucht und es gibt Lösungen:
    http://www.codeproject.com/KB/printing/printformview.aspx
    http://www.codeproject.com/KB/printing/prntscreen.aspx



  • Dafür gibt es WM_PRINT.
    Du brauchst nur ein passendes WM_PRINT an deinen Dialog/dein Fenster zu schicken, und den DC dann auszudrucken. Implementiert ist das alles schon (also die Behandlung von WM_PRINT), du musst es nurnoch verwenden.

    WM_PRINT geht auch mit Fenstern/Dialogen die komplett ausserhalb des sichtbaren Desktop-Bereiches liegen, ganz oder halb verdeckt sind o.ä.

    Noch besser: WM_PRINT ist *genau dafür* gemacht was du willst.



  • Hi Martin!

    Ja, das ist tatsächlich was anderes. Ich habe aber versucht mit Hilfe des bekannten Begriffs mein Problem zu beschreiben. Vielen Dank für die Links, hatte schon bei codeproject geschaut aber bin nie auf gute keywords gekommen und die Ergebnisse waren mangelhaft.



  • hustbaer: VIelen Dank! Da haben wir wohl fast gleichzeitig geschrieben. Werd mir Denien Hinweis genauer anschauen! 🙂



  • BIsher hab ichs mit WM_PRINT nicht geschafft. Ich weiss nicht was ich da übergeben muss. Ich habe für ATL/WTL nur so ne spartanische Hilfe und auch sonst find ich dazu leider nicht viel. Ich habe ein Handle meines Hauptprogramms und will davon den PRINT inkl. aller Steuerelemente haben. Das einzige was ich gefunden habe, ist dies:
    SendMessage(Form1->Handle, WM_PRINT, (LPARAM)Form1->Image1->Picture->Bitmap->Canvas->Handle, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);

    Hab aber keine Ahnung wie ich das auf mein Problem übetragen soll.

    Vielen Dank!


  • Mod

    Ich verstehe Deine Frage nicht. Hast Du Dir die Doku von WM_PRINT mal angesehen?

    Was brauchst Du? Einen DC! Gut, erzeuge Dir eien Memory DC wie das eben andere Snapshot Samples auch machen und Sende WM_PRINT mit den entsprechenden Flags...



  • In der MSDN find ich das:
    http://search.msdn.microsoft.com/search/Default.aspx?query=WM_PRINT&brand=msdn&locale=&refinement=00&lang=de-de

    Damit kann ich allerdings nichts anfangen und bei Codeproject finde ich keinen Treffer zu WM_PRINT im Zusammenhang mit der ATL/WTL!?

    Ich würde einfach mal gerne ne Doku haben, wo ich sehe was ich übergeben kann? Ich weiss auch nicht wozu WM_PRINT überhaupt gehört? Ist das von der WinAPI direkt oder MFC? Wo kann man sowas erfahren?


  • Mod

    Verstehe ich nicht, warum ich die SDuchmaschine spielen muss?
    http://msdn2.microsoft.com/en-us/library/ms534856.aspx



  • Danke, mit den Infos habe ich bisher das fertiggestellt. Es gibt auch nen Druckformular und der Drucker druckt auch, allerdings ist die Seite immer leer. So sieht der Quelltext aus:

    HRESULT hr;
    DOCINFO di;
    CPrintDialog tmp_CPD(FALSE, PD_PAGENUMS | PD_USEDEVMODECOPIES);
    if (tmp_CPD.DoModal() != IDOK) {	  
      return -1;
    }
    
    LPDEVMODE lpPrinterDevMode = tmp_CPD.GetDevMode();
    GlobalUnlock(lpPrinterDevMode);
    lpPrinterDevMode->dmOrientation=DMORIENT_LANDSCAPE;
    lpPrinterDevMode->dmPaperSize=DMPAPER_A4;
    GlobalLock(lpPrinterDevMode);
    
    CDC printerDC = tmp_CPD.GetPrinterDC();
    wDiag.Print(printerDC, NULL);
    
    di.cbSize = sizeof(DOCINFO) ;
    bstr_t printName = "Test";
    di.lpszDocName = printName;
    di.lpszOutput = NULL ;
    
    hr = printerDC.StartDoc(&di) ; 
    hr = printerDC.StartPage();
    
    hr = printerDC.EndPage();
    hr = printerDC.EndDoc();
    
    return 0;
    

    Nur warum ist der Druck noch leer?


  • Mod

    Ich sehe keinerlei Code der auch nur irgendwas auf den printerDC ausgibt...

    Umgekehrt also die Frage: Warum erwartest Du, dass hier irgendetwas auf dem Papier sichtbar werden soll?



  • Die Methode print() nutzt so weit ich weiss WM_PRINT. Ich habs jetzt auch geschafft dass was ausgedruckt wird. Nun hab ich nurnoch das Problem, dass das Ganze irgendwie wie ein "normaler Screenshot" arbeitet, d.h. wenn vor meinem Programm ein anderes Fenster oder die Taskleiste liegt wird diese mit ausgegeben. Und wenn das Programm außerhalb des Bildschirms liegt, wird diese Fläche schwarz dargestellt!

    Hast Du noch nen Tipp?

    HRESULT hr;
    DOCINFO di;
    DWORD dwError;
    
    CPrintDialog tmp_CPD(FALSE, PD_PAGENUMS | PD_USEDEVMODECOPIES);
    
    if (tmp_CPD.DoModal() != IDOK) {	  
    return -1;
    }
    
    //to-do: landscape
    LPDEVMODE lpPrinterDevMode = tmp_CPD.GetDevMode();
    GlobalUnlock(lpPrinterDevMode);
    lpPrinterDevMode->dmOrientation=DMORIENT_LANDSCAPE;
    lpPrinterDevMode->dmPaperSize=DMPAPER_A4;
    GlobalLock(lpPrinterDevMode);
    
    CDC printerDC = tmp_CPD.GetPrinterDC();
    
    dwError = GetLastError();
    
    di.cbSize = sizeof(DOCINFO);
    bstr_t printName = "Test";
    lpszDocName = printName;
    di.lpszOutput = NULL;
    
    hr = printerDC.StartDoc(&di) ; 
    hr = printerDC.StartPage();
    
    HDC hDC;
    
    hDC = GetWindowDC(); //Now get it's DC handle 
    HDC hMemDC = CreateCompatibleDC(hDC);
    RECT r;
    
    RedrawWindow(NULL,NULL,RDW_UPDATENOW);	// printdialogschatten entfernen
    
    GetWindowRect(&r); //need this for Form
    SIZE size;
    size.cx = r.right-r.left;
    size.cy = r.bottom-r.top;
    BitBlt(printerDC, 0, 0, size.cx, size.cy, hDC, 0, 0, SRCCOPY);
    DeleteDC(hMemDC);
    ReleaseDC(hDC);
    
    hr = printerDC.EndPage();
    hr = printerDC.EndDoc();
    
    return 0;
    

  • Mod

    Und warum setzt Du wDiag.Print(printerDC, NULL); nicht zwischen StartPage/EndPage!

    Lies doch wenigstens etwas die Doku, bevor Du irgendwelche Codesnippets zusammenbaust!



  • Hab ich auch versucht, ändert leider nichts. Ich lese schon die Doku dazu, nur versteh ich da nicht all zu viel :-(...


Anmelden zum Antworten