Search the Community
Showing results for tags 'gdiplus'.
-
I tried to apply dark mode to the SampleControls.au3 example. What I did so far: ; Coded by UEZ build 2026-03-04 beta ; not DPI aware! #include <APIConstants.au3> #include <AVIConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiDateTimePicker.au3> #include <GuiImageList.au3> #include <GuiMenu.au3> #include <GuiMonthCal.au3> #include <GuiScrollBars.au3> #include <GuiStatusBar.au3> #include <GuiTab.au3> #include <GuiTreeView.au3> #include <TreeViewConstants.au3> #include <ListViewConstants.au3> #include <WinAPIConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIRes.au3> #include <WinAPIShellEx.au3> #include <WinAPISys.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Enum $IHCM_USE_CACHED_VALUE, $IHCM_REFRESH Enum $APPMODE_DEFAULT = 0, $APPMODE_ALLOWDARK, $APPMODE_FORCEDARK, $APPMODE_FORCELIGHT, $APPMODE_MAX Const $PRF_CLIENT = 0x04 Const $ODS_HOTLIGHT = 0x0040 ; Dark Mode Colors (RGB) Global Const $COLOR_BG_DARK = 0x202020 Global Const $COLOR_TEXT_LIGHT = 0xF0F0F0 Global Const $COLOR_CONTROL_BG = 0x2B2B2B Global Const $COLOR_EDIT_BG = 0x1E1E1E Global Const $COLOR_BUTTON_BG = 0x333333 Global Const $COLOR_BORDER = 0x3F3F3F Global Const $COLOR_BORDER2 = 0xA0A0A0 Global Const $COLOR_HOTTRACK_MENU = 0x3A3A3A Global Const $COLOR_BORDER_LIGHT = 0xD8D8D8 ; Global variables for subclassing (MUST be declared before _Example()!) Global $g_hGUI = 0, $g_hTab, $g_ListView Global $g_aControls[50][3] = [[0, 0, 0]] ; [ControlID, hWnd, OldWndProc] Global $g_iControlCount = 0 Global $g_pSubclassProc = 0 ; Global brushes for _WM_CTLCOLOR (avoids memory leaks) Global $g_hBrushEdit = 0 Global $g_hBrushButton = 0 Global $g_hBrushBg = 0 Global $g_hBrushGreen Global $g_hLabelGreen = 0, $g_idLabelGreen Global $g_idLabelPic, $g_hLabelPic Global $g_hMenu = 0, $g_hMenu1, $g_hMenu2 Global $g_idDate = 0, $g_hDate = 0 ; Global variable for tab subclassing Global $g_hTab_CB, $g_pTab_CB, $g_hProc ; Global variable for SysDateTimePick32 subclassing Global $g_hDateProc_CB, $g_pDateProc_CB, $g_hDateOldProc ; Structure for NM_CUSTOMDRAW notification Global Const $tagNMCUSTOMDRAW = _ $tagNMHDR & ";" & _ ; Contains NM_CUSTOMDRAW / NMHDR header among other things "dword dwDrawStage;" & _ ; Current drawing stage (CDDS_*) "handle hdc;" & _ ; Device Context Handle "long left;long top;long right;long bottom;" & _ ; Drawing rectangle "dword_ptr dwItemSpec;" & _ ; Item index or other info (depending on the control) "uint uItemState;" & _ ; State Flags (CDIS_SELECTED, CDIS_FOCUS etc.) "lparam lItemlParam" ; lParam set by the item (e.g., via LVITEM.lParam) Global $g_hMenu = 0, $hMenuFont Global $g_aMenuText = [] ; dynamic array for top-level menu texts Global $arMenuItems[1][8] $arMenuItems[0][0] = 0 Global $arSideItems[1][10] $arSideItems[0][0] = 0 Const $ODT_MENU = 1 Const $ODS_SELECTED = 0x0001 Const $ODS_DISABLED = 0x0004 Global Enum $idAbout = 5000 Global $g_hMenu_Sys, $g_idAboutMenu, $g_AboutDummy Global $g_bHover = False _GDIPlus_Startup() _Example() _GDIPlus_Shutdown() Func _Example() ; Create global brushes $g_hBrushEdit = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_EDIT_BG)) $g_hBrushButton = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BUTTON_BG)) $g_hBrushBg = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) #Region GUI $g_hGUI = GUICreate("Sample GUI with Dark Mode", 400, 424) GUISetIcon(@SystemDir & "\mspaint.exe", 0) GUISetBkColor($COLOR_BG_DARK, $g_hGUI) $g_hMenu_Sys = _GUICtrlMenu_GetSystemMenu($g_hGUI) _GUICtrlMenu_AppendMenu($g_hMenu_Sys, $MF_SEPARATOR, 0, 0) _GUICtrlMenu_AppendMenu($g_hMenu_Sys, $MF_STRING, $idAbout, "About") ; Register GUI-level WM_CTLCOLOR messages GUIRegisterMsg($WM_CTLCOLOREDIT, "_WM_CTLCOLOR") GUIRegisterMsg($WM_CTLCOLORLISTBOX, "_WM_CTLCOLOR") GUIRegisterMsg($WM_CTLCOLORBTN, "_WM_CTLCOLOR") GUIRegisterMsg($WM_CTLCOLORSTATIC, "_WM_CTLCOLOR") GUIRegisterMsg($WM_MEASUREITEM, "_WM_MEASUREITEM") GUIRegisterMsg($WM_DRAWITEM, "_WM_DRAWITEM") GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUIRegisterMsg($WM_ACTIVATE, "_WM_ACTIVATE") GUIRegisterMsg($WM_WINDOWPOSCHANGED, "_WM_WINDOWPOSCHANGED") GUIRegisterMsg($WM_MENUCOMMAND, "_WM_MENUCOMMAND") GUIRegisterMsg($WM_SYSCOMMAND, "_WM_SYSCOMMAND") #EndRegion GUI #Region MENU Global $g_aMenuText[4] $g_aMenuText[0] = "Menu &One" $g_aMenuText[1] = "Menu &Two" $g_aMenuText[2] = "Menu Th&ree" $g_aMenuText[3] = "Menu &Four" Local $idMenu1 = GUICtrlCreateMenu($g_aMenuText[0]) Local $idMenu2 = GUICtrlCreateMenu($g_aMenuText[1]) GUICtrlCreateMenu($g_aMenuText[2]) GUICtrlCreateMenu($g_aMenuText[3]) GUICtrlCreateMenuItem('SubMenu One &A', $idMenu1) GUICtrlCreateMenuItem('SubMenu One &B', $idMenu1) $g_idAboutMenu = GUICtrlCreateMenuItem('About', $idMenu1) $g_hMenu1 = GUICtrlGetHandle($idMenu1) $g_hMenu2 = GUICtrlGetHandle($idMenu2) ; Owner-draw Top-Level Menu creation _MakeMenuOwnerDraw($g_hGUI) _EnableMenuHotTrack($g_hMenu) #EndRegion MENU #Region CONTEXT MENU Local $idContextMenu = GUICtrlCreateContextMenu() GUICtrlCreateMenuItem("Context Menu", $idContextMenu) GUICtrlCreateMenuItem("", $idContextMenu) GUICtrlCreateMenuItem("&Properties", $idContextMenu) #EndRegion CONTEXT MENU #Region PIC Local $idPic = GUICtrlCreatePic("", 0, 0, 169, 68) GUICtrlSetImage($idPic, "C:\Program Files (x86)\AutoIt3\Examples\GUI\logo4.gif") GUICtrlSetTip(-1, '#Region PIC') $g_idLabelPic = GUICtrlCreateLabel("Sample Pic", 75, 1, 53, 15) $g_hLabelPic = GUICtrlGetHandle($g_idLabelPic) #EndRegion PIC #Region AVI Local $idAvi = GUICtrlCreateAvi("C:\Program Files (x86)\AutoIt3\Examples\GUI\SampleAVI.avi", 0, 180, 10, 32, 32, $ACS_AUTOPLAY) GUICtrlSetTip(-1, '#Region AVI') GUICtrlCreateLabel("Sample avi", 175, 50) #EndRegion AVI #Region TAB Local $idTab = GUICtrlCreateTab(240, 0, 150, 70), $g_hTab = GUICtrlGetHandle($idTab) _AddControlForSubclass($idTab) GUICtrlCreateTabItem("One") GUICtrlSetTip(-1, '#Region TAB1') GUICtrlCreateLabel("Sample Tab with TabItems", 250, 40) GUICtrlCreateTabItem("Two") GUICtrlSetTip(-1, '#Region TAB2') Local $idCheckBoxTab2 = GUICtrlCreateCheckbox("Checkbox", 250, 30, 120, 20) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idCheckBoxTab2), "DarkMode_DarkTheme", 0) GUICtrlCreateTabItem("Three") GUICtrlSetTip(-1, '#Region TAB3') GUICtrlCreateTabItem("") $g_hTab = GUICtrlGetHandle($idTab) #EndRegion TAB #Region COMBO Local $idCombo = GUICtrlCreateCombo("Sample Combo", 250, 80, 120, 100) GUICtrlSetData($idCombo, "Item 2|Item 3", "Sample Combo") _AddControlForSubclass($idCombo) GUICtrlSetTip(-1, '#Region COMBO') #EndRegion COMBO #Region PROGRESS Local $idProgress = GUICtrlCreateProgress(60, 80, 150, 20) ;_AddControlForSubclass($idProgress) GUICtrlSetTip(-1, '#Region PROGRESS') GUICtrlSetData(-1, 60) GUICtrlCreateLabel("Progress:", 5, 82) #EndRegion PROGRESS #Region EDIT Local $idEdit = GUICtrlCreateEdit(@CRLF & " Sample Edit Control", 10, 110, 150, 70) _AddControlForSubclass($idEdit) GUICtrlSetTip(-1, '#Region EDIT') #EndRegion EDIT #Region LIST Local $idList = GUICtrlCreateList("", 5, 190, 100, 90) _AddControlForSubclass($idList) GUICtrlSetTip(-1, '#Region LIST') GUICtrlSetData(-1, "A.Sample|B.List|C.Control|D.Here", "B.List") #EndRegion LIST #Region ICON GUICtrlCreateIcon("explorer.exe", 0, 175, 120) GUICtrlSetTip(-1, '#Region ICON') GUICtrlCreateLabel("Icon", 180, 160, 50, 20) #EndRegion ICON #Region LIST VIEW Local $idListView = GUICtrlCreateListView("Sample|ListView|", 110, 190, 110, 80, $LVS_REPORT) _AddControlForSubclass($idListView) GUICtrlSetBkColor($idListView, $COLOR_EDIT_BG) GUICtrlSetColor($idListView, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region LIST VIEW') GUICtrlCreateListViewItem("A|One", $idListView) GUICtrlCreateListViewItem("B|Two", $idListView) GUICtrlCreateListViewItem("C|Three", $idListView) $g_ListView = GUICtrlGetHandle($idListView) #EndRegion LIST VIEW #Region GROUP WITH RADIO BUTTONS Local $idGroup = GUICtrlCreateGroup("Sample Group", 230, 120) GUICtrlSetColor($idGroup, $COLOR_TEXT_LIGHT) Local $idRadio1 = GUICtrlCreateRadio("Radio One", 250, 140, 80) GUICtrlSetTip($idRadio1, '#Region RADIO1') GUICtrlSetState($idRadio1, $GUI_CHECKED) Local $idRadio2 = GUICtrlCreateRadio("Radio Two", 250, 165, 80) GUICtrlSetTip($idRadio2, '#Region RADIO2') GUICtrlCreateGroup("", -99, -99, 1, 1) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idRadio1), "DarkMode_DarkTheme", 0) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idRadio2), "DarkMode_DarkTheme", 0) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idGroup), "DarkMode_DarkTheme", 0) #EndRegion GROUP WITH RADIO BUTTONS #Region UPDOWN GUICtrlCreateLabel("UpDown", 350, 115) GUICtrlSetColor(-1, $COLOR_TEXT_LIGHT) Local $idInput = GUICtrlCreateInput("42", 350, 130, 40, 20) _AddControlForSubclass($idInput) Local $idUpDown = GUICtrlCreateUpdown(-1) _AddControlForSubclass($idUpDown) #EndRegion UPDOWN #Region LABEL $g_idLabelGreen = GUICtrlCreateLabel("Green" & @CRLF & "Label", 350, 165, 40, 40) $g_hLabelGreen = GUICtrlGetHandle($g_idLabelGreen) GUICtrlSetTip($g_idLabelGreen, '#Region LABEL') $g_hBrushGreen = _WinAPI_CreateSolidBrush(_ColorToCOLORREF(0x00FF00)) ; green background #Region SLIDER GUICtrlCreateLabel("Slider:", 235, 215) Local $idSlider = GUICtrlCreateSlider(270, 210, 120, 30) _AddControlForSubclass($idSlider) GUICtrlSetTip(-1, '#Region SLIDER') GUICtrlSetData(-1, 30) #EndRegion SLIDER #Region INPUT Local $idInput2 = GUICtrlCreateInput("Sample Input Box", 235, 255, 130, 20) _AddControlForSubclass($idInput2) GUICtrlSetTip(-1, '#Region INPUT') #EndRegion INPUT #Region DATE $g_idDate = GUICtrlCreateDate("", 5, 280, 200, 20) $g_hDate = GUICtrlGetHandle($g_idDate) _AddControlForSubclass($g_idDate) GUICtrlSetTip(-1, '#Region DATE') GUICtrlCreateLabel("(Date control expands into a calendar)", 10, 305, 200, 20) #EndRegion DATE #Region BUTTON Local $idButton = GUICtrlCreateButton("Sample Button", 10, 330, 100, 30) _AddControlForSubclass($idButton) GUICtrlSetTip(-1, '#Region BUTTON') #EndRegion BUTTON #Region CHECKBOX Local $idCheckBox = GUICtrlCreateCheckbox("Checkbox", 130, 335, 80, 20) GUICtrlSetTip(-1, '#Region CHECKBOX') GUICtrlSetState(-1, $GUI_CHECKED) _WinAPI_SetWindowTheme(GUICtrlGetHandle($idCheckBox), "DarkMode_DarkTheme", 0) #EndRegion CHECKBOX #Region TREEVIEW ONE Local $idTreeView1 = GUICtrlCreateTreeView(210, 290, 80, 80) _AddControlForSubclass($idTreeView1) GUICtrlSetBkColor($idTreeView1, $COLOR_EDIT_BG) GUICtrlSetColor($idTreeView1, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region TREEVIEW ONE') Local $idTreeViewItem = GUICtrlCreateTreeViewItem("TreeView", $idTreeView1) GUICtrlCreateTreeViewItem("Item1", $idTreeViewItem) GUICtrlCreateTreeViewItem("Item2", $idTreeViewItem) GUICtrlCreateTreeViewItem("Foo", -1) GUICtrlSetState($idTreeViewItem, $GUI_EXPAND) #EndRegion TREEVIEW ONE #Region TREEVIEW TWO Local $idTreeView2 = GUICtrlCreateTreeView(295, 290, 103, 80, $TVS_CHECKBOXES) _AddControlForSubclass($idTreeView2) GUICtrlSetBkColor($idTreeView2, $COLOR_EDIT_BG) GUICtrlSetColor($idTreeView2, $COLOR_TEXT_LIGHT) GUICtrlSetTip(-1, '#Region TREEVIEW TWO') GUICtrlCreateTreeViewItem("TreeView", $idTreeView2) GUICtrlCreateTreeViewItem("With", $idTreeView2) GUICtrlCreateTreeViewItem("$TVS_CHECKBOXES", $idTreeView2) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlCreateTreeViewItem("Style", $idTreeView2) _SetDarkTreeViewCheckboxes(GUICtrlGetHandle($idTreeView2), 16, 16) #EndRegion TREEVIEW TWO #Region Statusbar Local $hStatusbar = _GUICtrlStatusBar_Create($g_hGUI) _AddControlHandleForSubclass($hStatusbar) Local $aParts[4] = [75, 150, 300, 400] _GUICtrlStatusBar_SetParts($hStatusbar, $aParts) _GUICtrlStatusBar_SetText($hStatusbar, "Part 0", 0) _GUICtrlStatusBar_SetText($hStatusbar, "Part 1", 1) _GUICtrlStatusBar_SetText($hStatusbar, "Part 2", 2) _GUICtrlStatusBar_SetText($hStatusbar, "Part 3", 3) #EndRegion Statusbar ; Apply Dark Mode _ApplyDarkModeToAllControls() ; Handle scrollbars for windows that have them _EnableDarkScrollBars() ; Register a custom window procedure for the tab control for owner-drawing $g_hTab_CB = DllCallbackRegister('_WinProc', 'ptr', 'hwnd;uint;wparam;lparam') $g_pTab_CB = DllCallbackGetPtr($g_hTab_CB) $g_hProc = _WinAPI_SetWindowLong($g_hTab, $GWL_WNDPROC, $g_pTab_CB) ; Register a custom window procedure for the date control for owner-drawing $g_hDateProc_CB = DllCallbackRegister('_DateProc', 'ptr', 'hwnd;uint;wparam;lparam') $g_pDateProc_CB = DllCallbackGetPtr($g_hDateProc_CB) $g_hDateOldProc = _WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_pDateProc_CB) $g_AboutDummy = GUICtrlCreateDummy() GUISetState(@SW_SHOW) _OverpaintWhiteLine() _WinAPI_RedrawWindow($g_hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) While 1 Switch GUIGetMsg() Case $GUI_EVENT_RESTORE _WinAPI_RedrawWindow($g_hGUI, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ERASE, $RDW_ALLCHILDREN)) Case $GUI_EVENT_CLOSE _CleanupSubclassing() _CleanupBrushes() ExitLoop Case $g_AboutDummy MsgBox($MB_SYSTEMMODAL, "About", "Example coded by UEZ :-)", 10, $g_hGUI) EndSwitch WEnd ; Restore the original window procedure for the tab control _WinAPI_SetWindowLong($g_hTab, $GWL_WNDPROC, $g_hProc) DllCallbackFree($g_hTab_CB) _WinAPI_SetWindowLong($g_hDate, $GWL_WNDPROC, $g_hDateOldProc) DllCallbackFree($g_hDateProc_CB) GUIDelete() EndFunc ;==>_Example Func _GDIPlus_DrawRoundRect($hGfx, $iX, $iY, $iW, $iH, $iDiameter, $iBrushARGB, $iPenARGB, $fPenWidth = 1.0) Local Const $hPath = _GDIPlus_PathCreate() ; Top-left arc _GDIPlus_PathAddArc($hPath, $iX, $iY, $iDiameter, $iDiameter, 180, 90) ; Top-right arc _GDIPlus_PathAddArc($hPath, $iX + $iW - $iDiameter, $iY, $iDiameter, $iDiameter, 270, 90) ; Bottom-right arc _GDIPlus_PathAddArc($hPath, $iX + $iW - $iDiameter, $iY + $iH - $iDiameter, $iDiameter, $iDiameter, 0, 90) ; Bottom-left arc _GDIPlus_PathAddArc($hPath, $iX, $iY + $iH - $iDiameter, $iDiameter, $iDiameter, 90, 90) _GDIPlus_PathCloseFigure($hPath) If $iBrushARGB <> 0 Then Local Const $hBrush = _GDIPlus_BrushCreateSolid($iBrushARGB) _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush) _GDIPlus_BrushDispose($hBrush) EndIf If $iPenARGB <> 0 Then Local Const $hPen = _GDIPlus_PenCreate($iPenARGB, $fPenWidth) _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen) _GDIPlus_PenDispose($hPen) EndIf _GDIPlus_PathDispose($hPath) EndFunc ;==>_GDIPlus_DrawRoundRect Func _SetDarkTreeViewCheckboxes($hTreeView, $iW = 16, $iH = 16) Local $hImageList = _GUIImageList_Create($iW, $iH, 5, 3) Local $hBmp = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hBmp) _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ; --- Index 0: Unchecked --- _GDIPlus_GraphicsClear($hGfx, 0xFF000000 + $COLOR_EDIT_BG) _GDIPlus_DrawRoundRect($hGfx, 2 / 16 * $iW, 2 / 16 * $iH, 12 / 16 * $iW, 12 / 16 * $iH, 3, 0, 0xFF000000 + $COLOR_BORDER2, 1.5) Local $hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp, 0) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) ; --- Index 1: Checked --- _GDIPlus_GraphicsClear($hGfx, 0xFF000000 + $COLOR_EDIT_BG) _GDIPlus_DrawRoundRect($hGfx, 2 / 16 * $iW, 2 / 16 * $iH, 12 / 16 * $iW, 12 / 16 * $iH, 3, 0xFF60CDFF, 0xFF60CDFF, 1.0) Local $hCheckPen = _GDIPlus_PenCreate(0xFF0F2028, 1.5) _GDIPlus_GraphicsDrawLine($hGfx, 5 / 16 * $iW, 8 / 16 * $iH, 7 / 16 * $iW, 10 / 16 * $iH, $hCheckPen) _GDIPlus_GraphicsDrawLine($hGfx, 7 / 16 * $iW, 10 / 16 * $iH, 11 / 16 * $iW, 6 / 16 * $iH, $hCheckPen) $hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp, 0) _GUIImageList_Add($hImageList, $hBmp_GDI) _WinAPI_DeleteObject($hBmp_GDI) ; --- Cleanup --- _GDIPlus_PenDispose($hCheckPen) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_ImageDispose($hBmp) _GUICtrlTreeView_SetStateImageList($hTreeView, $hImageList) Return True EndFunc ;==>_SetDarkTreeViewCheckboxes Func _EnableMenuHotTrack($hMenu) If Not $hMenu Then Return False Local $tagMENUINFO = "dword cbSize;dword fMask;dword dwStyle;uint cyMax;handle hbrBack;dword dwContextHelpID;ulong_ptr dwMenuData" Local Const $MIM_STYLE = 0x00000010 Local Const $MNS_HOTTRACK = 0x08000000 Local $tMI = DllStructCreate($tagMENUINFO) With $tMI .cbSize = DllStructGetSize($tMI) .fMask = $MIM_STYLE .dwStyle = $MNS_HOTTRACK EndWith _GUICtrlMenu_SetMenuInfo($hMenu, $tMI) ; redraw menus _GUICtrlMenu_DrawMenuBar($g_hGUI) Return True EndFunc ;==>_EnableMenuHotTrack Func _OverpaintWhiteLine() Local $hDC = _WinAPI_GetWindowDC($g_hGUI) If Not $hDC Then Return Local $tWndRect = _WinAPI_GetWindowRect($g_hGUI) Local $iWndWidth = $tWndRect.right - $tWndRect.left ; 1. Caption height Local $iCaptionHeight = _WinAPI_GetSystemMetrics($SM_CYCAPTION) ; 2. Border height (top) Local $iBorderHeight = _WinAPI_GetSystemMetrics($SM_CYSIZEFRAME) If $iBorderHeight = 0 Then $iBorderHeight = _WinAPI_GetSystemMetrics($SM_CYFIXEDFRAME) ; 3. Determine menu height dynamically Local $iMenuHeight = _WinAPI_GetSystemMetrics($SM_CYMENU) ; standard menu height ; Alternative: get menu height via GetMenuBarInfo Local $tMenuBarInfo = DllStructCreate("dword cbSize;long left;long top;long right;long bottom;handle hwndMenu;handle hwndItem;bool fBarFocused;bool fFocused") DllStructSetData($tMenuBarInfo, "cbSize", DllStructGetSize($tMenuBarInfo)) Local $aResult = DllCall("user32.dll", "bool", "GetMenuBarInfo", "hwnd", $g_hGUI, "long", 0xFFFFFFFD, "long", 0, "ptr", DllStructGetPtr($tMenuBarInfo)) If IsArray($aResult) And $aResult[0] Then ; Calculate the actual menu height from the coordinates Local $iMenuTop = $tMenuBarInfo.top Local $iMenuBottom = $tMenuBarInfo.bottom ; Convert to window coordinates $iMenuHeight = ($iMenuBottom - $iMenuTop) EndIf ; The white line is directly below the menu Local $iWhiteLineY = $iCaptionHeight + $iBorderHeight + $iMenuHeight - _WinAPI_GetSystemMetrics($SM_CYFIXEDFRAME) * 2 ; Overpaint the white line (1x2 pixels) Local $tRect = DllStructCreate($tagRECT) With $tRect .left = 0 .top = $iWhiteLineY .right = $iWndWidth .bottom = $iWhiteLineY + 2 ; 2 pixels high EndWith Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) _WinAPI_FillRect($hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) _WinAPI_ReleaseDC($g_hGUI, $hDC) EndFunc ;==>_OverpaintWhiteLine Func _ColorToCOLORREF($iColor) ;RGB to BGR Local $iR = BitAND(BitShift($iColor, 16), 0xFF) Local $iG = BitAND(BitShift($iColor, 8), 0xFF) Local $iB = BitAND($iColor, 0xFF) Return BitOR(BitShift($iB, -16), BitShift($iG, -8), $iR) EndFunc ;==>_ColorToCOLORREF Func _AddControlForSubclass($iCtrlID) Local $hCtrl = GUICtrlGetHandle($iCtrlID) If $hCtrl Then $g_aControls[$g_iControlCount][0] = $iCtrlID $g_aControls[$g_iControlCount][1] = $hCtrl $g_aControls[$g_iControlCount][2] = 0 ; Placeholder for OldWndProc $g_iControlCount += 1 EndIf EndFunc ;==>_AddControlForSubclass Func _AddControlHandleForSubclass($hCtrl) If $hCtrl Then $g_aControls[$g_iControlCount][0] = 0 $g_aControls[$g_iControlCount][1] = $hCtrl $g_aControls[$g_iControlCount][2] = 0 $g_iControlCount += 1 EndIf EndFunc ;==>_AddControlHandleForSubclass Func _ApplyDarkModeToAllControls() ; DWM Dark Mode for the main window _WinAPI_SetPreferredAppMode($APPMODE_FORCEDARK) ; Create subclass callback If Not $g_pSubclassProc Then $g_pSubclassProc = DllCallbackRegister("_SubclassProc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") ; Subclass all controls Local $hCtrl, $sClass, $hEdit, $hComboLBox, $hHeader, $hUpDown For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If $hCtrl Then $sClass = _WinAPI_GetClassName($hCtrl) ; Use SetWindowSubclass _WinAPI_SetWindowSubclass($hCtrl, DllCallbackGetPtr($g_pSubclassProc), $i, 0) ; Special themes for different control types Switch StringLower($sClass) Case "edit", "richedit", "richedit20a", "richedit20w" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_CFD", 0) Case "button" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "combobox" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_CFD", 0) ; Handle ComboBox child-edit $hEdit = _WinAPI_FindWindowEx($hCtrl, 0, "Edit", "") If $hEdit Then _WinAPI_SetWindowTheme($hEdit, "DarkMode_CFD", 0) _WinAPI_AllowDarkModeForWindow($hEdit, True) EndIf ; ComboBox dropdown list $hComboLBox = _WinAPI_FindWindowEx($hCtrl, 0, "ComboLBox", "") If $hComboLBox Then _WinAPI_SetWindowTheme($hComboLBox, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hComboLBox, True) EndIf Case "syslistview32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) ; ListView extended styles for better dark mode _SendMessage($hCtrl, $LVS_EX_DOUBLEBUFFER, 0x00010000, 0x00010000) ; Also make the ListView header dark $hHeader = _SendMessage($hCtrl, $LVM_GETHEADER, 0, 0) If $hHeader Then _WinAPI_SetWindowTheme($hHeader, "DarkMode_ItemsView", 0) EndIf Case "systreeview32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "msctls_trackbar32" ; Slider _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "systabcontrol32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", "") ;must be "" ; tab-Control background _SendMessage($hCtrl, 0x132D, 0, $COLOR_BG_DARK) ; TCM_SETBKCOLOR ; Try to make the UpDown (spinner for too many tabs) dark as well $hUpDown = _WinAPI_FindWindowEx($hCtrl, 0, "msctls_updown32", "") If $hUpDown Then _WinAPI_SetWindowTheme($hUpDown, "DarkMode_Explorer", 0) Case "listbox" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "msctls_progress32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_CopyEngine", 0) Case "scrollbar" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) Case "sysdatetimepick32" ;~ ConsoleWrite(_WinAPI_SetWindowTheme($hCtrl, "Explorer", 0) & @CRLF) ;~ _WinAPI_AllowDarkModeForWindow($hCtrl, True) Case "msctls_statusbar32" _WinAPI_SetWindowTheme($hCtrl, "DarkMode_DarkTheme", 0) Case Else _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) EndSwitch _WinAPI_AllowDarkModeForWindow($hCtrl, True) EndIf Next ; Update theme system _WinAPI_RefreshImmersiveColorPolicyState() _WinAPI_FlushMenuThemes() _WinAPI_DwmSetWindowAttribute($g_hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True) ; Redraw GUI _WinAPI_RedrawWindow($g_hGUI, 0, 0, $RDW_UPDATENOW) EndFunc ;==>_ApplyDarkModeToAllControls Func _CleanupSubclassing() ; Remove all subclasses If $g_pSubclassProc Then Local $hCtrl For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If $hCtrl Then _WinAPI_RemoveWindowSubclass($hCtrl, DllCallbackGetPtr($g_pSubclassProc), $i) EndIf Next DllCallbackFree($g_pSubclassProc) $g_pSubclassProc = 0 EndIf EndFunc ;==>_CleanupSubclassing Func _SubclassProc($hWnd, $iMsg, $wParam, $lParam, $iID, $pData) Switch $iMsg Case $WM_NOTIFY Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Local $hFrom = $tNMHDR.hWndFrom Local $iCode = $tNMHDR.Code If $iCode = $NM_CUSTOMDRAW Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwStage = $tNMCD.dwDrawStage Local $hDC = $tNMCD.hdc Switch StringLower(_WinAPI_GetClassName($hFrom)) Case "sysheader32" Switch $dwStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) _WinAPI_SetBkColor($hDC, _ColorToCOLORREF($COLOR_BG_DARK)) Return BitOR($CDRF_NEWFONT, $CDRF_NOTIFYPOSTPAINT) EndSwitch EndSwitch EndIf Case $WM_PAINT Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) ; <- gehört zu Case $WM_PAINT EndSwitch Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_SubclassProc Func _DateProc($hWnd, $iMsg, $wParam, $lParam) Switch $iMsg Case $WM_PAINT Local $tPaint = DllStructCreate($tagPAINTSTRUCT) Local $hDC = _WinAPI_BeginPaint($hWnd, $tPaint) Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iW = $tClient.Right Local $iH = $tClient.Bottom ; --- Memory DC for flicker-free rendering --- Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hOldBmp = _WinAPI_SelectObject($hMemDC, $hBitmap) ; 1. Let Windows draw the light-mode control into memory DC _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $WM_PRINTCLIENT, $hMemDC, $PRF_CLIENT) ; 2. Invert all pixels (background becomes black, text white, selection orange) Local $tRect = DllStructCreate($tagRECT) $tRect.right = $iW $tRect.bottom = $iH _WinAPI_InvertRect($hMemDC, $tRect) ; --- 3. PIXEL HACK: destroy orange highlight & set background color --- Local $iSize = $iW * $iH Local $tPixels = DllStructCreate("dword c[" & $iSize & "]") ; Load pixel array directly from bitmap memory Local $iBytes = DllCall("gdi32.dll", "long", "GetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels))[0] If $iBytes = $iSize * 4 Then Local $iPixel, $r, $g, $b, $iGray For $i = 1 To $iSize $iPixel = $tPixels.c(($i)) ; Split into color channels $b = BitAND($iPixel, 0xFF) $g = BitAND(BitShift($iPixel, 8), 0xFF) $r = BitAND(BitShift($iPixel, 16), 0xFF) ; Convert to grayscale (orange becomes mid-gray) $iGray = Int(($r + $g + $b) / 3) ; Very dark pixel = inverted white background If $iGray < 15 Then $iPixel = $COLOR_BG_DARK ; Replace with exact GUI background color Else ; Grayscale value for text (white) and selection (gray) ; (negative BitShift shifts left in AutoIt) $iPixel = BitOR(BitShift($iGray, -16), BitShift($iGray, -8), $iGray) EndIf $tPixels.c(($i)) = $iPixel Next ; Write cleaned pixels back into the bitmap DllCall("gdi32.dll", "long", "SetBitmapBits", "handle", $hBitmap, "long", $iSize * 4, "ptr", DllStructGetPtr($tPixels)) EndIf ; --- END PIXEL HACK --- ; --- Border color (hover effect) --- Local $iBorderColor = $COLOR_BORDER If _WinAPI_GetFocus() = $hWnd Then $iBorderColor = $COLOR_BORDER Local $tCursorPos = DllStructCreate($tagPOINT) DllCall("user32.dll", "bool", "GetCursorPos", "struct*", $tCursorPos) DllCall("user32.dll", "bool", "ScreenToClient", "hwnd", $hWnd, "struct*", $tCursorPos) If $tCursorPos.X >= 0 And $tCursorPos.X <= $iW And $tCursorPos.Y >= 0 And $tCursorPos.Y <= $iH Then $iBorderColor = $COLOR_BORDER_LIGHT EndIf ; --- Draw border --- Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($iBorderColor)) Local $hNullBr = _WinAPI_GetStockObject(5) Local $hOldPen = _WinAPI_SelectObject($hMemDC, $hPen) Local $hOldBr = _WinAPI_SelectObject($hMemDC, $hNullBr) DllCall("gdi32.dll", "bool", "Rectangle", "handle", $hMemDC, "int", 0, "int", 0, "int", $iW, "int", $iH) _WinAPI_SelectObject($hMemDC, $hOldPen) _WinAPI_SelectObject($hMemDC, $hOldBr) _WinAPI_DeleteObject($hPen) ; --- Copy finished result to screen in one step (no flicker) --- _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hMemDC, 0, 0, $SRCCOPY) ; --- Cleanup --- _WinAPI_SelectObject($hMemDC, $hOldBmp) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_EndPaint($hWnd, $tPaint) Return 0 Case $WM_ERASEBKGND Return 1 Case $WM_SETFOCUS, $WM_KILLFOCUS Local $iRet = _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) _WinAPI_InvalidateRect($hWnd, 0, False) Return $iRet Case $WM_MOUSEMOVE Local $iRet = _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) If Not $g_bHover Then $g_bHover = True _WinAPI_InvalidateRect($hWnd, 0, False) EndIf Return $iRet Case $WM_MOUSELEAVE $g_bHover = False _WinAPI_InvalidateRect($hWnd, 0, False) EndSwitch Return _WinAPI_CallWindowProc($g_hDateOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_DateProc Func _MakeMenuOwnerDraw($hWnd) ; Get menu handle $g_hMenu = _GUICtrlMenu_GetMenu($hWnd) If Not $g_hMenu Then Return False Local $iCount = _GUICtrlMenu_GetItemCount($g_hMenu) If $iCount <= 0 Then Return False ReDim $g_aMenuText[$iCount] Local $tText, $iLen For $i = 0 To $iCount - 1 ; retrieve text via GetMenuStringW (works better than _GUICtrlMenu_GetItemText) $tText = DllStructCreate("wchar s[256]") $iLen = DllCall("user32.dll", "int", "GetMenuStringW", "handle", $g_hMenu, "uint", $i, "struct*", $tText, "int", 255, "uint", $MF_BYPOSITION) If IsArray($iLen) And $iLen[0] > 0 Then $g_aMenuText[$i] = $tText.s Else $g_aMenuText[$i] = "" EndIf ; set top-level item to owner-draw _GUICtrlMenu_SetItemType($g_hMenu, $i, $MFT_OWNERDRAW, True) Next ; redraw menu bar immediately _GUICtrlMenu_DrawMenuBar($hWnd) _WinAPI_RedrawWindow($hWnd, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW)) Return True EndFunc ;==>_MakeMenuOwnerDraw Func _WM_MEASUREITEM($hWnd, $iMsg, $wParam, $lParam) Local $tagMEASUREITEM = "uint CtlType;uint CtlID;uint itemID;uint itemWidth;uint itemHeight;ulong_ptr itemData" Local $t = DllStructCreate($tagMEASUREITEM, $lParam) If Not IsDllStruct($t) Then Return $GUI_RUNDEFMSG If $t.CtlType <> $ODT_MENU Then Return $GUI_RUNDEFMSG Local $itemID = $t.itemID ; itemID is the control ID, not the position! ; We must derive the position from the itemID Local $iPos = -1 For $i = 0 To UBound($g_aMenuText) - 1 If $itemID = ($i + 3) Then ; Offset of 3 due to internal IDs $iPos = $i ExitLoop EndIf Next ; Fallback: try the itemID directly If $iPos < 0 Then $iPos = $itemID If $iPos < 0 Or $iPos >= UBound($g_aMenuText) Then $iPos = 0 Local $sText = $g_aMenuText[$iPos] ; Calculate text dimensions Local $hDC = _WinAPI_GetDC($hWnd) Local $hFont = _SendMessage($hWnd, $WM_GETFONT, 0, 0) If Not $hFont Then $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) Local $tSize = _WinAPI_GetTextExtentPoint32($hDC, $sText) Local $iTextWidth = $tSize.X Local $iTextHeight = $tSize.Y _WinAPI_SelectObject($hDC, $hOldFont) _WinAPI_ReleaseDC($hWnd, $hDC) ; Set dimensions with padding $t.itemWidth = $iTextWidth + 1 $t.itemHeight = $iTextHeight + 1 Return 1 EndFunc ;==>_WM_MEASUREITEM Func _WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam) Local $tagDRAWITEM = "uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;ptr hwndItem;handle hDC;" & _ "long left;long top;long right;long bottom;ulong_ptr itemData" Local $t = DllStructCreate($tagDRAWITEM, $lParam) If Not IsDllStruct($t) Then Return $GUI_RUNDEFMSG If $t.CtlType <> $ODT_MENU Then Return $GUI_RUNDEFMSG Local $hDC = $t.hDC Local $left = $t.left Local $top = $t.top Local $right = $t.right Local $bottom = $t.bottom Local $state = $t.itemState Local $itemID = $t.itemID ; convert itemID to position Local $iPos = -1 For $i = 0 To UBound($g_aMenuText) - 1 If $itemID = ($i + 3) Then $iPos = $i ExitLoop EndIf Next If $iPos < 0 Then $iPos = $itemID If $iPos < 0 Or $iPos >= UBound($g_aMenuText) Then $iPos = 0 Local $sText = $g_aMenuText[$iPos] $sText = StringReplace($sText, "&", "") ; Colors Local $clrBG = _ColorToCOLORREF($COLOR_BG_DARK) Local $clrSel = _ColorToCOLORREF(0x505050) Local $clrText = _ColorToCOLORREF($COLOR_TEXT_LIGHT) Static $iDrawCount = 0 Static $bFullBarDrawn = False ; Count how many items were drawn in this "draw cycle" $iDrawCount += 1 ; If we are at the first item AND the bar has not yet been drawn If $iPos = 0 And Not $bFullBarDrawn Then ; Get the full window width Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iFullWidth = $tClient.right ; Fill the entire menu bar Local $tFullMenuBar = DllStructCreate($tagRECT) With $tFullMenuBar .left = 0 .top = $top .right = $iFullWidth + 3 .bottom = $bottom EndWith Local $hFullBrush = _WinAPI_CreateSolidBrush($clrBG) _WinAPI_FillRect($hDC, $tFullMenuBar, $hFullBrush) _WinAPI_DeleteObject($hFullBrush) EndIf ; After drawing all items, mark as "drawn" If $iDrawCount >= UBound($g_aMenuText) Then $bFullBarDrawn = True $iDrawCount = 0 EndIf ; Draw background for the area AFTER the last menu item If $iPos = (UBound($g_aMenuText) - 1) Then ; Last menu Local $tClient = _WinAPI_GetClientRect($hWnd) Local $iFullWidth = $tClient.right ; Fill only the area to the RIGHT of the last menu item If $right < $iFullWidth Then Local $tEmptyArea = DllStructCreate($tagRECT) With $tEmptyArea .left = $right .top = $top .right = $iFullWidth + _WinAPI_GetSystemMetrics(7) .bottom = $bottom EndWith Local $hEmptyBrush = _WinAPI_CreateSolidBrush($clrBG) _WinAPI_FillRect($hDC, $tEmptyArea, $hEmptyBrush) _WinAPI_DeleteObject($hEmptyBrush) EndIf EndIf ; Draw item background (selected = lighter) Local $bSelected = BitAND($state, $ODS_SELECTED) Local $bHot = BitAND($state, $ODS_HOTLIGHT) Local $hBrush If $bSelected Then $hBrush = _WinAPI_CreateSolidBrush($clrSel) ElseIf $bHot Then $hBrush = _WinAPI_CreateSolidBrush($COLOR_HOTTRACK_MENU) Else $hBrush = _WinAPI_CreateSolidBrush($clrBG) EndIf Local $tItemRect = DllStructCreate($tagRECT) With $tItemRect .left = $left .top = $top .right = $right .bottom = $bottom EndWith _WinAPI_FillRect($hDC, $tItemRect, $hBrush) _WinAPI_DeleteObject($hBrush) ; Setup font Local $hFont = _SendMessage($hWnd, $WM_GETFONT, 0, 0) If Not $hFont Then $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont) _WinAPI_SetBkMode($hDC, $TRANSPARENT) _WinAPI_SetTextColor($hDC, $clrText) ; Draw text Local $tTextRect = DllStructCreate($tagRECT) With $tTextRect .left = $left + 10 .top = $top + 4 .right = $right - 10 .bottom = $bottom - 4 EndWith DllCall("user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $sText, "int", -1, "ptr", DllStructGetPtr($tTextRect), "uint", BitOR($DT_SINGLELINE, $DT_VCENTER, $DT_LEFT)) If $hOldFont Then _WinAPI_SelectObject($hDC, $hOldFont) Return 1 EndFunc ;==>_WM_DRAWITEM Func _WM_CTLCOLOR($hWnd, $iMsg, $wParam, $lParam) Local $hDC = $wParam Local $hCtrl = $lParam ; If the control is the special green label -> return green background If $hCtrl = $g_hLabelGreen Then ; black text on a green background _WinAPI_SetTextColor($hDC, _ColorToCOLORREF(0x000000)) _WinAPI_SetBkColor($hDC, _ColorToCOLORREF(0x00FF00)) _WinAPI_SetBkMode($hDC, $OPAQUE) ; important, otherwise it remains transparent and you cannot see the background If $g_hBrushGreen Then Return $g_hBrushGreen EndIf ; --- Special case: Make "Sample Pic" label transparent --- If $hCtrl = $g_hLabelPic Then ; set transparent background _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; set text color (if necessary) - e.g., white _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) ; return NULL_BRUSH (stock object), so Windows does NOT fill with your dark brush Local $hNull = _WinAPI_GetStockObject(5) ; 5 = NULL_BRUSH If $hNull Then Return $hNull ; Fallback if not available: Return $GUI_RUNDEFMSG EndIf ; --- Default behavior for all other statics / controls --- _WinAPI_SetTextColor($hDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) Local $hBrush = $g_hBrushEdit Local $iColor = $COLOR_EDIT_BG Switch $iMsg Case $WM_CTLCOLORBTN $hBrush = $g_hBrushButton $iColor = $COLOR_BUTTON_BG Case $WM_CTLCOLORSTATIC $hBrush = $g_hBrushBg $iColor = $COLOR_BG_DARK EndSwitch _WinAPI_SetBkColor($hDC, _ColorToCOLORREF($iColor)) _WinAPI_SetBkMode($hDC, $TRANSPARENT) Return $hBrush EndFunc ;==>_WM_CTLCOLOR Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $tBuffer, $tBuffer2, $iCtrl $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd($tNMHDR.hWndFrom) $iIDFrom = $tNMHDR.IDFrom $iCode = $tNMHDR.Code ; --- Slider (msctls_trackbar32) custom drawing --- If $iCode = $NM_CUSTOMDRAW And StringLower(_WinAPI_GetClassName($hWndFrom)) = "msctls_trackbar32" Then Local $tNMCD = DllStructCreate($tagNMCUSTOMDRAW, $lParam) Local $dwStage = $tNMCD.dwDrawStage Local $hDC = $tNMCD.hdc Local $dwItemSpec = $tNMCD.dwItemSpec Switch $dwStage Case $CDDS_PREPAINT ; Remove focus rectangle from slider DllStructSetData($tNMCD, 'ItemState', BitXOR(DllStructGetData($tNMCD, 'ItemState'), $CDIS_FOCUS)) Return $CDRF_NOTIFYITEMDRAW ; request per-item notifications Case $CDDS_ITEMPREPAINT Local Const $TBCD_TICS = 0x0001 ; tick marks Local Const $TBCD_THUMB = 0x0002 ; draggable thumb Local Const $TBCD_CHANNEL = 0x0003 ; slider channel/track Local $tRect = DllStructCreate($tagRECT) $tRect.left = $tNMCD.left $tRect.top = $tNMCD.top $tRect.right = $tNMCD.right $tRect.bottom = $tNMCD.bottom Switch $dwItemSpec Case $TBCD_TICS ; Let Windows draw tick marks normally Return $CDRF_DODEFAULT Case $TBCD_THUMB ; Draw thumb as a pentagon (rectangle + downward arrow) Local $iL = $tNMCD.left Local $iT = $tNMCD.top Local $iR = $tNMCD.right - 1 ; -1 to stay within bounds and avoid paint artifacts Local $iB = $tNMCD.bottom Local $iMid = ($iL + $iR) / 2 ; horizontal center (tip of arrow) Local $iSplit = $iB - ($iR - $iL) / 2 ; y-position where rectangle ends and arrow begins ; Pentagon points: top-left, top-right, right-middle, bottom-tip, left-middle Local $tPoints = DllStructCreate("int p[10]") $tPoints.p((1)) = $iL $tPoints.p((2)) = $iT $tPoints.p((3)) = $iR $tPoints.p((4)) = $iT $tPoints.p((5)) = $iR $tPoints.p((6)) = $iSplit $tPoints.p((7)) = $iMid $tPoints.p((8)) = $iB $tPoints.p((9)) = $iL $tPoints.p((10)) = $iSplit ; Fill and outline thumb with blue accent color Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF(0x0078D4)) Local $hPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_CONTROL_BG)) Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush) Local $hOldPen = _WinAPI_SelectObject($hDC, $hPen) DllCall("gdi32.dll", "bool", "Polygon", "handle", $hDC, "struct*", $tPoints, "int", 5) _WinAPI_SelectObject($hDC, $hOldBrush) _WinAPI_SelectObject($hDC, $hOldPen) _WinAPI_DeleteObject($hBrush) _WinAPI_DeleteObject($hPen) Return $CDRF_SKIPDEFAULT ; skip default drawing Case $TBCD_CHANNEL ; Fill channel with border color Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BORDER)) _WinAPI_FillRect($hDC, $tRect, $hBrush) _WinAPI_DeleteObject($hBrush) Return $CDRF_SKIPDEFAULT ; skip default drawing EndSwitch EndSwitch EndIf ; --- Per-control notification handling --- Local Static $iTheme Switch $hWndFrom Case $g_hDate ; thanks to argumentum for the code :-) Switch $iCode Case $NM_SETFOCUS ; Disable visual theme when DateTime control receives focus _WinAPI_SetThemeAppProperties(0) Case $NM_KILLFOCUS _WinAPI_SetThemeAppProperties($iTheme) ; argumentum Case $DTN_DROPDOWN ; Apply dark colors when the calendar dropdown opens _WinAPI_SetWindowTheme($iCtrl, "", "") Local $iCtrl = _GUICtrlDTP_GetMonthCal($hWndFrom) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TEXT, $COLOR_TEXT_LIGHT) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TITLEBK, $COLOR_BG_DARK) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TITLETEXT, $COLOR_TEXT_LIGHT) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_MONTHBK, $COLOR_BG_DARK) _GUICtrlMonthCal_SetColor($iCtrl, $MCSC_TRAILINGTEXT, $COLOR_TEXT_LIGHT) Case $DTN_CLOSEUP ; Calendar dropdown closed - no action needed EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_NOTIFY Func _WM_ACTIVATE($hWnd, $iMsg, $wParam, $lParam) If $hWnd <> $g_hGUI Then Return $GUI_RUNDEFMSG _OverpaintWhiteLine() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_ACTIVATE Func _WM_WINDOWPOSCHANGED($hWnd, $iMsg, $wParam, $lParam) If $hWnd <> $g_hGUI Then Return $GUI_RUNDEFMSG _OverpaintWhiteLine() Return $GUI_RUNDEFMSG EndFunc ;==>_WM_WINDOWPOSCHANGED Func _WM_MENUCOMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg Local $iPos = $wParam ;Menu Item Position (0-based index) Local $hMenu = $lParam ;Menu Handle Switch $hMenu Case $g_hMenu1 ConsoleWrite("From Menu One" & @CRLF) Switch $iPos Case 0 ; SubMenu One A ConsoleWrite("SubMenu One A clicked" & @CRLF) Case 1 ; SubMenu One B ConsoleWrite("SubMenu One B clicked" & @CRLF) Case 2 ; About ConsoleWrite("About clicked!" & @CRLF) GUICtrlSendToDummy($g_AboutDummy) Return 0 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_MENUCOMMAND Func _WM_SYSCOMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam Switch BitAND($wParam, 0x0000FFFF) Case $idAbout GUICtrlSendToDummy($g_AboutDummy) EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>_WM_SYSCOMMAND Func _CleanupBrushes() ; Delete all brushes If $g_hBrushEdit Then _WinAPI_DeleteObject($g_hBrushEdit) If $g_hBrushButton Then _WinAPI_DeleteObject($g_hBrushButton) If $g_hBrushBg Then _WinAPI_DeleteObject($g_hBrushBg) If $g_hBrushGreen Then _WinAPI_DeleteObject($g_hBrushGreen) EndFunc ;==>_CleanupBrushes Func _EnableDarkScrollBars() ; Try to enable Dark Mode for all scrollbars (also for TreeView with checkboxes) Local $tScrollInfo, $sClass, $hCtrl, $hCtrl For $i = 0 To $g_iControlCount - 1 $hCtrl = $g_aControls[$i][1] If Not $hCtrl Then ContinueLoop ; 1ï¸ Normal attempt (works for most controls) $tScrollInfo = _GUIScrollBars_GetScrollInfoEx($hCtrl, 1) If IsDllStruct($tScrollInfo) Then _WinAPI_SetWindowTheme($hCtrl, "DarkMode_Explorer", 0) ; 2ï¸ Extension: If the control has its own scrollbar child windows (e.g., TreeView with $TVS_CHECKBOXES) $hChild = _WinAPI_GetWindow($hCtrl, $GW_CHILD) While $hChild $sClass = _WinAPI_GetClassName($hChild) If StringCompare($sClass, "ScrollBar") = 0 Then ; Set DarkMode on the ScrollBar itself _WinAPI_SetWindowTheme($hChild, "DarkMode_Explorer", 0) _WinAPI_AllowDarkModeForWindow($hChild, True) EndIf $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT) WEnd Next EndFunc ;==>_EnableDarkScrollBars Func _WinProc($hWnd, $iMsg, $wParam, $lParam) ; Custom window procedure for tab control with Dark Mode Switch $iMsg Case $WM_ERASEBKGND Return 1 ; Prevent background erase to avoid flicker Case $WM_PAINT Local $tPaint = DllStructCreate($tagPAINTSTRUCT) Local $hDC = DllCall("user32.dll", "handle", "BeginPaint", "hwnd", $hWnd, "struct*", $tPaint) If @error Or Not $hDC[0] Then Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam) $hDC = $hDC[0] ; Get client rectangle Local $tClient = _WinAPI_GetClientRect($hWnd) If Not IsDllStruct($tClient) Then _WinAPI_EndPaint($hWnd, $tPaint) Return 0 EndIf Local $iWidth = $tClient.Right Local $iHeight = $tClient.Bottom ; Create memory DC for double buffering Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC) Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight) Local $hOldBmp = _WinAPI_SelectObject($hMemDC, $hBitmap) ; Fill background but exclude overlapping GUI controls from painting Local $hParent = _WinAPI_GetParent($hWnd) Local $hChild = _WinAPI_GetWindow($hParent, $GW_CHILD) Local $tCR, $tPR = _WinAPI_GetWindowRect($hWnd) Local $left, $top, $right, $bottom While $hChild If $hChild <> $hWnd And _WinAPI_IsWindowVisible($hChild) Then $tCR = _WinAPI_GetWindowRect($hChild) ; Only exclude controls that lie fully within the tab control area If $tCR.left >= $tPR.left And $tCR.right <= $tPR.right And $tCR.top >= $tPR.top And $tCR.bottom <= $tPR.bottom Then $left = $tCR.left - $tPR.left $top = $tCR.top - $tPR.top $right = $tCR.right - $tPR.left $bottom = $tCR.bottom - $tPR.top ; Exclude from offscreen bitmap (prevents black fill) DllCall("gdi32.dll", "int", "ExcludeClipRect", "handle", $hMemDC, "int", $left, "int", $top, "int", $right, "int", $bottom) ; Exclude from screen DC (prevents BitBlt overwrite) DllCall("gdi32.dll", "int", "ExcludeClipRect", "handle", $hDC, "int", $left, "int", $top, "int", $right, "int", $bottom) EndIf EndIf $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT) WEnd ; Fill background Local $hBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($COLOR_BG_DARK)) _WinAPI_FillRect($hMemDC, $tClient, $hBrush) _WinAPI_DeleteObject($hBrush) ; Get tab info Local $iTabCount = _SendMessage($hWnd, $TCM_GETITEMCOUNT, 0, 0) Local $iCurSel = _SendMessage($hWnd, $TCM_GETCURSEL, 0, 0) ; Setup font Local $hFont = _SendMessage($hWnd, $WM_GETFONT, 0, 0) If Not $hFont Then $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT) Local $hOldFont = _WinAPI_SelectObject($hMemDC, $hFont) _WinAPI_SetBkMode($hMemDC, $TRANSPARENT) _WinAPI_SetTextColor($hMemDC, _ColorToCOLORREF($COLOR_TEXT_LIGHT)) ; Draw each tab Local $tRect, $tRect, $iLeft, $iTop, $iRight, $iBottom, $tItem, $tText, $bSelected, $iTabColor, $hTabBrush, $tTabRect, _ $sText, $hPen, $hOldPen, $hPenSep, $hOldPenSep, $tTextRect, $hBorderPen, $hOldBorderPen, $hNullBrush, $hOldBorderBrush For $i = 0 To $iTabCount - 1 ; Get tab rectangle using TCM_GETITEMRECT $tRect = DllStructCreate($tagRECT) $aResult = DllCall("user32.dll", "lresult", "SendMessageW", _ "hwnd", $hWnd, _ "uint", $TCM_GETITEMRECT, _ "wparam", $i, _ "struct*", $tRect) If @error Or Not $aResult[0] Then ContinueLoop $iLeft = $tRect.Left $iTop = $tRect.Top $iRight = $tRect.Right $iBottom = $tRect.Bottom ; Skip if rectangle is invalid If $iLeft >= $iRight Or $iTop >= $iBottom Then ContinueLoop ; Get tab text $tItem = DllStructCreate("uint Mask;dword dwState;dword dwStateMask;ptr pszText;int cchTextMax;int iImage;lparam lParam") $tText = DllStructCreate("wchar Text[256]") With $tItem .Mask = 0x0001 ; TCIF_TEXT .pszText = DllStructGetPtr($tText) .cchTextMax = 256 EndWith DllCall("user32.dll", "lresult", "SendMessageW", _ "hwnd", $hWnd, _ "uint", $TCM_GETITEMW, _ "wparam", $i, _ "struct*", $tItem) $sText = DllStructGetData($tText, "Text") ; Draw tab background $bSelected = ($i = $iCurSel) $iTabColor = $bSelected ? $COLOR_BUTTON_BG : $COLOR_BG_DARK $hTabBrush = _WinAPI_CreateSolidBrush(_ColorToCOLORREF($iTabColor)) $tTabRect = DllStructCreate($tagRECT) With $tTabRect .Left = $iLeft .Top = $iTop .Right = $iRight .Bottom = $iBottom EndWith _WinAPI_FillRect($hMemDC, $tTabRect, $hTabBrush) _WinAPI_DeleteObject($hTabBrush) ; Draw selection indicator (top border for selected tab) If $bSelected Then $hPen = _WinAPI_CreatePen(0, 2, _ColorToCOLORREF(0x0078D4)) ; Blue accent $hOldPen = _WinAPI_SelectObject($hMemDC, $hPen) _WinAPI_MoveTo($hMemDC, $iLeft, $iTop) _WinAPI_LineTo($hMemDC, $iRight - 2, $iTop) _WinAPI_SelectObject($hMemDC, $hOldPen) _WinAPI_DeleteObject($hPen) EndIf ; Draw separator between tabs If $i < $iTabCount - 1 Then $hPenSep = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) $hOldPenSep = _WinAPI_SelectObject($hMemDC, $hPenSep) _WinAPI_MoveTo($hMemDC, $iRight - 1, $iTop + 4) _WinAPI_LineTo($hMemDC, $iRight - 1, $iBottom - 4) _WinAPI_SelectObject($hMemDC, $hOldPenSep) _WinAPI_DeleteObject($hPenSep) EndIf ; Draw text centered in tab $tTextRect = DllStructCreate($tagRECT) With $tTextRect .Left = $iLeft + 6 .Top = $iTop + 3 .Right = $iRight - 6 .Bottom = $iBottom - 3 EndWith DllCall("user32.dll", "int", "DrawTextW", _ "handle", $hMemDC, _ "wstr", $sText, _ "int", -1, _ "struct*", $tTextRect, _ "uint", BitOR($DT_CENTER, $DT_VCENTER, $DT_SINGLELINE)) Next ; Draw border around entire control $hBorderPen = _WinAPI_CreatePen(0, 1, _ColorToCOLORREF($COLOR_BORDER)) $hOldBorderPen = _WinAPI_SelectObject($hMemDC, $hBorderPen) $hNullBrush = _WinAPI_GetStockObject(5) ; NULL_BRUSH $hOldBorderBrush = _WinAPI_SelectObject($hMemDC, $hNullBrush) DllCall("gdi32.dll", "bool", "Rectangle", "handle", $hMemDC, "int", 0, "int", 0, "int", $iWidth, "int", $iHeight) _WinAPI_SelectObject($hMemDC, $hOldBorderPen) _WinAPI_SelectObject($hMemDC, $hOldBorderBrush) _WinAPI_DeleteObject($hBorderPen) ; Copy to screen _WinAPI_BitBlt($hDC, 0, 0, $iWidth, $iHeight, $hMemDC, 0, 0, $SRCCOPY) ; Cleanup _WinAPI_SelectObject($hMemDC, $hOldFont) _WinAPI_SelectObject($hMemDC, $hOldBmp) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_EndPaint($hWnd, $tPaint) Return 0 EndSwitch Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_WinProc Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc ;==>_WinAPI_FindWindowEx #Region DarkMode API Func _WinAPI_ShouldAppsUseDarkMode() Local $aResult = DllCall("UxTheme.dll", "bool", 132) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_ShouldAppsUseDarkMode Func _WinAPI_AllowDarkModeForWindow($hWND, $bAllow = True) Local $aResult = DllCall("UxTheme.dll", "bool", 133, "hwnd", $hWND, "bool", $bAllow) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_AllowDarkModeForWindow Func _WinAPI_FlushMenuThemes() Local $aResult = DllCall("UxTheme.dll", "none", 136) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_FlushMenuThemes Func _WinAPI_RefreshImmersiveColorPolicyState() Local $aResult = DllCall("UxTheme.dll", "none", 104) If @error Then Return SetError(1, 0, False) Return True EndFunc ;==>_WinAPI_RefreshImmersiveColorPolicyState Func _WinAPI_IsDarkModeAllowedForWindow($hWND) Local $aResult = DllCall("UxTheme.dll", "bool", 137, "hwnd", $hWND) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_IsDarkModeAllowedForWindow Func _WinAPI_GetIsImmersiveColorUsingHighContrast($iIMMERSIVE_HC_CACHE_MODE) Local $aResult = DllCall("UxTheme.dll", "bool", 106, "long", $iIMMERSIVE_HC_CACHE_MODE) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_GetIsImmersiveColorUsingHighContrast Func _WinAPI_OpenNcThemeData($hWND, $tClassList) Local $aResult = DllCall("UxTheme.dll", "hwnd", 49, "hwnd", $hWND, "struct*", $tClassList) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_OpenNcThemeData Func _WinAPI_ShouldSystemUseDarkMode() Local $aResult = DllCall("UxTheme.dll", "bool", 138) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_ShouldSystemUseDarkMode Func _WinAPI_IsDarkModeAllowedForApp() Local $aResult = DllCall("UxTheme.dll", "bool", 139) If @error Then Return SetError(1, 0, False) Return ($aResult[0] <> 0) EndFunc ;==>_WinAPI_IsDarkModeAllowedForApp Func _WinAPI_AllowDarkModeForApp($bAllow = True) ;Windows 10 Build 17763 Return _WinAPI_SetPreferredAppMode($bAllow ? 1 : 0) ; 1 = AllowDark, 0 = Default EndFunc ;==>_WinAPI_AllowDarkModeForApp Func _WinAPI_SetPreferredAppMode($iPreferredAppMode) ;Windows 10 Build 18362+ Local $aResult = DllCall("UxTheme.dll", "long", 135, "long", $iPreferredAppMode) If @error Then Return SetError(1, 0, False) Return $aResult[0] EndFunc ;==>_WinAPI_SetPreferredAppMode #EndRegion DarkMode API Does anyone know how to switch the date picker to dark mode? -> made a fake date picker.
-
I enhanced the Delaunay function in my _GDIPlus_BitmapApplyFilter Dll and created a front-end GUI to generate Low-Polygon images: Code: ;Coded by UEZ v0.70build 2026-02-20 ;Requires 3.3.15.0+ version #AutoIt3Wrapper_Version=p #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_HiDpi=y #include <Array.au3> #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <EditConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <ScreenCapture.au3> #include <StaticConstants.au3> #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> #include "_GDIPlus_BitmapApplyFilter.au3" Global Const $hDLL = _GDIPlus_BitmapApplyFilter_Open("c:\_BZ25LN\Coding\FreeBASIC\__UEZ\__Projects\_GDIPlus_BitmapApplyFilter\_GDIPlus_BitmapApplyFilter_x64.dll") Global Const $sVer = _GDIPlus_BitmapApplyFilter_Ver2() Global $tokenVer = StringRegExpReplace($sVer, "v(.+?)\h+.+", "$1") Global $tokenBuild = StringRegExpReplace($sVer, ".+build\h+(.+?)\hbeta", "$1") If Not CheckVer($tokenVer, "1.0.0") Or $tokenBuild < "2026-02-19" Then MsgBox(16, "Error", "Requires at least DLL v1.0.0 build 2026-02-19." & @CRLF & "Found: " & $sVer) Exit EndIf Global Const $hGUI = GUICreate("Low-Polygon Maker v0.71", 252, 906, @DesktopWidth - 260, 10, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST)) GUISetFont(8, 400, 0, "Consolas") GUISetBkColor(0xABCDEF, $hGUI) Global $iInp_x = 96, $iInp_w = 100, $y = 60, $y2 = 92, $p Global Const $iLbl_Title = GUICtrlCreateLabel("Low-Polygon Maker", 0, 8, 238, 32, $SS_CENTER) GUICtrlSetFont(-1, 18, 400, 0, "Consolas") Global Const $iLbl_EdgeDetection = GUICtrlCreateLabel("Edge Detection", 4, $y, 88, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iCombo_EdgeDetection = GUICtrlCreateCombo("", 96, $y - 4, 145, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetData($iCombo_EdgeDetection, "SOBEL|" & _ "SCHARR|" & _ "PREWITT|" & _ "SOVELVSPREWITT|" & _ "FREI_CHEN|" & _ "ROBINSON_COMPASS|" & _ "KAYYALI|" & _ "ROBERTS_CROSS|" & _ "RIDGE_DETECTION|" & _ "DIAGONAL_EDGES|" & _ "OUTLINE3X3|" & _ "LAPLACE3x3_1|" & _ "LAPLACE3x3_2|" & _ "LAPLACE5x5|" & _ "EDGE_DETECTION1|" & _ "EDGE_DETECTION2|" & _ "EDGE_DETECTION3|" & _ "EDGE_DETECTION4|" & _ "EDGE_DETECTION5|" & _ "EDGE_DETECTION6|" & _ "EMBOSS1|" & _ "EMBOSS2|" & _ "EMBOSS3|" & _ "EMBOSS4|" & _ "KIRSCH|" & _ "ISOTROPIC_SOBEL", _ "ROBERTS_CROSS") $y += 36 Global $aRet = _GDIPlus_BitmapCreateVerticalText("Coded by UEZ 2026", 21.75, "Consolas", 0x380000FF, 0x28000000, 2, 1) Global Const $iPic_Label = GUICtrlCreatePic("", 204, $y - 4, $aRet[1], $aRet[2]) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_Label, $STM_SETIMAGE, $IMAGE_BITMAP, $aRet[0])) Global Const $iLbl_Threshold = GUICtrlCreateLabel("ED Threshold", 4, $y, 76, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Threshold = GUICtrlCreateInput(1.2, $iInp_x, $y2, $iInp_w, 21) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "The lower the value, the larger the triangles.") Global Const $iLbl_Blur = GUICtrlCreateLabel("Blur Level", 4, $y + 1 * 32, 64, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Blur = GUICtrlCreateInput(1, $iInp_x, $y2 + 1 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_Colors = GUICtrlCreateLabel("Max. Colors", 4, $y + 2 * 32, 70, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Colors = GUICtrlCreateInput(256, $iInp_x, $y2 + 2 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "Valid values are: 2, 16, 256") Global Const $iLbl_MinSpace = GUICtrlCreateLabel("Min Space", 4, $y + 3 * 32, 58, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_MinSpace = GUICtrlCreateInput(8, $iInp_x, $y2 + 3 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_MaxSpace = GUICtrlCreateLabel("Max Space", 4, $y + 4 * 32, 58, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_MaxSpace = GUICtrlCreateInput(45, $iInp_x, $y2 + 4 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_BorderSpaceX = GUICtrlCreateLabel("Border Space X", 4, $y + 5 * 32, 88, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_BorderSpaceX = GUICtrlCreateInput(8, $iInp_x, $y2 + 5 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_BorderSpaceY = GUICtrlCreateLabel("Border Space Y", 4, $y + 6 * 32, 88, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_BorderSpaceY = GUICtrlCreateInput(8, $iInp_x, $y2 + 6 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_Alpha = GUICtrlCreateLabel("Edges Alpha", 4, $y + 7 * 32, 70, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Alpha = GUICtrlCreateInput(24, $iInp_x, $y2 + 7 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_PosterizeLvl = GUICtrlCreateLabel("Posterize Lvl", 4, $y + 8 * 32, 85, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_PosterizeLvl = GUICtrlCreateInput(10, $iInp_x, $y2 + 8 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "When the posterization level is set, the value for 'Max. Colors' input is ignored.") Global Const $iLbl_Denoise = GUICtrlCreateLabel("Denoise Lvl", 4, $y + 9 * 32, 85, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_DenoiseLvl = GUICtrlCreateInput(1, $iInp_x, $y2 + 9 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "The higher the value, the slower the operation.") Global Const $iLbl_EdgePoints = GUICtrlCreateLabel("Edge Points", 4, $y + 10 * 32, 85, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_EdgePoints = GUICtrlCreateInput(16, $iInp_x, $y2 + 10 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "The lower the value, the more triangles.") Global Const $iLbl_CartoonRadius = GUICtrlCreateLabel("Cartoon Radius", 4, $y + 11 * 32, 85, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_CartoonRadius = GUICtrlCreateInput(7, $iInp_x, $y2 + 11 * 32, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "The higher the value, the slower the operation.") Global Const $iLbl_CartoonIntens = GUICtrlCreateLabel("Cartoon Intens", 4, $y + 12 * 32, 85, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_CartoonIntens = GUICtrlCreateInput(150.00, $iInp_x, $y2 + 12 * 32, $iInp_w, 21) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") $y2 += 102 $p = 10 Global Const $iChkB_ShowEdges = GUICtrlCreateCheckbox("Show Edges", 4, $y2 + $p * 32, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") GUICtrlSetState(-1, $GUI_CHECKED) $p += 1 Global Const $iChkB_Wireframe = GUICtrlCreateCheckbox("Show Wireframes only", 4, $y2 + $p * 32, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") $p += 1 Global Const $iChkB_GIFAnim = GUICtrlCreateCheckbox("Convert all GIF frames", 4, $y2 + $p * 32, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") $p += 1 Global Const $iChkB_CartoonMode = GUICtrlCreateCheckbox("Enable Cartoon Mode", 4, $y2 + $p * 32, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetTip(-1, "Very CPU intensive calculation.") $p += 1 Global Const $iChkB_AutoResize = GUICtrlCreateCheckbox("Resize large image to screen size", 4, $y2 + $p * 32, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetTip(-1, "Large images are scaled to fit the screen size for faster processing, except GIF images.") $p += 1 $y2 += $p * 32 $p = 0 Global Const $iBtn_Apply = GUICtrlCreateButton("&Apply", 8, $y2 + $p * 72, 235, 57, $BS_DEFPUSHBUTTON) GUICtrlSetFont(-1, 12, 400, 0, "Consolas") GUICtrlSetBkColor(-1, 0xCCCCFF) GUICtrlSetState($iBtn_Apply, $GUI_DISABLE) $p += 1 Global Const $iBtn_Load = GUICtrlCreateButton("&Load Image", 8, $y2 + $p * 72, 235, 57) GUICtrlSetFont(-1, 12, 400, 0, "Consolas") GUICtrlSetBkColor(-1, 0xCCCCFF) $p += 1 Global Const $iBtn_Save = GUICtrlCreateButton("&Save Image", 8, $y2 + $p * 72, 235, 57) GUICtrlSetFont(-1, 12, 400, 0, "Consolas") GUICtrlSetBkColor(-1, 0xCCCCFF) GUICtrlSetState($iBtn_Save, $GUI_DISABLE) Global $aParts[1] = [-1] Global Const $hStatusBar = _GUICtrlStatusBar_Create($hGUI, $aParts, "Ready") Local $hFont = _WinAPI_CreateFont(12, 0, 0, 0, $FW_MEDIUM, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DRAFT_QUALITY, 0, "Segoe UI") _WinAPI_SetFont($hStatusBar, $hFont, True) GUISetState(@SW_SHOW) Global $aAccelKeys[4][2] = [["^s", $iBtn_Save], ["^l", $iBtn_Load], ["^a", $iBtn_Apply], ["{ENTER}", $iBtn_Apply]] GUISetAccelerators($aAccelKeys) GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") GUIRegisterMsg($WM_DROPFILES, "_WM_DROPFILES") Global $aMsg, $hImage, $sImgFile, $hGUI_Display = 0, $hGDI_LowPoly, $sFileLowPoly, $g_iW, $g_iH, $hImgTmp = 0 ConsoleWrite("Screen: " & @DesktopWidth & "x" & @DesktopHeight & @CRLF) Dim $aFrameDelays[1], $aFramesGDI[1], $aFrames_LowPoly[1] Global $iCurrentFrame = 0, $iAnimFrameCount = 0, $bIsGIF, $iPic_LowPoly, $iSeed, $i, $r, $hImage_OrginalSize, $iDummy_Load = GUICtrlCreateDummy() While 1 $aMsg = GUIGetMsg(1) Switch $aMsg[1] Case $hGUI Switch $aMsg[0] Case $GUI_EVENT_CLOSE GUIRegisterMsg($WM_COMMAND, "") GUIRegisterMsg($WM_DROPFILES, "") AdlibUnRegister("PlayGIFAnimPreview") If $hGDI_LowPoly Then $r = MsgBox(BitOR($MB_ICONQUESTION, $MB_YESNO), "Question", "Save image before closing?", 5) If $r = $IDYES Then SaveImage() EndIf GUIDelete($hGUI) If UBound($aFrameDelays) > 1 Then For $i = 0 To UBound($aFramesGDI) - 1 _WinAPI_DeleteObject($aFramesGDI[$i]) Next For $i = 1 To $aFrames_LowPoly[0] _GDIPlus_ImageDispose($aFrames_LowPoly[$i]) Next EndIf If $hImage_OrginalSize Then _GDIPlus_ImageDispose($hImage_OrginalSize) If $hImgTmp Then _GDIPlus_ImageDispose($hImgTmp) _GDIPlus_BitmapApplyFilter_Close() Exit Case $iBtn_Load $sImgFile = FileOpenDialog("Select a GDI+ supported image", "", "Images (*.bmp;*.gif;*.png;*.jpg;*.tif)", $FD_FILEMUSTEXIST, "", $hGUI) If @error Then ContinueLoop If Not FileExists($sImgFile) Then MsgBox($MB_ICONERROR, "Error", $sImgFile & " doesn't exist", 30) ContinueLoop EndIf LoadImage($sImgFile) Case $iBtn_Save If $sImgFile = "" Or ($bIsGIF ? UBound($aFrames_LowPoly) < 2 : $hGDI_LowPoly = 0) Then ContinueLoop SaveImage() Case $iBtn_Apply If $sImgFile = "" Or $hImage = 0 Then ContinueLoop GUICtrlSetState($iBtn_Apply, $GUI_DISABLE) GUICtrlSetState($iBtn_Load, $GUI_DISABLE) GUICtrlSetState($iBtn_Save, $GUI_DISABLE) $iCurrentFrame = 0 EncodeAndDisplay($hImage) GUICtrlSetState($iBtn_Apply, $GUI_ENABLE) GUICtrlSetState($iBtn_Load, $GUI_ENABLE) GUICtrlSetState($iBtn_Save, $GUI_ENABLE) Case $iDummy_Load LoadImage($sImgFile) EndSwitch Case $hGUI_Display Switch $aMsg[0] Case $GUI_EVENT_CLOSE AdlibUnRegister("PlayGIFAnimPreview") GUIDelete($hGUI_Display) $hGUI_Display = 0 EndSwitch EndSwitch WEnd Func Min($a, $b) Return $a < $b ? $a : $b EndFunc ;==>Min Func Max($a, $b) Return $a > $b ? $a : $b EndFunc ;==>Max Func CalcResizeDim(ByRef $iW, ByRef $iH, $fFactor) Local $fScaleX, $fScaleY, $iMode = 0 If $iH > @DesktopHeight And $iW < @DesktopWidth + 1 Then $fScaleY = @DesktopHeight / $iH $iW *= $fScaleY $iH *= $fScaleY $iMode = 1 ElseIf $iH < @DesktopHeight + 1 And $iW > @DesktopWidth Then $fScaleX = @DesktopWidth / $iW $iW *= $fScaleX $iH *= $fScaleX $iMode = 2 ElseIf $iH > @DesktopHeight And $iW > @DesktopWidth Then If $iH > $iW Then $fScaleY = @DesktopHeight / $iH $iH *= $fScaleY $iW *= $fScaleY Else $fScaleX = @DesktopWidth / $iW $iH *= $fScaleX $iW *= $fScaleX EndIf $iMode = 3 EndIf If $iMode Or ($iW = @DesktopWidth Or $iH = @DesktopHeight) Then $iW *= $fFactor $iH *= $fFactor EndIf $iW = Int($iW) $iH = Int($iH) Return $iMode EndFunc Func EncodeAndDisplay($hImage, $ResizeInGUI = True) If $g_iW = 0 Or $g_iH = 0 Or $hImage = 0 Then Return SetError(1, 0, 0) Local $iW = $g_iW, $iH = $g_iH Local $fFactor = 0.925, $iMode = 0 If $ResizeInGUI Then $iMode = CalcResizeDim($iW, $iH, $fFactor) EndIf ConsoleWrite("Original: " & $g_iW & "x" & $g_iH & @CRLF) ConsoleWrite("Display: " & $iW & "x" & $iH & @CRLF) Static $iWp = 0, $iHp = 0 If ($iW <> $iWp Or $iH <> $iHp) Or $hGUI_Display = 0 Then If $hGUI_Display Then GUIDelete($hGUI_Display) $hGUI_Display = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, $WS_EX_OVERLAPPEDWINDOW) $iPic_LowPoly = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1, -1, $GUI_WS_EX_PARENTDRAG) GUISetState(@SW_SHOWNORMAL, $hGUI_Display) WinActivate($hGUI) EndIf $iWp = $iW $iHp = $iH If $hGDI_LowPoly Then _WinAPI_DeleteObject($hGDI_LowPoly) $hGDI_LowPoly = 0 ;~ ConsoleWrite("Blur level: " & Number(GUICtrlRead($iInp_Blur)) & @CRLF & _ ;~ "Kernel: " & Execute("$" & GUICtrlRead($iCombo_EdgeDetection)) & @CRLF & _ ;~ "Threshold: " & Number(GUICtrlRead($iInp_Threshold), $NUMBER_DOUBLE) & @CRLF & _ ;~ "Amount of Colors: " & Number(GUICtrlRead($iInp_Colors)) & @CRLF & _ ;~ "Min Space: " & Number(GUICtrlRead($iInp_MinSpace)) & @CRLF & _ ;~ "Max Space: " & Number(GUICtrlRead($iInp_MaxSpace)) & @CRLF & _ ;~ "Border Space X: " & Number(GUICtrlRead($iInp_BorderSpaceX)) & @CRLF & _ ;~ "Border Space Y: " & Number(GUICtrlRead($iInp_BorderSpaceY)) & @CRLF & _ ;~ "Show Edges Checked: " & Int(BitAND(GUICtrlRead($iChkB_ShowEdges), $GUI_CHECKED) = $GUI_CHECKED) & @CRLF & _ ;~ "Alpha Value: " & Number(GUICtrlRead($iInp_Alpha)) & @CRLF & _ ;~ "Wireframe Checked: " & Int(BitAND(GUICtrlRead($iChkB_Wireframe), $GUI_CHECKED) = $GUI_CHECKED) & @CRLF & _ ;~ "Posterize level: " & Number(GUICtrlRead($iInp_PosterizeLvl)) & @CRLF & _ ;~ "GIF Mode Checked: " & Int(BitAND(GUICtrlRead($iChkB_GIFAnim), $GUI_CHECKED) = $GUI_CHECKED) & @CRLF & _ ;~ "Posterize Lvl: " & Number(GUICtrlRead($iInp_PosterizeLvl)) & @CRLF & _ ;~ "Denoise Lvl: " & Number(GUICtrlRead($iInp_DenoiseLvl)) & @CRLF & _ ;~ "EdgePoints): " & Number(GUICtrlRead($iInp_EdgePoints)) & @CRLF & _ ;~ "CornerPoints: " & Number(GUICtrlRead($iInp_CornerPoints)) & @CRLF) ;~ ConsoleWrite("-----------------------------------------------------------------------" & @CRLF) AdlibUnRegister("PlayGIFAnimPreview") Local $i Local $iAnimDimCount = _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage) Local $tGUID = _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iAnimDimCount) $iAnimFrameCount = _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID) $aFrameDelays = _GDIPlus_GIFAnimGetFrameDelays($hImage, $iAnimFrameCount) If $iAnimFrameCount Then _GDIPlus_GIFAnimSelectActiveFrame($hImage, $tGUID, 0) _GUICtrlStatusBar_SetText($hStatusBar, "Calculation has started. Please wait...", 0, $SBT_POPOUT) ConsoleWrite("Image processing has started - please wait...") Local Const $fTimer = TimerInit() If Int(BitAND(GUICtrlRead($iChkB_GIFAnim), $GUI_CHECKED) = $GUI_CHECKED) And $bIsGIF And $iAnimFrameCount > 1 Then If UBound($aFramesGDI) > 1 Then For $i = 0 To UBound($aFramesGDI) - 1 _WinAPI_DeleteObject($aFramesGDI[$i]) _GDIPlus_ImageDispose($aFrames_LowPoly[$i + 1]) Next EndIf ReDim $aFramesGDI[$iAnimFrameCount] ReDim $aFrames_LowPoly[$iAnimFrameCount + 1] $aFrames_LowPoly[0] = $iAnimFrameCount For $i = 0 To $iAnimFrameCount - 1 _GDIPlus_GIFAnimSelectActiveFrame($hImage, $tGUID, $i) $aFrames_LowPoly[$i + 1] = _GDIPlus_BitmapApplyFilter_Delaunay3($hImage, _ Number(GUICtrlRead($iInp_Blur)), _ Execute("$" & GUICtrlRead($iCombo_EdgeDetection)), _ Number(GUICtrlRead($iInp_Threshold), $NUMBER_DOUBLE), _ Number(GUICtrlRead($iInp_Colors)), _ Number(GUICtrlRead($iInp_MinSpace)), _ Number(GUICtrlRead($iInp_MaxSpace)), _ Number(GUICtrlRead($iInp_BorderSpaceX)), _ Number(GUICtrlRead($iInp_BorderSpaceY)), _ Int(BitAND(GUICtrlRead($iChkB_ShowEdges), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_Alpha)), _ Int(BitAND(GUICtrlRead($iChkB_Wireframe), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_PosterizeLvl)), _ $iSeed, _ 0xFFFFFFFF, _ Number(GUICtrlRead($iInp_DenoiseLvl)), _ Number(GUICtrlRead($iInp_EdgePoints)), _ 50, _ Int(BitAND(GUICtrlRead($iChkB_CartoonMode), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_CartoonRadius)), _ Number(GUICtrlRead($iInp_CartoonIntens), $NUMBER_DOUBLE), _ False) $aFramesGDI[$i] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($aFrames_LowPoly[$i + 1]) _GDIPlus_BitmapConvertTo8Bit($aFrames_LowPoly[$i + 1], 256, $GDIP_DitherTypeNone, $GDIP_PaletteTypeFixedHalftone256) ToolTip($i + 1 & "/" & $iAnimFrameCount & " : " & Round(($i + 1) / UBound($aFrameDelays) * 100, 2) & "%", MouseGetPos(0), MouseGetPos(1) + 30, "", 0, $TIP_CENTER) Next ToolTip("") AdlibRegister("PlayGIFAnimPreview", 10) Else $hGDI_LowPoly = _GDIPlus_BitmapApplyFilter_Delaunay3($hImage, _ Number(GUICtrlRead($iInp_Blur)), _ Execute("$" & GUICtrlRead($iCombo_EdgeDetection)), _ Number(GUICtrlRead($iInp_Threshold), $NUMBER_DOUBLE), _ Number(GUICtrlRead($iInp_Colors)), _ Number(GUICtrlRead($iInp_MinSpace)), _ Number(GUICtrlRead($iInp_MaxSpace)), _ Number(GUICtrlRead($iInp_BorderSpaceX)), _ Number(GUICtrlRead($iInp_BorderSpaceY)), _ Int(BitAND(GUICtrlRead($iChkB_ShowEdges), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_Alpha)), _ Int(BitAND(GUICtrlRead($iChkB_Wireframe), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_PosterizeLvl)), _ $iSeed, _ 0, _ Number(GUICtrlRead($iInp_DenoiseLvl)), _ Number(GUICtrlRead($iInp_EdgePoints)), _ 50, _ Int(BitAND(GUICtrlRead($iChkB_CartoonMode), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_CartoonRadius)), _ Number(GUICtrlRead($iInp_CartoonIntens), $NUMBER_DOUBLE), _ True) If $hGDI_LowPoly = 0 Then GUIDelete($hGUI_Display) $hGUI_Display = 0 Return SetError(1, 0, 0) EndIf If $iMode Then ResizeImage($hGDI_LowPoly, $iW, $iH) Local $hHBmp = GUICtrlSendMsg($iPic_LowPoly, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDI_LowPoly) If $hHBmp Then _WinAPI_DeleteObject($hHBmp) EndIf Local $fEnd = Round(TimerDiff($fTimer), 2) ConsoleWrite($fEnd & " ms." & @CRLF & @CRLF) _GUICtrlStatusBar_SetText($hStatusBar, "Generated in: " & $fEnd & " ms. Dimension: " & _GDIPlus_ImageGetWidth($hImage) & "x" & _GDIPlus_ImageGetHeight($hImage), 0, $SBT_POPOUT) _WinAPI_InvalidateRect($hGUI_Display) _WinAPI_RedrawWindow($hGUI_Display) EndFunc ;==>EncodeAndDisplay Func PlayGIFAnimPreview() AdlibUnRegister("PlayGIFAnimPreview") Local $iDelay = $aFrameDelays[$iCurrentFrame] Local Static $iTimerCurrentFrame = TimerInit() _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_LowPoly, 0x0172, 0, $aFramesGDI[$iCurrentFrame])) ;$STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0 If TimerDiff($iTimerCurrentFrame) > $iDelay Then $iCurrentFrame += 1 $iTimerCurrentFrame = TimerInit() EndIf If $iCurrentFrame > UBound($aFrameDelays) - 1 Then $iCurrentFrame = 0 AdlibRegister("PlayGIFAnimPreview", 10) EndFunc ;==>PlayGIFAnimPreview Func ResizeImage(ByRef $hBitmapGDI, $newW, $newH) Local $hImageCopy = _GDIPlus_BitmapCreateFromHBITMAP($hBitmapGDI) If $hImage_OrginalSize Then _GDIPlus_ImageDispose($hImage_OrginalSize) $hImage_OrginalSize = _GDIPlus_BitmapCloneArea($hImageCopy, 0, 0, $g_iW, $g_iH, $GDIP_PXF32ARGB) ;save original size of low-polygon image to save original size Local $hImageResized = _GDIPlus_ImageResize($hImageCopy, $newW, $newH) _WinAPI_DeleteObject($hBitmapGDI) $hBitmapGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImageResized, 0) _GDIPlus_ImageDispose($hImageResized) EndFunc ;==>ResizeImage Func LoadImage($sImgFile) If $hImage Then _GDIPlus_ImageDispose($hImage) $hImage = _GDIPlus_ImageLoadFromFile($sImgFile) If Not $hImage Then MsgBox($MB_ICONERROR, "Error", "Unable to load file to GDI+", 30) Return 0 EndIf $g_iW = _GDIPlus_ImageGetWidth($hImage) $g_iH = _GDIPlus_ImageGetHeight($hImage) $bIsGIF = False If StringRight($sImgFile, 4) = ".gif" Then $bIsGIF = True If $bIsGIF = False And Int(BitAND(GUICtrlRead($iChkB_AutoResize), $GUI_CHECKED) = $GUI_CHECKED) Then Local $iWt = $g_iW, $iHt = $g_iH, $iMode CalcResizeDim($iWt, $iHt, 1) If $iWt < $g_iW Or $iHt < $g_iH Then $hImgTmp = _GDIPlus_ImageResize($hImage, $iWt, $iHt) _GDIPlus_ImageDispose($hImage) $hImage = $hImgTmp ConsoleWrite("Original image " & $g_iW & "x" & $g_iH & " resized to " & $iWt & "x" & $iHt & @CRLF) $g_iW = _GDIPlus_ImageGetWidth($hImage) $g_iH = _GDIPlus_ImageGetHeight($hImage) EndIf EndIf $iSeed = Int(Random() * 0xFFFFFF) $iCurrentFrame = 0 $iAnimFrameCount = 0 Local $iMax = Int(Max($g_iW, $g_iH) / 192) If $iMax > 1 Then GUICtrlSetData($iInp_MinSpace, $iMax) GUICtrlSetData($iInp_MaxSpace, Ceiling($iMax * 4.5)) EndIf If $hImage Then GUICtrlSetState($iBtn_Apply, $GUI_ENABLE) GUICtrlSetState($iBtn_Save, $GUI_ENABLE) EndIf GUICtrlSetData($iInp_BorderSpaceX, Int($g_iW / 16)) GUICtrlSetData($iInp_BorderSpaceY, Int($g_iH / 16)) EncodeAndDisplay($hImage) EndFunc Func SaveImage() $sFileLowPoly = FileSaveDialog("Save Low-Polygone Image", "", "Images (*.bmp;*.gif;*.png;*.jpg;*.jpeg;*.tif;*.tiff)", 0, StringRegExpReplace($sImgFile, "^.*\\([^\\]+)(\.[^.]+)$", "\1_Low-Polygon\2"), $hGUI) If @error Or $sFileLowPoly = "" Then Return 0 If FileExists($sFileLowPoly) Then Local $r = MsgBox(BitOR($MB_ICONQUESTION, $MB_YESNO), "Question", "File already exists - overwwrite?", 5) If $r <> $IDYES Then Return MsgBox($MB_ICONINFORMATION, "Information", "Save aborted!", 15, $hGUI) EndIf EndIf If ((UBound($aFrames_LowPoly) > 1 And $bIsGIF) ? _ _GDIPlus_GIFAnimCreateFile2($aFrames_LowPoly, $sFileLowPoly, $aFrameDelays) _ : _ ($hImage_OrginalSize ? _GDIPlus_ImageSaveToFile($hImage_OrginalSize, $sFileLowPoly) _ : _ScreenCapture_SaveImage($sFileLowPoly, $hGDI_LowPoly, False))) Then MsgBox($MB_ICONINFORMATION, "Information", "Low-Poly image saved.", 15, $hGUI) Else MsgBox($MB_ICONERROR, "Error", "Low-Poly image could not be save!", 15, $hGUI) EndIf EndFunc ;==>SaveImage Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam) Local $iNotifyCode = BitShift($wParam, 16) Local $iCtrlID = BitAND($wParam, 0x0000FFFF) Local $var If $iNotifyCode = $EN_KILLFOCUS Then Switch $iCtrlID Case $iInp_Blur $val = GUICtrlRead($iInp_Blur) If $val = "" Then $val = 5 $val = Number($val) If $val < 0 Then $val = 0 If $val > 127 Then $val = 127 GUICtrlSetData($iInp_Blur, $val) Case $iInp_Threshold $val = GUICtrlRead($iInp_Threshold) If $val = "" Then $val = 0.35 $val = Number($val) If $val < 0 Then $val = 0 If $val > 10 Then $val = 10 GUICtrlSetData($iInp_Threshold, StringFormat("%.2f", $val)) Case $iInp_Colors $val = GUICtrlRead($iInp_Colors) If $val = "" Then $val = 32 $val = Number($val) If $val < 2 Then $val = 2 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_Colors, $val) Case $iInp_MinSpace $val = GUICtrlRead($iInp_MinSpace) If $val = "" Then $val = 1 $val = Number($val) If $val < 1 Then $val = 1 GUICtrlSetData($iInp_MinSpace, $val) Case $iInp_MaxSpace $val = GUICtrlRead($iInp_MaxSpace) If $val = "" Then $val = 8 $val = Number($val) If $val < 1 Then $val = 2 GUICtrlSetData($iInp_MaxSpace, $val) Case $iInp_BorderSpaceX, $iInp_BorderSpaceY $val = GUICtrlRead($iCtrlID) If $val = "" Then $val = 2 $val = Number($val) If $val < 1 Then $val = 1 If $val > 4096 Then $val = 4096 GUICtrlSetData($iCtrlID, $val) Case $iInp_Alpha $val = GUICtrlRead($iInp_Alpha) If $val = "" Then $val = 32 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_Alpha, $val) Case $iInp_PosterizeLvl $val = GUICtrlRead($iInp_PosterizeLvl) If $val = "" Then $val = 8 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_PosterizeLvl, $val) Case $iInp_DenoiseLvl $val = GUICtrlRead($iInp_DenoiseLvl) If $val = "" Then $val = 0 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_DenoiseLvl, $val) Case $iInp_EdgePoints $val = GUICtrlRead($iInp_EdgePoints) If $val = "" Then $val = 30 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_EdgePoints, $val) Case $iInp_CartoonRadius $val = GUICtrlRead($iInp_CartoonRadius) If $val = "" Then $val = 8 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_CartoonRadius, $val) Case $iInp_CartoonIntens $val = GUICtrlRead($iInp_CartoonIntens) If $val = "" Then $val = 20 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_CartoonIntens, StringFormat("%.2f", $val)) EndSwitch EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_WM_COMMAND Func _WM_DROPFILES($hWnd, $iMsg, $wParam, $lParam) Local $i = 1 Local $aFileList = _WinAPI_DragQueryFileEx($wParam) Do If StringInStr(FileGetAttrib($aFileList[$i]), "D") Then _ArrayDelete($aFileList, $i) Else $i += 1 EndIf Until $i = UBound($aFileList) $aFileList[0] = UBound($aFileList) - 1 $sImgFile = $aFileList[1] _WinAPI_DragFinish($wParam) GUICtrlSendToDummy($iDummy_Load) Return 0 EndFunc ;==>WM_DROPFILES# Func _GDIPlus_BitmapCreateVerticalText($sString, $fFontSize = 10, $sFont = "Arial", $iColor_Text = 0xFF000000, $iTxtBorderColor = 0x80808080, $iTxtBorderSize = 1, $iFlip = 3) $iFlip = ($iFlip <> 3 And $iFlip <> 1) ? 3 : $iFlip Local Const $hDC = _WinAPI_GetWindowDC(0) Local Const $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC) Local Const $hBrush = _GDIPlus_BrushCreateSolid($iColor_Text), $hPen = _GDIPlus_PenCreate($iTxtBorderColor, $iTxtBorderSize) Local Const $hFormat = _GDIPlus_StringFormatCreate() Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFont) Local Const $hFont = _GDIPlus_FontCreate($hFamily, $fFontSize) Local Const $hPath = _GDIPlus_PathCreate() Local $tLayout = _GDIPlus_RectFCreate() Local $iError = 1 Local Const $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat) If Not @error Then Local Const $iW = Ceiling($aInfo[0].Width), $iH = Ceiling($aInfo[0].Height) Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetTextRenderingHint($hCanvas, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) $tLayout.X = 0 $tLayout.Y = 0 $tLayout.Width = $iW $tLayout.Height = $iH _GDIPlus_PathAddString($hPath, $sString, $tLayout, $hFamily, 0, $fFontSize, $hFormat) ;~ _GDIPlus_GraphicsDrawStringEx($hCanvas, $sString, $hFont, $tLayout, $hFormat, $hBrush) _GDIPlus_GraphicsFillPath($hCanvas, $hPath, $hBrush) _GDIPlus_GraphicsDrawPath($hCanvas, $hPath, $hPen) _GDIPlus_ImageRotateFlip($hBitmap, $iFlip) Local Const $hBitmap_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _GDIPlus_GraphicsDispose($hCanvas) _GDIPlus_BitmapDispose($hBitmap) $iError = 0 EndIf _GDIPlus_PathDispose($hPath) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_ReleaseDC(0, $hDC) If $iError Then Return SetError(1, 0, 0) Local $aResult[3] = [$hBitmap_GDI, $iH, $iW] Return $aResult EndFunc ;==>_GDIPlus_BitmapCreateVerticalText Func CheckVer($sVerInstalled, $sVerRequired) Local $aInst = StringSplit($sVerInstalled, ".") Local $aReq = StringSplit($sVerRequired, ".") Local $iInst, $iReq For $i = 1 To $aReq[0] $iInst = ($i <= $aInst[0]) ? Int($aInst[$i]) : 0 $iReq = Int($aReq[$i]) If $iInst > $iReq Then Return True If $iInst < $iReq Then Return False Next Return True EndFunc ;==>CheckVer #Region GIF ;_GDIPlus_GIFAnim* function taken from _GDIPlus_GIFAnim UDF Func _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage) Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "handle", $hImage, "ulong*", 0) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(10, $aResult[0], 0) Return $aResult[2] EndFunc ;==>_GDIPlus_GIFAnimGetFrameDimensionsCount Func _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iFramesCount) Local Const $tGUID = DllStructCreate($tagGUID) Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameDimensionsList", "handle", $hImage, "struct*", $tGUID, "uint", $iFramesCount) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(10, $aResult[0], 0) Return $tGUID EndFunc ;==>_GDIPlus_GIFAnimGetFrameDimensionsList Func _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID) Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameCount", "handle", $hImage, "struct*", $tGUID, "ptr*", 0) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(10, $aResult[0], 0) Return Int($aResult[3]) EndFunc ;==>_GDIPlus_GIFAnimGetFrameCount Func _GDIPlus_GIFAnimSelectActiveFrame($hImage, $tGUID, $iCurrentFrame) Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageSelectActiveFrame", "handle", $hImage, "struct*", $tGUID, "uint", $iCurrentFrame) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(10, $aResult[0], 0) Return True EndFunc ;==>_GDIPlus_GIFAnimSelectActiveFrame Func _GDIPlus_GIFAnimGetFrameDelays($hImage, $iAnimFrameCount) If $iAnimFrameCount < 2 Then Return SetError(1, 0, 0) Local Const $GDIP_PROPERTYTAGFRAMEDELAY = 0x5100 Local $tPropItem = __GDIPlus_ImageGetPropertyItem($hImage, $GDIP_PROPERTYTAGFRAMEDELAY) If IsDllStruct($tPropItem) And (Not @error) Then Local $iType = $tPropItem.type, $iLength, $tVal If $iType Then $iLength = $tPropItem.length Switch $iType Case 1 $tVal = DllStructCreate("byte delay[" & $iLength & "]", $tPropItem.value) Case 3 $tVal = DllStructCreate("short delay[" & Ceiling($iLength / 2) & "]", $tPropItem.value) Case 4 $tVal = DllStructCreate("long delay[" & Ceiling($iLength / 4) & "]", $tPropItem.value) Case Else Return SetError(3, 0, 0) EndSwitch Local $aFrameDelays[Int($iAnimFrameCount)], $i For $i = 0 To UBound($aFrameDelays) - 1 $aFrameDelays[$i] = $tVal.delay(($i + 1)) * 10 Next EndIf Return $aFrameDelays EndIf Return SetError(2, 0, 0) EndFunc ;==>_GDIPlus_GIFAnimGetFrameDelays Func __GDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItemSize", "handle", $hImage, "uint", $iPropID, "ulong*", 0) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(10, $aResult[0], 0) Local Static $tBuffer $tBuffer = DllStructCreate("byte[" & $aResult[3] & "]") $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", $iPropID, "ulong", $aResult[3], "struct*", $tBuffer) If @error Then Return SetError(@error, @extended, 0) If $aResult[0] Then Return SetError(11, $aResult[0], 0) Local Const $tagGDIPPROPERTYITEM = "uint id;ulong length;word type;ptr value" Local $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, DllStructGetPtr($tBuffer)) If @error Then Return SetError(20, $aResult[0], 0) Return $tPropertyItem EndFunc ;==>__GDIPlus_ImageGetPropertyItem Func _GDIPlus_GIFAnimCreateFile2($aImages, $sFilename, $aDelays = 100, $bReplay = True) Local Const $GDIP_EVTFrameDimensionTime = 21 Local $iMax = $aImages[0] If $iMax < 1 Then Return SetError(1, 0, False) Local Const $sCLSID = _GDIPlus_EncodersGetCLSID("GIF") Local $tMultiFrameParam = DllStructCreate("int type;") $tMultiFrameParam.type = 18 Local $tParams = _GDIPlus_ParamInit(1) _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, 4, DllStructGetPtr($tMultiFrameParam)) Local Const $hStream = _WinAPI_CreateStreamOnHGlobal() Local $tGUID = _WinAPI_GUIDFromString($sCLSID) _GDIPlus_ImageSaveToStream($aImages[1], $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams)) If $iMax > 1 Then $tMultiFrameParam.type = $GDIP_EVTFrameDimensionTime $tParams = _GDIPlus_ParamInit(1) _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, 4, DllStructGetPtr($tMultiFrameParam)) For $i = 2 To $iMax _GDIPlus_ImageSaveAddImage($aImages[1], $aImages[$i], $tParams) Next $tMultiFrameParam.type = 19 $tParams = _GDIPlus_ParamInit(1) _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, 4, DllStructGetPtr($tMultiFrameParam)) _GDIPlus_ImageSaveAdd($aImages[1], $tParams) EndIf $tMultiFrameParam.type = 20 $tParams = _GDIPlus_ParamInit(1) _GDIPlus_ParamAdd($tParams, $GDIP_EPGSAVEFLAG, 1, 4, DllStructGetPtr($tMultiFrameParam)) _GDIPlus_ImageSaveAdd($aImages[1], $tParams) Local Const $hMemory = _WinAPI_GetHGlobalFromStream($hStream) Local Const $iMemSize = _MemGlobalSize($hMemory) Local Const $pMem = _MemGlobalLock($hMemory) Local Const $iNewSize = $bReplay ? ($iMemSize + 19) : $iMemSize Local Const $hNewMem = _MemGlobalAlloc($iNewSize, 0x0002) Local Const $pNewMem = _MemGlobalLock($hNewMem) Local $tNewData = DllStructCreate("byte mem[" & $iNewSize & "]", $pNewMem) Local Const $hDLL_msvcrt = DllOpen("msvcrt.dll") Local $iCopyOffset = 0 If $bReplay Then Local $tNetscape = DllStructCreate("byte mem[19]") $tNetscape.mem = Binary("0x21FF0B4E45545343415045322E300301000000") Local $aResult = DllCall($hDLL_msvcrt, "ptr:cdecl", "memchr", "ptr", $pMem, "int", 0x21, "ulong_ptr", $iMemSize) If @error Or Not IsArray($aResult) Then _MemGlobalUnlock($hMemory) _MemGlobalUnlock($hNewMem) _MemGlobalFree($hNewMem) _WinAPI_ReleaseStream($hStream) DllClose($hDLL_msvcrt) Return SetError(3, 0, False) EndIf Local $pFound = $aResult[0], $tCheck, $iInsertPos While $pFound <> 0 $tCheck = DllStructCreate("byte mem[3]", $pFound) If $tCheck.mem(1) = 0x21 And $tCheck.mem(2) = 0xF9 And $tCheck.mem(3) = 0x04 Then $iInsertPos = $pFound - $pMem DllCall($hDLL_msvcrt, "ptr:cdecl", "memcpy", "ptr", $pNewMem, "ptr", $pMem, "ulong_ptr", $iInsertPos) DllCall($hDLL_msvcrt, "ptr:cdecl", "memcpy", "ptr", $pNewMem + $iInsertPos, "struct*", $tNetscape, "ulong_ptr", 19) DllCall($hDLL_msvcrt, "ptr:cdecl", "memcpy", "ptr", $pNewMem + $iInsertPos + 19, "ptr", $pMem + $iInsertPos, "ulong_ptr", $iMemSize - $iInsertPos) $iCopyOffset = 19 ExitLoop EndIf $aResult = DllCall($hDLL_msvcrt, "ptr:cdecl", "memchr", "ptr", $pFound + 1, "int", 0x21, "ulong_ptr", $iMemSize - ($pFound - $pMem) - 1) $pFound = $aResult[0] WEnd Else DllCall($hDLL_msvcrt, "ptr:cdecl", "memcpy", "ptr", $pNewMem, "ptr", $pMem, "ulong_ptr", $iMemSize) EndIf _MemGlobalUnlock($hMemory) _WinAPI_ReleaseStream($hStream) _MemGlobalFree($hMemory) Local $pSearch = $pNewMem Local $iRemainingByte = $iNewSize Local $iFrameCount = 0, $iDelay, $aResult, $pFound, $tCheck, $isArray = IsArray($aDelays) While $iFrameCount < $iMax And $iRemainingByte > 6 $aResult = DllCall($hDLL_msvcrt, "ptr:cdecl", "memchr", "ptr", $pSearch, "int", 0x21, "ulong_ptr", $iRemainingByte) If $aResult[0] = 0 Then ExitLoop $pFound = $aResult[0] $tCheck = DllStructCreate("byte mem[6]", $pFound) If $tCheck.mem(2) = 0xF9 And $tCheck.mem(3) = 0x04 Then $iDelay = $isArray ? $aDelays[$iFrameCount] : $aDelays $iDelay = Int($iDelay / 10) $tCheck.mem(5) = BitAND($iDelay, 0xFF) $tCheck.mem(6) = BitShift($iDelay, 8) $iFrameCount += 1 $pSearch = $pFound + 8 Else $pSearch = $pFound + 1 EndIf $iRemainingByte = $iNewSize - ($pSearch - $pNewMem) WEnd DllClose($hDLL_msvcrt) Local $hFile = FileOpen($sFilename, BitOR(16, 2)) If $hFile = -1 Then _MemGlobalUnlock($hNewMem) _MemGlobalFree($hNewMem) Return SetError(2, 0, False) EndIf FileWrite($hFile, $tNewData.mem) FileClose($hFile) _MemGlobalUnlock($hNewMem) _MemGlobalFree($hNewMem) Return True EndFunc ;==>_GDIPlus_GIFAnimCreateFile2 Func _GDIPlus_BitmapConvertTo8Bit(ByRef $hBitmap, $iColorCount = 256, $iDitherType = 9, $iPaletteType = 8, $bUseTransparentColor = True) $iColorCount = ($iColorCount > 2 ^ 8) ? 2 ^ 8 : $iColorCount Local $tPalette = _GDIPlus_PaletteInitialize(256, $iPaletteType, $iColorCount, $bUseTransparentColor, $hBitmap) If @error Then Return SetError(1, @error, 0) Local $iRet = _GDIPlus_BitmapConvertFormat($hBitmap, 0x00030803, $iDitherType, $iPaletteType, $tPalette) If @error Then Return SetError(2, @error, 0) Return $iRet EndFunc ;==>_GDIPlus_BitmapConvertTo8Bit #EndRegion GIF Examples: The required DLLs (_GDIPlus_BitmapApplyFilter.dll / _GDIPlus_BitmapApplyFilter_x64.dll) and _GDIPlus_BitmapApplyFilter.au3 can be found on my OneDrive: _GDIPlus_BitmapApplyFilter
-
Direct2D UDF Is Direct2D the new GDIPlus? Hmm - I think it is not! It is too complicated and Microsoft failed at the design But Direct2D is hardware accelerated and it has some features I always missed in GDIPlus, like loading/saving animated GIF´s, combining path´s or drawing bitmap´s in a perspective view... check out the examples to see, what can be done Download: https://autoit.de/index.php/Attachment/70-Direct2D-7z/ Or visit the original topic at the german forum - link in my signature
-
I ported half of the Cairo functions to Autoit. You can read more about the functions here: https://www.cairographics.org/documentation/ The probability is high that errors have crept in and I have only tested a fraction of the functions. Anyone who wants to can contribute examples. All needed files (DLLs, UDF and examples) can be download from my OneDrive: Cairo for Autoit If you find a mistake, I am sure you will, then please report it.
-
#include <GUIConstants.au3> #include <WinAPI.au3> ; for _WinAPI_CreateWindowEx() Opt("MustDeclareVars", 1) ; example from "https://www.autoitscript.com/forum/topic/178961-resize-control/?do=findComment&comment=1336645" Global Const $SBS_SIZEBOX = 0x08 Global Const $SBS_SIZEGRIP = 0x10 Global $hGui, $hSizebox Example() Func Example() Local $iW = 250, $iH = 50 $hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x00FF) Local $idResizeLabel = GUICtrlCreateLabel("", $iW - 20, $iH - 20, 22, 22) GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT) GUICtrlSetCursor(-1, 12) $hSizebox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, $iW - 20, $iH - 20, 20, 20, $hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetState() Local $iResize = 0 While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_PRIMARYUP If $iResize Then $iResize = 0 ; restore the default mouse behaviour GUISetCursor(2, 0, $hGui) GUICtrlSetState($idResizeLabel, $GUI_SHOW) EndIf Case $idResizeLabel $iResize = 1 GUICtrlSetState($idResizeLabel, $GUI_HIDE) GUISetCursor(12, 1, $hGui) MouseDown("MAIN") ; ..now that the Ctrl is hidden, nothing is held down, so we fake it ;) EndSwitch WEnd GUIDelete($hGui) Exit EndFunc ;==>Example Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) Local $aSize = WinGetClientSize($hGui) WinMove($hSizebox, "", $aSize[0] - 20, $aSize[1] - 20) EndFunc ;==>WM_SIZE The question is: how do I color that CreateWindowEx ? Thanks
- 9 replies
-
- sbs_sizebox
- sbs_sizegrip
-
(and 3 more)
Tagged with:
-
I think that _GDIPlus_ImageGetPropertyItem should return a Property Item that can readily be set as a property of another image. Why would one want to do this? A script might (as one of mine does) edit an image of a .jpg file then write the result to a .jpg file. In editing it, in my case, the number of horizontal and vertical pixels change, and the date/time edited should be set as a property. All other property items remain the same. Other GDI+ users may change other properties. So an approach is to copy all the property items from image1 to image2, then update a few properties. M$ provides a Property Item class (id, length, pointer to an array of values) but _GDIPlus_ImageGetPropertyItem returns something different. I think that, wherever reasonable, UDFs that are wrappers for M$ methods should work like M$'s methods. _GDIPlus_ImageGetPropertyItem does not do this: While M$ returns 2 values for a value that is a ratio of 2 numbers, _GDIPlus_ImageGetPropertyItem returns numerator/denominator as a single value (often a Double). _GDIPlus_ImageSetPropertyItem (when included in GDIPlus.au3) will be unable to set ratio property items properly because it cannot know what the numerator and denominator are. So copying such property items will not work properly. M$ has a Void* buffer where the buffer is an array of values but _GDIPlus_ImageGetPropertyItem() returns the values in the same 1-d array as id, length and type. M$'s approach produces a 1-d array with the same number of elements for all property items while _GDIPlus_ImageGetPropertyItem produces a 1-d array with various numbers of elements. To me, this is not good programming practice. For a photo from a Sony camera, the worst case has 1-d array with 67 elements. When combined into a 2-d array with the property items of all properties, there are 66 rows and 67 columns, with many elements not used. So I suggest that _GDIPlus_ImageGetPropertyItem look like this: ; #FUNCTION# ==================================================================================================================== ; Name ..........: cGDIPlus_ImageGetPropertyItem ; Description ...: Gets a specified property item (piece of meta data) from an Image object ; Syntax ........: cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success: Array containing the values of the property item ; [0] - identifier ; [1] - size, in bytes, of the value array ; [2] - type of value(s) in the value array ; [3] - value array ; Failure: Sets the @error flag to non-zero, @extended may contain GPSTATUS error code ($GPID_ERR*). ; Author ........: Eukalyptus ; Modified ......: c.haslam ; Remarks .......: types: unsigned byte = 1, ASCII string = 2, unsigned short = 3, unsigned long = 4, ; unsinged rational = 5, undefined = 7, signed long = 9, signed rational = 10 ; Related .......: _GDIPlus_ImageGetPropertyIdList ; Link ..........: https://msdn.microsoft.com/en-us/library/windows/desktop/ms535390(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534414(v=vs.85).aspx ; Example .......: Yes ; =============================================================================================================================== Func cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $iSize = __GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) If @error Then Return SetError(@error, @extended, -1) Local $tBuffer = DllStructCreate("byte[" & $iSize & "];") Local $pBuffer = DllStructGetPtr($tBuffer) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", _ $iPropID, "uint", $iSize, "struct*", $tBuffer) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], False) Local $tPropertyItem = DllStructCreate("int id; int length; short type; ptr pvalue;", $pBuffer) Local $iBytes = DllStructGetData($tPropertyItem, "length") Local $pValue = DllStructGetData($tPropertyItem, "pvalue") Local $aRet[4] Local $type = DllStructGetData($tPropertyItem,'type') Local $tValues, $iValues Switch $type Case 2 ;ASCII String $iValues = 1 $tValues = DllStructCreate("char[" & $iBytes & "];", $pValue) Case 3 ;Array of UShort $iValues = Int($iBytes / 2) $tValues = DllStructCreate("ushort[" & $iValues & "];", $pValue) Case 4, 5 ;Array of UInt / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("uint[" & $iValues & "];", $pValue) Case 9, 10 ;Array of Int / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("int[" & $iValues & "];", $pValue) Case Else ;Array of Bytes $iValues = 1 $tValues = DllStructCreate("byte[" & $iBytes & "];", $pValue) EndSwitch $aRet[0] = DllStructGetData($tPropertyItem,'id') $aRet[1] = $iBytes $aRet[2] = $type Local $aVals[$iValues] If $type=2 Or $type=7 Then ; ASCII string or undefined $aVals[0] = DllStructGetData($tValues,1) Else For $i = 0 To $iValues-1 $aVals[$i] = DllStructGetData($tValues,1,$i+1) Next EndIf $aRet[3] = $aVals Return $aRet EndFunc And here is an example: #include <GDIPlus.au3> #include <Array.au3> Example() Func Example() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile(RegRead((@AutoItX64 = True ? "HKLM\SOFTWARE\Wow6432Node\AutoIt v3\AutoIt" : "HKLM\SOFTWARE\AutoIt v3\AutoIt"), "InstallDir") & "\Examples\GUI\Torus.png") If @error Then _GDIPlus_Shutdown() MsgBox(16, "", "An error has occured - unable to load image!", 30) Return False EndIf Local $ar = _GDIPlus_ImageGetPropertyIdList($hImage) Local $vPropNbrs[UBound($ar,1)-1] ; Extract ID numbers For $i = 1 To UBound($ar,1)-1 $vPropNbrs[$i-1] = $ar[$i][0] Next ; Get all property items Local $aPropItems[UBound($vPropNbrs)][4],$vPropItem For $i = 0 To UBound($vPropNbrs)-1 $vPropItem = cGDIPlus_ImageGetPropertyItem($hImage,$vPropNbrs[$i]) For $j = 0 To 3 $aPropItems[$i][$j] = $vPropItem[$j] Next Next ; Collapse values arrays so _ArrayDisplay can display them Local $ar = $aPropItems For $i = 0 To UBound($aPropItems,1)-1 $ar[$i][0] = '0x'&Hex($ar[$i][0],4) $ar[$i][3] = '' For $j = 0 To UBound($aPropItems[$i][3])-1 $ar[$i][3] &= ($aPropItems[$i][3])[$j]&'|' Next $ar[$i][3] = StringTrimRight($ar[$i][3],1) Next _ArrayDisplay($ar) _GDIPlus_Shutdown() EndFunc Unfortunately this example (based on one now in the Help) does not exercise most of the item types, but I do not know of a file with EXIF metadata that is on most PCs. I have tested this code by updating and adding property items to torus.jpg and to a photo taken by a Sony camera. The code for implementing and calling _GDIPlus_ImageSetPropertyItem will be fairly simple [see below]. Your thoughts?
-
#include <GDIPlus.au3> Text2PNG(@ScriptDir & "\x_2.png", 0x7DFFFFFF) ; Transparent text Func Text2PNG($sFile, $iColor) _GDIPlus_Startup() Local $hImage = _GDIPlus_BitmapCreateFromFile ( $sFile ) ;Local $hImage = _GDIPlus_BitmapCreateFromScan0(400, 250) ;$sFile2 = @ScriptDir & "\x_3.png" ;_GDIPlus_ImageSaveToFile($hImage, $sFile2) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $GDIP_TEXTRENDERINGHINT_ANTIALIAS) _GDIPlus_GraphicsClear($hGraphics, $iColor) _GDIPlus_GraphicsDrawString($hGraphics, "Hello", 0, 0, "Arial", 32, 0) _GDIPlus_ImageSaveToFile($hImage, $sFile) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() EndFunc ;==>Text2PNG The image is at 50% transparency, im trying to write the text on it with the same transparency. What transparency lvl the text will need to be drawn, to achieve the same transparency as on the image, 50% too? (0x7DFFFFFF) But atm it does not draw anything unless i create a new bitmap from scan, whats going on?
-
This is a project that I have been working on for several months off and on. It's a simple "What You Hear" MP3 @ 320Kbps and WAV audio recorder. Features: - LoudMax, a Gain Controller and Look-Ahead Limiter - Auto Shut-Off after one minute of silence - Side-by-Side Simulated LED Meter - Running Time Counter It started off being a large project, but I eventually stripped it down to its bare essentials because I came to realize that it would be very difficult to deal with every sound card and every way a PC is set up for audio. It would have been a nightmare that I was not willing to go through. This project contains the most up-to-date BASS.dll v.2.4.15.0 - December 17, 2019. All BASS Dll's are 32bit. Those and the needed UDF's are included in the zip file. I will try to explain how it works in the next post. Download: BASS VST Recorder v1.1.zip
-
I have been working on audio graphical scripts these last several months. This is my last script on this subject for now. On to other projects. Credits: UEZ, Eukalyptus, BrettF, Prog@ndy, Authenticity and the AutoIt Community. Thanks to all that made these scripts possible! Please let me know if you have any problems with it. Download: LIVE Stereo Audio Waveform v2.zip
- 10 replies
-
- audio wave
- gdiplus
-
(and 1 more)
Tagged with:
-
I have been playing with this script off and on for about a month - trying to get the needles to look more realistic. It's best to use with an audio limiter on the source audio, or else you'll be tweaking the input levels on every song. It should work with any version of AutoIt, starting with 3.3.8.1. Please report any problems with it. Credits are in the script. Download: LIVE Analog Stereo Meter.au3
-
- analog meter
- gdiplus
-
(and 1 more)
Tagged with:
-
How can you select the specific style of a font with multiple * .otf files? The font in question has several files: Thin Thin Italic Extra-Light Extra-Light Italic Light Light Italic Regular Regular Italic Medium Medium Italic Semi-Bold Semi-Bold Italic Bold Bold Italic Extra-Bold Extra-Bold Italic Black Black Italic But after doing several tests I can recall the font like this, without being able to specify the precise style: Local $hFamily = _GDIPlus_FontFamilyCreate("Poppins") ; Local $hFont = _GDIPlus_FontCreate($hFamily, 95, 1+2, 3) ; Example I cannot therefore select "Poppins Black Italic" but only "Poppins" Thank you
-
I ran across a topic while researching the BASS UDF... https://www.autoitscript.com/forum/topic/155845-carpenter-needs-help-performing-serious-surgery-on-audiometer2/ and then remembered another topic... https://www.autoitscript.com/forum/topic/121624-sound-level-sampling/ which got me to thinking as to how I could get the first topic to go LIVE without the need of loading an mp3. This will accept any LIVE AUDIO INPUT. Be sure to read this post if you have trouble with it... https://www.autoitscript.com/forum/topic/121624-sound-level-sampling/?do=findComment&comment=1400178 Also, read the comments I made in the script, so you will know how it will react to LIVE INPUT streams. Live FFT Visual Spectrum.zip LIVE Multiband FFT Visual Spectrum.au3
-
Hello folks, I've been working on a couple of GDI+ gauges, they need a bit of polish here and there I'd appreciate it if you guys/girls could play around and give me some suggestions. Cheers. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=Gauges With Sliders.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstants.au3> #include <GDIplus.au3> #include <ColorConstants.au3> #include <Array.au3> Global Const $width = @DesktopWidth * 3 / 4 Global Const $height = @DesktopHeight Global $title = "GDI+" ; Build your GUI here Opt("GUIOnEventMode", 1) Global $hwnd = GUICreate($title, @DesktopWidth, @DesktopHeight, -1, -1, $WS_SIZEBOX) GUISetOnEvent($GUI_EVENT_CLOSE, "close") GUISetState() #Region Sliders Global $VariableMaxValue = 100 Global $SecondaryMaxValue = 100 Global $VariableMinValue = 0 Global $HexLabel = GUICtrlCreateLabel("Hex Value: ", @DesktopWidth - 300, 50, 150, 20) GUICtrlSetColor($HexLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idSliderThick = GUICtrlCreateSlider(@DesktopWidth - 300, 100, 250, 20) GUICtrlSetLimit(-1, 240, 0) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $ThickLabel = GUICtrlCreateLabel("Thickness Value: " & GUICtrlRead($idSliderThick), @DesktopWidth - 300, 120, 150, 20) GUICtrlSetColor($ThickLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idSliderVal = GUICtrlCreateSlider(@DesktopWidth - 300, 150, 250, 20) GUICtrlSetLimit(-1, $VariableMaxValue, $VariableMinValue) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $ValLabel = GUICtrlCreateLabel("Variable Value: " & GUICtrlRead($idSliderVal), @DesktopWidth - 300, 170, 150, 20) GUICtrlSetColor($ValLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idSliderScale = GUICtrlCreateSlider(@DesktopWidth - 300, 200, 250, 20) GUICtrlSetLimit(-1, 20, 0) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $ScaleLabel = GUICtrlCreateLabel("Scale Value: " & (GUICtrlRead($idSliderScale) * .1), @DesktopWidth - 300, 220, 150, 20) GUICtrlSetColor($ScaleLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idStartAngleScale = GUICtrlCreateSlider(@DesktopWidth - 300, 250, 250, 20) GUICtrlSetLimit(-1, 360, 0) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $StartAngleLabel = GUICtrlCreateLabel("Angle Value: " & GUICtrlRead($idStartAngleScale), @DesktopWidth - 300, 270, 150, 20) GUICtrlSetColor($StartAngleLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idSweepScale = GUICtrlCreateSlider(@DesktopWidth - 300, 300, 250, 20) GUICtrlSetLimit(-1, 360, 0) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $SweepLabel = GUICtrlCreateLabel("Sweep Value: " & GUICtrlRead($idSweepScale), @DesktopWidth - 300, 320, 150, 20) GUICtrlSetColor($SweepLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idCheckmarksScale = GUICtrlCreateSlider(@DesktopWidth - 300, 350, 250, 20) GUICtrlSetLimit(-1, 20, 0) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $CheckmarkLabel = GUICtrlCreateLabel("No. of Checkmarks: " & GUICtrlRead($idCheckmarksScale), @DesktopWidth - 300, 370, 150, 20) GUICtrlSetColor($CheckmarkLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $idVarMin = GUICtrlCreateSlider(@DesktopWidth - 300, 450, 250, 20) GUICtrlSetLimit(-1, 0, -50) ; change min/max value GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $MinLabel = GUICtrlCreateLabel("Min Value: " & GUICtrlRead($idVarMin), @DesktopWidth - 300, 470, 150, 20) GUICtrlSetColor($MinLabel, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $RadioGroup1 = GUICtrlCreateGroup("", @DesktopWidth - 300, 500, 200, 50) Global $clockwiseCtrl = GUICtrlCreateRadio("Clockwise", @DesktopWidth - 280, 520, 80, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetColor(-1, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $antiClockwiseCtrl = GUICtrlCreateRadio("Anti-clockwise", @DesktopWidth - 200, 520, 85, 20) GUICtrlSetColor(-1, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $RadioGroup2 = GUICtrlCreateGroup("", @DesktopWidth - 300, 550, 200, 50) Global $RadialCtrl = GUICtrlCreateRadio("Radial", @DesktopWidth - 280, 570, 80, 20) GUICtrlSetState(-1, $GUI_CHECKED) GUICtrlSetColor(-1, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) Global $SquareCtrl = GUICtrlCreateRadio("Linear", @DesktopWidth - 200, 570, 85, 20) GUICtrlSetColor(-1, $COLOR_WHITE) GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKVCENTER) GUICtrlSetData($idSliderThick, 35) GUICtrlSetData($idSliderScale, 10) GUICtrlSetData($idStartAngleScale, 180) GUICtrlSetData($idSweepScale, 180) GUICtrlSetData($idCheckmarksScale, 10) #EndRegion Sliders GUISetBkColor(0x303030) Global $aWindowSize = WinGetClientSize($hwnd) ; Load your GDI+ resources here: _GDIPlus_Startup() Global $graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd) Global $bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics) Global $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap) While 1 _GDIPlus_GraphicsClear($backbuffer, 0xFF303030) Sleep(50) #Region Test Variables Global $Thickness = GUICtrlRead($idSliderThick) Global $Variable = GUICtrlRead($idSliderVal) Global $tValue = 0xFF000000 Global $rValue = 0x00FF0000 Global $gValue = BitShift((255 - (($Variable / $VariableMaxValue) * 255)), -8) Global $bValue = 0x00 Global $ScalingFactor = GUICtrlRead($idSliderScale) / 10 GUICtrlSetData($HexLabel, "Hex Value: " & HEX(BitOR($tValue, $rValue, $gValue, $bValue))) Global $PenColour = ("0x" & HEX(BitOR($tValue, $rValue, $gValue, $bValue))) GUICtrlSetData($ValLabel, "Variable Value: " & GUICtrlRead($idSliderVal)) GUICtrlSetData($ThickLabel, "Thickness Value: " & GUICtrlRead($idSliderThick)) GUICtrlSetData($ScaleLabel, "Scale Value: " & (GUICtrlRead($idSliderScale) * .1)) GUICtrlSetData($StartAngleLabel, "Angle Value: " & GUICtrlRead($idStartAngleScale)) GUICtrlSetData($SweepLabel, "Sweep Value: " & GUICtrlRead($idSweepScale)) GUICtrlSetData($CheckmarkLabel, "No. Of Checkmarks: " & GUICtrlRead($idCheckmarksScale)) GUICtrlSetData($MinLabel, "Min Value: " & GUICtrlRead($idVarMin)) GUICtrlSetLimit($idSliderVal, $VariableMaxValue, $VariableMinValue) Local $Radius = 300 If GUICtrlRead($clockwiseCtrl) = $GUI_CHECKED Then Local $Clockwise = True Else Local $Clockwise = False EndIf Local $StartAngle = GUICtrlRead($idStartAngleScale) Local $SweepAngle = GUICtrlRead($idSweepScale) Local $CentrePointX = 500 Local $CentrePointY = 500 Local $NoOfCheckmarks = GUICtrlRead($idCheckmarksScale) Local $CheckLength = 15 Local $AllowedLimit = 75 Local $VariableLimit = True Local $VariableMinValue = GUICtrlRead($idVarMin) #EndRegion Test Variables #Region Function Call If GUICtrlRead($RadialCtrl) = $GUI_CHECKED Then _GDIPlus_GraphicsDrawPath($backbuffer, _Gauges_DrawRadialGauge($backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Variable, $ScalingFactor, $Clockwise, $StartAngle, $SweepAngle, $VariableMaxValue, $NoOfCheckmarks, $CheckLength, $VariableLimit, $AllowedLimit, $VariableMinValue)) GUICtrlSetState($idSliderThick, $GUI_SHOW) GUICtrlSetState($ThickLabel, $GUI_SHOW) GUICtrlSetState($idStartAngleScale, $GUI_SHOW) GUICtrlSetState($StartAngleLabel, $GUI_SHOW) GUICtrlSetState($idSweepScale, $GUI_SHOW) GUICtrlSetState($SweepLabel, $GUI_SHOW) GUICtrlSetState($RadioGroup1, $GUI_SHOW) GUICtrlSetState($clockwiseCtrl, $GUI_SHOW) GUICtrlSetState($antiClockwiseCtrl, $GUI_SHOW) Else _GDIPlus_GraphicsDrawPath($backbuffer, _Gauges_DrawLinearGauge($backbuffer, $CentrePointX, $CentrePointY, 600, 100, $Variable, $ScalingFactor, $NoOfCheckmarks, $CheckLength, $VariableMaxValue, $VariableLimit, $AllowedLimit, $VariableMinValue)) GUICtrlSetState($idSliderThick, $GUI_HIDE) GUICtrlSetState($ThickLabel, $GUI_HIDE) GUICtrlSetState($idStartAngleScale, $GUI_HIDE) GUICtrlSetState($StartAngleLabel, $GUI_HIDE) GUICtrlSetState($idSweepScale, $GUI_HIDE) GUICtrlSetState($SweepLabel, $GUI_HIDE) GUICtrlSetState($RadioGroup1, $GUI_HIDE) GUICtrlSetState($clockwiseCtrl, $GUI_HIDE) GUICtrlSetState($antiClockwiseCtrl, $GUI_HIDE) EndIf #EndRegion Function Call _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height) WEnd Func close() _GDIPlus_GraphicsDispose($backbuffer) _GDIPlus_BitmapDispose($bitmap) _GDIPlus_GraphicsDispose($graphics) _GDIPlus_Shutdown() Exit EndFunc ;==>close #Region Functions #Region Draw Linear Gauge ; #FUNCTION# ==================================================================================================================== ; Name...........: _Gauges_DrawLinearGauge ; Description ...: Creates a horizontal or vertical gauge in the graphics backbuffer ; Syntax.........: _Gauges_DrawLinearGauge(ByRef $backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $Variable, [$ScalingFactor = 1, [$NoOfCheckmarks = 6, [$CheckLength = 20, ; + [$VariableMaxValue = 256, [$VariableLimit = False, [$AllowedLimit = 0, [$VariableMinValue = 0]]]]]]] ) ; Parameters ....: $backbuffer - [byref] The graphics object to draw the gauge to. ; $CentrePointX - The horizontal coordinate of the centre of the gauge. ; $CentrePointY - The vertical coordinate of the centre of the gauge. ; $GaugeWidth - The width of the gauge (Duh). ; $GaugeHeight - The height of the gauge. ; $Variable - The variable used to change the gauge. ; $ScalingFactor - [optional] Scales the gauge by this factor. Default is 1, i.e. no scaling. ; $NoOfCheckmarks - [optional] The number of dashes indicating a scale around the gauge. Default is 6. ; $CheckLength - [optional] The length of the checkmarks in pixels. Default is 20. ; $VariableMaxValue - [optional] The maximum value of the variable. Default is 256. ; $VariableLimit - [optional] Boolean, if TRUE, displays a red limit indicator on the scale. Default is FALSE. ; $AllowedLimit -[optional] The value of the above limit if it is drawn. Default is 0. ; $VariableMinValue -[optional] The minimum value of the variable. Only used if negative numbers are required. Default is 0. ; Author ........: Simon Renardson (Sidley) ; Modified.......: ; Remarks .......: There is a more comprehensive function available, but I deemed it overkill for the majority of people. ; Related .......: _GDIPlus_ ; Example .......: Yes ; =============================================================================================================================== ;Draw a Linear gauge to the screen Func _Gauges_DrawLinearGauge(ByRef $backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $Variable, $ScalingFactor = 1, $NoOfCheckmarks = 6, $CheckLength = 20, $VariableMaxValue = 256, $VariableLimit = False, $AllowedLimit = 0, $VariableMinValue = 0) If $Variable >= 0 Then Local $BrushColour = ("0xFF4BF221") Else Local $BrushColour = ("0xFFFF0000") EndIf If $GaugeWidth >= $GaugeHeight Then Local $GaugeBrush = _GDIPlus_HatchBrushCreate(1, 0x00000000, $BrushColour) ;Set to vertical hatch if the gauge is horizontal Else Local $GaugeBrush = _GDIPlus_HatchBrushCreate(0, 0x00000000, $BrushColour) ;Set to horizontal hatch if the gauge is vertical EndIf Local $TextBrush = _GDIPlus_BrushCreateSolid($BrushColour) Local $Path = _GDIPlus_PathCreate() Local $hPen = _GDIPlus_PenCreate("0xFF96A29F", 2 * $ScalingFactor) ; Off-white pen for outlines Local $AllowedPen = _GDIPlus_PenCreate("0xFFFF0000", 8 * $ScalingFactor) ;Red pen for allowed speed indicators If $GaugeWidth >= $GaugeHeight Then ;If the gauge is to be length wise _GDIPlus_PathAddLine($Path, $CentrePointX - ((($GaugeWidth / 2) + $VariableMinValue * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue))) * $ScalingFactor), ($CentrePointY + ($GaugeHeight / 2) * $ScalingFactor), $CentrePointX - ((($GaugeWidth / 2) + $VariableMinValue * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue))) * $ScalingFactor) + ($Variable * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor), ($CentrePointY + ($GaugeHeight / 2) * $ScalingFactor)) _GDIPlus_PathAddLine($Path, $CentrePointX - ((($GaugeWidth / 2) + $VariableMinValue * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue))) * $ScalingFactor) + ($Variable * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor), ($CentrePointY - ($GaugeHeight / 2) * $ScalingFactor), $CentrePointX - ((($GaugeWidth / 2) + $VariableMinValue * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue))) * $ScalingFactor), ($CentrePointY - ($GaugeHeight / 2) * $ScalingFactor)) _GDIPlus_PathCloseFigure($Path) Else ;If the gauge is to be height wise _GDIPlus_PathAddLine($Path, ($CentrePointX + ($GaugeWidth / 2) * $ScalingFactor), ($CentrePointY + (($GaugeHeight / 2) * $ScalingFactor)) + ($VariableMinValue * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor), ($CentrePointX + ($GaugeWidth / 2) * $ScalingFactor), ($CentrePointY + (($GaugeHeight / 2) * $ScalingFactor)) + ($VariableMinValue * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor) - $Variable * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor) _GDIPlus_PathAddLine($Path, ($CentrePointX - ($GaugeWidth / 2) * $ScalingFactor), ($CentrePointY + (($GaugeHeight / 2) * $ScalingFactor)) + ($VariableMinValue * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor) - $Variable * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor, ($CentrePointX - ($GaugeWidth / 2) * $ScalingFactor), ($CentrePointY + (($GaugeHeight / 2) * $ScalingFactor)) + ($VariableMinValue * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor)) _GDIPlus_PathCloseFigure($Path) EndIf _GDIPlus_GraphicsFillPath($backbuffer, $Path, $GaugeBrush) ;Draw the gauge _DrawBar($backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $VariableMaxValue, $VariableMinValue, $hPen, $ScalingFactor) ;Draw the outline for the gauge _DrawLinearGaugeCheckMarks($backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $ScalingFactor, $VariableMaxValue, $NoOfCheckmarks, $CheckLength, $hPen) ;Draw the checkmarks for the gauge If $VariableLimit Then _DrawLinearAllowedSpeed($backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $VariableMaxValue, $AllowedLimit, $AllowedPen, $ScalingFactor, $VariableLimit) ;Draw the allowed speed indicator(s) for the gauge EndIf _LinearGaugeText($backbuffer, $Variable, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $ScalingFactor, $TextBrush) ;Put the gauge text above the gauge _GDIPlus_PathDispose($Path) ;Tidy up _GDIPlus_BrushDispose($GaugeBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($AllowedPen) _GDIPlus_BrushDispose($TextBrush) EndFunc ;==>_DrawLinearGauge ;Draw the text for the main gauge Func _LinearGaugeText(ByRef $backbuffer, $Variable, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $ScalingFactor, ByRef $TextBrush) Local $FontSize = 80 * $ScalingFactor ;Linear gauge font size Local $Path = _GDIPlus_PathCreate() Local $Format = _GDIPlus_StringFormatCreate() Local $Family = _GDIPlus_FontFamilyCreate("Agency FB") ;Centre text font Local $Font = _GDIPlus_FontCreate($Family, $FontSize, 2) _GDIPlus_StringFormatSetAlign($Format, 2) ;Right align _GDIPlus_GraphicsSetSmoothingMode($backbuffer, 2) ;Change smoothing mode for text If $GaugeWidth >= $GaugeHeight Then Local $Layout = _GDIPlus_RectFCreate($CentrePointX - ($FontSize * $ScalingFactor / 2), $CentrePointY - ($GaugeHeight / 2 * $ScalingFactor) - $FontSize * 1.5 * $ScalingFactor) ;Set text position for inner text Else Local $Layout = _GDIPlus_RectFCreate($CentrePointX - ($GaugeWidth / 2) * $ScalingFactor - $FontSize * 2, ($CentrePointY - $FontSize * $ScalingFactor / 2)) ;Set text positionfor inner text EndIf _GDIPlus_PathAddString($Path, $Variable, $Layout, $Family, 0, $FontSize * $ScalingFactor) _GDIPlus_GraphicsFillPath($backbuffer, $Path, $TextBrush) $Layout = 0 _GDIPlus_PathDispose($Path) _GDIPlus_FontDispose($Font) _GDIPlus_StringFormatDispose($Format) _GDIPlus_FontFamilyDispose($Family) EndFunc ;==>_LinearGaugeText ;Draw the outline of the gauge Func _DrawBar(ByRef $backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $VariableMaxValue, $VariableMinValue, ByRef $hPen, $ScalingFactor = 1) Local $Path = _GDIPlus_PathCreate() _GDIPlus_PathAddLine($Path, $CentrePointX - ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2) * $ScalingFactor, $CentrePointX + ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2) * $ScalingFactor) _GDIPlus_PathAddLine($Path, $CentrePointX + ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY + ($GaugeHeight / 2) * $ScalingFactor, $CentrePointX - ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY + ($GaugeHeight / 2) * $ScalingFactor) _GDIPlus_PathCloseFigure($Path) If $GaugeWidth >= $GaugeHeight Then _GDIPlus_GraphicsDrawLine($backbuffer, $CentrePointX - ($GaugeWidth / 2 * $ScalingFactor) - $VariableMinValue * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2) * $ScalingFactor, $CentrePointX - ($GaugeWidth / 2 * $ScalingFactor) - $VariableMinValue * ($GaugeWidth / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor, $CentrePointY + ($GaugeHeight / 2) * $ScalingFactor, $hPen) Else _GDIPlus_GraphicsDrawLine($backbuffer, $CentrePointX - ($GaugeWidth / 2 * $ScalingFactor), ($CentrePointY + (($GaugeHeight / 2) * $ScalingFactor)) + ($VariableMinValue * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor), $CentrePointX + ($GaugeWidth / 2 * $ScalingFactor), ($CentrePointY + (($GaugeHeight / 2) * $ScalingFactor)) + ($VariableMinValue * ($GaugeHeight / ($VariableMaxValue - $VariableMinValue)) * $ScalingFactor), $hPen) EndIf _GDIPlus_GraphicsDrawPath($backbuffer, $Path, $hPen) ;Draw the outline _GDIPlus_PathDispose($Path) EndFunc ;==>_DrawBar ;Draw the checkmarks Func _DrawLinearGaugeCheckMarks(ByRef $backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $ScalingFactor, $VariableMaxValue, $NoOfCheckmarks, $CheckLength, ByRef $hPen) Local $TextBrush = _GDIPlus_BrushCreateSolid("0xFFFFFFFF") ;Solid white brush for the checkmarks Local $aPoints[$NoOfCheckmarks][2] ;Two cartesian coordinates for each checkmark Local $aMarkText[$NoOfCheckmarks] ; The text for each checkmark ;Create the font for the checkmarks Local $FontSize = 15 * $ScalingFactor ;The font size (Scaled) Local $Format = _GDIPlus_StringFormatCreate() Local $Family = _GDIPlus_FontFamilyCreate("Agency FB") Local $Font = _GDIPlus_FontCreate($Family, $FontSize, 2) For $i = 0 to($NoOfCheckmarks - 1) $aMarkText[$i] = Round($VariableMinValue + (($VariableMaxValue - $VariableMinValue) / ($NoOfCheckmarks - 1)) * $i) Next If $GaugeWidth >= $GaugeHeight Then _GDIPlus_GraphicsDrawLine($backbuffer, $CentrePointX - ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2 + 10) * $ScalingFactor, $CentrePointX + ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2 + 10) * $ScalingFactor, $hPen) For $i = 0 to($NoOfCheckmarks - 1) ;Set the coordinates of each checkmark $aPoints[$i][0] = ($CentrePointX - ($GaugeWidth / 2) * $ScalingFactor) + ($GaugeWidth * $ScalingFactor / ($NoOfCheckmarks - 1)) * $i ;Set x position depending on the number of checkmarks and the length of the gauge $aPoints[$i][1] = $CentrePointY - ($GaugeHeight / 2 + 10) * $ScalingFactor ;Height remains uniform Next For $i = 0 to($NoOfCheckmarks - 1) _GDIPlus_GraphicsDrawLine($backbuffer, $aPoints[$i][0], $aPoints[$i][1], $aPoints[$i][0], ($aPoints[$i][1] - $CheckLength * $ScalingFactor), $hPen) ;Draw a line $Checklength long $Layout = _GDIPlus_RectFCreate(($aPoints[$i][0] - $FontSize), ($aPoints[$i][1] - $CheckLength * $ScalingFactor - ($FontSize * 1.5) * $ScalingFactor), 0, 0) _GDIPlus_GraphicsDrawStringEx($backbuffer, $aMarkText[$i], $Font, $Layout, $Format, $TextBrush) ;Draw the sext for the checkmark Next Else _GDIPlus_GraphicsDrawLine($backbuffer, $CentrePointX - ($GaugeWidth / 2 * $ScalingFactor) - 10 * $ScalingFactor, $CentrePointY + ($GaugeHeight / 2) * $ScalingFactor, $CentrePointX - ($GaugeWidth / 2 * $ScalingFactor) - 10 * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2) * $ScalingFactor, $hPen) For $i = 0 to($NoOfCheckmarks - 1) $aPoints[$i][0] = $CentrePointX - ($GaugeWidth / 2 + 10) * $ScalingFactor $aPoints[$i][1] = ($CentrePointY + ($GaugeHeight / 2) * $ScalingFactor) - ($GaugeHeight * $ScalingFactor / ($NoOfCheckmarks - 1)) * $i Next For $i = 0 to($NoOfCheckmarks - 1) _GDIPlus_GraphicsDrawLine($backbuffer, $aPoints[$i][0], $aPoints[$i][1], $aPoints[$i][0] - $CheckLength * $ScalingFactor, $aPoints[$i][1], $hPen) $Layout = _GDIPlus_RectFCreate(($aPoints[$i][0] - $CheckLength * $ScalingFactor - $FontSize * 2.5), $aPoints[$i][1] - $FontSize / 1.5, 0, 0) _GDIPlus_GraphicsDrawStringEx($backbuffer, $aMarkText[$i], $Font, $Layout, $Format, $TextBrush) Next EndIf $Layout = 0 _GDIPlus_BrushDispose($TextBrush) _GDIPlus_FontDispose($Font) _GDIPlus_StringFormatDispose($Format) _GDIPlus_FontFamilyDispose($Family) EndFunc ;==>_DrawLinearGaugeCheckMarks Func _DrawLinearAllowedSpeed(ByRef $backbuffer, $CentrePointX, $CentrePointY, $GaugeWidth, $GaugeHeight, $MaxValue, $AllowedLimit, ByRef $AllowedPen, $ScalingFactor, $PrimaryAllowedSpeed) Local $Path = _GDIPlus_PathCreate() If $PrimaryAllowedSpeed Then If $GaugeWidth >= $GaugeHeight Then _GDIPlus_PathAddLine($Path, $CentrePointX - ($GaugeWidth / 2) * $ScalingFactor, $CentrePointY - ($GaugeHeight / 2 + 15) * $ScalingFactor + 3 * $ScalingFactor, ($CentrePointX - (($GaugeWidth / 2) * $ScalingFactor)) + ($GaugeWidth * $AllowedLimit / 100 * $ScalingFactor), $CentrePointY - ($GaugeHeight / 2 + 15) * $ScalingFactor + 3 * $ScalingFactor) Else _GDIPlus_PathAddLine($Path, $CentrePointX - ($GaugeWidth / 2) * $ScalingFactor - 10 * $ScalingFactor, $CentrePointY + ($GaugeHeight / 2) * $ScalingFactor, $CentrePointX - ($GaugeWidth / 2) * $ScalingFactor - 10 * $ScalingFactor, ($CentrePointY + ($GaugeHeight / 2) * $ScalingFactor) - ($GaugeHeight * $AllowedLimit / 100 * $ScalingFactor)) EndIf EndIf _GDIPlus_GraphicsDrawPath($backbuffer, $Path, $AllowedPen) _GDIPlus_PathDispose($Path) EndFunc ;==>_DrawLinearAllowedSpeed #EndRegion Draw Linear Gauge #Region Draw Radial Gauge ; #FUNCTION# ==================================================================================================================== ; Name...........: _Gauges_DrawRadialGauge ; Description ...: Creates a radial gauge in the graphics backbuffer ; Syntax.........: _Gauges_DrawRadialGauge(ByRef $backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Variable, $ScalingFactor = 1, $Clockwise = True, $StartAngle = 0, ; + $SweepAngle = 180, $NoOfCheckmarks = 6, $CheckLength = 20, $VariableMaxValue = 256, $VariableLimit = True, $AllowedLimit = 0, $VariableMinValue = 0) ; Parameters ....: $backbuffer - [byref] The graphics object to draw the gauge to. ; $CentrePointX - The horizontal coordinate of the centre of the gauge. ; $CentrePointY - The vertical coordinate of the centre of the gauge. ; $Radius - The radius of the outer edge of the gauge. ; $Thickness - The thickness of the gauge in pixels. ; $Variable - The variable used to change the gauge. ; $ScalingFactor - [optional] Scales the gauge by this factor. Default is 1, i.e. no scaling. ; $Clockwise - [optional] Boolean, determines whether the gauge fills clockwise or anti-clockwise. Default is TRUE, i.e. clockwise. ; $StartAngle - [optional] The starting angle of the gauge. Default is 0 (East). ; $SweepAngle - [optional] The sweep angle of the gauge (How many degrees it rotates through). The default is 180. ; $NoOfCheckmarks - [optional] The number of dashes indicating a scale around the gauge. Default is 6. ; $CheckLength - [optional] The length of the checkmarks in pixels. Default is 20. ; $VariableMaxValue - [optional] The maximum value of the variable. Default is 256. ; $VariableLimit - [optional] Boolean, if TRUE, displays a red limit indicator on the scale. Default is FALSE. ; $AllowedLimit -[optional] The value of the above limit if it is drawn. Default is 0. ; $VariableMinValue -[optional] The minimum value of the variable. Only used if negative numbers are required. Default is 0. ; Author ........: Simon Renardson (Sidley) ; Modified.......: ; Remarks .......: There is a more comprehensive function available, but I deemed it overkill for the majority of people. ; Related .......: _GDIPlus_ ; Example .......: Yes ; =============================================================================================================================== ;Draw Gauge (Speed/Load Level) ;Creates Completed Radial Gauge ;~ _DrawRadialGauge($CentrePointX, $CentrePointY, $Radius, $Thickness, $Variable, [$ScalingFactor = 1, [$Clockwise = True, [$StartAngle = 0, [$SweepAngle = 180, [$MaxValue = 256, [$NoOfCheckmarks = 10, [$CheckLength = 20]]]]]]]) Func _Gauges_DrawRadialGauge(ByRef $backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Variable, $ScalingFactor = 1, $Clockwise = True, $StartAngle = 0, $SweepAngle = 180, $NoOfCheckmarks = 6, $CheckLength = 20, $VariableMaxValue = 256, $VariableLimit = True, $AllowedLimit = 0, $VariableMinValue = 0) Local $BrushColour = ("0x" & HEX(BitOR(0xFFFF0000, BitShift((255 - (($Variable / $VariableMaxValue) * 255)), -8)))) Local $GaugeBrush = _GDIPlus_HatchBrushCreate(39, 0xFF000000, $BrushColour) Local $TextBrush = _GDIPlus_BrushCreateSolid($BrushColour) Local $Path = _GDIPlus_PathCreate() Local $hPen = _GDIPlus_PenCreate("0xFF96A29F", 2 * $ScalingFactor) ;Pen colour Local $AllowedPen = _GDIPlus_PenCreate("0xFFFF0000", 10 * $ScalingFactor) _GDIPlus_GraphicsSetSmoothingMode($backbuffer, 2) ;TODO may need to be removed If $Clockwise Then ;If clockwise rotation _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle - $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue)), $Variable * $SweepAngle / ($VariableMaxValue - $VariableMinValue)) ;Add outer arc of gauge $Radius -= ($Thickness * $ScalingFactor) ;Reduce radius for inner arc by the thickness of the gauge _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle - $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue)) + ($Variable * $SweepAngle / ($VariableMaxValue - $VariableMinValue)), (-1 * $Variable * $SweepAngle / ($VariableMaxValue - $VariableMinValue))) ;Add inner arc of Gauge Else ;If anti-clockwise rotation _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle + $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue)), (-1 * $Variable * $SweepAngle / ($VariableMaxValue - $VariableMinValue))) ;Add outer arc of gauge $Radius -= ($Thickness * $ScalingFactor) ;Reduce radius for inner arcby the thickness of the gauge _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle + $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue)) - ($Variable * $SweepAngle / ($VariableMaxValue - $VariableMinValue)), $Variable * $SweepAngle / ($VariableMaxValue - $VariableMinValue)) ;Add inner arc of Gauge EndIf $Radius += ($Thickness * $ScalingFactor) ;Return radius to original size _GDIPlus_PathCloseFigure($Path) ;Close the two arcs _GDIPlus_GraphicsFillPath($backbuffer, $Path, $GaugeBrush) ;Fill the gauge and centre text with colour _DrawRadialGaugeText($backbuffer, $Variable, $CentrePointX, $CentrePointY, $Clockwise, $Radius, $ScalingFactor, $TextBrush) ;Draw the centre text _DrawGaugeOutline($backbuffer, $CentrePointX, $CentrePointY, $Radius, $VariableMaxValue, $VariableMinValue, $Thickness, $ScalingFactor, $Clockwise, $StartAngle, $SweepAngle, $hPen) ;Draw the gauge outline _DrawIndicators($backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Clockwise, $ScalingFactor, $StartAngle, $SweepAngle, $hPen, True) ;Draw scale arc _DrawCheckMarks($backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $ScalingFactor, $VariableMaxValue, $NoOfCheckmarks, $CheckLength, $StartAngle, $SweepAngle, $hPen, True) ;Draw scale checkmarks If $VariableLimit Then _DrawRadialAllowedSpeed($backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Clockwise, $ScalingFactor, $StartAngle, $SweepAngle, $AllowedLimit, $AllowedPen, True) ;Draw allowed speed limits EndIf _GDIPlus_PathDispose($Path) ;Tidy up _GDIPlus_BrushDispose($GaugeBrush) _GDIPlus_BrushDispose($TextBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($AllowedPen) EndFunc ;==>_DrawRadialGauge ;Draw Variable Value (Text, Load/Speed Value) ;Creates The Centre Text of the Radial Gauge ;~ Func _DrawRadialGaugeText($ValueText, $CentrePointX, $CentrePointY, $Clockwise, $Radius, $ScalingFactor) Func _DrawRadialGaugeText(ByRef $backbuffer, $ValueText, $CentrePointX, $CentrePointY, $Clockwise, $Radius, $ScalingFactor, ByRef $TextBrush) Local $FontSize = 180 * $ScalingFactor ;Default font size (Scaled) Local $Text = _GDIPlus_PathCreate() Local $Format = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($Format, 2) ;Align right (Doesn't seem to make a difference) Local $Family = _GDIPlus_FontFamilyCreate("Agency FB") ;Centre text font Local $Font = _GDIPlus_FontCreate($Family, $FontSize, 2) Local $Layout = _GDIPlus_RectFCreate($CentrePointX - ($FontSize / 1.3) * $ScalingFactor, $CentrePointY - $FontSize * $ScalingFactor / 2) ;Set position (Top left) _GDIPlus_PathAddString($Text, Round($ValueText, 1), $Layout, $Family, 0, $FontSize * $ScalingFactor) ;Add value to path (To 1 decimal place) _GDIPlus_GraphicsFillPath($backbuffer, $Text, $TextBrush) $Layout = 0 ;Tidy up _GDIPlus_PathDispose($Text) _GDIPlus_FontDispose($Font) _GDIPlus_StringFormatDispose($Format) _GDIPlus_FontFamilyDispose($Family) EndFunc ;==>_DrawRadialGaugeText ;Draw Gauge Outline ;Creates the Outline of the Radial Gauge ;~ Func _DrawGaugeOutline($CentrePointX, $CentrePointY, $Radius, $Thickness, $ScalingFactor, $Clockwise, $StartAngle, $SweepAngle) Func _DrawGaugeOutline(ByRef $backbuffer, $CentrePointX, $CentrePointY, $Radius, $VariableMaxValue, $VariableMinValue, $Thickness, $ScalingFactor, $Clockwise, $StartAngle, $SweepAngle, ByRef $hPen) Local $Path = _GDIPlus_PathCreate() Local Const $PI = 3.141592653589793 $Radius += 2 ;Put the outline 2 px outside the gauge If $Clockwise Then ;If the gauge is to be filled clockwise _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle, $SweepAngle) _GDIPlus_GraphicsDrawLine($backbuffer, $CentrePointX + ($Radius * $ScalingFactor * Cos(($PI / 180) * ($StartAngle - $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue))))), $CentrePointY + ($Radius * $ScalingFactor * Sin(($PI / 180) * ($StartAngle - $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue))))), $CentrePointX + (($Radius - ($Thickness * $ScalingFactor) - (4 * $ScalingFactor)) * Cos(($PI / 180) * ($StartAngle - $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue)))) * $ScalingFactor), $CentrePointY + (($Radius - ($Thickness * $ScalingFactor) - 4) * $ScalingFactor * Sin(($PI / 180) * ($StartAngle - $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue))))), $hPen) $Radius -= ($Thickness * $ScalingFactor) ;Reduce radius for inner arc $Radius -= 4 _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), ($StartAngle + $SweepAngle), -$SweepAngle) Else _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle, -$SweepAngle) _GDIPlus_GraphicsDrawLine($backbuffer, $CentrePointX + ($Radius * $ScalingFactor * Cos(($PI / 180) * ($StartAngle + $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue))))), $CentrePointY + ($Radius * $ScalingFactor * Sin(($PI / 180) * ($StartAngle + $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue))))), $CentrePointX + (($Radius - ($Thickness * $ScalingFactor) - (4 * $ScalingFactor)) * Cos(($PI / 180) * ($StartAngle + $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue)))) * $ScalingFactor), $CentrePointY + (($Radius - ($Thickness * $ScalingFactor) - 4) * $ScalingFactor * Sin(($PI / 180) * ($StartAngle + $VariableMinValue * ($SweepAngle / ($VariableMaxValue - $VariableMinValue))))), $hPen) $Radius -= ($Thickness * $ScalingFactor) ;Reduce radius for inner arc $Radius -= 4 _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle - $SweepAngle, $SweepAngle) EndIf _GDIPlus_PathCloseFigure($Path) ;Close the path _GDIPlus_GraphicsDrawPath($backbuffer, $Path, $hPen) ;Draw the path _GDIPlus_PathDispose($Path) EndFunc ;==>_DrawGaugeOutline ;Draw Scale(s) ;Creates a number of indicative markings around the centre of the radial gauge ;~ Func _DrawIndicators($CentrePointX, $CentrePointY, $Radius, $Thickness, $Clockwise, $ScalingFactor, $StartAngle, $SweepAngle) Func _DrawIndicators(ByRef $backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Clockwise, $ScalingFactor, $StartAngle, $SweepAngle, ByRef $hPen, $Inside) Local $Path = _GDIPlus_PathCreate() $Radius -= ($Thickness + 20) * $ScalingFactor If $Clockwise Then _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle, $SweepAngle) Else ;Doesn't make much difference, but it will be 180 degrees out _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle, -$SweepAngle) EndIf _GDIPlus_GraphicsDrawPath($backbuffer, $Path, $hPen) _GDIPlus_PathDispose($Path) EndFunc ;==>_DrawIndicators ;Draw the allowed speed marker Func _DrawRadialAllowedSpeed(ByRef $backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $Clockwise, $ScalingFactor, $StartAngle, $SweepAngle, _ $AllowedLimit, ByRef $AllowedPen, $Inside) Local $Path = _GDIPlus_PathCreate() $Radius -= ($Thickness + 24) * $ScalingFactor If $Clockwise Then ;Display in a clockwise direction _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle, $SweepAngle * $AllowedLimit / 100) ElseIf NOT $Clockwise Then ;Display in an anti-clockwise direction _GDIPlus_PathAddArc($Path, ($CentrePointX - ($Radius * $ScalingFactor)), ($CentrePointY - ($Radius * $ScalingFactor)), ($Radius * $ScalingFactor * 2), ($Radius * $ScalingFactor * 2), $StartAngle, -$SweepAngle * $AllowedLimit / 100) EndIf _GDIPlus_GraphicsDrawPath($backbuffer, $Path, $AllowedPen) ;Draw with the red pen ($AllowedPen) _GDIPlus_PathDispose($Path) EndFunc ;==>_DrawRadialAllowedSpeed ;DrawCheckmarks (Checkmarks) ;Creates the checkmarks and text around the indicator gauge ;~ Func _DrawCheckMarks($CentrePointX, $CentrePointY, $Radius, $Thickness, $ScalingFactor, $MaxValue, $NoOfCheckmarks, $CheckLength, $StartAngle, $SweepAngle, $hPen) Func _DrawCheckMarks(ByRef $backbuffer, $CentrePointX, $CentrePointY, $Radius, $Thickness, $ScalingFactor, $VariableMaxValue, $NoOfCheckmarks, $CheckLength, $StartAngle, _ $SweepAngle, ByRef $hPen, $Inside) Local Const $PI = 3.141592653589793 Local $TextBrush = _GDIPlus_BrushCreateSolid("0xFFFFFFFF") Local $aPoints[$NoOfCheckmarks][4] ;Creates an array of four points for each check line Local $aMarkText[$NoOfCheckmarks] ;Creates the text for the checkmarks $Radius -= ($Thickness + 20) * $ScalingFactor For $i = 0 to ($NoOfCheckmarks-1) $aMarkText[$i] = Round((($VariableMaxValue - $VariableMinValue) / ($NoOfCheckmarks - 1)) * $i) + $VariableMinValue ;Round checkmark values to one decimal place Next Local $aAngles[$NoOfCheckmarks] = [] ;Create an array to hold the angles at which the checkmarks should be If $Clockwise Then For $i = 0 to($NoOfCheckmarks - 1) $aAngles[$i] = $StartAngle + (($SweepAngle / ($NoOfCheckmarks - 1)) * $i) ;Spread out checkmarks evenly over the gauge Next Else ;For anticlockwise filling gauge For $i = 0 to($NoOfCheckmarks - 1) $aAngles[$i] = $StartAngle - (($SweepAngle / ($NoOfCheckmarks - 1)) * $i) ;Spread out checkmarks evenly over the gauge Next EndIf For $i = 0 to($NoOfCheckmarks - 1) $aAngles[$i] = $aAngles[$i] * $PI / 180 ;Convert degrees to radians $aPoints[$i][0] = $CentrePointX + ($Radius * Cos($aAngles[$i]) * $ScalingFactor) ;Create cartesian coordinates for the check lines from polar coordinates (Radius, angle) $aPoints[$i][1] = $CentrePointY + ($Radius * Sin($aAngles[$i]) * $ScalingFactor) $aPoints[$i][2] = $CentrePointX + (($Radius - ($CheckLength * $ScalingFactor)) * Cos($aAngles[$i]) * $ScalingFactor) $aPoints[$i][3] = $CentrePointY + (($Radius - ($CheckLength * $ScalingFactor)) * Sin($aAngles[$i]) * $ScalingFactor) Next ;Font data for checkmark text Local $Format = _GDIPlus_StringFormatCreate() Local $Family = _GDIPlus_FontFamilyCreate("Agency FB") Local $FontSize = 15 Local $Font = _GDIPlus_FontCreate($Family, $FontSize * $ScalingFactor, 2) For $i = 0 to($NoOfCheckmarks - 1) ;For each checkmark _GDIPlus_GraphicsDrawLine($backbuffer, $aPoints[$i][0], $aPoints[$i][1], $aPoints[$i][2], $aPoints[$i][3], $hPen) ;Draw the lines $Layout = _GDIPlus_RectFCreate($aPoints[$i][2] - ($FontSize * Cos($aAngles[$i])) - (18 * $ScalingFactor), $aPoints[$i][3] - ($FontSize * Sin($aAngles[$i]) + 10), 0, 0) _GDIPlus_GraphicsDrawStringEx($backbuffer, $aMarkText[$i], $Font, $Layout, $Format, $TextBrush) Next $Layout = 0 _GDIPlus_BrushDispose($TextBrush) _GDIPlus_FontDispose($Font) _GDIPlus_StringFormatDispose($Format) _GDIPlus_FontFamilyDispose($Family) EndFunc ;==>_DrawCheckMarks #EndRegion Draw Radial Gauge #EndRegion Functions
-
I'm creating a tool which automatically saves screenshots. I've found that some images appear corrupt after saving. I've narrowed the source down to screenshots taken from within an RDP session via the Ctrl+Alt+Plus (PrtScn equivalent) and Ctrl+Alt+Minus (Alt+PrtScn equivalent) key combos. Here is the example code: #include <ClipBoard.au3> #include <GDIPlus.au3> If _ClipBoard_IsFormatAvailable($CF_BITMAP) Then ConsoleWrite("+Bitmap found on Clipboard" & @CRLF) If Not _ClipBoard_Open(0) Then MsgBox(16, "Error", "_ClipBoard_Open failed") Exit EndIf $hClipboardImage = _ClipBoard_GetDataEx($CF_BITMAP) _ClipBoard_Close() _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hClipboardImage) $sCLSID = _GDIPlus_EncodersGetCLSID("JPG") _GDIPlus_ImageSaveToFileEx($hBitmap, @ScriptDir & "\" & TimerInit() & "_Clipboard_Image.jpg", $sCLSID, 0) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() Else MsgBox(48, @ScriptName, "No Bitmap found on Clipboard") EndIf If you copy a local window to the clipboard via Alt+PrtScn the above works fine. If you copy a window in an RDP session via Ctrl+Alt+Minus it saves the image, but the left-hand edge appears to contain a few pixels sliced off the right-hand side of the bitmap (see two attached images for examples; one good, one bad). If you paste directly into MSPaint, the image appears correctly, so the clipboard contents is good. It seems to be the process of converting the bitmap handle to an image file via GDIPlus which corrupts it (though I may be wrong about this). I've tried inspecting the contents of the clipboard via the _ClipBoard_EnumFormats example and I've noticed the clipboard from the RDP session contains a couple more formats; Local: Clipboard formats ..: 3 Clipboard format 1 .: Bitmap Clipboard format 2 .: DIB Clipboard format 3 .: DIB V5 RDP: Clipboard formats ..: 5 Clipboard format 1 .: DataObject Clipboard format 2 .: DIB Clipboard format 3 .: DIB V5 Clipboard format 4 .: Ole Private Data Clipboard format 5 .: Bitmap However the _ClipBoard_GetDataEx function is specifying the $CF_BITMAP constant for the format, which both instances contain, so I'm not sure the extra formats have any impact? I've tried using a combination of _ClipBoard_GetDataEx($CF_DIB) and _GDIPlus_BitmapCreateFromMemory in an effort to write the binary directly to a file, instead of using a bitmap handle, however this doesn't appear to work and just returns a zero and doesn't set @error to anything, which isn't covered in the help file (a failure should return a zero and set the @error level to something). I've hunted around the forums and tried everything I can think of. I can normally figure most things out without posting but I've been dipping in and out of this script for a few months now and have finally thrown in the towel and must ask you guys for help, which isn't a decision I take lightly. Your help is, as always, greatly appreciated.
-
_GDIPlus_MarkScreenRegionAnimated build 2020-08-07 beta
UEZ posted a topic in AutoIt Example Scripts
Here another example to mark the desktop to get the marked region for capturing. This example is not perfect and not very fast (room for improvements). ;Coded by UEZ build 2020-08-07 beta ;Code cleanup up mLipok ; ;Short instruction: mark area on your desktop and press return key to capture. #include <APISysConstants.au3> #include <Array.au3> ;#include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <ScreenCapture.au3> #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> ; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE ;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAware) Global $__g_hGUI_MarkArea, $__g_hGUI_Bg, $__g_iLabel_TL, $__g_iLabel_TM, $__g_iLabel_TR, $__g_iLabel_LM, $__g_iLabel_RM, $__g_iLabel_BL, $__g_iLabel_BM, _ $__g_iLabel_BR, $__g_iOldCursor, $__g_iW, $__g_iH, $__g_iColor_ResizeDots = 0xFFFFFF, $__g_iBorder = 4, $__g_bSelectionDone = False Global $aRect = _GDIPlus_MarkScreenRegionAnimated() Global $hImage_Capture = _ScreenCapture_Capture(@TempDir & "\Test.png", $aRect[0], $aRect[1], $aRect[0] + $aRect[2] - 1, $aRect[1] + $aRect[3] - 1, False) ShellExecute(@TempDir & "\Test.png") ;_ArrayDisplay($aRect, "Marked area coordinates") Func _GDIPlus_MarkScreenRegionAnimated($bAnim = True) _GDIPlus_Startup() Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hFullScreen) $__g_hGUI_Bg = GUICreate("", $aFullScreen[2], $aFullScreen[3], $aFullScreen[0], $aFullScreen[1], BitOR($WS_CLIPCHILDREN, $WS_POPUP), $WS_EX_TOPMOST) ;to avoid cursor flickering and for proper control read WinSetTrans($__g_hGUI_Bg, "", 0x01) $__g_hGUI_MarkArea = GUICreate("", 1, 1, -1, -1, $bAnim ? $WS_POPUP : BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED), $__g_hGUI_Bg) GUISetBkColor(0xABCDEF, $__g_hGUI_MarkArea) If Not $bAnim Then $__g_iColor_ResizeDots = 0xFF0000 $__g_iLabel_TL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_LM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;left mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_RM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;right mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) GUISetState(@SW_SHOWNA, $__g_hGUI_Bg) GUISetState(@SW_SHOW, $__g_hGUI_MarkArea) $__g_iOldCursor = MouseGetCursor() GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) _WinAPI_SetLayeredWindowAttributes($__g_hGUI_MarkArea, 0xABCDEF, 0xF0) Local $aMPos, $aPrevMPos[2] = [MouseGetPos(0) + 1, MouseGetPos(1) + 1], $iID, $aCI, $iX, $iY, $aOldWinPos, $aOldMPos, $bMoved Local $aGUIStartPos, $iKey_Exit = GUICtrlCreateButton("", $aFullScreen[0] - 10, $aFullScreen[1] - 10, 1, 1), $aAccelKeys[1][2] = [["{ENTER}", $iKey_Exit]] GUISetAccelerators($aAccelKeys, $__g_hGUI_Bg) GUISetAccelerators($aAccelKeys, $__g_hGUI_MarkArea) #forceref $bMoved Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $iKey_Exit If $bAnim Then GUIRegisterMsg($WM_TIMER, "") DllCall("user32.dll", "bool", "KillTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", $iID) GUIRegisterMsg($WM_ERASEBKGND, "") EndIf _GDIPlus_Shutdown() Local $aResult = WinGetPos($__g_hGUI_MarkArea) $aResult[2] = WinGetClientSize($__g_hGUI_MarkArea)[0] $aResult[3] = WinGetClientSize($__g_hGUI_MarkArea)[1] GUIDelete($__g_hGUI_MarkArea) GUIDelete($__g_hGUI_Bg) If Not $__g_bSelectionDone Then $aResult = 0 Return $aResult EndSwitch $aMPos = MouseGetPos() If ($aMPos[0] <> $aPrevMPos[0] Or $aMPos[1] <> $aPrevMPos[1]) And (Not $__g_bSelectionDone) Then WinMove($__g_hGUI_MarkArea, "", $aMPos[0], $aMPos[1]) $aPrevMPos = $aMPos EndIf $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If $aCI[2] And (Not $__g_bSelectionDone) Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $bAnim Then GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") $iID = DllCall("User32.dll", "uint_ptr", "SetTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", 1, "uint", 50, "ptr", 0)[0] EndIf While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) $aMPos = MouseGetPos() $__g_iW = Abs($aMPos[0] - $aGUIStartPos[0]) + 1 $__g_iH = Abs($aMPos[1] - $aGUIStartPos[1]) + 1 If $aMPos[0] < $aGUIStartPos[0] Then $iX = $aMPos[0] Else $iX = $aGUIStartPos[0] EndIf If $aMPos[1] < $aGUIStartPos[1] Then $iY = $aMPos[1] Else $iY = $aGUIStartPos[1] EndIf WinMove($__g_hGUI_MarkArea, "", $iX, $iY, $__g_iW, $__g_iH) UpdateCtrlPos($bAnim) WEnd $__g_bSelectionDone = True GUISetCursor(3, 1, $__g_hGUI_MarkArea) ElseIf $aCI[3] And $__g_bSelectionDone Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If _WinAPI_PtInRectEx(MouseGetPos(0), MouseGetPos(1), $aGUIStartPos[0], $aGUIStartPos[1], $aGUIStartPos[0] + $aGUIStartPos[2], $aGUIStartPos[1] + $aGUIStartPos[3]) Then $aMPos = MouseGetPos() $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) While $aCI[3] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aGUIStartPos[0] - ($aMPos[0] - MouseGetPos(0)), $aGUIStartPos[1] - ($aMPos[1] - MouseGetPos(1)), $__g_iW, $__g_iH) GUISetCursor(0, 1, $__g_hGUI_Bg) GUISetCursor(0, 1, $__g_hGUI_MarkArea) WEnd GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndIf EndIf If $__g_bSelectionDone Then $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If @error Then ContinueLoop Switch $aCI[4] Case $__g_iLabel_TL GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), MouseGetPos(1), $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BR GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TR GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BL GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_LM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_RM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2], $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2], $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case Else GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndSwitch EndIf Until False EndFunc ;==>_GDIPlus_MarkScreenRegionAnimated Func UpdateCtrlPos($bAnim = True) Local Const $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "") $__g_iW = $aGUIStartPos[2] $__g_iH = $aGUIStartPos[3] ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TL, 0, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TM, ($__g_iW - $__g_iBorder) / 2, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_LM, 0, ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_RM, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BL, 0, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BM, ($__g_iW - $__g_iBorder) / 2, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") EndFunc ;==>UpdateCtrlPos Func PlayBorderAnim() Local $aWinPos = WinGetClientSize($__g_hGUI_MarkArea), $iW = $aWinPos[0], $iH = $aWinPos[1] Local Static $fOffset = 0 Local Const $iSize = $__g_iBorder / 2 Local Const $hDC = _WinAPI_GetDC($__g_hGUI_MarkArea) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) Local Const $hPen = _GDIPlus_PenCreate(0xFF0178D7, $iSize), $hPen2 = _GDIPlus_PenCreate(0xFFFFFFFF, $iSize), _ $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000 + $__g_iColor_ResizeDots), $hPen3 = _GDIPlus_PenCreate(0xFF000000) _GDIPlus_PenSetDashStyle($hPen, $GDIP_DASHSTYLEDASHDOT) _GDIPlus_GraphicsClear($hCanvas, 0xFFABCDEF) ;for faster performance direct dll calls DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen2, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipSetPenDashOffset", "handle", $hPen, "float", $fOffset) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) $fOffset += 0.5 _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($__g_hGUI_MarkArea, $hDC) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPen2) _GDIPlus_PenDispose($hPen3) _GDIPlus_BrushDispose($hBrush) EndFunc ;==>PlayBorderAnim Func WM_ERASEBKGND($hWnd, $iMsgm, $wParam, $lParam) ;suppress repainting to avoid flickering but causes some other side effects #forceref $iMsgm, $wParam, $lParam, $hWnd Local Const $hBrush = _WinAPI_CreateSolidBrush(0xEFCDAB) ;BGR format ;~ _WinAPI_RedrawWindow($__g_hGUI_MarkArea, 0, 0, BitOR($RDW_NOERASE, $RDW_NOCHILDREN, $RDW_NOFRAME, $RDW_VALIDATE)) _WinAPI_SetClassLongEx($__g_hGUI_MarkArea, $GCL_HBRBACKGROUND, $hBrush) _WinAPI_DeleteObject($hBrush) Return 0 EndFunc ;==>WM_ERASEBKGND ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 3) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode Switch $iMode Case 1 Local $hDC = _WinAPI_GetDC($hGUI) Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0) _WinAPI_ReleaseDC(0, $hDC) Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0) Case 2 ;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle()) Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0) Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0) Case 3 Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0) Local $aResult32 = DllCall("user32.dll", "ptr", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0) Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0) EndSwitch Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext Just press the lmb and move your mouse. When lmb is released you can adjust the size of the window by dragging the white rectangle to any direction. Rmb will move the marked area. Press ESC to get the coordinates of the marked region. If you have any improvements, please post it here. Tested on Win10 x64 only. -
Hi Community, I'm looking for a way to do a Video Overlay GUI or something like that. The idea is to create a GUI which plays a video loop (with transparency/alpha channel) in front of an other GUI. Before you asking why - because I don't believe that GDIPlus can do it out of the box. My skillset for that kind of graphical things isn't good enough to do that, but here are some specialist like @UEZ maybe who can help. Example alpha channel video (visualized as animated *.gif): I tried to do the light rays effect directly with GDIPlus, but honestly that's a bit too difficult for me. I would be very glad and grateful if there are some suggestions, ideas or recommendations. Code for the Video play: Example video "End.mpeg": The next challenge is that the overlay GUI should be not clickable. If I hover over the overlay area, I want to have the possibility to control the GUI or what ever, in the background. But if there is any chance to make it with GDIPlus as a Video Overlay for light rays, I would prefer that approach instead of my crazy work-around idea. Thanks for any suggestion - I'm grateful! Sven
- 1 reply
-
- video overlay gui
- gdiplus
-
(and 1 more)
Tagged with:
-
I have a strange symptom of a problem somewhere in my code, or in a UDF: when I add code to get all properties of a GDI+ image to a 6000-line script, the variable type of a parameter is reported as a pointer when the caller clearly has this argument as a string. If I comment out my code that gets the properties, the function properly sees the parameter as a string. [Edit: The reporting as a pointer and getting image properties are miles apart, both in where they are in the script code and in where they are run.] At this point, I am looking for clues as to why this is happening, so the hunt is on! I have noticed one odd thing, in _GDIPlus_ImageGetPropertyIdList() I see a line that begins Local $sPropertyTagInfo = . This "line" is split into 2 lines. SCiTE shows that the first line is 2454 characters and the second 2400. Adding these numbers I get 4854 characters. But the Help for AutoIt3 Limits/defaults says that MAXLINESIZE, Maximum size for a line of script, is 4096 characters. The line would exceed the limit if AutoIt considers the subject line to be 1 line and not 2 lines. My question: is this line legal? Is buffer overun possible?
-
I find _GDIPlus_ImageClone in the Help, but neither in SciTe auto-complete nor in GDIPlus.au3 Shoud this be reported in Trac? By searching the forum (and changing the name of the first arguement ot DLLCall, the code appears to be: Func _GDIPlus_ImageClone($hImage) Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCloneImage", "handle", $hImage, "int*", 0) If @error Then Return SetError(@error, @extended, 0) Return $aResult[2] EndFunc ;==>_GDIPlus_ImageClone
-
Nothing special - just another analogue clock. -> Read https://en.wikipedia.org/wiki/Swiss_railway_clock for more information. Requires Windows7+ OS! Widget style GUI: ;The Hilfiker / MobaTime Swiss Railway Clock ;Coded by UEZ build 2019-07-07 ;Thanks to Eukalyptus for the _CreateBrushedAluminum() function! #pragma Compile(Icon, "GDI+ Swiss Railway Clock.ico") #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe /rm #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3" #AutoIt3Wrapper_UseX64=n Break(0) #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> ProcessSetPriority(@AutoItPID, $PROCESS_LOW) _GDIPlus_Startup() Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit Global $iW, $iH, $iX, $iY, $sTitle = "GDI+ Swiss Railway Clock v1.16" $iW = IniRead(@ScriptDir & "\GDI+ Swiss Railway Clock.ini", "Settings", "GUI_Size", 200) $iW = $iW < 100 ? 100 : $iW > 800 ? 800 : $iW $iH = $iW $iX = IniRead(@ScriptDir & "\GDI+ Swiss Railway Clock.ini", "Settings", "GUI_PosX", -1) $iY = IniRead(@ScriptDir & "\GDI+ Swiss Railway Clock.ini", "Settings", "GUI_PosY", -1) Global Const $fRad = ACos(-1) / 180, $fDeg = 180 / ACos(-1), $iTimer = 30, $ULW_ALPHA = 2, $SC_DRAGMOVE = 0xF012, $fDeltaShadow = 20 Global $hBitmap, $hHBitmap, $hCanvas, $hBitmap_Clock, $hBrush_Shadow, $hBrush_Update, $hPen_Update, $fDiameter = $iW, $fShadowAngle, $fMin_next, _ $fRadius = $fDiameter / 2, $fSec, $fMin, $fHr, $fAmplitude = 3, $fSize, $hOld Global $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) $tSize.X = $iW $tSize.Y = $iH $tBlend.Alpha = 255 $tBlend.Format = 1 Global Const $hScrDC = _WinAPI_GetDC($hGUI), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) AutoItSetOption("GUIOnEventMode", 1) GDIPlus_SwissRailwayClockWidget() AutoItSetOption("GUIOnEventMode", 0) _GDIPlus_Shutdown() Func GDIPlus_SwissRailwayClockWidget() $bExit = False $hGUI = GUICreate($sTitle, $iW, $iH, $iX, $iY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED)) GUISetState(@SW_SHOW, $hGUI) ;create canvas elements $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW + $fDeltaShadow, $iH + $fDeltaShadow) $hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap) Local Const $iAlpha = 0x0D / $iW * 200 $hBrush_Shadow = _GDIPlus_BrushCreateSolid(BitShift(0x0D + $iAlpha, -24) + 0x202020) $hPen_Update = _GDIPlus_PenCreate(0xFFA02020) $hBrush_Update = _GDIPlus_BrushCreateSolid(0) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) $hBitmap_Clock = GenerateClockBg($fDiameter) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") $fMin_next = @MIN GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN") GUIRegisterMsg($WM_TIMER, "Draw") ;$WM_TIMER = 0x0113 Local $iID = DllCall("User32.dll", "uint_ptr", "SetTimer", "hwnd", $hGUI, "uint_ptr", 1, "uint", $iTimer, "ptr", 0)[0] Do If $bExit Then ExitLoop Until Not Sleep(100) ;release resources GUIRegisterMsg($WM_TIMER, "") DllCall("user32.dll", "bool", "KillTimer", "hwnd", $hGUI, "uint_ptr", $iID) GUIRegisterMsg($WM_LBUTTONDOWN, "") _GDIPlus_PenDispose($hPen_Update) _GDIPlus_BrushDispose($hBrush_Shadow) _GDIPlus_BrushDispose($hBrush_Update) _GDIPlus_GraphicsDispose($hCanvas) _GDIPlus_ImageDispose($hCanvas) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_DeleteDC($hMemDC) IniWrite(@ScriptDir & "\GDI+ Swiss Railway Clock.ini", "Settings", "GUI_Size", WinGetPos($hGUI)[2]) IniWrite(@ScriptDir & "\GDI+ Swiss Railway Clock.ini", "Settings", "GUI_PosX", WinGetPos($hGUI)[0]) IniWrite(@ScriptDir & "\GDI+ Swiss Railway Clock.ini", "Settings", "GUI_PosY", WinGetPos($hGUI)[1]) GUIDelete($hGUI) EndFunc ;==>GDIPlus_SwissRailwayClockWidget Func Draw($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam _GDIPlus_GraphicsClear($hCanvas, 0x00000000) _GDIPlus_GraphicsDrawImageRect($hCanvas, $hBitmap_Clock, 0, 0, $fDiameter + $fDeltaShadow, $fDiameter + $fDeltaShadow) UpdateClock($hCanvas, $fDiameter) $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hHBitmap) EndFunc ;==>Draw Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam) Switch $hWnd Case $hGUI _SendMessage($hWnd, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0) EndSwitch EndFunc ;==>_WM_LBUTTONDOWN Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func UpdateClock($hGfx, $fDiameter) Static $bBounce = 0, $f = 0 Local $m1 = $fDiameter * 0.015 ;hour $fHr = 30 * (@HOUR + @MIN / 60) _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, $fHr) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) Local $iWidth1 = $fDiameter * 0.0375, _ $iHeight1 = $fDiameter / 2.5, _ $iWidth12 = $iWidth1 / 2, _ $fPosY = $fDiameter * 0.2, $iWidth2, $iWidth22, $fPosY2 _GDIPlus_BrushSetSolidColor($hBrush_Update, 0xFF101010) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius - $iWidth12 + Cos(($fShadowAngle - $fHr) * $fRad) * $m1, _ "float", $fPosY + Sin(($fShadowAngle - $fHr) * $fRad) * $m1, _ "float", $iWidth1, "float", $iHeight1) ;~ DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Update, _ ;~ "float", $fRadius - $iWidth12, _ ;~ "float", $fPosY, _ ;~ "float", $iWidth1, "float", $iHeight1) Local $tPoints = DllStructCreate("float p[8]"), $factor = $iW / 160 ; 1----2 ; | | ; 4----3 ;1 $tPoints.p(1) = $fRadius - $iWidth12 $tPoints.p(2) = $fPosY ;2 $tPoints.p(3) = $tPoints.p(1) + $iWidth1 $tPoints.p(4) = $fPosY ;3 $tPoints.p(5) = $tPoints.p(3) + $factor $tPoints.p(6) = $fPosY + $iHeight1 ;4 $tPoints.p(7) = $tPoints.p(1) - $factor $tPoints.p(8) = $tPoints.p(6) DllCall($__g_hGDIPDll, "int", "GdipFillPolygon", "handle", $hGfx, "handle", $hBrush_Update, _ "struct*", $tPoints, "int", 4, "int", "FillModeAlternate") _GDIPlus_GraphicsResetTransform($hGfx) ;min If $fMin_next <> @MIN Then $bBounce = 1 Switch $bBounce Case 1 $fMin = (6 * Mod(($fMin_next + 1), 60)) + Sin($f * 1.9) * $fAmplitude If $fAmplitude = 0 Then $fMin_next = @MIN $f = 0 $fAmplitude = 3 $bBounce = 0 Else $fAmplitude -= 0.5 $fAmplitude = $fAmplitude <= 0 ? 0 : $fAmplitude $f += 1 EndIf Case Else $fMin = (6 * @MIN) EndSwitch _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, $fMin) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) $iWidth1 = $fDiameter * 0.03 $iHeight1 = $fRadius $iWidth12 = $iWidth1 / 2 $fPosY = $fDiameter * 0.1 DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius - $iWidth12 + Cos(($fShadowAngle - $fMin) * $fRad) * $m1, _ "float", $fPosY + Sin(($fShadowAngle - $fMin) * $fRad) * $m1, _ "float", $iWidth1, "float", $iHeight1) ;~ DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Update, _ ;~ "float", $fRadius - $iWidth12, _ ;~ "float", $fPosY, _ ;~ "float", $iWidth1, "float", $iHeight1) ;1 $tPoints.p(1) = $fRadius - $iWidth12 $tPoints.p(2) = $fPosY ;2 $tPoints.p(3) = $tPoints.p(1) + $iWidth1 $tPoints.p(4) = $fPosY ;3 $tPoints.p(5) = $tPoints.p(3) + $factor $tPoints.p(6) = $fPosY + $iHeight1 ;4 $tPoints.p(7) = $tPoints.p(1) - $factor $tPoints.p(8) = $tPoints.p(6) DllCall($__g_hGDIPDll, "int", "GdipFillPolygon", "handle", $hGfx, "handle", $hBrush_Update, _ "struct*", $tPoints, "int", 4, "int", "FillModeAlternate") _GDIPlus_GraphicsResetTransform($hGfx) ;sec $fSec = 6 * (@SEC * 1.02564 + @MSEC / 1000) If $fSec >= 360 Then $fSec = 0 _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, $fSec) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) $fPosY = $fDiameter * 0.27 $fPosY2 = $fDiameter * 0.19 $iWidth1 = $fDiameter * 0.0095 $iHeight1 = $fRadius * 1.3 - $fPosY $iWidth12 = $iWidth1 / 2 $iWidth2 = $fDiameter * 0.083333 $iWidth22 = $iWidth2 / 2 ;shadow seconds DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius + Cos(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $fPosY + Sin(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $iWidth1 + $fDiameter * 0.006667, "float", $iHeight1 + $fDiameter * 0.006667) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius - $iWidth22 + Cos(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $fPosY2 + Sin(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $iWidth2, "float", $iWidth2) ;seconds _GDIPlus_BrushSetSolidColor($hBrush_Update, 0xFFC01010) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth12, _ "float", $fPosY, _ "float", $iWidth1, "float", $iHeight1) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth22, _ "float", $fPosY2, _ "float", $iWidth2, "float", $iWidth2) _GDIPlus_GraphicsResetTransform($hGfx) ;button in the center DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth1, _ "float", $fRadius - $iWidth1, _ "float", 2 * $iWidth1, "float", 2 * $iWidth1) DllCall($__g_hGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfx, "handle", $hPen_Update, _ "float", $fRadius - $iWidth1, _ "float", $fRadius - $iWidth1, _ "float", 2 * $iWidth1, "float", 2 * $iWidth1) EndFunc ;==>UpdateClock Func GenerateClockBg($fDiameter, $iBGColor = 0xF8FFFFFF) Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($fDiameter + $fDeltaShadow, $fDiameter + $fDeltaShadow), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), _ $hBrush = _GDIPlus_BrushCreateSolid($iBGColor), $fBorderSize = $fDiameter * 0.03333, _ $hEffect = _GDIPlus_EffectCreateBlur($fDiameter / 50, 1), $hPen = _GDIPlus_PenCreate(0xA0000000, $fBorderSize) _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4) _GDIPlus_GraphicsSetPixelOffsetMode($hGfx, 4) _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 4) Local Const $fSize = $fDiameter * 0.942 - $fBorderSize / 2 Local Const $hLBrush = _GDIPlus_LineBrushCreate($fBorderSize, $fBorderSize, $fSize, $fSize, 0xFCFFFFFF, 0xF8F0F0F0, 3) _GDIPlus_LineBrushSetSigmaBlend($hLBrush, 0.33333) _GDIPlus_LineBrushSetGammaCorrection($hLBrush) Local Const $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixTranslate($hMatrix, -$fSize, -$fSize, True) _GDIPlus_MatrixRotate($hMatrix, 90, True) _GDIPlus_MatrixTranslate($hMatrix, $fSize, $fSize, True) _GDIPlus_LineBrushMultiplyTransform($hLBrush, $hMatrix, True) _GDIPlus_MatrixDispose($hMatrix) _GDIPlus_GraphicsFillEllipse($hGfx, $fBorderSize, $fBorderSize, $fSize, $fSize, $hLBrush) ;~ Local Const $hPath = _GDIPlus_PathCreate() ;~ _GDIPlus_PathAddEllipse($hPath, $fBorderSize, $fBorderSize, $fSize, $fSize) ;~ Local $hLBrush = _GDIPlus_PathBrushCreateFromPath($hPath) ;~ _GDIPlus_PathBrushSetCenterColor($hLBrush, 0xF8F0F0FF) ;~ _GDIPlus_PathBrushSetCenterPoint($hLBrush, $fSize * 0.70, $fSize * 0.70) ;~ _GDIPlus_PathBrushSetSurroundColor($hLBrush, 0xFBFFFFFF) ;~ _GDIPlus_PathBrushSetGammaCorrection($hLBrush, True) ;~ _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hLBrush) ;~ _GDIPlus_PathDispose($hPath) Local $fShadow_vx = $fDiameter * 0.0095, $fShadow_vy = $fDiameter * 0.01 $fShadowAngle = ATan($fShadow_vy / $fShadow_vx) * $fDeg If $fShadow_vx < 0 And $fShadow_vy >= 0 Then $fShadowAngle += 180 If $fShadow_vx < 0 And $fShadow_vy < 0 Then $fShadowAngle -= 180 _GDIPlus_GraphicsDrawEllipse($hGfx, $fBorderSize + $fShadow_vx, $fBorderSize + $fShadow_vy, $fSize, $fSize, $hPen) _GDIPlus_BitmapApplyEffect($hBitmap, $hEffect) _GDIPlus_BrushSetSolidColor($hBrush) _GDIPlus_PenSetColor($hPen, 0xF0000000) Local Const $hBitmap_Texture = _CreateBrushedAluminum($fDiameter, $fDiameter, $fShadowAngle) Local Const $hTexture = _GDIPlus_TextureCreate($hBitmap_Texture) DllCall($__g_hGDIPDll, "int", "GdipSetPenBrushFill", "ptr", $hPen, "ptr", $hTexture) _GDIPlus_GraphicsDrawEllipse($hGfx, $fBorderSize, $fBorderSize, $fSize, $fSize, $hPen) _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, -6) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) Local $iWidth1 = $fDiameter * 0.026667, $iHeight1 = $fDiameter / 10, $iWidth12 = $iWidth1 / 2, $fPosY = $fDiameter * 0.083333, _ $iWidth2 = $fDiameter * 0.013333, $iHeight2 = $fDiameter * 0.0416667, $iWidth22 = $iWidth2 / 2 For $i = 0 To 59 _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, 6) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) Switch Mod($i, 5) Case 0 _GDIPlus_GraphicsFillRect($hGfx, $fRadius - $iWidth12, $fPosY, $iWidth1, $iHeight1, $hBrush) Case Else _GDIPlus_GraphicsFillRect($hGfx, $fRadius - $iWidth22, $fPosY, $iWidth2, $iHeight2, $hBrush) EndSwitch Next _GDIPlus_GraphicsResetTransform($hGfx) Local Const $hBitmap_Logo = _GDIPlus_BitmapCreateFromMemory(_Au3_Icon()) Local Const $hBitmap_Logo_Scaled = _GDIPlus_ImageResize($hBitmap_Logo, $fDiameter * 0.125, $fDiameter * 0.125) Local $aDim = _GDIPlus_ImageGetDimension($hBitmap_Logo_Scaled) _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap_Logo_Scaled, $fRadius - $aDim[0] / 2, $fRadius / 2, $aDim[0], $aDim[1]) _GDIPlus_ImageDispose($hBitmap_Logo) _GDIPlus_ImageDispose($hBitmap_Logo_Scaled) Local Const $hFamily = _GDIPlus_FontFamilyCreate("Segoe Script"), $hFont = _GDIPlus_FontCreate($hFamily, $fDiameter * 0.025), $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) _GDIPlus_BrushSetSolidColor($hBrush, 0xE0000000) _GDIPlus_GraphicsDrawStringEx($hGfx, "Clock coded by" & @CRLF & "UEZ", $hFont, _GDIPlus_RectFCreate($fRadius - $fRadius * 0.2, $fRadius + $fRadius * 0.2, $fRadius * 0.4, $fRadius * 0.4), $hFormat, $hBrush) _GDIPlus_ImageDispose($hBitmap_Texture) _GDIPlus_BrushDispose($hTexture) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_EffectDispose($hEffect) _GDIPlus_PenDispose($hPen) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hLBrush) _GDIPlus_GraphicsDispose($hGfx) Return $hBitmap EndFunc ;==>GenerateClockBg Func _CreateBrushedAluminum($iW, $iH, $fLightAngle = 40, $iBlurDist = 12, $fBlurTrans = 0.6666, $fRed = 0.8, $fGreen = 0.9, $fBlue = 1, $iLightColor = 0xF0FFFFFF, $fLightSigma = 0.5, $fLightScale = 0.83) ;coded by Eukalyptus! $iBlurDist = Ceiling($iBlurDist) $iBlurDist += 1 - Mod($iBlurDist, 2) Local $iOverSize = 0 For $i = 1 To $iBlurDist Step 2 $iOverSize += $i + $i + 1 Next Local $iWO = $iW + $iOverSize ;========================================= ; Add Noise ;========================================= Local $iNoiseSize = 40 Local $hBmp_Noise = _GDIPlus_BitmapCreateFromScan0($iNoiseSize, $iNoiseSize) Local $hGfx_Noise = _GDIPlus_ImageGetGraphicsContext($hBmp_Noise) Local $tData = _GDIPlus_BitmapLockBits($hBmp_Noise, 0, 0, $iNoiseSize, $iNoiseSize, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) Local $iStride = DllStructGetData($tData, "Stride") Local $iWidth = DllStructGetData($tData, "Width") Local $iHeight = DllStructGetData($tData, "Height") Local $pScan0 = DllStructGetData($tData, "Scan0") Local $tPixel = DllStructCreate("dword[" & $iWidth * $iHeight & "];", $pScan0) Local $iAmp For $row = 0 To $iHeight - 1 For $col = 0 To $iWidth - 1 $iAmp = Random(0, 0xFF, 1) DllStructSetData($tPixel, 1, BitOR(0xFF000000, BitShift($iAmp, -16), BitShift($iAmp, -8), $iAmp), $row * $iWidth + $col + 1) Next Next _GDIPlus_BitmapUnlockBits($hBmp_Noise, $tData) ;========================================= ; Create Full NoiseBitmap ;========================================= Local $hBmp_Full = _GDIPlus_BitmapCreateFromScan0($iWO, $iH) Local $hGfx_Full = _GDIPlus_ImageGetGraphicsContext($hBmp_Full) _GDIPlus_GraphicsSetSmoothingMode($hGfx_Full, 4) _GDIPlus_GraphicsSetInterpolationMode($hGfx_Full, 3) Local $iXOff, $iYOff, $iSizeX, $iSizeY For $y = 0 To $iH Step $iNoiseSize / 2 For $x = 0 To $iWO Step $iNoiseSize / 2 $iXOff = Random(0, $iNoiseSize / 2, 1) $iYOff = Random(0, $iNoiseSize / 2, 1) $iSizeX = $iNoiseSize - $iXOff $iSizeY = $iNoiseSize - $iYOff _GDIPlus_GraphicsDrawImageRectRect($hGfx_Full, $hBmp_Noise, $iXOff, $iYOff, $iSizeX, $iSizeY, $x, $y, $iSizeX, $iSizeY) Next Next _GDIPlus_GraphicsDispose($hGfx_Noise) _GDIPlus_BitmapDispose($hBmp_Noise) ;========================================= ; MotionBlur ;========================================= Local $hBmp_Full2 = _GDIPlus_BitmapCreateFromScan0($iWO, $iH) Local $hGfx_Full2 = _GDIPlus_ImageGetGraphicsContext($hBmp_Full2) _GDIPlus_GraphicsSetSmoothingMode($hGfx_Full2, 4) _GDIPlus_GraphicsSetInterpolationMode($hGfx_Full, 3) Local $tColorMatrix = DllStructCreate("float[5]; float[5]; float[5]; float[5]; float[5];") DllStructSetData($tColorMatrix, 1, 1, 1) DllStructSetData($tColorMatrix, 2, 1, 2) DllStructSetData($tColorMatrix, 3, 1, 3) DllStructSetData($tColorMatrix, 4, $fBlurTrans, 4) DllStructSetData($tColorMatrix, 5, 1, 5) Local $hImgAttrib = _GDIPlus_ImageAttributesCreate() DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, "int", 1, "struct*", $tColorMatrix, "struct*", 0, "int", 0) For $i = 1 To $iBlurDist Step 2 DllCall($__g_hGDIPDll, "int", "GdipDrawImageRectRect", "ptr", $hGfx_Full2, "ptr", $hBmp_Full, _ "float", $i, "float", 0, "float", $iWO, "float", $iH, _ "float", 0, "float", 0, "float", $iWO, "float", $iH, _ "int", 2, "ptr", $hImgAttrib, "ptr", 0, "ptr", 0) If $i >= $iBlurDist Then DllStructSetData($tColorMatrix, 1, $fRed, 1) DllStructSetData($tColorMatrix, 2, $fGreen, 2) DllStructSetData($tColorMatrix, 3, $fBlue, 3) DllStructSetData($tColorMatrix, 4, 1, 4) DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, "int", 1, "struct*", $tColorMatrix, "struct*", 0, "int", 0) EndIf DllCall($__g_hGDIPDll, "int", "GdipDrawImageRectRect", "ptr", $hGfx_Full, "ptr", $hBmp_Full2, _ "float", $i + 1, "float", 0, "float", $iWO, "float", $iH, _ "float", 0, "float", 0, "float", $iWO, "float", $iH, _ "int", 2, "ptr", $hImgAttrib, "ptr", 0, "ptr", 0) Next _GDIPlus_ImageAttributesDispose($hImgAttrib) _GDIPlus_GraphicsDispose($hGfx_Full2) _GDIPlus_BitmapDispose($hBmp_Full2) _GDIPlus_GraphicsDispose($hGfx_Full) ;========================================= ; Add Light ;========================================= Local $hBmp_Alu = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hGfx_Alu = _GDIPlus_ImageGetGraphicsContext($hBmp_Alu) _GDIPlus_GraphicsSetSmoothingMode($hGfx_Alu, 4) _GDIPlus_GraphicsSetInterpolationMode($hGfx_Alu, 3) _GDIPlus_GraphicsDrawImage($hGfx_Alu, $hBmp_Full, -$iOverSize, 0) _GDIPlus_BitmapDispose($hBmp_Full) Local $tPointF1 = DllStructCreate("float; float;") Local $tPointF2 = DllStructCreate("float; float;") DllStructSetData($tPointF2, 2, $iH * $fLightScale) $aResult = DllCall($__g_hGDIPDll, "int", "GdipCreateLineBrush", "struct*", $tPointF1, "struct*", $tPointF2, "uint", 0, "uint", $iLightColor, "int", 0, "handle*", 0) If @error Or Not IsArray($aResult) Then Return SetError(1, 4, False) Local $hBrush = $aResult[6] _GDIPlus_LineBrushSetSigmaBlend($hBrush, $fLightSigma) _GDIPlus_LineBrushSetGammaCorrection($hBrush) DllCall($__g_hGDIPDll, "int", "GdipRotateLineTransform", "ptr", $hBrush, "float", $fLightAngle, "int", 0) _GDIPlus_GraphicsFillRect($hGfx_Alu, 0, 0, $iW, $iH, $hBrush) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGfx_Alu) Return $hBmp_Alu EndFunc ;==>_CreateBrushedAluminum ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2018-02-02 Func _Au3_Icon($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Au3_Icon $Au3_Icon &= 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAP0ElEQVR4XtWZW4hs6VXHf+v79qWquruquqtvZ/r0uc8540yScTIQQ0JkDOYyGhIkhhAxxhdR8mDAgAg+6FsE9UVffNMH8S0ERAwS1DFeEo3m6owzmUySc+Zc+15VXZd9+dZyp6ro4pDTORlGIfnDn703TW/+//X9v/Wt3i3PPfccP85w/GhBgLqkS23ixhpRfau6bgItIPpRN5Ag0Xl88jYrxu/E+KA492E0vJd44d245BKQ/H8bkAe80wMOEE5HA5c8SpQ822yv/ubW9vnfffyxR3+vs7r6YcS9HewZnP9ZXPwE0Py/NuCBJj65iERvQPybcNFP4JKzuPgq+CeR6GnwV3FJB4juM+mSNj55Ehe97/LFC5947PL2ey5tb755daW1+fiVc295+qk3fuTShfPPPnb10d+J60sfI6o9BbRer4EIaOLis1Nh6dtBfs6ljY82ljqfiNLFX8X597uk/ksrG4/8ftJo/lq62P51XPQOJHoc3DV8egZYxLkLcW3xQ088fvWTj2ysXItjnxRlGY6Ojmxvb98iJwtnz6xeXO80tx+9tP0Rcf6tuHhzLuS1YwmJLiHuslRVbzQbjydJsrXSbl4RIVlpLZ0xM71+e+cbC41a+8zayuVxlo9CCPnX/vslt7S89iEzy4/7R/+MT7+Lhq2V5dbbO63Ftbwog/feDYdDt7e3R71eo9vt2tbWlkZRRC1NFkHWQDpACmQ/bBuVWUyaiN+Kk9oH2q3mO/Ky0HNn1p9sNxeaBpiBmpl3TlTNqouoqkmFoKp5XuT1NKlVFS5ffOXm54ui2EFIr17afudCLV1SM5mBity+fRuAzc1NVC1EkfN3dg+/9e1vf/ePMfssYXz9hzXQJKo/BTyKlovrZ7Y+fPXi1luryubOOeKqPBpKQiilLAMhBAwEw7x3RN9jFImPIhTR8TjPQghFvZY2s7wYpkmc' $Au3_Icon &= 'Ag5ARFBVuXHjBpVPqurTaDRMVRERQgjll776wp9YKP+KMP5a9NCsS7SBuHMgb2stt9+13FraXltubYegmkRRMh4POTwccdAbMy4CQTFDBBEDABMvYmnirNVIaC3UpVFP667WqFdmrRLfYA7MDIBWq0WaplQRIo5j8d6bVvDOxbV6fXV03C0BeYgBvyxx7R1prfbs2srym8+e6bxhtrwMjnt276Bv3UGOuYQ4bVCrJ1JVWtxEvxO0xBHIiiBVpbnbLexetysLidjmygKLCwsYzjATwACpQK/XY2VlBTNjZ2cHVTXvvYkgg3F2lI2z2+ByIEScjgRx23GSPvPU41d+BQE1zMqCnb197h2NxCeLttBeliiOmCUGDIIJFgIbzYh2IyUoqBrHo0LuHQ4ozMl37g1sqTaUrdWWJbW6haAChnOOPM/Z3d1lNBpRVX/CEJTIOxkOs2Mt8z4iAHa6ARdvVnzL+a3NnzfMVNEyz/z1Wzt2XHgWW+tUwkUV8tKYlQ81IZLA9nJMI40IaohAFAnLSxHeSm7sDWi0VuR4cMxLN/fl0maLxsICqlRUVldXOTg4IEkSOp2OVUAE1Iz+YLSHyAAYndZGE1yyAXqt1Wq/b3Vl6WxQC/lo4F5+dccK15Dmchs1yEpAHCAwEe+IKbm8GhN5T6mKEwGmwgAWFxdYHo7Y6fdoLDUZDz0vvnrI1S1lYXEJnRmuhANYBalozolT1dDt97+Chq+j+f6DDUh0Bh8/k9br7754buOng5oW2ci9fGNHxtRoLrbIgwEecw5sasAQRAPnVx3eC0UIE/FmxhxgwMZqm1G+T/d4SL3eoAzKizcPefycUG8soqqEEAxMzFARIcvL8fWbO18YH/c+DfICcPwgA4JZa2lp6b3XLp39kK8QQtBbd/ZlUIgttJakNFA8OIeZQ5hVPyhnm0Y9dpTBEMDMeBBMPGc6i/RvdRnnCVWTIMvHfPPWEU+c97iohpmad47jcda/u3Pw/MHh' $Au3_Icon &= '0b+Zll8GfREtd08bJSJ81DgeDO6WQYOBHh3uy04/M5c0RCaxEBSHmsNMUKBUo5Uo6w0hVwEzToOZQcW01uCR5ZQym2zqSRcbZyW39gdgATPEgLu7hy/v7+3+jWn5GUz/Hi1vAPagUaKGS65geqndbD2ZJnE8Hh3bzb0BuFgkignq0FnmMWaCIHElFzuO0jwOQ+bR+YFGaomHMJyumIvAp1RdirVmnaRWMxGcqwi2i9mrhGyHOe43gEQrLq698+wj6x9f77SvWYVefyjjgOBjwKMiGG4uXsBZydU1jyGoKhpK8iLHe08cJ4gID4aAAhZQA8GBj7Gi4Ob+gMuPREBCGUKJWQNYBASw08bpBbDVtZXWNQPLs6FVvV6QyHAROmuRChigCGjg0rIjdTqpYlHk3L5zl2rO4Tu39iZmDDCzCZnfT4gTmL8PnAMXczTIyPOAqlk1JJ73Sf2NOH9pZoIHGYiApXqjcQVMMXQ8GssoV8NFgngMhyLA1IgLGRfa0K4beZCJ2J3dXfa7Q6I4pV9E3D0YYmV2f/7n90RRTC1yWChQExAPPsJUORzkTjVYNaVuXLm0/UHEXcDXaqcZSBBZi6NoAwRMGWUlhkzE4zwgqBoGYIGzLWG1rmQlOIHjfo+j45z11RUKE6ivcHsYca+bI9j0d21OMMR5Uq9okaEA4k5YGTBMKVV1MBwfYhpVbJy+AuKaYJEZqAbpjQoQx5yCMTspG8ZG05Opm4kL9IYZucJOd0AZL4G4yQgQxTXAMO6PkAF5NqY/KjAXA8LcgGecl6JBEcH1+sd3QFpA68EGosbC7IfxNNqlZaWdCAem92Y0IuXiMuQB5EQUdNotttY7bK52OL+6yLWO8pObsLboCMr3nws2NZAFAZ8whZwY0aAoAoY16rVVIIAVD+5CpklVqcvVmHwFM1TVBTU5GRNwiBnLDcfVjpIHB6bMAbVaQqNeQ8RQVcBRmCGnHWYYWZ5jEoGraDoTP6WpEYKK91YV' $Au3_Icon &= 'pX1ld+/Ah6zonxYhFCsXGumqqk2fDDspCkanIVxbKRkHh6l+X09XNcoQKEolmKAnwgUDzO7fyKZKVgTwMYh7gEFsQtNw697BC6HIR4ic0oUEESQKqkFEHCYmjpMe5zAudCLGFoHp97dDQEQwZmbKchqPYZ9B/4DxoIdqeSJezQhlwTAvwaecQDiBiMwe8cvtxS0fpxfAWoB7QIQoQlm8/NIrNz9z7fLZ94vzSeycZaWJYDzxSB1MmW2q+0TrieAReZ6RF4FRHhgXSqEQJkl0PLadkiR+ZkIIoWCUGdRjmB/rJxQRvBfMQIwESEGSmQG930AY7+HS5/N8fCXPy6KeuiSNnR2Pc1mqJ5ONOywU78BsLjwfjRj0e5NO0s+UIH5aUV+HKJlm21fUkkwhwVAzBCiLgmCAiwG7n6b4yIub6VcsA7uO6Q4QHjRKFGg5rObzs/VasmiqZZr4qJrd7bGtBcnyAifzHIeg9LoH7B70GWoEyRIsLEzFu1nnMuaVRRjmBUupYgrihLIsURyIZ155nVIDjSRR50Sq9tx7+ZXrf46Gf8TKm4CdMguJz4uil+fFKIp80lxo2NZ6g+oZVQXmq9w9OuDmzhFaW4HFzrTSGNicU9hJsPMAmAIOwyjLAM7PzOr9xGgvpZhBvz/aE/HerMiA0WldSIGeqXZFJC6Dulq9ThmChBAwM0wVMxgOj7m730NrHVhYB+fAwikjtIAACGqAKjp7V1AD8QD3VZ5Q4H1kywux5EXQ732Ra7eab0I1AO40AyCupxpe2T/qf9P7yMTUiqKwk9YnMhnWDg+PyKUOjc682gg/EMJ8jzKFqoG4k8xjYUot6LQagikGriyDdnv9zyNyBJSnG9C8b0X2D3mpN9MkcveJB1SV7tE+B4MwFY8ADxEv833pBEwAM8bjMaNxBshcvJYQcpyPbKtTpyjNIufk7l73q1qMvoiVuwCnGRAgixvNKxe21t+VZVlpZq6izA4pBsd9dg5HkDZn' $Au3_Icon &= 'J2eYb9RTMPdn1GLBcJhN33WUCcQNCMWEUwMF2+st0RCsAkf94W7/ePAVzO4Ag1MNzNDcPrP+B2aBEALARLzBJDp7B10CHnwCIQct59l/iAlBaUSgBoJRBp2KdxHo7F3FiFaraZ0Fb3kRDCyr/pz8pyIbfRa4B+hpBhLAti9cfmahnjyd53kBRFYBwFSt1+vZOC8hSkHnFZsygCmg87zcvwSIMR2bDcyUrFSAaSFCCeWIWr1hV9YbMspKjSPnrt/e/fdsNPg7TL9xWnyYn2qkYL/ovVPVWVLNBGA4HNLrDzmz1rbVVsMIGRVtugoFWDE3MjMzp4HmRGSIQBXNybfOLC/BbGqgGFq93uCJc21GeaFR5P0oK3pl0Bugz6P57R+U0wgoN7fO/8Zyq/nRooJhEYZUsLIsqDqA1Bs1lpotW9IgiXfcORqJlSNwCfgIxE84H78FYHofCupRCfjJp8K9wz4BD24SQVtpt+XiRsOqTY2A6/aGt1+9c+8vLBSfI4RXgIzTQQSki43axzHVEILI/Eua9fsDd9TtXd/c2Iy9d49kQfP2YhotNWJ5dW/EMJusguBicBMTcwPCFKqYQCgDg1FGXhqIWpQmnD/Tpplig9EYAesNsnu37tz7S9Pw14Tsf4AeD0F0/tLlReekphoEEDAB0SzL5ODoqI/qn+0e9ZezUp9dbjbOJ/W0aRAurNUlK+vubndsw6zAilwQARy4+SqIlZShIGt2LIQgca1h651l1tt1iqKQ42EIceTdzn7v+b39/U+L889j4VtT8Q+HfOUbL3zq7Ob6J800VlWbfR3W3b193z06/EPEfwoXP+ai+BdWO+0PFEXIq/3wBjAwVGazd29U0q+YFYGghjFF7KDmApVGGQ2PbWOtI1WzIC8Vg1Bp94fdwau37+78KdhzaHgFLbpA4OEgwmzNmPR8RCZDVuj2elG3e/S5NIn/KMuLQyR+Ucv80zs7ey+BbVVinIjUVpcXL816O82613Zd' $Au3_Icon &= 'gMTEOQcCqIo4RlkpVRu2Uk129w8DneWxeO9v3N79l+pCnuVfxvRfCdkLwIDXAPnSf33tU+fOnvktEXNFUUi1af3e3sHXNRQfA746P0+p4eJlxJ9D5I3OR09fPnfml6vD5m6rubCdRC4FAUDNdDTOe977ej2NUjOjdzxgNBwVh73h3/ooGXrvk2w8esE0PI9Nus11oM9rhHzhi//xtpXV1c+msW92uz0ODw6fA/1t4Es8GDEu3kDcFRclP6Ua2nGcbMdxvI4hzossLdQvAeRFeS/Liv00jddUtej2Bs9pKP4TDYdgOdBD3C4h2wcCrx1M/8kn7j2Y/gxwM03Tz2RZdouHo4GLOuA2EGliNBGpY3qM8+uAoeV3MBvjXBucTJ5dfIcwGgIGlIDxOjAx8DrhgQioEdUjxCmmEQDlaDATGTPF+JRKv24Dbp71GX9M8L84Jo46QVTs6gAAAABJRU5ErkJggg==' Local $bString = _WinAPI_Base64Decode($Au3_Icon) If @error Then Return SetError(1, 0, 0) $bString = Binary($bString) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\au3-icon2.png", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Au3_Icon Func _WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_WinAPI_Base64Decode Download: GDI+ Swiss Railway Clock v1.16 (Widget).au3 GUI version (discontinued): ;the Hilfiker / MobaTime Swiss Railway Clock ;coded by UEZ build 2018-03-01 ;thanks to Eukalyptus for the _CreateBrushedAluminum() function! #Pragma Compile(Icon, "GDI+ Swiss Railway Clock.ico") #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe /rm #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3" #AutoIt3Wrapper_UseX64=n Break(0) #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> ProcessSetPriority(@AutoItPID, $PROCESS_LOW) _GDIPlus_Startup() Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit Global Const $iW = 512, $iH = $iW, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ Swiss Railway Clock v1.1" Global Const $fRad = ACos(-1) / 180, $fDeg = 180 / ACos(-1), $iTimer = 30, $fDeltaShadow = $iW * 0.020 Global $hDC, $hCanvas, $hBitmap_Clock, $hBrush_Shadow, $hBrush_Update, $hPen_Update, $fDiameter = $iW, $hDC_backbuffer, $fShadowAngle, $fMin_next, _ $fRadius = $fDiameter / 2, $fSec, $fMin, $fHr, $fAmplitude = 3 AutoItSetOption("GUIOnEventMode", 1) GDIPlus_SwissRailwayClock() AutoItSetOption("GUIOnEventMode", 0) _GDIPlus_Shutdown() Func GDIPlus_SwissRailwayClock() $bExit = False $hGUI = GUICreate($sTitle, $iW + $fDeltaShadow, $iH + $fDeltaShadow, -1, -1, -1, $WS_EX_TOPMOST) GUISetBkColor(0xFFFFFF, $hGUI) GUISetState(@SW_SHOW, $hGUI) ;~ GUISetCursor(16, 1) ;create canvas elements $hDC = _WinAPI_GetDC($hGUI) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW + $fDeltaShadow, $iH + $fDeltaShadow) $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) $hBrush_Shadow = _GDIPlus_BrushCreateSolid(0x14A0A0A0) $hPen_Update = _GDIPlus_PenCreate(0xFFA02020) $hBrush_Update = _GDIPlus_BrushCreateSolid(0) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) $fDiameter = $fDiameter < 128 ? 128 : $fDiameter > 1024 ? 1024 : $fDiameter $hBitmap_Clock = GenerateClockBg($fDiameter) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") $fMin_next = @MIN GUIRegisterMsg($WM_TIMER, "Draw") ;$WM_TIMER = 0x0113 Local $iID = DllCall("User32.dll", "uint_ptr", "SetTimer", "hwnd", $hGUI, "uint_ptr", 1, "uint", $iTimer, "ptr", 0)[0] Do If $bExit Then ExitLoop Until Not Sleep(100) ;release resources GUIRegisterMsg($WM_TIMER, "") DllCall("user32.dll", "bool", "KillTimer", "hwnd", $hGUI, "uint_ptr", $iID) _GDIPlus_PenDispose($hPen_Update) _GDIPlus_BrushDispose($hBrush_Shadow) _GDIPlus_BrushDispose($hBrush_Update) _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI, $hDC) GUIDelete($hGUI) EndFunc ;==>GDIPlus_SwissRailwayClock Func Draw($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam _GDIPlus_GraphicsDrawImageRect($hCanvas, $hBitmap_Clock, 0, 0, $fDiameter + $fDeltaShadow, $fDiameter + $fDeltaShadow) UpdateClock($hCanvas, $fDiameter) _WinAPI_BitBlt($hDC, 0, 0, $iW + $fDeltaShadow, $iH + $fDeltaShadow, $hDC_backbuffer, 0, 0, $SRCCOPY) EndFunc Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func UpdateClock($hGfx, $fDiameter) Static $bBounce = 0, $f = 0 Local $m1 = $fDiameter * 0.015 ;hour $fHr = 30 * (@HOUR + @MIN / 60) _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, $fHr) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) Local $iWidth1 = $fDiameter * 0.0375, _ $iHeight1 = $fDiameter / 2.5, _ $iWidth12 = $iWidth1 / 2, _ $fPosY = $fDiameter * 0.2, $iWidth2, $iWidth22, $fPosY2 _GDIPlus_BrushSetSolidColor($hBrush_Update, 0xFF101010) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius - $iWidth12 + Cos(($fShadowAngle - $fHr) * $fRad) * $m1, _ "float", $fPosY + Sin(($fShadowAngle - $fHr) * $fRad) * $m1, _ "float", $iWidth1, "float", $iHeight1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth12, _ "float", $fPosY, _ "float", $iWidth1, "float", $iHeight1) _GDIPlus_GraphicsResetTransform($hGfx) ;min If $fMin_next <> @MIN Then $bBounce = 1 Switch $bBounce Case 1 $fMin = (6 * Mod(($fMin_next + 1), 60)) + Sin($f * 1.9) * $fAmplitude If $fAmplitude = 0 Then $fMin_next = @MIN $f = 0 $fAmplitude = 3 $bBounce = 0 Else $fAmplitude -= 0.5 $fAmplitude = $fAmplitude <= 0 ? 0 : $fAmplitude $f += 1 EndIf Case Else $fMin = (6 * @MIN) EndSwitch _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, $fMin) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) $iWidth1 = $fDiameter * 0.03 $iHeight1 = $fRadius $iWidth12 = $iWidth1 / 2 $fPosY = $fDiameter * 0.1 DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius - $iWidth12 + Cos(($fShadowAngle - $fMin) * $fRad) * $m1, _ "float", $fPosY + Sin(($fShadowAngle - $fMin) * $fRad) * $m1, _ "float", $iWidth1, "float", $iHeight1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth12, _ "float", $fPosY, _ "float", $iWidth1, "float", $iHeight1) _GDIPlus_GraphicsResetTransform($hGfx) ;sec $fSec = 6 * (@SEC * 1.02564 + @MSEC / 1000) If $fSec >= 360 Then $fSec = 0 _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, $fSec) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) $fPosY = $fDiameter * 0.27 $fPosY2 = $fDiameter * 0.19 $iWidth1 = $fDiameter * 0.0095 $iHeight1 = $fRadius * 1.3 - $fPosY $iWidth12 = $iWidth1 / 2 $iWidth2 = $fDiameter * 0.083333 $iWidth22 = $iWidth2 / 2 ;shadow seconds DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius + Cos(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $fPosY + Sin(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $iWidth1 + $fDiameter * 0.006667, "float", $iHeight1 + $fDiameter * 0.006667) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGfx, "handle", $hBrush_Shadow, _ "float", $fRadius - $iWidth22 + Cos(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $fPosY2 + Sin(($fShadowAngle - $fSec) * $fRad) * $m1, _ "float", $iWidth2, "float", $iWidth2) ;seconds _GDIPlus_BrushSetSolidColor($hBrush_Update, 0xFFC01010) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth12, _ "float", $fPosY, _ "float", $iWidth1, "float", $iHeight1) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth22, _ "float", $fPosY2, _ "float", $iWidth2, "float", $iWidth2) _GDIPlus_GraphicsResetTransform($hGfx) ;button in the center DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hGfx, "handle", $hBrush_Update, _ "float", $fRadius - $iWidth1, _ "float", $fRadius - $iWidth1, _ "float", 2 * $iWidth1, "float", 2 * $iWidth1) DllCall($__g_hGDIPDll, "int", "GdipDrawEllipse", "handle", $hGfx, "handle", $hPen_Update, _ "float", $fRadius - $iWidth1, _ "float", $fRadius - $iWidth1, _ "float", 2 * $iWidth1, "float", 2 * $iWidth1) EndFunc Func GenerateClockBg($fDiameter) Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($fDiameter + $fDeltaShadow, $fDiameter + $fDeltaShadow), $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap), _ $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000), $fBorderSize = $fDiameter * 0.03333, _ $hEffect = _GDIPlus_EffectCreateBlur($fDiameter / 50, 0), $hPen = _GDIPlus_PenCreate(0xA0000000, $fBorderSize) _GDIPlus_GraphicsSetSmoothingMode($hGfx, 4) _GDIPlus_GraphicsSetPixelOffsetMode($hGfx, 4) _GDIPlus_GraphicsSetTextRenderingHint($hGfx, 4) _GDIPlus_GraphicsClear($hGfx, 0xFFFFFFFF) Local Const $fSize = $fDiameter * 0.95 - $fBorderSize / 2 Local $fShadow_vx = $fDiameter * 0.0095, $fShadow_vy = $fDiameter * 0.01 $fShadowAngle = ATan($fShadow_vy / $fShadow_vx) * $fDeg If $fShadow_vx < 0 And $fShadow_vy >= 0 Then $fShadowAngle += 180 If $fShadow_vx < 0 And $fShadow_vy < 0 Then $fShadowAngle -= 180 _GDIPlus_GraphicsDrawEllipse($hGfx, $fBorderSize + $fShadow_vx, $fBorderSize + $fShadow_vy, $fSize, $fSize, $hPen) _GDIPlus_BitmapApplyEffect($hBitmap, $hEffect) _GDIPlus_PenSetColor($hPen, 0xF0000000) Local Const $hBitmap_Texture = _CreateBrushedAluminum($fDiameter, $fDiameter, $fShadowAngle) Local Const $hTexture = _GDIPlus_TextureCreate($hBitmap_Texture) DllCall($__g_hGDIPDll, "int", "GdipSetPenBrushFill", "ptr", $hPen, "ptr", $hTexture) _GDIPlus_GraphicsDrawEllipse($hGfx, $fBorderSize, $fBorderSize, $fSize, $fSize, $hPen) _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, -6) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) Local $iWidth1 = $fDiameter * 0.026667, $iHeight1 = $fDiameter / 10, $iWidth12 = $iWidth1 / 2, $fPosY = $fDiameter * 0.083333, _ $iWidth2 = $fDiameter * 0.013333, $iHeight2 = $fDiameter * 0.0416667, $iWidth22 = $iWidth2 / 2 For $i = 0 to 59 _GDIPlus_GraphicsTranslateTransform($hGfx, $fRadius, $fRadius) _GDIPlus_GraphicsRotateTransform($hGfx, 6) _GDIPlus_GraphicsTranslateTransform($hGfx, -$fRadius, -$fRadius) Switch Mod($i, 5) Case 0 _GDIPlus_GraphicsFillRect($hGfx, $fRadius - $iWidth12, $fPosY, $iWidth1, $iHeight1, $hBrush) Case Else _GDIPlus_GraphicsFillRect($hGfx, $fRadius - $iWidth22, $fPosY, $iWidth2, $iHeight2, $hBrush) EndSwitch Next _GDIPlus_GraphicsResetTransform($hGfx) Local Const $hBitmap_Logo = _GDIPlus_BitmapCreateFromMemory(_Au3_Icon()) Local Const $hBitmap_Logo_Scaled = _GDIPlus_ImageResize($hBitmap_Logo, $fDiameter * 0.08, $fDiameter * 0.08) Local $aDim = _GDIPlus_ImageGetDimension($hBitmap_Logo_Scaled) _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap_Logo_Scaled, $fRadius - $aDim[0] / 2, $fRadius / 1.75, $aDim[0], $aDim[1]) _GDIPlus_ImageDispose($hBitmap_Logo) _GDIPlus_ImageDispose($hBitmap_Logo_Scaled) Local Const $hFamily = _GDIPlus_FontFamilyCreate("Segoe Script"), $hFont = _GDIPlus_FontCreate($hFamily, $fDiameter * 0.025), $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) ;~ _GDIPlus_BrushSetSolidColor($hBrush, 0xFF400000) _GDIPlus_GraphicsDrawStringEx($hGfx, "Clock by" & @CRLF & "UEZ", $hFont, _GDIPlus_RectFCreate($fRadius - $fRadius * 0.2, $fRadius + $fRadius * 0.2, $fRadius * 0.4, $fRadius * 0.4), $hFormat, $hBrush) _GDIPlus_ImageDispose($hBitmap_Texture) _GDIPlus_BrushDispose($hTexture) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_EffectDispose($hEffect) _GDIPlus_PenDispose($hPen) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGfx) Return $hBitmap EndFunc Func _CreateBrushedAluminum($iW, $iH, $fLightAngle = 40, $iBlurDist = 12, $fBlurTrans = 0.6666, $fRed = 0.8, $fGreen = 0.9, $fBlue = 1, $iLightColor = 0xF0FFFFFF, $fLightSigma = 0.5, $fLightScale = 0.83) ;coded by Eukalyptus! $iBlurDist = Ceiling($iBlurDist) $iBlurDist += 1 - Mod($iBlurDist, 2) Local $iOverSize = 0 For $i = 1 To $iBlurDist Step 2 $iOverSize += $i + $i + 1 Next Local $iWO = $iW + $iOverSize ;========================================= ; Add Noise ;========================================= Local $iNoiseSize = 40 Local $hBmp_Noise = _GDIPlus_BitmapCreateFromScan0($iNoiseSize, $iNoiseSize) Local $hGfx_Noise = _GDIPlus_ImageGetGraphicsContext($hBmp_Noise) Local $tData = _GDIPlus_BitmapLockBits($hBmp_Noise, 0, 0, $iNoiseSize, $iNoiseSize, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) Local $iStride = DllStructGetData($tData, "Stride") Local $iWidth = DllStructGetData($tData, "Width") Local $iHeight = DllStructGetData($tData, "Height") Local $pScan0 = DllStructGetData($tData, "Scan0") Local $tPixel = DllStructCreate("dword[" & $iWidth * $iHeight & "];", $pScan0) Local $iAmp For $row = 0 To $iHeight - 1 For $col = 0 To $iWidth - 1 $iAmp = Random(0, 0xFF, 1) DllStructSetData($tPixel, 1, BitOR(0xFF000000, BitShift($iAmp, -16), BitShift($iAmp, -8), $iAmp), $row * $iWidth + $col + 1) Next Next _GDIPlus_BitmapUnlockBits($hBmp_Noise, $tData) ;========================================= ; Create Full NoiseBitmap ;========================================= Local $hBmp_Full = _GDIPlus_BitmapCreateFromScan0($iWO, $iH) Local $hGfx_Full = _GDIPlus_ImageGetGraphicsContext($hBmp_Full) _GDIPlus_GraphicsSetSmoothingMode($hGfx_Full, 4) _GDIPlus_GraphicsSetInterpolationMode($hGfx_Full, 3) Local $iXOff, $iYOff, $iSizeX, $iSizeY For $y = 0 To $iH Step $iNoiseSize / 2 For $x = 0 To $iWO Step $iNoiseSize / 2 $iXOff = Random(0, $iNoiseSize / 2, 1) $iYOff = Random(0, $iNoiseSize / 2, 1) $iSizeX = $iNoiseSize - $iXOff $iSizeY = $iNoiseSize - $iYOff _GDIPlus_GraphicsDrawImageRectRect($hGfx_Full, $hBmp_Noise, $iXOff, $iYOff, $iSizeX, $iSizeY, $x, $y, $iSizeX, $iSizeY) Next Next _GDIPlus_GraphicsDispose($hGfx_Noise) _GDIPlus_BitmapDispose($hBmp_Noise) ;========================================= ; MotionBlur ;========================================= Local $hBmp_Full2 = _GDIPlus_BitmapCreateFromScan0($iWO, $iH) Local $hGfx_Full2 = _GDIPlus_ImageGetGraphicsContext($hBmp_Full2) _GDIPlus_GraphicsSetSmoothingMode($hGfx_Full2, 4) _GDIPlus_GraphicsSetInterpolationMode($hGfx_Full, 3) Local $tColorMatrix = DllStructCreate("float[5]; float[5]; float[5]; float[5]; float[5];") DllStructSetData($tColorMatrix, 1, 1, 1) DllStructSetData($tColorMatrix, 2, 1, 2) DllStructSetData($tColorMatrix, 3, 1, 3) DllStructSetData($tColorMatrix, 4, $fBlurTrans, 4) DllStructSetData($tColorMatrix, 5, 1, 5) Local $hImgAttrib = _GDIPlus_ImageAttributesCreate() DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, "int", 1, "struct*", $tColorMatrix, "struct*", 0, "int", 0) For $i = 1 To $iBlurDist Step 2 DllCall($__g_hGDIPDll, "int", "GdipDrawImageRectRect", "ptr", $hGfx_Full2, "ptr", $hBmp_Full, _ "float", $i, "float", 0, "float", $iWO, "float", $iH, _ "float", 0, "float", 0, "float", $iWO, "float", $iH, _ "int", 2, "ptr", $hImgAttrib, "ptr", 0, "ptr", 0) If $i >= $iBlurDist Then DllStructSetData($tColorMatrix, 1, $fRed, 1) DllStructSetData($tColorMatrix, 2, $fGreen, 2) DllStructSetData($tColorMatrix, 3, $fBlue, 3) DllStructSetData($tColorMatrix, 4, 1, 4) DllCall($__g_hGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, "int", 1, "struct*", $tColorMatrix, "struct*", 0, "int", 0) EndIf DllCall($__g_hGDIPDll, "int", "GdipDrawImageRectRect", "ptr", $hGfx_Full, "ptr", $hBmp_Full2, _ "float", $i + 1, "float", 0, "float", $iWO, "float", $iH, _ "float", 0, "float", 0, "float", $iWO, "float", $iH, _ "int", 2, "ptr", $hImgAttrib, "ptr", 0, "ptr", 0) Next _GDIPlus_ImageAttributesDispose($hImgAttrib) _GDIPlus_GraphicsDispose($hGfx_Full2) _GDIPlus_BitmapDispose($hBmp_Full2) _GDIPlus_GraphicsDispose($hGfx_Full) ;========================================= ; Add Light ;========================================= Local $hBmp_Alu = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hGfx_Alu = _GDIPlus_ImageGetGraphicsContext($hBmp_Alu) _GDIPlus_GraphicsSetSmoothingMode($hGfx_Alu, 4) _GDIPlus_GraphicsSetInterpolationMode($hGfx_Full, 3) _GDIPlus_GraphicsDrawImage($hGfx_Alu, $hBmp_Full, -$iOverSize, 0) _GDIPlus_BitmapDispose($hBmp_Full) Local $tPointF1 = DllStructCreate("float; float;") Local $tPointF2 = DllStructCreate("float; float;") DllStructSetData($tPointF2, 2, $iH * $fLightScale) $aResult = DllCall($__g_hGDIPDll, "int", "GdipCreateLineBrush", "struct*", $tPointF1, "struct*", $tPointF2, "uint", 0, "uint", $iLightColor, "int", 0, "handle*", 0) If @error Or Not IsArray($aResult) Then Return SetError(1, 4, False) Local $hBrush = $aResult[6] _GDIPlus_LineBrushSetSigmaBlend($hBrush, $fLightSigma) _GDIPlus_LineBrushSetGammaCorrection($hBrush) DllCall($__g_hGDIPDll, "int", "GdipRotateLineTransform", "ptr", $hBrush, "float", $fLightAngle, "int", 0) _GDIPlus_GraphicsFillRect($hGfx_Alu, 0, 0, $iW, $iH, $hBrush) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGfx_Alu) Return $hBmp_Alu EndFunc ;==>_CreateBrushedAluminum ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2018-02-02 Func _Au3_Icon($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Au3_Icon $Au3_Icon &= 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAP0ElEQVR4XtWZW4hs6VXHf+v79qWquruquqtvZ/r0uc8540yScTIQQ0JkDOYyGhIkhhAxxhdR8mDAgAg+6FsE9UVffNMH8S0ERAwS1DFeEo3m6owzmUySc+Zc+15VXZd9+dZyp6ro4pDTORlGIfnDn703TW/+//X9v/Wt3i3PPfccP85w/GhBgLqkS23ixhpRfau6bgItIPpRN5Ag0Xl88jYrxu/E+KA492E0vJd44d245BKQ/H8bkAe80wMOEE5HA5c8SpQ822yv/ubW9vnfffyxR3+vs7r6YcS9HewZnP9ZXPwE0Py/NuCBJj65iERvQPybcNFP4JKzuPgq+CeR6GnwV3FJB4juM+mSNj55Ehe97/LFC5947PL2ey5tb755daW1+fiVc295+qk3fuTShfPPPnb10d+J60sfI6o9BbRer4EIaOLis1Nh6dtBfs6ljY82ljqfiNLFX8X597uk/ksrG4/8ftJo/lq62P51XPQOJHoc3DV8egZYxLkLcW3xQ088fvWTj2ysXItjnxRlGY6Ojmxvb98iJwtnz6xeXO80tx+9tP0Rcf6tuHhzLuS1YwmJLiHuslRVbzQbjydJsrXSbl4RIVlpLZ0xM71+e+cbC41a+8zayuVxlo9CCPnX/vslt7S89iEzy4/7R/+MT7+Lhq2V5dbbO63Ftbwog/feDYdDt7e3R71eo9vt2tbWlkZRRC1NFkHWQDpACmQ/bBuVWUyaiN+Kk9oH2q3mO/Ky0HNn1p9sNxeaBpiBmpl3TlTNqouoqkmFoKp5XuT1NKlVFS5ffOXm54ui2EFIr17afudCLV1SM5mBity+fRuAzc1NVC1EkfN3dg+/9e1vf/ePMfssYXz9hzXQJKo/BTyKlovrZ7Y+fPXi1luryubOOeKqPBpKQiilLAMhBAwEw7x3RN9jFImPIhTR8TjPQghFvZY2s7wYpkmc' $Au3_Icon &= 'Ag5ARFBVuXHjBpVPqurTaDRMVRERQgjll776wp9YKP+KMP5a9NCsS7SBuHMgb2stt9+13FraXltubYegmkRRMh4POTwccdAbMy4CQTFDBBEDABMvYmnirNVIaC3UpVFP667WqFdmrRLfYA7MDIBWq0WaplQRIo5j8d6bVvDOxbV6fXV03C0BeYgBvyxx7R1prfbs2srym8+e6bxhtrwMjnt276Bv3UGOuYQ4bVCrJ1JVWtxEvxO0xBHIiiBVpbnbLexetysLidjmygKLCwsYzjATwACpQK/XY2VlBTNjZ2cHVTXvvYkgg3F2lI2z2+ByIEScjgRx23GSPvPU41d+BQE1zMqCnb197h2NxCeLttBeliiOmCUGDIIJFgIbzYh2IyUoqBrHo0LuHQ4ozMl37g1sqTaUrdWWJbW6haAChnOOPM/Z3d1lNBpRVX/CEJTIOxkOs2Mt8z4iAHa6ARdvVnzL+a3NnzfMVNEyz/z1Wzt2XHgWW+tUwkUV8tKYlQ81IZLA9nJMI40IaohAFAnLSxHeSm7sDWi0VuR4cMxLN/fl0maLxsICqlRUVldXOTg4IEkSOp2OVUAE1Iz+YLSHyAAYndZGE1yyAXqt1Wq/b3Vl6WxQC/lo4F5+dccK15Dmchs1yEpAHCAwEe+IKbm8GhN5T6mKEwGmwgAWFxdYHo7Y6fdoLDUZDz0vvnrI1S1lYXEJnRmuhANYBalozolT1dDt97+Chq+j+f6DDUh0Bh8/k9br7754buOng5oW2ci9fGNHxtRoLrbIgwEecw5sasAQRAPnVx3eC0UIE/FmxhxgwMZqm1G+T/d4SL3eoAzKizcPefycUG8soqqEEAxMzFARIcvL8fWbO18YH/c+DfICcPwgA4JZa2lp6b3XLp39kK8QQtBbd/ZlUIgttJakNFA8OIeZQ5hVPyhnm0Y9dpTBEMDMeBBMPGc6i/RvdRnnCVWTIMvHfPPWEU+c97iohpmad47jcda/u3Pw/MHh' $Au3_Icon &= '0b+Zll8GfREtd08bJSJ81DgeDO6WQYOBHh3uy04/M5c0RCaxEBSHmsNMUKBUo5Uo6w0hVwEzToOZQcW01uCR5ZQym2zqSRcbZyW39gdgATPEgLu7hy/v7+3+jWn5GUz/Hi1vAPagUaKGS65geqndbD2ZJnE8Hh3bzb0BuFgkignq0FnmMWaCIHElFzuO0jwOQ+bR+YFGaomHMJyumIvAp1RdirVmnaRWMxGcqwi2i9mrhGyHOe43gEQrLq698+wj6x9f77SvWYVefyjjgOBjwKMiGG4uXsBZydU1jyGoKhpK8iLHe08cJ4gID4aAAhZQA8GBj7Gi4Ob+gMuPREBCGUKJWQNYBASw08bpBbDVtZXWNQPLs6FVvV6QyHAROmuRChigCGjg0rIjdTqpYlHk3L5zl2rO4Tu39iZmDDCzCZnfT4gTmL8PnAMXczTIyPOAqlk1JJ73Sf2NOH9pZoIHGYiApXqjcQVMMXQ8GssoV8NFgngMhyLA1IgLGRfa0K4beZCJ2J3dXfa7Q6I4pV9E3D0YYmV2f/7n90RRTC1yWChQExAPPsJUORzkTjVYNaVuXLm0/UHEXcDXaqcZSBBZi6NoAwRMGWUlhkzE4zwgqBoGYIGzLWG1rmQlOIHjfo+j45z11RUKE6ivcHsYca+bI9j0d21OMMR5Uq9okaEA4k5YGTBMKVV1MBwfYhpVbJy+AuKaYJEZqAbpjQoQx5yCMTspG8ZG05Opm4kL9IYZucJOd0AZL4G4yQgQxTXAMO6PkAF5NqY/KjAXA8LcgGecl6JBEcH1+sd3QFpA68EGosbC7IfxNNqlZaWdCAem92Y0IuXiMuQB5EQUdNotttY7bK52OL+6yLWO8pObsLboCMr3nws2NZAFAZ8whZwY0aAoAoY16rVVIIAVD+5CpklVqcvVmHwFM1TVBTU5GRNwiBnLDcfVjpIHB6bMAbVaQqNeQ8RQVcBRmCGnHWYYWZ5jEoGraDoTP6WpEYKK91YV' $Au3_Icon &= 'pX1ld+/Ah6zonxYhFCsXGumqqk2fDDspCkanIVxbKRkHh6l+X09XNcoQKEolmKAnwgUDzO7fyKZKVgTwMYh7gEFsQtNw697BC6HIR4ic0oUEESQKqkFEHCYmjpMe5zAudCLGFoHp97dDQEQwZmbKchqPYZ9B/4DxoIdqeSJezQhlwTAvwaecQDiBiMwe8cvtxS0fpxfAWoB7QIQoQlm8/NIrNz9z7fLZ94vzSeycZaWJYDzxSB1MmW2q+0TrieAReZ6RF4FRHhgXSqEQJkl0PLadkiR+ZkIIoWCUGdRjmB/rJxQRvBfMQIwESEGSmQG930AY7+HS5/N8fCXPy6KeuiSNnR2Pc1mqJ5ONOywU78BsLjwfjRj0e5NO0s+UIH5aUV+HKJlm21fUkkwhwVAzBCiLgmCAiwG7n6b4yIub6VcsA7uO6Q4QHjRKFGg5rObzs/VasmiqZZr4qJrd7bGtBcnyAifzHIeg9LoH7B70GWoEyRIsLEzFu1nnMuaVRRjmBUupYgrihLIsURyIZ155nVIDjSRR50Sq9tx7+ZXrf46Gf8TKm4CdMguJz4uil+fFKIp80lxo2NZ6g+oZVQXmq9w9OuDmzhFaW4HFzrTSGNicU9hJsPMAmAIOwyjLAM7PzOr9xGgvpZhBvz/aE/HerMiA0WldSIGeqXZFJC6Dulq9ThmChBAwM0wVMxgOj7m730NrHVhYB+fAwikjtIAACGqAKjp7V1AD8QD3VZ5Q4H1kywux5EXQ732Ra7eab0I1AO40AyCupxpe2T/qf9P7yMTUiqKwk9YnMhnWDg+PyKUOjc682gg/EMJ8jzKFqoG4k8xjYUot6LQagikGriyDdnv9zyNyBJSnG9C8b0X2D3mpN9MkcveJB1SV7tE+B4MwFY8ADxEv833pBEwAM8bjMaNxBshcvJYQcpyPbKtTpyjNIufk7l73q1qMvoiVuwCnGRAgixvNKxe21t+VZVlpZq6izA4pBsd9dg5HkDZn' $Au3_Icon &= 'J2eYb9RTMPdn1GLBcJhN33WUCcQNCMWEUwMF2+st0RCsAkf94W7/ePAVzO4Ag1MNzNDcPrP+B2aBEALARLzBJDp7B10CHnwCIQct59l/iAlBaUSgBoJRBp2KdxHo7F3FiFaraZ0Fb3kRDCyr/pz8pyIbfRa4B+hpBhLAti9cfmahnjyd53kBRFYBwFSt1+vZOC8hSkHnFZsygCmg87zcvwSIMR2bDcyUrFSAaSFCCeWIWr1hV9YbMspKjSPnrt/e/fdsNPg7TL9xWnyYn2qkYL/ovVPVWVLNBGA4HNLrDzmz1rbVVsMIGRVtugoFWDE3MjMzp4HmRGSIQBXNybfOLC/BbGqgGFq93uCJc21GeaFR5P0oK3pl0Bugz6P57R+U0wgoN7fO/8Zyq/nRooJhEYZUsLIsqDqA1Bs1lpotW9IgiXfcORqJlSNwCfgIxE84H78FYHofCupRCfjJp8K9wz4BD24SQVtpt+XiRsOqTY2A6/aGt1+9c+8vLBSfI4RXgIzTQQSki43axzHVEILI/Eua9fsDd9TtXd/c2Iy9d49kQfP2YhotNWJ5dW/EMJusguBicBMTcwPCFKqYQCgDg1FGXhqIWpQmnD/Tpplig9EYAesNsnu37tz7S9Pw14Tsf4AeD0F0/tLlReekphoEEDAB0SzL5ODoqI/qn+0e9ZezUp9dbjbOJ/W0aRAurNUlK+vubndsw6zAilwQARy4+SqIlZShIGt2LIQgca1h651l1tt1iqKQ42EIceTdzn7v+b39/U+L889j4VtT8Q+HfOUbL3zq7Ob6J800VlWbfR3W3b193z06/EPEfwoXP+ai+BdWO+0PFEXIq/3wBjAwVGazd29U0q+YFYGghjFF7KDmApVGGQ2PbWOtI1WzIC8Vg1Bp94fdwau37+78KdhzaHgFLbpA4OEgwmzNmPR8RCZDVuj2elG3e/S5NIn/KMuLQyR+Ucv80zs7ey+BbVVinIjUVpcXL816O82613Zd' $Au3_Icon &= 'gMTEOQcCqIo4RlkpVRu2Uk129w8DneWxeO9v3N79l+pCnuVfxvRfCdkLwIDXAPnSf33tU+fOnvktEXNFUUi1af3e3sHXNRQfA746P0+p4eJlxJ9D5I3OR09fPnfml6vD5m6rubCdRC4FAUDNdDTOe977ej2NUjOjdzxgNBwVh73h3/ooGXrvk2w8esE0PI9Nus11oM9rhHzhi//xtpXV1c+msW92uz0ODw6fA/1t4Es8GDEu3kDcFRclP6Ua2nGcbMdxvI4hzossLdQvAeRFeS/Liv00jddUtej2Bs9pKP4TDYdgOdBD3C4h2wcCrx1M/8kn7j2Y/gxwM03Tz2RZdouHo4GLOuA2EGliNBGpY3qM8+uAoeV3MBvjXBucTJ5dfIcwGgIGlIDxOjAx8DrhgQioEdUjxCmmEQDlaDATGTPF+JRKv24Dbp71GX9M8L84Jo46QVTs6gAAAABJRU5ErkJggg==' Local $bString = _WinAPI_Base64Decode($Au3_Icon) If @error Then Return SetError(1, 0, 0) $bString = Binary($bString) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\au3-icon2.png", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Au3_Icon Func _WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_WinAPI_Base64Decode If you want to run in x64 mode please use AutoIt version 3.3.14.3 since the bug in function _GDIPlus_EffectCreate() has been fixed!
-
The _ScreenCapture_CaptureWnd() logic may have an issue in v3.3.14.3. I was testing scripts using v3.3.14.3 and saw that the scripts' screen captures weren't getting created. I immediately ran the scripts using v3.3.14.2 and the screen captures were being created as expected. The _ScreenCapture_CaptureWnd() function, in v3.3.14.3, returns @error = -2. Can anyone else confirm that they are seeing the same issue? Below is a slightly modified version of the function's help file's _ScreenCapture_CaptureWnd() example that should allow you to recreate the issue. #include <Constants.au3> #include <ScreenCapture.au3> Example() Func Example() Local $hGUI ; Create GUI $hGUI = GUICreate("Screen Capture", 400, 300) GUISetState(@SW_SHOW) Sleep(250) ; Capture window _ScreenCapture_CaptureWnd(@TempDir & "\GDIPlus_Image.jpg", $hGUI) If @error Then MsgBox($MB_ICONERROR, "", _ "_ScreenCapture_CaptureWnd() failed." & @CRLF & @CRLF & _ "@error = " & @error _ ) Exit 1 EndIf ShellExecute(@TempDir & "\GDIPlus_Image.jpg") EndFunc ;==>Example
- 10 replies
-
- 3.3.14.3
- _screencapture_capturewnd
-
(and 1 more)
Tagged with:
-
#include <GDIPlus.au3> Text2PNG(@DesktopDir & "\MyPNG.png", 0x00FFFFFF) ; Transparent but bold ugly text ;Text2PNG(@DesktopDir & "\MyPNG.png", 0xFFFFFFFF) ; Nice Text but not transparent Func Text2PNG($sFile, $iColor) _GDIPlus_Startup() Local $hImage = _GDIPlus_BitmapCreateFromScan0(50, 25) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsClear($hGraphics, $iColor) _GDIPlus_GraphicsDrawString($hGraphics, "Hello", 0, 0, "Arial", 12, 0) _GDIPlus_ImageSaveToFile($hImage, $sFile) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() EndFunc ;==>Text2PNG Hello ladys and gentlemen, I have this piece of code and it does what it's supposed to do. I want to use it to create an image sequence with frame/image information for compositing overlay. However, when i use a transparent background the text starts to look kinda bold or fat. I dont know what causes this ugly effect. Is there a way to avoid this effect somehow? Thanks!
-
$hImage = _GDIPlus_ImageLoadFromFile($aImageSave) $X1 = _GDIPlus_ImageGetWidth($hImage) $Y1 = _GDIPlus_ImageGetHeight($hImage) $X2 = _GDIPlus_ImageGetWidth($hImage) $Y2 = _GDIPlus_ImageGetHeight($hImage) $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form1) ;$PicPreview = GUICtrlCreatePic("", 24, 152, 572, 268) _GDIPlus_GraphicsDrawImage ($hGraphic, 24, 152, 572, 268);? I have the same size and relative coords to $PicPreview in the image placement form1 I want to be Other Responsibility Is there a problem with _GDIPlus code sorting? #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Global $Form1, $hImage, $hGraphic, $OpenPictures, $PicPreview _GDIPlus_StartUp() $Form1 = GUICreate("Form1", 615, 438, 374, 347) $PicPreview = GUICtrlCreatePic("", 24, 152, 572, 268) $ButtonPreview = GUICtrlCreateButton("Preview", 520, 112, 75, 25) $InputImageDir = GUICtrlCreateInput("", 64, 48, 177, 21) $ButtonOpen = GUICtrlCreateButton("...", 256, 48, 75, 25) $ButtonWatermark = GUICtrlCreateButton("Watermark Add", 256, 112, 80, 25) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_ImageDispose($hImage) _GDIPlus_ShutDown() Exit Case $ButtonOpen $OpenPictures = FileOpenDialog("Where are the pictures?", @ScriptDir & "\", "Picture format (*.jpg;*.bmp;*.png)", $FD_FILEMUSTEXIST + $FD_MULTISELECT) If Not $OpenPictures Then MsgBox(64, "İnfo","No Files Selected!",5) Else GUICtrlSetData($InputImageDir,$OpenPictures) EndIf Case $ButtonWatermark $aImageLoad = $OpenPictures $aImageSave = @ScriptDir & "\Save.png" $aImageLogo = @ScriptDir & "\Logo.png" _Watermark($aImageSave, $aImageLoad, $aImageLogo) Case $ButtonPreview $hImage = _GDIPlus_ImageLoadFromFile($aImageSave) $X1 = _GDIPlus_ImageGetWidth($hImage) $Y1 = _GDIPlus_ImageGetHeight($hImage) $X2 = _GDIPlus_ImageGetWidth($hImage) $Y2 = _GDIPlus_ImageGetHeight($hImage) $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($Form1) ;$PicPreview = GUICtrlCreatePic("", 24, 152, 572, 268) _GDIPlus_GraphicsDrawImage ($hGraphic, 24, 152, 572, 268) EndSwitch WEnd Func _Watermark($sFile2, $sFile, $sLogo) Local $hImage1, $hImage2, $hGraphic _GDIPlus_Startup () $hImage1 = _GDIPlus_ImageLoadFromFile ($sFile) ; image $X1 = _GDIPlus_ImageGetWidth ($hImage1) $Y1 = _GDIPlus_ImageGetHeight ($hImage1) $hImage2 = _GDIPlus_ImageLoadFromFile ($sLogo) ; logo $X2 = _GDIPlus_ImageGetWidth ($hImage2) $Y2 = _GDIPlus_ImageGetHeight ($hImage2) $hGraphic = _GDIPlus_ImageGetGraphicsContext ($hImage1) _GDIPlus_GraphicsDrawImage ($hGraphic, $hImage2, 20, $Y1-$Y2-30) _GDIPlus_ImageSaveToFile ($hImage1, $sFile2) ; image watermarked _GDIPlus_ImageDispose ($hImage1) _GDIPlus_ImageDispose ($hImage2) _GDIPlus_ShutDown () EndFunc ;==>_Watermark
-
In the code that follows, it appears that DllStructCreate() is not allocating memory in $tag = 'byte val['&$iLength&']' . . Static Local $tvalue = DllStructCreate($tag) Running the code below, the problem does not show, but it does show in a much longer script: there _GDIPlus_ImageSaveToFile only writes about 30K bytes when it should write about 1MB, which it does when the code is $tag = 'char val['&$iLength&']' . . Static Local $tvalue = DllStructCreate($tag) It should write about 1 MB. I suggest caution in running the code below. On my PC, it caused a second instance of SciTE to appear at the top left of the Desktop, showing only the title bar, with a width of only approximately 200 pixels! Then rebooting the PC showed this at login. Further, double-clicking on the SciTE shortcut on the Desktop showed SciTE in the same way! (After running Regedit, and searching for SciTE, the shortcut behaves normally.) I would appreciate help in determining whether or not there is a bug in DLLStructCreate, preferably a way which does not clobber Windows. Of course, It is possible that there is a bug in my code. I have made $tvalue Static in the hope that this might make the code run properly. Doing this did not help. My code is based on code written by Authenticity and ChrisL. #include <GDIPlus.au3> #include <Array.au3> Opt('MustDeclareVars',1) ; Property Item structure Global Const $tagGDIPPROPERTYITEM = _ "uint id;" & _ ; ID of this property "ulong length;" & _ ; Length of the property value, in bytes "word type;" & _ ; Type of the value, as one of TAG_TYPE_XXX constants "ptr pvalue;" ; pointer to property value ; Image property types constants ; Ref: https://www.media.mit.edu/pia/Research/deepview/exif.html Global Const $GDIP_PROPERTYTAGTYPEUBYTE = 1 Global Const $GDIP_PROPERTYTAGTYPEASCII = 2 Global Const $GDIP_PROPERTYTAGTYPEUSHORT = 3 Global Const $GDIP_PROPERTYTAGTYPEULONG = 4 Global Const $GDIP_PROPERTYTAGTYPEURATIONAL = 5 Global Const $GDIP_PROPERTYTAGTYPESBYTE = 6 Global Const $GDIP_PROPERTYTAGTYPEUNDEFINED = 7 Global Const $GDIP_PROPERTYTAGTYPESSHORT = 8 Global Const $GDIP_PROPERTYTAGTYPESLONG = 9 Global Const $GDIP_PROPERTYTAGTYPESRATIONAL = 10 Global Const $GDIP_PROPERTYTAGTYPESFLOAT = 11 Global Const $GDIP_PROPERTYTAGTYPEDFLOAT = 12 main() Func main() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile('H:\temp\AP test data\DSC00824 - Copy.jpg') Local $ar = _GDIPlus_ImageGetAllPropertyItemsEx($hImage) Local $propsAr[UBound($ar,1)-1][5],$vec,$j=-1 For $i = 1 To $ar[0][0] If $ar[$i][3]<>0 Then ; pValue -- for Sony! $j += 1 $propsAr[$j][0] = $ar[$i][0] ; id $propsAr[$j][1] = $ar[$i][1] ; length $propsAr[$j][2] =$ar[$i][2]; type $vec = _GDIPlus_ImageGetPropertyItemValue($ar[$i][1],$ar[$i][2],$ar[$i][3]) $propsAr[$j][3] = $vec[0] ; val1 Switch $ar[$i][2] Case 5,10 ; $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL $propsAr[$j][4] = $vec[1] Case Else $propsAr[$j][4] = '' EndSwitch EndIf Next ReDim $propsAr[$j+1][5] For $i = 0 To UBound($propsAr,1)-1 Switch $propsAr[$i][2] ; type Case 5,10 ; $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL _GDIPlus_ImageSetPropertyItemEx($hImage,$propsAr[$i][0],$propsAr[$i][1], _ $propsAr[$i][2],$propsAr[$i][3],$propsAr[$i][4]) Case Else _GDIPlus_ImageSetPropertyItemEx($hImage,$propsAr[$i][0],$propsAr[$i][1], _ $propsAr[$i][2],$propsAr[$i][3]) EndSwitch Next _GDIPlus_ImageSaveToFile($hImage,'H:\b\1.jpg') _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndFunc Func _GDIPlus_ImageGetAllPropertyItemsEx($hImage) Local $iI, $iCount, $tBuffer, $pBuffer, $iBuffer, $tPropertyItem, $aSize, $aPropertyItems[1][1], $aResult $aSize = _GDIPlus_ImageGetPropertySize($hImage) If @error Then Return SetError(@error, @extended, -1) $iBuffer = $aSize[0] $tBuffer = DllStructCreate("byte[" & $iBuffer & "]") $pBuffer = DllStructGetPtr($tBuffer) $iCount = $aSize[1] $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetAllPropertyItems", "hwnd", $hImage, "uint", $iBuffer, "uint", $iCount, "ptr", $pBuffer) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], False) ReDim $aPropertyItems[$iCount + 1][4] $aPropertyItems[0][0] = $iCount For $iI = 1 To $iCount $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, $pBuffer) $aPropertyItems[$iI][0] = DllStructGetData($tPropertyItem, "id") $aPropertyItems[$iI][1] = DllStructGetData($tPropertyItem, "length") $aPropertyItems[$iI][2] = DllStructGetData($tPropertyItem, "type") $aPropertyItems[$iI][3] = DllStructGetData($tPropertyItem, "pvalue") $pBuffer += DllStructGetSize($tPropertyItem) Next Return $aPropertyItems EndFunc Func _GDIPlus_ImageGetPropertyItemValue($iLength, $iType, $pValue) Static Local $tvalue Switch $iType Case 1,6 ; $GDIP_PROPERTYTAGTYPEUBYTE,$GDIP_PROPERTYTAGTYPESBYTE $tvalue = DllStructCreate('byte val',$pValue) Case 2 ; $GDIP_PROPERTYTAGTYPEASCII $tvalue = DllStructCreate('char val['&$iLength&']',$pValue) Case 3 ; $GDIP_PROPERTYTAGTYPEUSHORT $tvalue = DllStructCreate('ushort val',$pValue) Case 4 ; $GDIP_PROPERTYTAGTYPEULONG $tvalue = DllStructCreate('ulong val',$pValue) Case 5 ; $GDIP_PROPERTYTAGTYPEURATIONAL $tvalue = DllStructCreate('ulong val1;ulong val2',$pValue) Case 7 ; $GDIP_PROPERTYTAGTYPEUNDEFINED ; undefined, per specification, but may be a long but is sometimes a string $tvalue = DllStructCreate('byte val['&$ilength&']',$pValue) ; see _GDIPlus_ImageSetPropertyItemEx ;~ $tvalue = DllStructCreate('char val['&$ilength&']',$pValue) Case 8 ; $GDIP_PROPERTYTAGTYPESSHORT $tvalue = DllStructCreate('short val',$pValue) Case 9 ; $GDIP_PROPERTYTAGTYPEULONG $tvalue = DllStructCreate('ulong val',$pValue) Case 10 ; $GDIP_PROPERTYTAGTYPESRATIONAL $tvalue = DllStructCreate('ulong val1;ulong val2',$pValue) Case 11 ; $GDIP_PROPERTYTAGTYPESFLOAT $tvalue = DllStructCreate('float val',$pValue) Case 12 ; $GDIP_PROPERTYTAGTYPEDFLOAT $tvalue = DllStructCreate('double val',$pValue) EndSwitch If @error Then Return SetError(@error,0,-1) Switch $iType Case 5,10 ; $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL Local $aRet[2] $aRet[0] = DllStructGetData($tvalue,'val1') $aRet[1] = DllStructGetData($tvalue,'val2') Case Else Local $aRet[1] $aRet[0] = DllStructGetData($tvalue,'val') EndSwitch Return $aRet EndFunc Func _GDIPlus_ImageGetPropertySize($hImage) Local $aSize[2], $aResult $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint*", 0, "uint*", 0) If @error Then Return SetError(@error, @extended, -1) $aSize[0] = $aResult[2] $aSize[1] = $aResult[3] Return $aSize EndFunc ;==>_GDIPlus_ImageGetPropertySize Func _GDIPlus_ImageSetPropertyItemEx($hImage,$id,$iLength,$iType,$value1,$value2=-1) Local $tProp = DllStructCreate($tagGDIPPROPERTYITEM) DllStructSetData($tProp,'id',$id) DllStructSetData($tProp,'type',$itype) DllStructSetData($tProp,'length',$ilength) Local $tag Switch $iType Case $GDIP_PROPERTYTAGTYPEUBYTE,$GDIP_PROPERTYTAGTYPESBYTE $tag = 'byte val' Case $GDIP_PROPERTYTAGTYPEASCII $tag = 'char val['&$iLength&']' Case $GDIP_PROPERTYTAGTYPEUSHORT $tag = 'ushort val' Case $GDIP_PROPERTYTAGTYPEULONG $tag = 'ulong val' Case $GDIP_PROPERTYTAGTYPEURATIONAL $tag = 'ulong val1;ulong val2' Case $GDIP_PROPERTYTAGTYPEUNDEFINED ; undefined, per specification, but may be a long but is sometimes a string $tag = 'byte val['&$iLength&']' ; causes saving to jpeg to write junk ;~ $tag = 'char val['&$iLength&']' Case $GDIP_PROPERTYTAGTYPESSHORT $tag = 'short val' Case $GDIP_PROPERTYTAGTYPEULONG $tag = 'ulong val' Case $GDIP_PROPERTYTAGTYPESRATIONAL $tag = 'long val1;long val2' Case $GDIP_PROPERTYTAGTYPESFLOAT $tag = 'float val' Case $GDIP_PROPERTYTAGTYPEDFLOAT $tag = 'double val' EndSwitch Static Local $tvalue = DllStructCreate($tag) Switch $iType Case $GDIP_PROPERTYTAGTYPEURATIONAL,$GDIP_PROPERTYTAGTYPESRATIONAL DllStructSetData($tvalue,'val1',$value1) DllStructSetData($tvalue,'val2',$value2) Case Else DllStructSetData($tvalue,1,$value1) EndSwitch DllStructSetData($tProp,'pvalue',DllStructGetPtr($tvalue)) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipSetPropertyItem", "hwnd", $hImage, "ptr", _ DllStructGetPtr($tProp)) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], -1) Return $aResult[0] = 0 EndFunc I have seen $iLength be as much as 37 KB for $GDIP_PROPERTYTAGTYPEUNDEFINED. Is there is a bug, how can this be demonstrated to the developers in a few lines of code (without clobbering Windows)?
- 11 replies
-
Here are two functions to provide pixel-accurate height and width dimensions for a given string. The more commonly-used _GDIPlus_GraphicsMeasureString built-in UDF is problematic because it returns the width padded by roughly one en-space (for reasons related to the various ways Windows produces anti-aliased fonts). These are AutoIt translations of Pierre Arnaud's C# functions, described in his CodeProject article "Bypass Graphics.MeasureString limitations" The first is an all-purpose version that takes a window handle, string, font family, font size (in points), style, and (optionally) width of the layout column (in pixels) as parameters. The second, more efficient version is intended for applications where GDI+ fonts are already in use, and takes handles to the existing graphics context, string, font, layout and format as parameters. Both functions return a two-row array with the exact width [0] and height [1] of the string (in pixels). EDIT: (Note that some of the same anti-aliasing measurement issues still apply. I did my best to work around them, but the output of the function may still be off by a pixel or two. Buyer beware.) #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels ; Description ...: Returns a pixel-accurate height and width for a given string using a given font, style and size. ; Syntax ........: _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle[, $iColWidth = 0]) ; Parameters ....: $hGUI - Handle to the window. ; $sString - The string to be measured. ; $sFontFamily - Full name of the font to use. ; $fSize - Font size in points (half-point increments). ; $iStyle - Combination of 0-normal, 1-bold, 2-italic, 4-underline, 8-strikethrough ; $iColWidth - [optional] If word-wrap is desired, column width in pixels ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This version is longer and less efficient but works for all purposes. ; Related .......: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Link ..........: ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle, $iColWidth = 0) _GDIPlus_Startup() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate($sFontFamily) Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aWinClient = WinGetClientSize($hGUI) If $iColWidth = 0 Then $iColWidth = $aWinClient[0] Local $tLayout = _GDIPlus_RectFCreate(10, 10, $iColWidth, $aWinClient[1]) Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] ; Clean up resources _GDIPlus_FontDispose($hFont) _GDIPlus_RegionDispose($aRegions[1]) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return $aWidthHeight EndFunc ;==>_StringInPixels ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels_gdip ; Description ...: Returns a pixel-accurate height and width for a given string using a GDI+ font, layout and format ; Syntax ........: _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) ; Parameters ....: $hGraphic - Handle to a GDI+ graphics object. ; $sString - The string to be measured. ; $hFont - Handle to a GDI+ font. ; $tLayout - A $tagGDIPRECTF structure that bounds the string. ; $hFormat - Handle to a GDI+ string format. ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This much more efficient version is for use with GDI+ fonts ; Related .......: ; Link ..........: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] _GDIPlus_RegionDispose($aRegions[1]) Return $aWidthHeight EndFunc ;==>_StringInPixels_gdip _StringInPixels.au3 Example-StringInPixels.au3