Jump to content

GuiSetState(@SW_SHOW,...) problem


RagsRevenge
 Share

Recommended Posts

In I outlined some problems I was having with a script to place a Unicode overlay on a program which doesn't support unicode.

In brief, my script places unicode labels over text in the existing program. Due to problems with showing/hiding shed loads of labels, I am creating a GUI for each page.

I have most of the problems from that thread fixed, but now have a new one....

For some reason, when I show a page of labels, the underlying application is flickering. You can see the effect I am talking about if you run the following short script (written for explanation purposes only) while having notepad with some text on it open in the background.

I have traced the problem to the GUISetState(@SW_SHOW, $aGuis[$iPageNumber]) function.

Can any provide an explanation why this is happening? Or even better... a fix :mellow:?

#include <GUIConstants.au3>
#include <GUIConstantsEX.au3>
#include <windowsconstants.au3>
#include <StaticConstants.au3>
#Include <WinAPI.au3>
#Include <File.au3>
#Include <Array.au3>
Opt("WinDetectHiddenText", 0)
const $TransparentColour = 0xABCDEF  ;any element this colour will be transparent
Global $aLabels[100][100]
Global $gui1
Global $aGuis[1]
main()
$index = 1
While 1
    ConsoleWrite("Looping" & @CRLF)
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch  
 
_showPage($index)
 
if $index = 1 Then
  _hidePage(98)
Else
  _hidePage($index - 1)
EndIf
 
sleep(500)
$index += 1
If $index > 98 Then
  $index = 1
EndIf
WEnd
Func _hidePage($iPageNumber)
GUISetState(@SW_LOCK, $aGuis[$iPageNumber])
GUISetState(@SW_HIDE, $aGuis[$iPageNumber])
GUISetStyle(-1, $WS_EX_TOOLWINDOW, $aGuis[$iPageNumber])
WinSetOnTop($aGuis[$iPageNumber],'',0)
GUISetState(@SW_UNLOCK, $aGuis[$iPageNumber])
EndFunc
Func _showPage($iPageNumber)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iPageNumber = ' & $iPageNumber & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
 
GUISetState(@SW_LOCK, $aGuis[$iPageNumber])
 
GUISetStyle(-1, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW), $aGuis[$iPageNumber])
 
_API_SetLayeredWindowAttributes($aGuis[$iPageNumber], $TransparentColour, 255);set special colour fully transparent
 
$ShowGuiResult = GUISetState(@SW_SHOW, $aGuis[$iPageNumber])
 
WinSetOnTop($aGuis[$iPageNumber],'',1)
 
GUISetState(@SW_UNLOCK, $aGuis[$iPageNumber])
EndFunc
func main()
    createBaseGui()
  
ReDim $aGuis[100]
 
    _createLabels()
EndFunc
func createBaseGui()
$gui1 = GUICreate("Visu Overlay", 1280, 1024, 0, 0, BitOR($WS_MAXIMIZEBOX,$WS_POPUP,$WS_TABSTOP),BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $gui1 = ' & $gui1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
GUISetBkColor(0xFFFFFF)
GUISetFont(6)
GUISetState()
WinSetTrans($gui1,"",0)  ;Makes underlying GUI totally transparent
EndFunc
Func _createSubGUI($iGuiIndex, $iWidth, $iHeight, $iTop = 0, $iLeft = 0)
$aGuis[$iGuiIndex] = GUICreate("Visu Overlay " & $iGuiIndex, $iWidth, $iHeight, $iLeft, $iTop, $WS_POPUP, $WS_EX_TOOLWINDOW)
 
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aGuis[$iGuiIndex] = ' & $aGuis[$iGuiIndex] & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
 
GUISetBkColor($TransparentColour, $aGuis[$iGuiIndex])
 
_API_SetLayeredWindowAttributes($aGuis[$iGuiIndex], $TransparentColour, 255);set special colour fully transparent
 
WinSetOnTop($aGuis[$iGuiIndex],'',1)
EndFunc
Func _createLabels()
Local $lastPageNum = 0
Local $pageNum
Local $LabelIndex = -1
Local $labelCol = -1
Local $caption
Local $labelCount = 1
 
For $i = 1 to 100 - 1
  $pageNum = $i
 
  ;This code is used for keeping track of the column where the control ID is stored.
  if $pageNum <> $lastPageNum Then
   _createSubGUI($pageNum, 1280, 800)  
  
   $labelCol = 0
   $lastPageNum = $pageNum
  EndIf
  
  for $j = 1 to 5
   $caption = "Label" & $j & " on Page " & $pageNum
   $aLabels[$pageNum][$labelCol] = GUICtrlCreateLabel($caption, 10, $j * 25, 100, 20, BitOr($SS_LeftNoWordWrap, $SS_CenterImage))
   ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aLabels[$pageNum][$labelCol] = ' & $aLabels[$pageNum][$labelCol] & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
   ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : GUICtrlRead($aLabels[$pageNum][$labelCol]) = ' & GUICtrlRead($aLabels[$pageNum][$labelCol]) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
   GUICtrlSetState($aLabels[$pageNum][$labelCol], $GUI_SHOW)
  
   $labelCount += 1
  
   GUICtrlSetTip(-1, $caption)
   ;GUICtrlSetState(-1, $GUI_HIDE)
   _BKColor(0xECE9D8, $aLabels[$pageNum][$labelCol])
  
   $labelCol += 1
  Next
Next
EndFunc
;===============================================================================
; Function Name:   _API_SetLayeredWindowAttributes
; Description:: Sets Layered Window Attributes:) See MSDN for more informaion
; Parameter(s):
;                 $hwnd - Handle of GUI to work on
;                 $i_transcolor - Transparent color
;                 $Transparency - Set Transparancy of GUI
;                 $isColorRef - If True, $i_transcolor is a COLORREF-Strucure, else an RGB-Color
; Requirement(s):  Layered Windows
; Return Value(s): Success: 1
;                 Error: 0
;                  @error: 1 to 3 - Error from DllCall
;                  @error: 4 - Function did not succeed - use
;                              _WinAPI_GetLastErrorMessage or _WinAPI_GetLastError to get more information
; Author(s):       Prog@ndy
;===============================================================================
Func _API_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $isColorRef = False)
    Local Const $AC_SRC_ALPHA = 1
    Local Const $ULW_ALPHA = 2
    Local Const $LWA_ALPHA = 0x2
    Local Const $LWA_COLORKEY = 0x1
    If Not $isColorRef Then
        $i_transcolor = Hex(String($i_transcolor), 6)
        $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $LWA_COLORKEY + $LWA_ALPHA)
    Select
        Case @error
            Return SetError(@error, 0, 0)
        Case $Ret[0] = 0
            Return SetError(4, 0, 0)
        Case Else
            Return 1
    EndSelect
EndFunc ;==>_API_SetLayeredWindowAttributes
;===========================================================================
; Function    : _BKColor( backgroundcolor, controlID, textcolor )
; Description   : Sets the background color of a control. (Transparent Label)
;              : Sets the text color of a control.
; Author        : Thunder-man (Frank Michalski)
; Date        : 19. September 2007
; Version      : V 1.20
; Example  :     _BKColor()                             :Transparent
;               _BKColor( -1, $MyLabel)                :Transparent
;               _BKColor(0x00ff00)                      :Color Green
;               _BKColor(0x00ff00, $MyLabel)              :Color Green
;               _BKColor( -1, $MyLabel, 0x00ff00)   :Text Color Green
;===========================================================================
Func _BKColor($BackColor_ = "", $GuiID_ = -1, $Textcolor_ = 0x000000)
    If $BackColor_ = "" or $BackColor_ = -1 Then
    GUICtrlSetBkColor($GuiID_, $GUI_BKCOLOR_TRANSPARENT)
    GUICtrlSetColor($GuiID_, $Textcolor_)
Else
    GUICtrlSetBkColor($GuiID_, $BackColor_)
    GUICtrlSetColor($GuiID_, $Textcolor_)
EndIf
EndFunc  ;==>_BKColor
Link to comment
Share on other sites

In your main loop call _showpage/_hidepage only when it's needed (when something changes) and not in every loop cycle.

Hi Zedna,

Thanks for the response.

this is just a test script for illustration purposes. The real script has a lot of dependancies, a slow start up time, and is very complex.

I am showing/hiding on each loop to try to find a solution to my problem(s). The main script only shows/hides based on user input.

However, your suggestion wouldn't remove the symptom, only make it less frequent? While of course, this flickering may become tolerable with less shows/hides, I am also having weird redraw problems with the non-unicode compatible program I am creating the overlay for. I'm guessing the redraw problem is possibly related to the issue I have described in this thread. Why would an underlying application be affected by showing a GUI in my AutoIt script?

Regards,

D

[EDIT]: Removed multi-quote

Edited by RagsRevenge
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...