|
Registriert seit: 10. Nov 2013 83 Beiträge |
#1
Delphi-Version: 10 Seattle
Ich versuche, einen C-Code zu übersetzen, der Screenshots in Z-Reihenfolge aufnehmen kann. Wenn ich den Delphi-Code teste, wird nur das Desktopfenster gedruckt. Wie kann das behoben werden?
C code:
Code:
#include "stdafx.h"
#include <Windows.h> #include <gdiplus.h> #include <conio.h> #pragma warning(disable : 4996) #pragma comment (lib,"Gdiplus.lib") using namespace Gdiplus; int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; UINT size = 0; ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if (size == 0) return -1; pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if (pImageCodecInfo == NULL) return -1; GetImageEncoders(num, size, pImageCodecInfo); for (UINT j = 0; j < num; ++j) { if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; } } free(pImageCodecInfo); return -1; } //======================================================================================================== BOOL xPrintWindow(HWND hWnd, HDC hDc, HDC hDcScreen) { BOOL ret = FALSE; RECT rect; GetWindowRect(hWnd, &rect); HDC hDcWindow = CreateCompatibleDC(hDc); HBITMAP hBmpWindow = CreateCompatibleBitmap(hDc, rect.right - rect.left, rect.bottom - rect.top); SelectObject(hDcWindow, hBmpWindow); if (PrintWindow(hWnd, hDcWindow, 0)) { BitBlt(hDcScreen, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hDcWindow, 0, 0, SRCCOPY); ret = TRUE; } DeleteObject(hBmpWindow); DeleteDC(hDcWindow); return ret; } void EnumWindowsTopToDown(HWND owner, WNDENUMPROC proc, LPARAM param) { HWND currentWindow = GetTopWindow(owner); if (currentWindow == NULL) return; if ((currentWindow = GetWindow(currentWindow, GW_HWNDLAST)) == NULL) return; while (proc(currentWindow, param) && (currentWindow = GetWindow(currentWindow, GW_HWNDPREV)) != NULL); } struct EnumHwndsPrintData { HDC hDc; HDC hDcScreen; }; BOOL CALLBACK EnumHwndsPrint(HWND hWnd, LPARAM lParam) { EnumHwndsPrintData *data = (EnumHwndsPrintData *)lParam; if (!IsWindowVisible(hWnd)) return TRUE; xPrintWindow(hWnd, data->hDc, data->hDcScreen); DWORD style = GetWindowLongA(hWnd, GWL_EXSTYLE); SetWindowLongA(hWnd, GWL_EXSTYLE, style | WS_EX_COMPOSITED); /*OSVERSIONINFOA versionInfo; ZeroMemory(&versionInfo, sizeof(OSVERSIONINFO)); versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); GetVersionExA(&versionInfo); if (versionInfo.dwMajorVersion < 6) EnumWindowsTopToDown(hWnd, EnumHwndsPrint, (LPARAM)data);*/ return TRUE; } void testPrintWindow(int serverWidth, int serverHeight) { RECT rect; HWND hWndDesktop = GetDesktopWindow(); GetWindowRect(hWndDesktop, &rect); HDC hDc = GetDC(NULL); HDC hDcScreen = CreateCompatibleDC(hDc); HBITMAP hBmpScreen = CreateCompatibleBitmap(hDc, rect.right, rect.bottom); SelectObject(hDcScreen, hBmpScreen); EnumHwndsPrintData data; data.hDc = hDc; data.hDcScreen = hDcScreen; EnumWindowsTopToDown(NULL, EnumHwndsPrint, (LPARAM)&data); if (serverWidth > rect.right) serverWidth = rect.right; if (serverHeight > rect.bottom) serverHeight = rect.bottom; if (serverWidth != rect.right || serverHeight != rect.bottom) { HBITMAP hBmpScreenResized = CreateCompatibleBitmap(hDc, serverWidth, serverHeight); HDC hDcScreenResized = CreateCompatibleDC(hDc); SelectObject(hDcScreenResized, hBmpScreenResized); SetStretchBltMode(hDcScreenResized, HALFTONE); StretchBlt(hDcScreenResized, 0, 0, serverWidth, serverHeight, hDcScreen, 0, 0, rect.right, rect.bottom, SRCCOPY); DeleteObject(hBmpScreen); DeleteDC(hDcScreen); hBmpScreen = hBmpScreenResized; hDcScreen = hDcScreenResized; } //======================================================================================================= // ========== HBITMAP to bmp file =========== GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); Bitmap *image = new Bitmap(hBmpScreen, NULL); CLSID myClsId; int retVal = GetEncoderClsid(L"image/bmp", &myClsId); image->Save(L"output.bmp", &myClsId, NULL); delete image; GdiplusShutdown(gdiplusToken); //======================================================================= } int _tmain(int argc, _TCHAR* argv[]) { testPrintWindow(800, 600); _getch(); return 0; }
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses Windows, Vcl.Graphics, SysUtils; type PEnumHwndsPrintData = ^TEnumHwndsPrintData; TEnumHwndsPrintData = record _hDc: HDC; hDcScreen: HDC; end; type TFNWndEnumProc = function(_hwnd: HWND; _lParam: LPARAM): BOOL; stdcall; function xPrintWindow(_hwnd: HWND; _hDc, hDcScreen: HDC): BOOL; const sPrintWindow = 'PrintWindow'; var PrintWindowAPI: function(sourceHandle: HWND; destinationHandle: HDC; nFlags: UINT): BOOL; stdcall; User32DLLHandle: THandle; bPrint: Boolean; Ret: BOOL; R: TRect; hDcWindow: HDC; hBmpWindow: HBITMAP; begin Ret := False; User32DLLHandle := GetModuleHandle(user32); if User32DLLHandle <> 0 then begin @PrintWindowAPI := GetProcAddress(User32DLLHandle, sPrintWindow); if @PrintWindowAPI <> nil then begin GetWindowRect(_hwnd, R); hDcWindow := CreateCompatibleDC(_hDc); hBmpWindow := CreateCompatibleBitmap(_hDc, R.Right - R.Left, R.Bottom - R.Top); SelectObject(hDcWindow, hBmpWindow); bPrint := PrintWindowAPI(_hwnd, hDcWindow, 0); if bPrint then begin BitBlt(hDcScreen, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top, hDcWindow, 0, 0, SRCCOPY); Ret := True; end; DeleteObject(hBmpWindow); DeleteDC(hDcWindow); end; end; Result := Ret; end; function GetPrevHwnd(hWindow: HWND): HWND; begin hWindow := GetWindow(hWindow, GW_HWNDPREV); Result := hWindow; end; procedure EnumWindowsTopToDown(Owner: HWND; Proc: TFNWndEnumProc; _Param: LPARAM); var CurrentWindow, _CurrentWindow: HWND; begin repeat CurrentWindow := GetTopWindow(Owner); if CurrentWindow = 0 then Exit; CurrentWindow := GetWindow(CurrentWindow, GW_HWNDLAST); if CurrentWindow = 0 then Exit; _CurrentWindow := GetPrevHwnd(CurrentWindow); until Proc(CurrentWindow, _Param) and (_CurrentWindow <> 0); end; function EnumHwndsPrint(wHandle: HWND; _lParam: LPARAM): BOOL; stdcall; var VersionInfo: TOSVersionInfo; Data: PEnumHwndsPrintData; Style: DWORD; begin Result := True; if not IsWindowVisible(wHandle) then Exit; Data := PEnumHwndsPrintData(_lParam); Writeln('oi'); xPrintWindow(wHandle, Data._hDc, Data.hDcScreen); Style := GetWindowLong(wHandle, GWL_EXSTYLE); SetWindowLong(wHandle, GWL_EXSTYLE, Style or WS_EX_COMPOSITED); VersionInfo.dwOSVersionInfoSize := SizeOf(VersionInfo); GetVersionEx(VersionInfo); if (VersionInfo.dwMajorVersion < 6) then EnumWindowsTopToDown(wHandle, EnumHwndsPrint, LPARAM(Data)); end; procedure testPrintWindow(Width, Height: Integer); var hWndDesktop: HWND; Data: TEnumHwndsPrintData; _hDcScreen, hDc_, hDcScreenResized: HDC; hBmpScreen, hBmpScreenResized: HBITMAP; Rect: TRect; bmp: TBitmap; begin hWndDesktop := GetDesktopWindow; GetWindowRect(hWndDesktop, Rect); hDc_ := GetDC(0); _hDcScreen := CreateCompatibleDC(hDc_); hBmpScreen := CreateCompatibleBitmap(hDc_, Rect.Right, Rect.Bottom); SelectObject(_hDcScreen, hBmpScreen); with Data do begin _hDc := hDc_; hDcScreen := _hDcScreen; end; EnumWindowsTopToDown(0, EnumHwndsPrint, LPARAM(@Data)); if (Width > Rect.Right) then Width := Rect.Right; if (Height > Rect.Bottom) then Height := Rect.Bottom; if (Width <> Rect.Right) or (Height <> Rect.Bottom) then begin hBmpScreenResized := CreateCompatibleBitmap(hDc_, Width, Height); hDcScreenResized := CreateCompatibleDC(hDc_); SelectObject(hDcScreenResized, hBmpScreenResized); SetStretchBltMode(hDcScreenResized, HALFTONE); StretchBlt(hDcScreenResized, 0, 0, Width, Height, _hDcScreen, 0, 0, Rect.Right, Rect.Bottom, SRCCOPY); DeleteObject(hBmpScreen); DeleteDC(_hDcScreen); hBmpScreen := hBmpScreenResized; _hDcScreen := hDcScreenResized; end; bmp := TBitmap.Create; bmp.Handle := hBmpScreen; bmp.SaveToFile('output.bmp'); bmp.Free; end; begin try testPrintWindow(800, 600); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. Geändert von flashcoder (27. Apr 2019 um 10:54 Uhr) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |