Jump to content

[Resolved] GDI+, GUIcrtlcreate and DLLs together


Recommended Posts

Below is some code that was originally written by UEZ for a rotating circular screen-saver-like item. I'm trying to use the same general concepts to create a radial or arc menu.

I've narrowed down the math that I'm assuming helps everything move in a beautiful circle, but my question is... when I try to replace the text that is being drawn with a guictrlcreatebutton nothing shows up. Is it a layering issue?

My code is below, without the .ini file:

;coded by UEZ 2009
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0_GDIPlus_ to make a button  autoit
#AutoIt3Wrapper_Run_After=upx.exe --best "%out%"
;~ #AutoIt3Wrapper_Run_After=upx.exe --ultra-brute "%out%" ;very slow
#AutoIt3Wrapper_Run_After=del "Rotating Letters Transparent_Obfuscated.au3"
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <String.au3>
#include <MouseOnEvent.au3>
#Include <APIConstants.au3>
#include <ScreenCapture.au3>
#Include <WinAPIEx.au3>
#include <GUIButton.au3>
; get mouse position for later
Global $Mpos = MouseGetPos()
; declare the ini file as a variable to make it easier to call later
Global $iniFile = "TEST_programList.ini"
HotKeySet("^{RIGHT}", "showTheGUI_RightARC")
HotKeySet("^{LEFT}", "showTheGUI_leftARC")
HotKeySet("^{DOWN}", "hideTheGUI")
Global Const $width = 1200
Global Const $height = @DesktopHeight
Global Const $pi_div_180 = 4 * ATan(1) / 180
Global $leftARC, $rightARC
Global $graphics, $backbuffer, $bitmap, $Pen, $arrTxt1, $arrTxt2, $fontsize_txt1, $fontsize_txt2, $text1
Global $graphics2, $backbuffer2, $bitmap2, $Pen2, $arrTxt12, $fontsize_txt12, $text12, $text2
Global $brush_color, $hFamily1, $hFamily2, $hFont1, $hFont2, $hFormat, $tLayout, $brush1
Global $brush_color2, $hFamily12, $hFont12, $hFormat2, $tLayout2, $brush12
Global $ScreenDc, $dc, $tSize, $pSize, $tSource, $pSource, $tBlend, $pBlend, $tPoint, $pPoint, $gdibitmap
Global $ScreenDc2, $dc2, $tSize2, $pSize2, $tSource2, $pSource2, $tBlend2, $pBlend2, $tPoint2, $pPoint2, $gdibitmap2
Global $x1, $x2, $y1, $y2, $a, $b, $c, $r, $g, $b
Global $a2, $b2, $c2, $r2, $g2, $b2
Global $i = 0, $j = 360, $m = 0, $n = 0
Global $i2 = 0, $j2 = 360, $m2 = 0, $n2 = 0
Global $radius_x, $radius_y
Global $radius_x_2, $radius_y_2
Global $title = "Floating Menu"
Global $button = ""
Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo"
;Register callback
$hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)
leftarc()
;~ rightArc()
Func leftarc()
;======================================================================================================================== LEFT ARC
;========================================================================================================================
Opt("GUIOnEventMode", 1)
$leftARC = GUICreate($title, 1200, $height, $Mpos[0], $Mpos[1], 0, $WS_EX_LAYERED + $WS_EX_TOPMOST)
GUISetOnEvent($GUI_EVENT_CLOSE, "Close")
_GDIPlus_Startup()
$graphics = _GDIPlus_GraphicsCreateFromHWND($leftARC)
$bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
$ScreenDc = _WinAPI_GetDC($leftARC)
$gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
$dc = _WinAPI_CreateCompatibleDC($ScreenDc)
_WinAPI_SelectObject($dc, $gdibitmap)
;~ ; _WinAPI_UpdateLayeredWindow parameters
$tSize = DllStructCreate($tagSIZE)
$pSize = DllStructGetPtr($tSize)
DllStructSetData($tSize, "X", ($width / 2) - 100)  ; adjust to show what is visible
DllStructSetData($tSize, "Y", $height)
; adjust to show what side is visible
; 0 0 - left side ...  # 0 right side
$tSource = DllStructCreate($tagPOINT)
$pSource = DllStructGetPtr($tSource)
;~ DllStructSetData($tSource, "X", 0)
;~ DllStructSetData($tSource, "Y", 0)
; transparency blending
$tBlend = DllStructCreate($tagBLENDFUNCTION)
$pBlend = DllStructGetPtr($tBlend)
Global $alpha = 1000
Global $alpha_steps = 5
DllStructSetData($tBlend, "Alpha", $alpha)
DllStructSetData($tBlend, "Format", 1)
$tPoint = DllStructCreate($tagPOINT)
$pPoint = DllStructGetPtr($tPoint)
DllStructSetData($tPoint, "X", 0)
DllStructSetData($tPoint, "Y", 0)
GUISetState(@SW_HIDE, $leftARC)
;scroll functions
_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, "scroll_up")
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, "scroll_down")
; set the font size of the visible text
$fontsize_txt1 = 12
$width_mul_045 = $width * 0.45
$height_mul_045 = $height * 0.45
$radius_x1 = ($width_mul_045) * 0.95
$radius_y1 = ($height_mul_045) * 0.95
readINIPROGNAME()
$arrTxt1 = StringSplit($text1, ",")
Dim $arrX1[UBound($arrTxt1)]
Dim $arrY1[UBound($arrTxt1)]
Dim $brush1[UBound($arrTxt1)]
For $k = 0 To UBound($arrTxt1) - 1
$brush_color = "0xff00ff00"  ; will change the font color - old:"0xFF" & Hex($r, 2) & Hex($g, 2) & Hex($b, 2)
$brush1[$k] = _GDIPlus_BrushCreateSolid($brush_color)
Next
; font control
$hFormat = _GDIPlus_StringFormatCreate()
$hFamily1 = _GDIPlus_FontFamilyCreate("Arial")
$hFont1 = _GDIPlus_FontCreate($hFamily1, $fontsize_txt1, 2)
$tLayout = _GDIPlus_RectFCreate(0, 0)
$a = 360 / (UBound($arrTxt1) - 1)
$y = 0
Do
_GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
For $x = 1 To UBound($arrTxt1) - 1
  $x1 = $width_mul_045 + Cos(($i + $m) * $pi_div_180) * $radius_x1
  $y1 = $height_mul_045 + Sin(($i + $m) * $pi_div_180) * $radius_y1 - $fontsize_txt1 / 10
  $arrX1[$x] = $x1
  $arrY1[$x] = $y1
  DllStructSetData($tLayout, "x", $arrX1[$x])
  DllStructSetData($tLayout, "y", $arrY1[$x])
  _GDIPlus_GraphicsDrawStringEx($backbuffer, $arrTxt1[$x], $hFont1, $tLayout, $hFormat, $brush1[$x])  ; draws a string
  $m += $a
Next
    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($leftARC, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)
_WinAPI_DeleteObject($gdibitmap)
Until False * Not Sleep(1)
EndFunc
; ================end
; ================end
Func Close()
DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
$hM_Hook[0] = 0
DllCallbackFree($hKey_Proc)
$hKey_Proc = 0
For $x = 0 To UBound($arrTxt1) - 1
  _GDIPlus_BrushDispose($brush1[$x])
Next
_WinAPI_DeleteDC($dc)
    _WinAPI_ReleaseDC($leftARC, $ScreenDc)
_GDIPlus_FontDispose($hFont1)
_GDIPlus_FontFamilyDispose($hFamily1)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_GraphicsDispose($backbuffer)
_GDIPlus_BitmapDispose($bitmap)
_GDIPlus_GraphicsDispose($graphics)
_GDIPlus_Shutdown()
WinClose($leftARC)
Exit
EndFunc

func scroll_up()
$i += 5
EndFunc

Func scroll_down()
$i -= 5
EndFunc
func showTheGUI_leftARC()
   ; if it's already visible - don't rerun the function - otherwise, make it visible
    $s = ""
    $style = ""
    $Mpos = MouseGetPos()
   $style = GUIGetStyle($leftARC)
    $s = BitAND($style[0], $WS_VISIBLE)
    If $s = 0 Then
          $Mpos = MouseGetPos()
          WinMove($leftARC, "", $Mpos[0] - ($width/2), $Mpos[1] - ($height/2))
   GUISetState(@SW_SHOW, $leftARC)
      Elseif $s <> 0 Then
;~       hideTheGUI() - helps with if the user spams ctrl up
        $Mpos = MouseGetPos()
          WinMove($leftARC, "", $Mpos[0] - ($width/2), $Mpos[1] - ($height/2))
          GUISetState(@SW_SHOW, $leftARC)
EndIf
EndFunc
func showTheGUI_RightARC()
   ; if it's already visible - don't rerun the function - otherwise, make it visible
    $s = ""
    $style = ""
    $Mpos = MouseGetPos()
   $style = GUIGetStyle($rightARC)
    $s = BitAND($style[0], $WS_VISIBLE)
;~ GUISetState(@SW_DISABLE, $leftARC)
;~ GUISetState(@SW_HIDE, $leftARC)
    If $s = 0 Then
          $Mpos = MouseGetPos()
          WinMove($rightARC, "", $Mpos[0], $Mpos[1] - ($height/2))
    GUISetState(@SW_SHOW, $rightARC)
      Elseif $s <> 0 Then
;~       hideTheGUI() - helps with if the user spams ctrl up
        $Mpos = MouseGetPos()
          WinMove($rightARC, "", $Mpos[0], $Mpos[1] - ($height/2))
          GUISetState(@SW_SHOW, $rightARC)
    EndIf
EndFunc
func hideTheGUI()
      GUISetState(@SW_HIDE, $leftARC)
   GUISetState(@SW_HIDE, $rightARC)
EndFunc
Func readINIPROGNAME()
; first part is to read the entire ini file in pieces and then the contents of each section
; read the section names
Local $arraySectionAll = IniReadSection($iniFile, "PROGNAME")
If @error Then
    MsgBox(4096, "", "Error occurred, probably no INI file.")
EndIf
_ArraySort($arraySectionAll, 1, 0, 0, 1)

For $i = 1 To $arraySectionAll[0][0]
if $i <> $arraySectionAll[0][0] Then
  $text1 &= $arraySectionAll[$i][1] & ","
Else
  $text1 &= $arraySectionAll[$i][1]
EndIf
Next
EndFunc

;==>Close

The section I am trying to add the button in is:

Do
_GDIPlus_GraphicsClear($backbuffer, 0xFF000000)
For $x = 1 To UBound($arrTxt1) - 1
  $x1 = $width_mul_045 + Cos(($i + $m) * $pi_div_180) * $radius_x1
  $y1 = $height_mul_045 + Sin(($i + $m) * $pi_div_180) * $radius_y1 - $fontsize_txt1 / 10
  $arrX1[$x] = $x1
  $arrY1[$x] = $y1
  DllStructSetData($tLayout, "x", $arrX1[$x])
  DllStructSetData($tLayout, "y", $arrY1[$x])
  _GDIPlus_GraphicsDrawStringEx($backbuffer, $arrTxt1[$x], $hFont1, $tLayout, $hFormat, $brush1[$x])  ; draws a string
  $m += $a
Next
    $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
    _WinAPI_SelectObject($dc, $gdibitmap)
    _WinAPI_UpdateLayeredWindow($leftARC, $ScreenDc, 0, $pSize, $dc, $pSource, 0, $pBlend, 2)
_WinAPI_DeleteObject($gdibitmap)
Until False * Not Sleep(1)

and i've tried replacing...

_GDIPlus_GraphicsDrawStringEx($backbuffer, $arrTxt1[$x], $hFont1, $tLayout, $hFormat, $brush1[$x])  ; draws a string

...with...

GUICtrlCreateButton("Test", $arrX1[$x], $arrY1[$x], 175, 30)

But nothing shows up on the screen anywhere.

Is it a layering conflict maybe or am I just putting the code together wrong?

Any intel on what I'm doing wrong is always appreciated.

Thanks again to UEZ for the original design.

Edited by xeroTechnologiesLLC
Link to comment
Share on other sites

You cannot place controls on the layered window.

Have a look to made by eukalyptus! This is probably what you are trying to do!

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • Moderators

xeroTechnologiesLLC,

helping me build my april fool's joke for the office

We regard "joke" scripts as malware - please be careful what you post here. :oops:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 2 weeks later...

Sorry I didn't reply to this sooner - long weekend and laid up in bed for a few days. ;)

Absolutely understandable and my eternal apologies. :

All it did was make a button spin on a GUI and unfortunately I was out injured and unable to share in my office's April Fool's fun....such a loss too from what I heard. :D

However, I will make note of it for the future and mark this one as closed as I found a solution in the Icon Dock for the shortcut problem. :dance:

Just an example tidbit extracted from the overall code:

Func _centerRad()
; get mouse position to load it near the mouse
$MposL = MouseGetPos()

; load location exact
Global $hIconDockC = _IconDock_Create($MposL[0] - 55, $MposL[1] - 75, $iWidth, $iHeight, _
   BitOR($IconDock_Align_Free, $IconDock_Center), $IconDock_Center, $iIconSizeMin / 2, $iIconSizeMax / 2, True)
; ellipse to draw the icons in
Global $aPoints = _EllipsePoints(50, 50, 2)
; transparency
_IconDock_SetAlpha($hIconDockC, 1, 0.2)
; shadow
_IconDock_SetShadowOffset($hIconDockC, -0.18, 0.22)

_IconDock_BeginUpdate($hIconDockC)
; icon example
; global $hIcon_# = _WinAPI_ShellExtractIcon($iconLocation[#][1], 0, $iIconSizeMax, $iIconSizeMax)
; add example
; _IconDock_IconAdd($hIconDock, $hIcon_#, "_EventFunction", $IconDock_LBUTTONUP, $progName[#][1], $iIconSizeMax / 2 + $aPoints[1][0] - $iIconSizeMin / 2, $iIconSizeMax / 2 + $aPoints[1][1] - $iIconSizeMin / 2)
For $o = 1 to 2
  $hMiniIcon_C[$o] = _WinAPI_ShellExtractIcon($iconLocation[$o][1], 0, $iIconSizeMax, $iIconSizeMax)
  _IconDock_IconAdd($hIconDockC, $hMiniIcon_C[$o], "_EventFunction", $IconDock_LBUTTONUP, $progName[$o][1], _
  $iIconSizeMax / 2 + $aPoints[$o][0] - $iIconSizeMin / 2, $iIconSizeMax / 2 + $aPoints[$o][1] - $iIconSizeMin / 3)
  ;successful
Next
_IconDock_EndUpdate($hIconDockC)
EndFunc

The ellipse function:

Func _EllipsePoints($iW, $iH, $iP)
Local $iCnt = 0
Local $pi = ATan(1) * 4
Local $degToRad = $pi / 180
Local $aPoints[$iP + 1][3] = [[$iP]]
For $i = 1 To $iP
  $aPoints[$i][2] = $i * 360 / $iP
  $aPoints[$i][0] = Cos($aPoints[$i][2] * $degToRad) * $iW / 2 + $iW / 2
  $aPoints[$i][1] = Sin($aPoints[$i][2] * $degToRad) * $iH / 2 + $iH / 2
Next
Local $iD1, $iD2, $iX1, $iY1, $iX2, $iY2, $iMax, $iMin, $iDiff, $fW = 1
Do
  $iCnt += 1
  $iDiff = $iMax - $iMin
  $iMax = 0
  $iMin = $iW
  For $i = 1 To $iP
   Switch $i
    Case 1
     $iX1 = $aPoints[$iP][0]
     $iY1 = $aPoints[$iP][1]
     $iX2 = $aPoints[$i + 1][0]
     $iY2 = $aPoints[$i + 1][1]
    Case $iP
     $iX1 = $aPoints[$i - 1][0]
     $iY1 = $aPoints[$i - 1][1]
     $iX2 = $aPoints[1][0]
     $iY2 = $aPoints[1][1]
    Case Else
     $iX1 = $aPoints[$i - 1][0]
     $iY1 = $aPoints[$i - 1][1]
     $iX2 = $aPoints[$i + 1][0]
     $iY2 = $aPoints[$i + 1][1]
   EndSwitch
   $iD1 = Sqrt(Abs($iX1 - $aPoints[$i][0]) ^ 2 + Abs($iY1 - $aPoints[$i][1]) ^ 2)
   $iD2 = Sqrt(Abs($iX2 - $aPoints[$i][0]) ^ 2 + Abs($iY2 - $aPoints[$i][1]) ^ 2)
   If $iD1 > $iMax Then $iMax = $iD1
   If $iD2 > $iMax Then $iMax = $iD2
   If $iD1 < $iMin Then $iMin = $iD1
   If $iD2 < $iMin Then $iMin = $iD2
   If $iD1 > $iD2 Then
    $aPoints[$i][2] -= $fW
   Else
    $aPoints[$i][2] += $fW
   EndIf
   $aPoints[$i][0] = Round(Cos($aPoints[$i][2] * $degToRad) * $iW / 2) + $iW / 2
   $aPoints[$i][1] = Round(Sin($aPoints[$i][2] * $degToRad) * $iH / 2) + $iH / 2
  Next
  $fW /= 1.01
Until $iMax - $iMin = $iDiff Or $iCnt > 500
Return $aPoints
EndFunc   ;==>_EllipsePoints

modified event Function to load web pages or programs

Func _EventFunction($hID, $iIconIndex, $iEventMsg)
Switch $hID
  Case $hIconDock
   Switch $iIconIndex
    ; case $appLocation[#][1]
     ; if the $appLocation[#][1] has ".exe" in it it needs to be run as a program not launched as a webpage
     ; _iecreate($appLocation[#][1])
    Case 1
     If StringInStr($appLocation[1][1], ".exe") <> 0 Then
      Run($appLocation[1][1])
     ElseIf StringInStr($appLocation[1][1], ".elc") <> 0 Then
      ShellExecute("defaultnew.elc", "", "")
     Else
      _IECreate($appLocation[1][1])
     EndIf
    Case 2
     If StringInStr($appLocation[1][1], ".exe") <> 0 Then
      Run($appLocation[1][1])
     ElseIf StringInStr($appLocation[1][1], ".elc") <> 0 Then
      ShellExecute("defaultnew.elc", "", "")
     Else
      _IECreate($appLocation[1][1])
     EndIf
    Case 3
     If StringInStr($appLocation[1][1], ".exe") <> 0 Then
      Run($appLocation[1][1])
     ElseIf StringInStr($appLocation[1][1], ".elc") <> 0 Then
      ShellExecute("defaultnew.elc", "", "")
     Else
      _IECreate($appLocation[1][1])
     EndIf
    Case Else
     MsgBox(0x40000, "Error", "No link to webpage/program noted for this item")
   EndSwitch
EndSwitch
EndFunc   ;==>_EventFunction

Hope this helps someone in the future. Please note that I did NOT code this from scratch. It was modified code provided in the Icon Dock UDF that can be found here in the forums....and I highly recommend it mainly because it's just fun... :D

When the entire project is done I plan to post the end result somewhere for others to use if they find it useful, but it'll be months before I'm done with it, but wanted to thank everyone for the help provided through the AutoIT community thus far. :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...