Sign in to follow this  
Followers 0
MyEarth

GDI + Hang + GUIRegisterMsg

13 posts in this topic

#1 ·  Posted (edited)

Hi guys,

this script is important to me and has a problem that I do not know how to explain:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
 
Global $hGUI, $hGraphics, $hBackbuffer, $hBitmap, $hPen1
Global $iW = 100, $iH = $iW
 
T1()
 
Func T1()
 HotKeySet("{DEL}", "T2")
 _GDIPlus_Startup()
 $hGUI = GUICreate("Test", $iW, $iH, 10, 10, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
 GUISetState()
 $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
 $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
 $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
 _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
 DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hBackbuffer, "int", 3)
 $hPen1 = _GDIPlus_PenCreate(0xFF800010, 4)
 GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")
 Draw()
 GUIRegisterMsg($WM_TIMER, "Draw") ;$WM_TIMER = 0x0113
 DllCall("User32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", 500, "int", 0)
 While 1
  Sleep(100)
 WEnd
EndFunc   ;==>T1

Func Draw()
 _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF) ;needed for transparent images
 _GDIPlus_GraphicsDrawEllipse($hBackbuffer, 25, 25, 6, 6, $hPen1)
 _WinAPI_RedrawWindow($hGUI)
EndFunc   ;==>Draw
 
Func WM_ERASEBKGND($hWnd, $Msg, $wParam, $lParam)
 _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iW, $iH)
 Return True
EndFunc   ;==>WM_ERASEBKGND
 
Func _Clean()
 GUIRegisterMsg($WM_TIMER, "")
 GUIRegisterMsg($WM_ERASEBKGND, "")
 _GDIPlus_PenDispose($hPen1)
 _GDIPlus_BitmapDispose($hBitmap)
 _GDIPlus_GraphicsDispose($hBackbuffer)
 _GDIPlus_GraphicsDispose($hGraphics)
 _GDIPlus_Shutdown()
 GUIDelete($hGUI)
EndFunc   ;==>_Clean
 
Func T2()
 HotKeySet("{DEL}")
 _Clean()

 $hGUI = GUICreate("Form1", 250, 250, -1, -1)
 GUISetState(@SW_SHOW)
 While 1
  $nMsg = GUIGetMsg()
  Switch $nMsg
   Case $GUI_EVENT_CLOSE
    _Clean()
    T1()
  EndSwitch
 WEnd
EndFunc   ;==>T2

 

 This is only a "stripped" part of code

I need to swith between the normal gui and the gdi gui, the problem are:

- If i switch 11 times ( yes, every eleven times, slow, fast doesn't matter! ) the WM_ERASEBKGND not work anymore, i don't see the GDI but only the bk of the GUI:

Before:

2v2jdhu.jpg

After:

35iqbz6.jpg

I have this issue only on XP

- The most important, sometimes during a switch ( it's totally random, can be the first, the fourth i don't know ) the second GUI T2() HANG, i need to close it in task manager. In the event viewer i see error 1002. I don't have any error by autoit. I have this problem both on Xp and 7, compiled or not.

I HOPE i have make some mistake in the code, i really don't have idea.

Thanks as always

Edited by MyEarth

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

MyEarth,

 

The GUI hanging is a classic case of recursion - you call the T1 function from the HotKey while the function is still running.  Try moving your idle loop out of the function and use a flag to fire it - that way you let all the functions end properly:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $hGUI, $hGraphics, $hBackbuffer, $hBitmap, $hPen1
Global $iW = 100, $iH = $iW
Global $fRun_T1 = True

_GDIPlus_Startup()

While 1
    If $fRun_T1 Then
        T1()
        $fRun_T1 = False ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    EndIf
    Sleep(10)
WEnd

_GDIPlus_Shutdown()

Func T1()
    HotKeySet("{DEL}", "T2")
    $hGUI = GUICreate("Test", $iW, $iH, 10, 10, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetState()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hBackbuffer, "int", 3)
    $hPen1 = _GDIPlus_PenCreate(0xFF800010, 4)
    GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")
    Draw()
    GUIRegisterMsg($WM_TIMER, "Draw") ;$WM_TIMER = 0x0113
    DllCall("User32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", 500, "int", 0)
EndFunc   ;==>T1

Func Draw()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF) ;needed for transparent images
    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, 25, 25, 6, 6, $hPen1)
    _WinAPI_RedrawWindow($hGUI)
EndFunc   ;==>Draw

Func WM_ERASEBKGND($hWnd, $Msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iW, $iH)
    Return True
EndFunc   ;==>WM_ERASEBKGND

Func _Clean()
    GUIRegisterMsg($WM_TIMER, "")
    GUIRegisterMsg($WM_ERASEBKGND, "")
    _GDIPlus_PenDispose($hPen1)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    
    GUIDelete($hGUI)
EndFunc   ;==>_Clean

Func T2()
    HotKeySet("{DEL}")
    _Clean()
    GUIDelete($hGUI)
    $hGUI = GUICreate("Form1", 250, 250, -1, -1)
    GUISetState(@SW_SHOW)
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                GUIDelete($hGUI)
                $fRun_T1 = True ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                ExitLoop
        EndSwitch
    WEnd
EndFunc   ;==>T2
You might like to read the Recursion tutorial in the Wiki to learn more about recursion. ;)

I cannot help with the GDI problem - you will have to wait for someone who really understands that to come along. :)

M23

Edited by Melba23
Typo

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Melba, using your script i have the first issue ( the WM_ERASEBKGND ) at the first switch and not at eleven!

I open the script

Switch to T2, close it

The T1 appers ---> WM_ERASEBKGND/GDI Not work!

From bad to worse :D

Hope at least i have resolved the hang issue but i don't know, i'll see

Edited by MyEarth

Share this post


Link to post
Share on other sites

MyEarth,

No it is not worse - you have solved the recursion problem. I did say that the GDI problem would have to wait until someone who understood it came along. ;)

Anyway, why not hide/show the GUIs ratehr than deleting them each time? :huh:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

MyEarth,

No it is not worse - you have solved the recursion problem

 

I really hope you have right

Anyway, why not hide/show the GUIs ratehr than deleting them each time?

 

 It's a long story, the second gui edit the element of the first gui, i need to delete it for "redraw" it

Edited by MyEarth

Share this post


Link to post
Share on other sites

MyEarth,

I can run that code any number of times and the GDI graphic appears each time. Anyway I have other things to do than be criticised for helping - I hope you get a solution some time. :bye:

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______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

 

Share this post


Link to post
Share on other sites

Melba i have do in my script what you have suggested but randomly hangs :(

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

This is couple of error i have see during "hang" and stop Executing

Process failed to respond; forcing abrupt termination...
Exit code: 1   
 

and

AutoIT3.exe ended.rc:1073807364

There is a way to see wtf my script hangs? :(

And everviewer:

v.3.3.8.0 - hungapp, version 0.0.0.0 - 0x00000000 - ID: 1002

Edited by MyEarth

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Seems ( maybe ) the problem is related to _GDIPlus_Startup() and _GDIPlus_Shutdown(). When close ( so GDI shutdown ) and reopen sometime seems _GDIPlus_Startup() create a background thread that create the problem to my GUI / hang

I don't know if it is the problem but i don't have any other idea.

This is the script to convert in autoit:

static GdiplusStartupInput gdiplusStartupInput; 
                static GdiplusStartupOutput gdiplusStartupOutput; 
                 
                // Initialization 
                gdiplusStartupInput.SuppressBackgroundThread = TRUE; 
                GdiplusStartup(&gdiplusToken, &gdiplusStartupInput,  
                                                     &gdiplusStartupOutput); 
                Status stat = gdiplusStartupOutput.NotificationHook( 
                                                     &gdiplusBGThreadToken); 
                ASSERT(stat == Ok); 
                 
                // Termination 
                gdiplusStartupOutput.NotificationUnhook(gdiplusBGThreadToken); 
                GdiplusShutdown(gdiplusToken);

On help parameter are NONE but on MSDN i see token, input and output.

It's possible to use this parameter in autoit? How?

Edited by MyEarth

Share this post


Link to post
Share on other sites

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $hGUI, $hGraphics, $hBackbuffer, $hBitmap, $hPen1
Global $iW = 100, $iH = $iW

_GDIPlus_Startup()

HotKeySet("{DEL}", "T2")
$hGUI_Gfx = GUICreate("Test", $iW, $iH, 10, 10, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
GUISetState()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI_Gfx)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hBackbuffer, "int", 3)
$hPen1 = _GDIPlus_PenCreate(0xFF800010, 4)
GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")

OnAutoItExitRegister("_Clean")
HotKeySet("!q", "_Clean") ;alt+q quit

While 1
    Draw()
    Sleep(30)
WEnd

Func Draw()
    _GDIPlus_GraphicsClear($hBackbuffer, 0xFFFFFFFF) ;needed for transparent images
    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, 25, 25, 6, 6, $hPen1)
    _WinAPI_RedrawWindow($hGUI_Gfx)
EndFunc   ;==>Draw

Func WM_ERASEBKGND($hWnd, $Msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iW, $iH)
    Return True
EndFunc   ;==>WM_ERASEBKGND

Func _Clean()
    GUIRegisterMsg($WM_ERASEBKGND, "")
    _GDIPlus_PenDispose($hPen1)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc   ;==>_Clean

Func T2()
    HotKeySet("{DEL}")
    GUISetState(@SW_HIDE, $hGUI_Gfx)
    Local $hGUI = GUICreate("Form1", 250, 250, -1, -1)
    GUISetState(@SW_SHOW)
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                GUIDelete($hGUI)
                GUISetState(@SW_SHOW, $hGUI_Gfx)
                HotKeySet("{DEL}", "T2")
        EndSwitch
    WEnd
EndFunc   ;==>T2 

Br,

UEZ

Try this:

 


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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

UEZ, i'll really appreciate your help but there are some mistake:

1) If you don't deregister GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") the bk of the normal gui is trasparent :D

2) I need to delete the gui and not simply hide, as i say before i need to "redraw" the gdi+ gui

I have try to add a sort of "debug" to my gui like:

$debug = GUIRegisterMsg($WM_ERASEBKGND, "")

If $debug = 0 Then MsgBox etc.

Nothing of the element of Clean() Func give me the MsgBox before hang of the gui. Ad not only:

My first version has _GDIPlus_Startup() _GDIPlus_Shutdown() every time i'll call the func like the MSDN document:

Call GdiplusStartup and GdiplusShutdown in each of your functions that make GDI+ calls

So Call T1() --> _GDIPlus_Startup() + Script --> Call T2() --> _GDIPlus_Shutdown

That version has "hangs" also during switch, but follow the post of melba i have put _GDIPlus_Startup() at first and close it at the end of the script.

Now, magically, i don't have the hangs during switch but only at startup, randomly:

_GDIPlus_Startup()  --> T1() + script --> (Random hangs when call T2 from T1) Call T2() --> END = _GDIPlus_Shutdown

So i'm sure at 70% this problem is related to _GDIPlus_Startup() - _GDIPlus_Shutdown, and i'd like to try to add SuppressBackgroundThread = TRUE and see if happened again, but i don't know how

Thanks again for your help

Edited by MyEarth

Share this post


Link to post
Share on other sites

Currently I don't understand what you want to do exactly. You create a GDI+ gui, press del key, delete the GDI+ gui, create a "normal" gui and finally when closing the normal GUI you create again the GDI+ gui.

What will displayed in the GDI+ gui? Why is to hide it not the correct way? For me is nothing transparent.

Br,

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

In the normal gui i select what type of element create/remove in the gdi+ gui, like a "option" gui for gdi+, i don't know if i was clear.

For this reason i'll delete and recreate the gdi gui, more easy that delete/create single element everytime and more less code

Anyway the hangs happened also if i dont' change anything like my script in the first post, just open-close randomly in the malba's script version or my first version randomly during switch

For this reason i think is related to Startup - Shutdown GDI

Edited by MyEarth

Share this post


Link to post
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
Sign in to follow this  
Followers 0