Jump to content

Date control increment/decrement buttons disappear after updating GUI background


Recommended Posts

Hi everyone,

I found this bug in my GUI and I am not sure how to solve it, the date control's buttons disappear whenever I update the GUI background, here is a screenshot:

eFlX5Z7.png

Notice the red void inside the control, that is where the controls are normally supposed to be, they appear if I hover my mouse over them, but they disappear again after another background update. Here is a little reproducer script I wrote:

#include <ColorConstants.au3>
#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    GUICreate("My GUI get time", 200, 200, 800, 200)
    ToggleColour()
    Local $idDate = GUICtrlCreateDate("", 20, 20, 100, 20, $DTS_TIMEFORMAT)
    GUICtrlSetBkColor(-1, $COLOR_WHITE)
    GUISetState(@SW_SHOW)
    AdlibRegister(ToggleColour, 1000)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

Func ToggleColour()
    Local Static $bActive = False
    GUISetBkColor($bActive ? $COLOR_GREEN : $COLOR_RED)
    $bActive = Not $bActive
EndFunc

Thank you for the help in advance! :)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

I think it's some bug, probably in AutoIt.

I tried this workaround in several ways but with no luck,

;~ #include "<SendMessage.au3>"
#include <WindowsConstants.au3>
#include <WinAPIGDIInternals.au3>
;~ #include "<GUIDateTimePicker.au3>"
;~ #include "<DateTimeConstants.au3>"

#include <ColorConstants.au3>
#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Global $idDate, $hDate

Example()

Func Example()
    GUICreate("My GUI get time", 200, 200, 800, 200)
    ToggleColour()
    $idDate = GUICtrlCreateDate("", 20, 20, 100, 20, $DTS_TIMEFORMAT)
    $hDate = GUICtrlGetHandle($idDate)
    GUICtrlSetBkColor(-1, $COLOR_WHITE)
    GUISetState(@SW_SHOW)
    AdlibRegister(ToggleColour, 2000)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

Func ToggleColour()
    Local Static $bActive = False
    GUISetBkColor($bActive ? $COLOR_GREEN : $COLOR_RED)
    $bActive = Not $bActive

;~  GUICtrlSendMsg($idDate, $DTM_SETFORMATW, 0, 'HH:mm:ss')

;~  _SendMessage($hDate, $WM_SETREDRAW, True)
    GUICtrlSendMsg($idDate, $WM_SETREDRAW, 1, 0)
;~  GUICtrlSendMsg($hDate, $WM_SETREDRAW, 1, 0)
;~  _WinAPI_RedrawWindow($hDate)
EndFunc

princip is to invoke redraw of DateTime picker control after GUISetBkColor()

I think it have to be changed/improved by getting handle to UpDown control (Inside DateTime control) by DTM_GETDATETIMEPICKERINFO message

see HWND hwndUD (A handle to the up/down control) in struct tagDATETIMEPICKERINFO

https://docs.microsoft.com/en-us/windows/win32/controls/dtm-getdatetimepickerinfo

https://docs.microsoft.com/en-us/windows/win32/api/commctrl/ns-commctrl-datetimepickerinfo

then try

GUICtrlSendMsg($hUpDown, $WM_SETREDRAW, 1, 0)

or

_WinAPI_RedrawWindow($hUpDown)

 

Hardest part is creating AutoIt's declaration of structure tagDATETIMEPICKERINFO

Edited by Zedna
Link to comment
Share on other sites

@Zedna Thanks for investigating the issue

@InnI Thank you for the solution! InvalidateRect did not work for me (no visible change) but $WS_CLIPCHILDREN did work :thumbsup:

However I had a small complaint, using that style alone removed the minimize, close etc. buttons from the window's header, so I combined it with the default styles and it worked perfectly, here is the final code:

#include <ColorConstants.au3>
#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    GUICreate("My GUI get time", 200, 200, 800, 200, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_CLIPCHILDREN))
    ToggleColour()
    Local $idDate = GUICtrlCreateDate("", 20, 20, 100, 20, $DTS_TIMEFORMAT)
    GUISetState(@SW_SHOW)
    AdlibRegister(ToggleColour, 1000)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

Func ToggleColour()
    Local Static $bActive = False
    GUISetBkColor($bActive ? $COLOR_GREEN : $COLOR_RED)
    $bActive = Not $bActive
EndFunc

 

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Spoke too soon :(

While $WS_CLIPCHILDREN does fix the issue, it also messes up some things when using groups and labels:

#include <ColorConstants.au3>
#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    GUICreate("My GUI get time", 200, 200, 800, 200, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_CLIPCHILDREN))
    ToggleColour()
    GUICtrlCreateGroup("Time", 8, 72, 153, 73)
    GUICtrlCreateLabel("Start:", 16, 94, 32, 17)
    GUICtrlCreateLabel("Stop:", 16, 118, 29, 17)
    Global $idTimeStart = GUICtrlCreateDate("", 56, 88, 89, 21, $DTS_TIMEFORMAT)
    Global $idTimeStop = GUICtrlCreateDate("", 56, 115, 89, 21, $DTS_TIMEFORMAT)
    GUISetState(@SW_SHOW)
    AdlibRegister(ToggleColour, 1000)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

Func ToggleColour()
    Local Static $bActive = False
    GUISetBkColor($bActive ? $COLOR_GREEN : $COLOR_RED)
    $bActive = Not $bActive
EndFunc

zUbxNqd.png

Notice that the red background for labels is from the initial paint of red. Here is how it is supposed to look (without CLIPCHILDREN)

XPfr499.png

So for the moment it looks like @Zedna's solution of getting the handle of UpDown buttons and handling redraw is the best we have...

3 hours ago, Zedna said:

Hardest part is creating AutoIt's declaration of structure tagDATETIMEPICKERINFO

Here is my quick partial attempt:

Global Const $tagDATETIMEPICKERINFO = 'dword cbSize;' & $tagRECT & ';dword stateCheck;' & $tagRECT & ';dword stateButton;hwnd hwndEdit;hwnd hwndUD;hwnd hwndDropDown'

I don't know how I can name the RECT struct members, but once that is done, it should be compatible with tagDATETIMEPICKERINFO.

Windows GUI is not my strong suit, so I need help with receiving/sending messages too.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

@argumentum Thanks for sharing, however I don't think I see any code which we could use for this issue.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

#include <ColorConstants.au3>
#include <DateTimeConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>

Global $hGui

Example()

Func Example()
    $hGui = GUICreate("My GUI get time", 200, 200, 800, 200, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
    ToggleColour()
    GUICtrlCreateGroup("Time", 8, 72, 153, 73)
    GUICtrlCreateLabel("Start:", 16, 94, 32, 17)
    GUICtrlCreateLabel("Stop:", 16, 118, 29, 17)
    Global $idTimeStart = GUICtrlCreateDate("", 56, 88, 89, 21, $DTS_TIMEFORMAT)
    Global $idTimeStop = GUICtrlCreateDate("", 56, 115, 89, 21, $DTS_TIMEFORMAT)
    GUISetState(@SW_SHOW)
    AdlibRegister(ToggleColour, 1000)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>Example

Func ToggleColour()
    Local Static $bActive = False
    GUISetBkColor($bActive ? $COLOR_GREEN : $COLOR_RED)
    _WinAPI_RedrawWindow($hGui, 0, 0, $RDW_INVALIDATE+$RDW_ALLCHILDREN)
    $bActive = Not $bActive
EndFunc

 

Link to comment
Share on other sites

@LarsJ Can't believe the solution can be so simple... especially with WinAPI :lol:

I actually avoided this in my project and I am now using a different approach... and I didn't test your code because I'd have to fire up my VM and I am lazy 😴

But I am more than confident that you did, so thanks for providing a solution :)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

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...