TreeView自适应各DPI行高度


  • XP对高DPI的支持比较差劲, 大部分情况下就是字体的放大, 当然我们程序也可以通过GetDeviceCaps(hDC, LOGPIXELSX)获取DPI后自己对绘画的内容进行缩放。
  • 我们知道Vista/Win7我们可以禁止DWM(Desktop Window Manager), 该模式我们称之为Basic模式, 这种模式下的高DPI效果和XP一样。对于DWM没有禁掉的情况, Vista/Win7/Win8 对高DPI的支持又分为2种情况
  1. 高DPI支持是通过DWM的缩放实现的,比如我们当前系统的DPI是200%,系统会告诉你当前DPI仍然是96(100%),程序会按照100%的方式进行绘画, 但是系统给我们的坐标是根据DPI缩小后的(调用GetWindowRect或是通过GetSystemMetrics(SM_CXSCREEN)),当我们画完之后再对整个窗口进行200% 放大后画到屏幕上,程序就自动支持高DPI了。
  2. 系统给我们提供了2个APi:SetProcessDPIAwareIsProcessDPIAware,通过调用SetProcessDPIAware,我们告诉系统不要对我们的程序进行DWM虚拟化。

这个demo是用来用在开始菜单的。
首先开始菜单有大小图标之分,可以在菜单的设置中设置。第二系统有各个DPI,不同的dpi有不同的大小需要处理。下面就是一些实现过程

  • 首先获取图标获取大小图标,菜单程序快捷地址在C:\ProgramData\Microsoft\Windows\Start Menu\Programs\
function TGetInkImageHelper.GetFileIcon(FileName: string; ASmall: Boolean):
  HIcon;
var
  Info: TSHFileInfo;
  Flags: Cardinal;
begin
  result := 0;
  try
    FileName := ExpCmd(FileName);
    if ASmall then
      Flags := SHGFI_ICON or SHGFI_SMALLICON
    else
      Flags := SHGFI_ICON or SHGFI_LARGEICON;

    SHGetFileInfo(PChar(FileName), FILE_ATTRIBUTE_NORMAL, Info,
      SizeOf(TSHFileInfo), Flags);
    Result := Info.hIcon;
  except

  end;
end;
  • 获取更具大图标和小图标 设置不同行高度
    TreeViewInk.Perform(TVM_SETITEMHEIGHT, 20, 0);

  • 获取DPI

function TSetTreeViewHigh.GetDPI: Integer;
var
  DC: HDC;
begin
  DC := GetDC(0);
  Result := GetDeviceCaps(DC, logpixelsx);
  ReleaseDC(0, DC);
end;
  • 与DPI有关的图片参数
DPI setting Icon (SM_CXICON) Small icon (SM_CXSMICON)
96 32*32 16*16
120 40*40 20*20
144 48*48 24*24
192 64*64 32*32
  • 由上,我们可以总结出显示的规律了
    1.都是4的倍数
    2.大图片是小图片的显示的2倍
    3.间隔的大小话比图片大小大1号
procedure TSetTreeViewHigh.SetNum(num: Integer);
begin
  smallSpace := 5 * num;
  largeSpace := 10 * num;

  mySmallList.Height := 4 * num;
  myLargeList.Height := 8 * num;
end;

你可能感兴趣的:(TreeView自适应各DPI行高度)