Skip to content

Instantly share code, notes, and snippets.

@lxfly2000
Last active July 3, 2022 05:36
Show Gist options
  • Save lxfly2000/d1a37814c0b714a97ad26b509b6dc657 to your computer and use it in GitHub Desktop.
Save lxfly2000/d1a37814c0b714a97ad26b509b6dc657 to your computer and use it in GitHub Desktop.
#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