
matrix200
Active Members-
Posts
41 -
Joined
-
Last visited
matrix200's Achievements

Seeker (1/7)
0
Reputation
-
Using _GDIPlus_BitmapCreateFromGraphics question
matrix200 replied to matrix200's topic in AutoIt General Help and Support
Ok problem solved fully The right way to make sure WM_PAINT doesn't get stuck is to call ValidateRect function on the window for which drawing is complete and no additonal paitning is required. Other things that others might find useful , I do not recommend using GDIplus library at all because it is leaking memory as hell (if you decide to reuse same brushes , pens and other drawing resources and don't want to recreate them for each drawing). The painting with GDIplus seems to be slower then plain GDI (There was some article I found on the Internet with direct comparisons). GDIplus created an additional thread inside the program which I find alarming (regular GDI doesn't do that). Of course GDIplus is fine if you draw a line or two . But if you decide to use it for something reasonably heavy like the dials (see my dial gauge example script) then GDIplus is probably a bad idea. And just by the way it seems the native WM_PAINT handler of Autoit is somewhat buggy . The part that decides which window part is visible and needs to be redrawn anyway. If you cover your window with winamp or another similar application quite often the window will remain corrupted after internal handler. That was the problem all along and getting rid of internal WM_PAINT handler is indeed solving all redrawing issues. -
Using _GDIPlus_BitmapCreateFromGraphics question
matrix200 replied to matrix200's topic in AutoIt General Help and Support
Ok forget what I have written in the first two posts After rewriting the whole drawing functions using plain gdi and seeing it didn't help I have a different idea. Is it possible to consume WM_PAINT event internally? What I mean is I don't want to rely on internal AuotIt handler regarding these windows. Anyway I don't have any controls and everything drawn on them is something I draw myself. Now if I don't return $GUI_RUNDEFMSG my WM_PAINT event gets "stuck" That is I keep receiving it over and over again and program becomes unresponsive. Is there a way to have the WM_PAINT event deleted after I have redrawn the window contents? -
Using _GDIPlus_BitmapCreateFromGraphics question
matrix200 replied to matrix200's topic in AutoIt General Help and Support
Ok I was able to somehow alleviate the problem with flicker by checking the actual window getting WM_PAINT and redrawing only that window. Now I have a different problem though. If I take some window with dynamic content (like winamp or video playing window of bsplayer) and drag it over my application sometimes (usually if I drag really fast ) one or more windows are not redrawn anymore and lose their contents. Now I was able to reproduce it by sending a WM_PAINT event to a single window if InvalidateRectangle is called on it before WM_PAINT is sent. For some reason unknown to me a window with changing content is invalidating parts of my windows even though it shouldn't Is there anyway to intercept that rectangle structure being passed so I can decide for myself whether a certain region is validated or not? To show an example of what I think is the problem I have that small program. CODE #include <GDIPlus.au3> #include <GUIConstants.au3> #Include <WinAPI.au3> Global $myBlackPen InitGraphics() $GUI = GUICreate("WinNutClient", 640, 380, -1 , -1,Bitor($GUI_SS_DEFAULT_GUI,$WS_CLIPCHILDREN)) $GUI_Indicator = GUICreate ("", 150, 120, 10, 10, BitOR ($WS_CHILD, $WS_DLGFRAME,$WS_EX_TOPMOST),$WS_EX_CLIENTEDGE,$GUI) GuiSetState(@SW_SHOW,$GUI) GuiSetState(@SW_SHOW,$GUI_Indicator) GUISetBkColor (0x00FFFF) $hWnd = WinGetHandle($GUI_Indicator) $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd) AllThatGoodStuff() AdlibEnable("test",3000) GuiRegisterMsg(0x000F,"rePaint") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func InitGraphics() _GDIPlus_Startup () $myBlackPen = _GDIPlus_PenCreate(0xFF000000, 1) EndFunc Func rePaint($window ) if $window == $hWnd then AllThatGoodStuff() EndIf return $GUI_RUNDEFMSG EndFunc Func test() _WinAPI_InvalidateRect($GUI_Indicator) _WinAPI_UpdateWindow($GUI) _WinAPI_UpdateWindow($GUI_Indicator) EndFunc Func AllThatGoodStuff() _GDIPlus_GraphicsDrawString($hGraphic, "hello world",10,10) EndFunc Func OnAutoItExit() _GDIPlus_GraphicsDispose ($hGraphic) _GDIPlus_Shutdown () EndFunc The adlib function invalidates the child window contents and calls WM_PAINT Then the child window contents dissappear. I believe this is what is causing my problem -
When using the aforementioned function for storing temporarily bitmap of the window I get a black rectangle instead of actual window contents. All drawing on the window is performed using Gdiplus functions. Is there any other way to capture window contents as bitmap to be redrawn later on a WM_PAINT event? I need this because I found that redrawing the window all over creates some shadows on letters being redrawn and if I use _GDIPlus_GraphicsFillRect to refill the window with background color I get flickering . Is there any example on how to use _GDIPlus_BitmapCreateFromGraphics properly or maybe some other way to copy window contents? I did search the forum for that function , but I saw it only used with window whose contents are created by regular control creation functions as opposed to GDIplus calls.
-
If you run those two examples separately you will see that the message font appears to be thicker where DrawString is called twice. CODE #include <GDIPlus.au3> #include <GUIConstants.au3> Global $hGraphic Global $hWnd Global $GUI,$GUI_Indicator $GUI = GUICreate("WinNutClient", 640, 380, -1 , -1,Bitor($GUI_SS_DEFAULT_GUI,$WS_CLIPCHILDREN)) $GUI_Indicator = GUICreate ("", 150, 120, 10, 10, BitOR ($WS_CHILD, $WS_DLGFRAME),$WS_EX_CLIENTEDGE,$GUI) GuiSetState(@SW_SHOW,$GUI) GuiSetState(@SW_SHOW,$GUI_Indicator) _GDIPlus_Startup () $hWnd = WinGetHandle($GUI_Indicator) $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd) _GDIPlus_GraphicsDrawString($hGraphic , "hello world",10,10) _GDIPlus_GraphicsDrawString($hGraphic , "hello world",10,10) Do ;Sleep(100) Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_Shutdown() Exit CODE #include <GDIPlus.au3> #include <GUIConstants.au3> Global $hGraphic Global $hWnd Global $GUI,$GUI_Indicator $GUI = GUICreate("WinNutClient", 640, 380, -1 , -1,Bitor($GUI_SS_DEFAULT_GUI,$WS_CLIPCHILDREN)) $GUI_Indicator = GUICreate ("", 150, 120, 10, 10, BitOR ($WS_CHILD, $WS_DLGFRAME),$WS_EX_CLIENTEDGE,$GUI) GuiSetState(@SW_SHOW,$GUI) GuiSetState(@SW_SHOW,$GUI_Indicator) _GDIPlus_Startup () $hWnd = WinGetHandle($GUI_Indicator) $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd) _GDIPlus_GraphicsDrawString($hGraphic , "hello world",10,10) Do ;Sleep(100) Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_Shutdown() Exit This is a problem if I use a WM_PAINT handler since window looks different after first repaint event. Therefore I am forced to run the drawing twice in the beginning to make sure it doesn't change afterwards. Could be a bug in GDIplus dll maybe?
-
Nothing stops me from doing that. I am just pointing out that the code examples that come with Autoit are "buggy" and it would be a better idea to have a WM_PAINT handler included in the example scripts. And arcker how come you use $WM_ACTIVATEAPP? If I understand right this event would be fired when the window becomes active. I think this is a problem since you might have another application blocking partly or fully your window and then your window would remain inactive and you might end up with "damaged" window content.
-
Well I was not able to find any mention of that in the forum. Forgive me if I missed. Anyway all gdiplus examples in the help files lack a very important thing. Since gdiplus functions drawn stuff is not being repainted on WM_PAINT event I think it could be useful to add an appropriate GuiRegister handler to have them refreshed. I was trying various examples and couldn't figure out why things would dissappear after I minimized and restored the window.
-
This is a script for drawing a dial with a needle for displaying various numeric data. Thanks go to bobneumann for the original idea and implementation! This is still work in progress , while the final goal is UDF with gauge drawing functions (will all kinds of customizations ) as well as functions for updating the needle position. This is implemented using Gdiplus UDF . Things to do in the short run : 1. Make a single function to draw a dial window with all parameters (including size , labels inside the dial etc) 2. Make a single function to update the dial (change needle position , update labels inside etc) 3. Hook the repaint event for proper refreshing of the gui after being overlapped or minimized Yes I know refreshing works as is because there is a loop redrawing it . It is not proper way though since the goal is to have the dial on self service so we can do other stuff with the GUI. Comments , contributions to the code etc are welcome dial.au3
-
Dial Indicator (Needle Gauge)
matrix200 replied to bobneumann's topic in AutoIt General Help and Support
I don't think I have a permission to do that. Can someone of the mods create the topic for me? Then I will put my script there. OK I do apologize. Anyway I created the topic in example scripts and put my script there Those interested in the script please go there. -
Dial Indicator (Needle Gauge)
matrix200 replied to bobneumann's topic in AutoIt General Help and Support
Ok I couldn't find the topic in example scripts . I do apologize if I missed it and it is a wrong thread to post. Anyway I found this wonderful script and wanted to make it more useful for my application (UPS monitoring client). So I started modifying it in all kinds of ways. First I replaced all dll stuff with Gdiplus library calls to make the program easier to read. Second I made the gauge half height (If you run it you will see what I mean). This is still a work in progress while the ultimate goal for me is to make one function with all parameters (scale values , colors to draw on the scale , labels etc and the size of window) which will draw the dial and another function to update dial's value. Then I hope others will be able to use it in their applications. Anyway thanks to all who contributed to the original script and of course comments are welcome The script is attached to the message. dial.au3 -
Hey I have a similar problem with my script where I need to detect going to hibernate and back to normal operation of a script. Is there a code for Hibernate and Resume from Hibernate as well or does it use the Suspend event?
-
Question regarding treeview control
matrix200 replied to matrix200's topic in AutoIt GUI Help and Support
Thanks a lot smashly! That worked like a charm You just earned yourself a mention in the thanks section of the readme file of the next version -
In my script I need to detect when a treeview control has focus (is clicked on) or keyboard is used to traverse the items. Then I need to detect the path of the selected item and do some operation with it (It is a full ups variable name that I am sending to the UPS for getting its value). Now the problem is when I use the GuiTreeView , I can't detect the ControlId of it and therefore have no way of knowing that indeed TreeViewItem was clicked. On the other hand if I use GUICtrlCreateTreeViewItem , I have no way of knowing the ControlId of an item using its path . I need that for recursively creating the path in tree. For example say I have the following path "Root|Child1|Child2" that I want to add. Using recursion I need to first look if such path already exists and have its ControlId and there is no way of doing that. What are my options? Sure I can have it resolved using the Adlib and constantly polling for selected items on the tree and doing all the stuff. I am not liking that since I have to give up another Adlib which is more important (monitoring UPS variables for proper shutdown in case of blackout) and for performance reasons because I need to send lots of chatter on TCP and interpert its results. It is preferable to perform only if selection changes on the tree.
-
_GUICtrlTreeViewGetTree vs _GUICtrlTreeView_GetTree
matrix200 replied to MadBoy's topic in AutoIt General Help and Support
I think it is a bug so I have rewritten the function to always work Here is my rewritten function that works fine CODE Func _GUICtrlTreeViewGetTree1($i_treeview, $s_sep_char , $h_item) If Not _WinAPI_IsClassName ($i_treeview, "SysTreeView32") Then Return SetError(-1, -1, "") EndIf Local $szPath = "", $hParent If Not IsHWnd($i_treeview) Then $i_treeview = GUICtrlGetHandle($i_treeview) If $h_item = 0 Then $h_item = _SendMessage($i_treeview, $TVM_GETNEXTITEM, $TVGN_CARET, 0) ;$h_item = GUICtrlSendMsg($i_treeview, $TVM_GETNEXTITEM, $TVGN_CARET, 0) If $h_item > 0 Then $szPath = _GUICtrlTreeView_GetText($i_treeview, $h_item) Do; Get now the parent item handle if there is one $hParent = _SendMessage($i_treeview, $TVM_GETNEXTITEM, $TVGN_PARENT, $h_item) If $hParent > 0 Then $szPath = _GUICtrlTreeView_GetText($i_treeview, $hParent) & $s_sep_char & $szPath $h_item = $hParent Until $h_item <= 0 EndIf Return $szPath EndFunc ;==>_GUICtrlTreeViewGetTree I have slightly changed it to make it more comfortable for my needs. The error checking part in the beginning is a leftover from the previous version. I also have added the separator char back as a parameter since I find it more convenient then using Opt which affects things on a global scope and might affect behavior of code in other places. -
_GUICtrlTreeViewGetTree vs _GUICtrlTreeView_GetTree
matrix200 replied to MadBoy's topic in AutoIt General Help and Support
Don't want to hijack this thread , but I believe the new function _GUICtrlTreeView_GetTree has a bug. Somehow when used with GuiCtrlTreeView it is never traversing the tree because hItems it finds are considered to be negative (<0) and it quits right on first hItem. Only after I changed all (<0) to (<> 0) did the function work and produce the path to the root of the tree. CODE #include <GUIConstants.au3> #Include <nutTreeView.au3> #include <GuiTreeView.au3> $TreeView1 = 0 $Label4 = "" Func showselected() $selected = _GUICtrlTreeView_GetTree($TreeView1, 0) GuiCtrlSetData($Label4 , $selected) ;display the path to root from currently selected item EndFunc #Region ### START Koda GUI section ### Form=c:\winnut\winnut\listvars.kxf $guilistvar = GUICreate("Test Tree", 365, 331, 196, 108) $TreeView1 = GUICtrlCreateTreeView(0, 8, 361, 169) $Group1 = GUICtrlCreateGroup("Item properties", 0, 184, 361, 105, $BS_CENTER) $Label1 = GUICtrlCreateLabel("Path :", 8, 200, 38, 17) $Label4 = GUICtrlCreateLabel("", 50, 200, 291, 17, $SS_SUNKEN) GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### _addPath($TreeView1 , "test4.text1.text21") _addPath($TreeView1 , "test4.text1.11") ;_WalkTree1($TreeView1 , 0) _GUICtrlTreeView_Expand($TreeView1) AdlibEnable("showselected",500) While 1 $nMsg = GUIGetMsg(1) if ($nMsg[0] == $GUI_EVENT_CLOSE) Then Exit EndIf WEnd Don't mind the _addPath function. What it does is simply adding a subtree to the tree made of the items separated by "." I believe the effect should be the same if you add the items manually using the usual one item adding functions