我遵循了this answer,它可以与一台显示器配合使用(尽管当时11岁:D)。但是,当我连接第二台显示器并使用它时,它不再起作用。相反,当class MissionSerializer(HyperlinkedModelSerializer):
queryset = KnownLocation.objects.all()
known_location = ChoiceField(choices=queryset, read_only=True)
gdt = KnownLocationSerializer(many=False, read_only=True)
redirect_to_knownlocation = URLField # not implented yet.
class Meta:
model = Mission
fields = ('MissionName', 'UavLatitude', 'UavLongitude', 'UavElevation', 'Area',
'gdt', 'known_location')
编辑:我发现了问题,这是由于两个显示器上的文字比例不同(第一个是125%,第二个是100%),我将设置都更改为125%并像超级按钮一样工作。现在的问题是,如何在其他显示器上自动检测字体缩放(当前我在第一台显示器上使用this)
答案 0 :(得分:0)
所以问题是每台显示器的比例不同
首先,我使用this answer检测输入point
在哪个监视器的索引:
private int ConvertMousePointToScreenIndex(Point mousePoint)
{
//first get all the screens
System.Drawing.Rectangle ret;
for (int i = 1; i <= Screen.AllScreens.Count(); i++)
{
ret = Screen.AllScreens[i - 1].Bounds;
if (ret.Contains(mousePoint))
return i - 1;
}
return 0;
}
第二,我只需要基于this answer
获取该索引监视器的real width / virtual width
const int ENUM_CURRENT_SETTINGS = -1;
public double GetScale(Point point)
{
Screen screen = Screen.AllScreens[ConvertMousePointToScreenIndex(point)];
DEVMODE dm = new DEVMODE();
dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE));
EnumDisplaySettings(screen.DeviceName, ENUM_CURRENT_SETTINGS, ref dm);
double RealWidth = dm.dmPelsWidth;
double VirtualWidth = screen.Bounds.Width;
return RealWidth / VirtualWidth;
}
[DllImport("user32.dll")]
public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
private const int CCHDEVICENAME = 0x20;
private const int CCHFORMNAME = 0x20;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public int dmPositionX;
public int dmPositionY;
public ScreenOrientation dmDisplayOrientation;
public int dmDisplayFixedOutput;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmReserved1;
public int dmReserved2;
public int dmPanningWidth;
public int dmPanningHeight;
}
最后,将其应用于GetColorAt:
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
public Color GetColorAt(Point location)
{
double scale = GetScale(location);
using (Graphics gdest = Graphics.FromImage(screenPixel))
{
using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
{
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, (int)Math.Round(point.X * scale), (int)Math.Round(point.Y * scale), (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
}