144 lines
4.2 KiB
C++
144 lines
4.2 KiB
C++
#pragma once
|
|
|
|
#include <easyx.h>
|
|
#include <windows.h>
|
|
|
|
#include <cstdint>
|
|
#include <filesystem>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace VisualProbe
|
|
{
|
|
constexpr int CanvasWidth = 960;
|
|
constexpr int CanvasHeight = 720;
|
|
|
|
struct Options
|
|
{
|
|
std::string mode;
|
|
std::filesystem::path outputDirectory;
|
|
std::string requestedDpiAwareness = "inherit";
|
|
std::string expectedImeName = "unspecified";
|
|
unsigned int autoCloseMilliseconds = 0;
|
|
};
|
|
|
|
struct DpiConfiguration
|
|
{
|
|
std::string requested = "inherit";
|
|
bool attempted = false;
|
|
bool applied = false;
|
|
DWORD error = ERROR_SUCCESS;
|
|
};
|
|
|
|
struct EvidenceFile
|
|
{
|
|
std::string relativePath;
|
|
std::string purpose;
|
|
std::string captureBackend;
|
|
};
|
|
|
|
struct PixelBounds
|
|
{
|
|
bool present = false;
|
|
int left = 0;
|
|
int top = 0;
|
|
int right = 0;
|
|
int bottom = 0;
|
|
std::uint64_t pixelCount = 0;
|
|
};
|
|
|
|
struct GdiState
|
|
{
|
|
int mapMode = 0;
|
|
POINT viewportOrigin{};
|
|
POINT windowOrigin{};
|
|
SIZE viewportExtent{};
|
|
SIZE windowExtent{};
|
|
int graphicsMode = 0;
|
|
bool worldTransformAvailable = false;
|
|
XFORM worldTransform{};
|
|
int backgroundMode = 0;
|
|
COLORREF textColor = CLR_INVALID;
|
|
COLORREF backgroundColor = CLR_INVALID;
|
|
UINT textAlign = GDI_ERROR;
|
|
int textCharacterExtra = 0;
|
|
RECT clipBox{};
|
|
int clipType = ERROR;
|
|
};
|
|
|
|
struct SurfaceFingerprint
|
|
{
|
|
std::uintptr_t hdc = 0;
|
|
std::uintptr_t hbitmap = 0;
|
|
std::uintptr_t hfont = 0;
|
|
int bitmapWidth = 0;
|
|
int bitmapHeight = 0;
|
|
int planes = 0;
|
|
int bitsPerPixel = 0;
|
|
int stride = 0;
|
|
bool bitmapInfoAvailable = false;
|
|
bool dibSection = false;
|
|
bool logFontAvailable = false;
|
|
LOGFONTW logFont{};
|
|
std::uint64_t pixelDigest = 0;
|
|
GdiState gdiState{};
|
|
};
|
|
|
|
struct EnvironmentSnapshot
|
|
{
|
|
DWORD processId = 0;
|
|
DWORD threadId = 0;
|
|
bool windowUnicode = false;
|
|
UINT dpiForWindow = 0;
|
|
int deviceDpiX = 0;
|
|
int deviceDpiY = 0;
|
|
std::string processAwareness;
|
|
std::string threadAwareness;
|
|
std::string windowAwareness;
|
|
std::string osBuild;
|
|
std::string easyxVersion;
|
|
RECT clientRect{};
|
|
RECT windowRect{};
|
|
};
|
|
|
|
bool parseOptions(int argc, char** argv, Options& options, std::string& error);
|
|
DpiConfiguration applyRequestedDpiAwareness(const std::string& requested) noexcept;
|
|
EnvironmentSnapshot captureEnvironment(HWND hwnd) noexcept;
|
|
GdiState captureGdiState(HDC hdc) noexcept;
|
|
bool sameGdiState(const GdiState& left, const GdiState& right) noexcept;
|
|
SurfaceFingerprint captureSurfaceFingerprint(HDC hdc, int width, int height) noexcept;
|
|
std::uint64_t capturePixelRegionDigest(HDC hdc, const RECT& region) noexcept;
|
|
PixelBounds findColorBounds(HDC hdc, const RECT& region, COLORREF color) noexcept;
|
|
PixelBounds findChangedBounds(HDC hdc, const RECT& region, COLORREF background) noexcept;
|
|
bool saveHdcImage(HDC source, int width, int height, const std::filesystem::path& path) noexcept;
|
|
bool captureClientImage(
|
|
HWND hwnd,
|
|
const std::filesystem::path& path,
|
|
std::string* captureBackend = nullptr) noexcept;
|
|
std::wstring makeUtf16(const std::vector<std::uint32_t>& codePoints, bool& valid);
|
|
std::string utf16UnitsJson(const std::wstring& text);
|
|
std::string codePointsJson(const std::vector<std::uint32_t>& codePoints);
|
|
std::string jsonString(const std::string& value);
|
|
std::string hexValue(std::uint64_t value);
|
|
void writeBoolean(std::ostream& output, bool value);
|
|
void writeRectJson(std::ostream& output, const RECT& rect);
|
|
void writePointJson(std::ostream& output, const POINT& point);
|
|
void writeSizeJson(std::ostream& output, const SIZE& size);
|
|
void writeBoundsJson(std::ostream& output, const PixelBounds& bounds);
|
|
void writeGdiStateJson(std::ostream& output, const GdiState& state);
|
|
void writeSurfaceFingerprintJson(std::ostream& output, const SurfaceFingerprint& fingerprint);
|
|
bool writeRawResult(
|
|
const Options& options,
|
|
const DpiConfiguration& dpiConfiguration,
|
|
const EnvironmentSnapshot& environment,
|
|
bool completed,
|
|
const std::vector<EvidenceFile>& evidence,
|
|
const std::string& resultJson,
|
|
std::string& error);
|
|
|
|
int runWideTextProbe(const Options& options, const DpiConfiguration& dpiConfiguration);
|
|
int runDpiCoordinateProbe(const Options& options, const DpiConfiguration& dpiConfiguration);
|
|
int runImePositionProbe(const Options& options, const DpiConfiguration& dpiConfiguration);
|
|
}
|