Last active
July 3, 2022 05:36
-
-
Save lxfly2000/d1a37814c0b714a97ad26b509b6dc657 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <CommCtrl.h> | |
#include <iostream> | |
#include <iomanip> | |
#include <vector> | |
#include <string> | |
#include <strsafe.h> | |
struct ENTRY | |
{ | |
int param; | |
LPCSTR descEN,descCN; | |
}; | |
const ENTRY dcParams[] = { | |
{DRIVERVERSION,"Device driver version","设备驱动版本"}, | |
{TECHNOLOGY,"Device classification","设备等级"}, | |
{HORZSIZE,"Horizontal size in millimeters","水平毫米数"}, | |
{VERTSIZE,"Vertical size in millimeters","垂直毫米数"}, | |
{HORZRES,"Horizontal width in pixels","水平分辨率"}, | |
{VERTRES,"Vertical height in pixels","垂直分辨率"}, | |
{BITSPIXEL,"Number of bits per pixel","像素位深"}, | |
{PLANES,"Number of planes","平面数"}, | |
{NUMBRUSHES,"Number of brushes the device has","画刷数量"}, | |
{NUMPENS,"Number of pens the device has","笔刷数量"}, | |
{NUMMARKERS,"Number of markers the device has","标记数量"}, | |
{NUMFONTS,"Number of fonts the device has","字体数量"}, | |
{NUMCOLORS,"Number of colors the device supports","颜色数量"}, | |
{PDEVICESIZE,"Size required for device descriptor","设备描述符大小"}, | |
{CURVECAPS,"Curve capabilities","曲线级别"}, | |
{LINECAPS,"Line capabilities","直线级别"}, | |
{POLYGONALCAPS,"Polygonal capabilities","多边形级别"}, | |
{TEXTCAPS,"Text capabilities","文字级别"}, | |
{CLIPCAPS,"Clipping capabilities","剪切级别"}, | |
{RASTERCAPS,"Bitblt capabilities","像素传送级别"}, | |
{ASPECTX,"Length of the X leg","X边长"}, | |
{ASPECTY,"Length of the Y leg","Y边长"}, | |
{ASPECTXY,"Length of the hypotenuse","斜边长"}, | |
{LOGPIXELSX,"Logical pixels/inch in X","X逻辑像素密度"}, | |
{LOGPIXELSY,"Logical pixels/inch in Y","Y逻辑像素密度"}, | |
{SIZEPALETTE,"Number of entries in physical palette","物理调色板数量"}, | |
{NUMRESERVED,"Number of reserved entries in palette","调色板保留数量"}, | |
{COLORRES,"Actual color resolution","实际颜色分辨率"}, | |
}; | |
std::vector<std::vector<std::string>>resultstr; | |
void GetData() | |
{ | |
for (int i = 0; i < ARRAYSIZE(dcParams); i++) | |
resultstr.push_back({ dcParams[i].descEN,dcParams[i].descCN }); | |
HDC hdc = GetDC(GetDesktopWindow()); | |
for (int i = 0; i < ARRAYSIZE(dcParams); i++) | |
resultstr[i].push_back(std::to_string(GetDeviceCaps(hdc, dcParams[i].param))); | |
int cx = GetSystemMetrics(SM_CXSCREEN), cy = GetSystemMetrics(SM_CYSCREEN); | |
SetProcessDPIAware(); | |
hdc = GetDC(GetDesktopWindow()); | |
for (int i = 0; i < ARRAYSIZE(dcParams); i++) | |
resultstr[i].push_back(std::to_string(GetDeviceCaps(hdc, dcParams[i].param))); | |
resultstr.push_back({ "SM_CXSCREEN (SAME AS HORZRES)","分辨率X",std::to_string(cx),std::to_string(GetSystemMetrics(SM_CXSCREEN)) }); | |
resultstr.push_back({ "SM_CYSCREEN (SAME AS VERTRES)","分辨率Y",std::to_string(cy),std::to_string(GetSystemMetrics(SM_CYSCREEN)) }); | |
} | |
#define DPI_SCALED_VALUE(hwnd,x) MulDiv(x,GetDeviceCaps(GetDC(hwnd),LOGPIXELSY),USER_DEFAULT_SCREEN_DPI) | |
#define ID_LIST_VDCAP 2000 | |
void VdcapCreateWindow(HWND hwnd) | |
{ | |
const char*header[] = { "属性(英文)","属性(中文)","值(DPI=96)","值(当前DPI)" }; | |
HWND hList = CreateWindowA("SysListView32", "List", WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_ALIGNLEFT, 0, 0, CW_USEDEFAULT, 0, hwnd, (HMENU)ID_LIST_VDCAP, NULL, NULL); | |
SendMessageA(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); | |
LVCOLUMNA col{}; | |
col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; | |
col.cx = DPI_SCALED_VALUE(hList, 240); | |
for (int i = 0; i < ARRAYSIZE(header); i++) | |
{ | |
col.fmt = i < 2 ? LVCFMT_LEFT : LVCFMT_RIGHT; | |
col.pszText = (LPSTR)header[i]; | |
SendMessageA(hList, LVM_INSERTCOLUMNA, i, (LPARAM)&col); | |
col.cx = DPI_SCALED_VALUE(hList, 140); | |
} | |
for (int i = 0; i < resultstr.size(); i++) | |
{ | |
LVITEMA lvi{}; | |
lvi.mask = LVIF_TEXT; | |
lvi.iItem = i; | |
lvi.iSubItem = 0; | |
lvi.pszText = (LPSTR)resultstr[i][0].c_str(); | |
SendMessageA(hList, LVM_INSERTITEMA, 0, (LPARAM)&lvi); | |
for (int j = 1; j < resultstr[i].size(); j++) | |
{ | |
lvi.iSubItem = j; | |
lvi.pszText = (LPSTR)resultstr[i][j].c_str(); | |
SendMessageA(hList, LVM_SETITEMTEXTA, i, (LPARAM)&lvi); | |
} | |
} | |
} | |
void VdcapDestroyWindow(HWND hwnd) | |
{ | |
DestroyWindow(GetDlgItem(hwnd, ID_LIST_VDCAP)); | |
} | |
void VdcapMoveWindow(HWND hwnd) | |
{ | |
RECT r; | |
GetClientRect(hwnd, &r); | |
MoveWindow(GetDlgItem(hwnd, ID_LIST_VDCAP), r.left, r.top, r.right - r.left, r.bottom - r.top, FALSE); | |
} | |
BOOL SetClipBoardText(HWND hWnd, LPCTSTR text) | |
{ | |
if (FAILED(OpenClipboard(hWnd))) | |
return FALSE; | |
EmptyClipboard(); | |
HGLOBAL hClip = GlobalAlloc(GMEM_MOVEABLE, (lstrlen(text) + 1) * sizeof(TCHAR));//申请剪贴板内存 | |
TCHAR *pBuffer = (TCHAR*)GlobalLock(hClip);//获取剪贴板的地址并锁定。 | |
StringCchCopy(pBuffer, lstrlen(text) + 1, text); | |
GlobalUnlock(hClip);//释放锁 | |
SetClipboardData(CF_UNICODETEXT, hClip); | |
CloseClipboard(); | |
return TRUE; | |
} | |
void VdcapCopySel(HWND hwnd) | |
{ | |
HWND hList = GetDlgItem(hwnd, ID_LIST_VDCAP); | |
int nItem = ListView_GetItemCount(hList); | |
std::wstring str; | |
for (int i = 0; i < nItem; i++) | |
{ | |
if (ListView_GetItemState(hList, i, LVIS_SELECTED)) | |
{ | |
TCHAR buf[64]; | |
for (int j = 0; j < 4; j++) | |
{ | |
if (j) | |
str += '\t'; | |
ListView_GetItemText(hList, i, j, buf, ARRAYSIZE(buf)); | |
str += buf; | |
} | |
str += '\n'; | |
} | |
} | |
SetClipBoardText(hwnd, str.c_str()); | |
} | |
#define ID_MENU_COPY 10000 | |
LRESULT CALLBACK VdcapProc(HWND hwnd,UINT msg, WPARAM wParam,LPARAM lParam) | |
{ | |
switch (msg) | |
{ | |
case WM_CREATE: | |
VdcapCreateWindow(hwnd); | |
break; | |
case WM_DESTROY: | |
VdcapDestroyWindow(hwnd); | |
break; | |
case WM_SIZE: | |
VdcapMoveWindow(hwnd); | |
break; | |
case WM_CLOSE: | |
PostQuitMessage(0); | |
break; | |
case WM_NOTIFY: | |
LPNMHDR pn = (LPNMHDR)lParam; | |
if (pn->idFrom == ID_LIST_VDCAP && pn->code == NM_RCLICK) | |
{ | |
LPNMITEMACTIVATE pi = (LPNMITEMACTIVATE)lParam; | |
if (pi->iItem != -1) | |
{ | |
HMENU hPop = CreatePopupMenu(); | |
AppendMenuA(hPop, MF_STRING, ID_MENU_COPY, "复制(&C)"); | |
POINT pt; | |
GetCursorPos(&pt); | |
if (TrackPopupMenu(hPop, TPM_RETURNCMD, pt.x, pt.y, NULL, hwnd, NULL) == ID_MENU_COPY) | |
VdcapCopySel(hwnd); | |
DestroyMenu(hPop); | |
} | |
} | |
break; | |
} | |
return DefWindowProcA(hwnd, msg, wParam, lParam); | |
} | |
void ShowData(HINSTANCE hInst,int iShow) | |
{ | |
WNDCLASSA wc{}; | |
wc.lpszClassName = "VdcapWindow"; | |
wc.lpfnWndProc = VdcapProc; | |
wc.style = CS_HREDRAW | CS_VREDRAW; | |
wc.hInstance = hInst; | |
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); | |
wc.hCursor = LoadCursor(NULL, IDC_ARROW); | |
RegisterClassA(&wc); | |
HWND hwnd = CreateWindowA(wc.lpszClassName, "显示属性", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL); | |
ShowWindow(hwnd,iShow); | |
UpdateWindow(hwnd); | |
MSG msg; | |
while (GetMessage(&msg, NULL, 0, 0)) | |
{ | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPrev,LPSTR param,int iShow) | |
{ | |
GetData(); | |
ShowData(hInst,iShow); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment