Unfortunately, that still did not make the pixels perfectly scaled.
I've extracted the menu code from my project script and pasted below... Please run the script at 125% scaling (or change the DPI calculation to
to test at 100% scaling), take a screenshot, paste into an image editor, and then zoom into the pixels. You will see the sizes are not consistent.
The image looks perfect at 100% scale, but I'm trying to ensure that it will look the same at different DPI scaling. Hopefully this is possible. Maybe I'm doing something wrong?
Code: Select all
#SingleInstance, Force
; Calculate DPI scaling
DPI := (A_ScreenDPI / 96)
; GDI+ Startup
hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll") ; Load module
VarSetCapacity(GdiplusStartupInput, (A_PtrSize = 8 ? 24 : 16), 0) ; GdiplusStartupInput structure
NumPut(1, GdiplusStartupInput, 0, "UInt") ; GdiplusVersion
DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &GdiplusStartupInput, "Ptr", 0) ; Initialize GDI+
; Create Bitmap object
DllCall("Gdiplus.dll\GdipCreateBitmapFromScan0", "Int", (640 * DPI), "Int", (512 * DPI), "Int", 0, "Int", 0x26200A, "Ptr", 0, "PtrP", pBitmap)
; Create Graphics object associated with Bitmap object
DllCall("Gdiplus.dll\GdipGetImageGraphicsContext", "Ptr", pBitmap, "PtrP", pGraphics)
; Indicates that pixel centers have coordinates that are half way between integer values.
DllCall("Gdiplus.dll\GdipSetPixelOffsetMode", "Ptr", pGraphics, "Int", 4) ; PixelOffsetModeHalf
; Set rendering quality of Graphics object
DllCall("Gdiplus.dll\GdipSetSmoothingMode", "Ptr", pGraphics, "Int", 3) ; None
; Set interpolation mode of Graphics object
DllCall("Gdiplus.dll\GdipSetInterpolationMode", "Ptr", pGraphics, "Int", 5) ; NearestNeighbor
; Menu Background
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFFFCC00, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (0 * DPI), "Float", (0 * DPI), "Float", (640 * DPI), "Float", (512 * DPI))
; Menu Layer 1
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF999999, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (192 * DPI), "Float", (96 * DPI), "Float", (256 * DPI), "Float", (288 * DPI))
; Menu Layer 2
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFFFFFFF, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (194 * DPI), "Float", (98 * DPI), "Float", (252 * DPI), "Float", (284 * DPI))
; Menu Layer 3
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFEEEEEE, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (196 * DPI), "Float", (100 * DPI), "Float", (248 * DPI), "Float", (280 * DPI))
; Button Layer 1
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF618B98, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (224 * DPI), "Float", (128 * DPI), "Float", (192 * DPI), "Float", (32 * DPI))
; Button Layer 2
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFA2E8FE, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (226 * DPI), "Float", (130 * DPI), "Float", (188 * DPI), "Float", (28 * DPI))
; Button Layer 3
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF98D9ED, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (228 * DPI), "Float", (132 * DPI), "Float", (184 * DPI), "Float", (24 * DPI))
; Button Layer 1
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF618B98, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (224 * DPI), "Float", (192 * DPI), "Float", (192 * DPI), "Float", (32 * DPI))
; Button Layer 2
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFA2E8FE, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (226 * DPI), "Float", (194 * DPI), "Float", (188 * DPI), "Float", (28 * DPI))
; Button Layer 3
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF98D9ED, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (228 * DPI), "Float", (196 * DPI), "Float", (184 * DPI), "Float", (24 * DPI))
; Button Layer 1
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF618B98, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (224 * DPI), "Float", (256 * DPI), "Float", (192 * DPI), "Float", (32 * DPI))
; Button Layer 2
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFA2E8FE, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (226 * DPI), "Float", (258 * DPI), "Float", (188 * DPI), "Float", (28 * DPI))
; Button Layer 3
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF98D9ED, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (228 * DPI), "Float", (260 * DPI), "Float", (184 * DPI), "Float", (24 * DPI))
; Button Layer 1
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF618B98, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (224 * DPI), "Float", (320 * DPI), "Float", (192 * DPI), "Float", (32 * DPI))
; Button Layer 2
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFFA2E8FE, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (226 * DPI), "Float", (322 * DPI), "Float", (188 * DPI), "Float", (28 * DPI))
; Button Layer 3
DllCall("Gdiplus.dll\GdipCreateSolidFill", "UInt", 0xFF98D9ED, "PtrP", pBrushMenu)
DllCall("Gdiplus.dll\GdipFillRectangle", "Ptr", pGraphics, "Ptr", pBrushMenu, "Float", (228 * DPI), "Float", (324 * DPI), "Float", (184 * DPI), "Float", (24 * DPI))
; Delete Brush object
DllCall("Gdiplus.dll\GdipDeleteBrush", "Ptr", pBrushMenu)
; Creates GDI bitmap from Bitmap object
DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "UInt", pBitmap, "UInt*", hBitmap, "Int", 0XFFFFFFFF)
; Create Gui
Gui, +E0x02000000 +E0x00080000 ; WS_EX_COMPOSITED & WS_EX_LAYERED (Double Buffer)
Gui, +LastFound -Resize +DPIScale +HWNDhExample
Gui, Margin, 0, 0
Gui, Color, FFFFFF
Gui, Add, Picture, % "x0 y0 w" (640 * DPI) " h" (512 * DPI) " +HWNDhCanvas +0xE"
Gui, Show, w640 h512, Example
; Associate image with static control
SM := DllCall("User32.dll\SendMessage", "Ptr", hCanvas, "UInt", 0x172, "Ptr", 0x0, "Ptr", hBitmap) ; STM_SETIMAGE
; Delete Bitmap object previously assigned
DllCall("Gdi32.dll\DeleteObject", "Ptr", SM)
; Delete Bitmap object
DllCall("Gdi32.dll\DeleteObject", "Ptr", hBitmap)
; Delete Graphics object
DllCall("Gdiplus.dll\GdipDeleteGraphics", "Ptr", pGraphics)
; Clean up resources used by GDI+
DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
; Free module from memory
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)