WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jballi
Posts: 624
Joined: 29 Sep 2013, 17:34

WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

30 Jan 2016, 14:13

Found another problem while trying to resolve the Maximize window anomaly problem.

While using the web browser control, adding or removing the WS_MAXIMIZEBOX style, i.e. "gui +MaximizeBox" or "gui -MaximizeBox", will cause the web browser control to hide or disappear. This example will illustrate the problem.

Code: Select all

#NoEnv
#SingleInstance Force

gui -DPIScale -MinimizeBox
gui Margin,0,0
gui Add,ActiveX,w600 r26 +hWndhWB vWB,Shell.Explorer
gui Add,Button,xm     gMaxBoxAdd,%A_Space%+MaximizeBox%A_Space%
gui Add,Button,x+0 wp gMaxBoxDel,-MaximizeBox
WB.Navigate("https://www.google.com/")
gui Show
return

MaxBoxAdd:
gui +MaximizeBox
return

MaxBoxDel:
gui -MaximizeBox
return

GUIClose:
GUIEscape:
ExitApp
The web browser control is not actually hidden. The contents of the control (including the background) are just not showing itself. If you click on the control or just move the mouse over the control, you will start to see elements of the page. If you press the PageUp or PageDown keys while the control has input focus, everything magically reappears.

Adding or removing the WS_MAXIMIZEBOX style is not the only time I've seen the web browser control go into this pseudo-hidden stage, but it's the only way I've been able to consistently reproduce the problem.

Any ideas why this happens and what can be done to prevent it from happening? More importantly, is there any way to force the control to redraw itself so I can get it out this "Don't look at me, I'm shy" stage?

I've tried (or I think I've tried) all the standard stuff to get the contents of the control to show itself. I tried Redraw on the main control window and on all of the sub-windows. Nothing. I've tried to invalidate the space occupied by the control using the "InvalidateRect" function. Nothing. Tried to invalidate using the Invalidate method, ie WB.Invalidate or WB.Invalidate(). COM gives me 0x80020006 - Unknown name error.

Thank you for your assistance.
User avatar
jballi
Posts: 624
Joined: 29 Sep 2013, 17:34

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

31 Jan 2016, 15:28

OK... Was anyone able to duplicate the problem I'm seeing? Thanks.
wizardzedd
Posts: 319
Joined: 23 Jan 2016, 23:03

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

31 Jan 2016, 22:13

Yep, I saw it. Its kind of cool really. https://encyclopediadramatica.se/It's_n ... _a_feature
This may be slightly annoying (flashing), but to get rid of it you can hide and show the gui.

Code: Select all

#SingleInstance, force
 
gui -DPIScale -MinimizeBox
gui Margin,0,0
gui Add,ActiveX,w600 r26 +hWndhWB vWB,Shell.Explorer
gui Add,Button,xm     gMaxBoxAdd,%A_Space%+MaximizeBox%A_Space%
gui Add,Button,x+0 wp gMaxBoxDel,-MaximizeBox
WB.Navigate("https://www.google.com/")
gui Show
return
 
MaxBoxAdd:
gui +MaximizeBox
gui hide
gui show
return
 
MaxBoxDel:
gui -MaximizeBox
gui Hide
gui show
return
 
GUIClose:
GUIEscape:
ExitApp
User avatar
kczx3
Posts: 1195
Joined: 06 Oct 2015, 21:39

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

01 Feb 2016, 08:54

I have this problem when working with Tabs and AnimateWindow(). I ended up just hiding and show the controls. That may be your easiest solution if it works, though as wizardzedd said, there will be a flicker.
User avatar
jballi
Posts: 624
Joined: 29 Sep 2013, 17:34

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

01 Feb 2016, 20:09

My original objective was to figure out how to stop the web browser control from going into this hidden/fugue state. Sometimes this can be resolved by simply changing the order the commands are performed. But sometimes, as in this example, it's unavoidable and so the objective changes from avoidance to figuring out how to restore the control to it's original state.

I've compiled a few workarounds that will force the web browser control to restore itself back to normal. This is what we have so far:
  • Refreshing the contents of the control, Ex: WB.Refresh, will force the web browser control to redraw. Not an option I would recommend since it takes the longest and uses the most resources.
  • Resizing the control, even by only pixel, forces the control to redraw. In my example, adding the WS_MAXIMIZEBOX style is not the real problem because the control is immediately resized and redrawn after that. The problem is when the WS_MAXIMIZEBOX style is subsequently removed.
  • Adding or Removing window styles. Yes, adding or removing the WS_MAXIMIZEBOX style causes the problem. However, adding, removing, or double-toggling other window styles will force the web browser control to redraw. For example, removing the WS_SYSMENU style will force the web browser control to show/redraw. No, I don't know why. I'm sure there are other windows styles that will force the web browser control to redraw when added or removed but I've stopped digging for now.
  • Thanks to wizardzedd, hiding and showing the entire window will force the web browser control to redraw. The flicking can be significant sometimes but so far, it works every time.
  • Thanks to kczx3, hiding and showing the web browser control. I also thought of solution after wizardzedd posted his/her idea but your post made it more of a substantive solution. Flickering is also a problem but it's not bad.
Hiding/Showing the web browser control appears to be the best (least intrusive?) workaround for now. Flickering is a nuisance but since this workaround is only used in rare cases, it makes for viable workaround.

Thanks to wizardzedd and kczx3 for your feedback. This a problem that has been occurring for many years and will continue to be an annoyance for years to come. If anyone has alternative workaround, please post it!
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

02 Feb 2016, 01:43

You can prevent redraw as a workaround ...

Code: Select all

MaxBoxAdd:
SendMessage 0xB, 0  ; WM_SETREDRAW, FALSE
gui +MaximizeBox
SendMessage 0xB, 1
return
 
MaxBoxDel:
SendMessage 0xB, 0
gui -MaximizeBox
SendMessage 0xB, 1
return
... but on systems without desktop composition, the title bar won't redraw to reflect the changes. (When desktop composition is enabled, the titlebar is rendered by the desktop window manager, not the application, so the changes will be visible.) If you add WinSet Redraw after SendMessage, the problem returns. Instead, you can redraw just the non-client area:

Code: Select all

;...
SendMessage 0xB, 1
RedrawNonClientArea(WinExist())
;...

RedrawNonClientArea(hwnd) {
	DllCall("SetWindowPos", "ptr", hwnd, "ptr", 0, "int", 0, "int", 0, "int", 0, "int", 0
		, "int", 0x27) ; SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
}
User avatar
jballi
Posts: 624
Joined: 29 Sep 2013, 17:34

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

02 Feb 2016, 17:07

@lexikos. I've just started to test it, but your solution appears to be significantly more reliable that just hiding and showing the web browser control. And now that I know a little bit more about the desktop composition element of the Desktop Window Manager, I will extend my testing to include "without the Desktop Window Manager". Thanks. :)
User avatar
jballi
Posts: 624
Joined: 29 Sep 2013, 17:34

Re: WebBrowser control disappears when adding or removing the WS_MAXIMIZEBOX style

12 Feb 2016, 07:09

The lexikos methodology for preventing redraw is significantly more reliable and user-friendly (no flickering) than the other solutions. Thanks. :) However, I had a significant amount of trouble implementing it into a real-world application because the WM_SETREDRAW messages introduced some unexpected side effects.

From the "just in case you care" department, I've updated the example/test script from the Maximize window anomaly post to include the lexikos methodology and modified it so that it can (OK, "should be able to be") used in any script with only a few modifications. Who knows? It might be useful to someone someday.

Code: Select all

/*
    Preface: Do not change the order of the GUI options

    Instructions:

    Test 1
    ------
    Comment out the "-SysMenu" option (may already commented out).  When the
    window is shown, the Maximize button is showing but is not enabled.

    Run the script.  Press F11 to maximize the window.  Press F11 again to
    restore the window.  The contents of the web browser control should be
    visible in all cases.


    Test 2
    ------
    Uncomment the "-SysMenu" option.  When the window is shown, everything on
    the title bar is hidden.  Because the -MaximizeBox option is also used, the
    MaximizeBox is not showing _and_ it is not enabled.

    Run the script.  Press F11 to maximize the window. Press F11 again to
    restore the window.  The contents of the web browser control should be
    visible in all cases.


    Test 3 (if you get bored)
    ------
    Uncomment all GUI options including -Sysmenu.  Delete or comment out the
    -MaximizeBox option.

    Run the script.  Press F11 to maximize the window.  Press F11 again to
    restore the window.  The contents of the web browser control should be
    visible in all cases.

    Because the -SysMenu option is used, no buttons on the title bar are
    visible.  However, since the -MaximizeBox option was removed, the window
    still has the WS_MAXIMIZEBOX style and and so the window operates the same
    as if the Maximize button were showing.  The script uses the standard "gui
    Maximize" command without any of the before and after code.
*/

#NoEnv
#SingleInstance Force

;-- Window style flags
WS_MAXIMIZEBOX :=0x10000
WS_SIZEBOX     :=0x40000
WS_SYSMENU     :=0x80000

;-- Messages
WM_SETREDRAW :=0xB

;-- Build GUI
gui -DPIScale +hWndhWindow +Resize -MaximizeBox  ;-SysMenu
GroupAdd MyWindowGroup,ahk_id %hWindow%
gui Margin,0,0
gui Add,ActiveX,w600 r26 +hWndhWB vMyWB,Shell.Explorer
gui Add,Text,h20 vMyText,Text control - 20 pixels high
MyWB.Navigate("https://www.google.com/")

;-- Show it
gui Show
return

GUISize:
$Maximized:=(A_EventInfo=2) ? True:False
GUIControl Move,MyWB,% "w" . A_GUIWidth . " h" . A_GUIHeight-20
GUIControl Move,MyText,% "y" . A_GUIHeight-20
return

GUIClose:
GUIEscape:
ExitApp

#IfWinActive ahk_group MyWindowGroup
F11::
if $Maximized
    gui Restore
else
    {
    WinGet l_Style,Style,ahk_id %hWindow%
    if (l_Style & WS_MAXIMIZEBOX)
        gui Maximize
    else
        {
        ;-- Add the WS_MAXIMIZEBOX style to the window.  Without the
        ;   WS_MAXIMIZEBOX style, the OS will not size the window correctly when
        ;   the Maximize command is executed.
        ;
        ;   There are two undesired side effects of adding the WS_MAXIMIZEBOX
        ;   style.  First of all, the WS_MAXIMIZEBOX style cannot exist without
        ;   the WS_SYSMENU style and so the WS_SYSMENU style is automatically
        ;   added when the WS_MAXIMIZEBOX style is added if it wasn't already
        ;   included.  Also, this command causes the content of the web browser
        ;   control to disappear in most cases. No, I don't know why.
        ;
        ;   To counteract the "web browser control disappears" effect of adding
        ;   the WS_MAXIMIZEBOX style, the WM_SETREDRAW message is sent to the
        ;   window before (to disable redraw) and after (to enable redraw)
        ;   adding the WS_MAXIMIZEBOX style.
        ;
        ;   There is one undesired side effect of sending the WM_SETREDRAW
        ;   message to disable redrawing.  This message removes the window from
        ;   the list of visible windows.  This is the same as if the window were
        ;   hidden.  To ensure that the window is visible for all AutoHotkey
        ;   commands, DetectHiddenWindows is temporarily set On.
        ;
        $DetectHiddenWindows:=A_DetectHiddenWindows
        DetectHiddenWindows On
        SendMessage WM_SETREDRAW,False,,,ahk_id %hWindow%
        gui +MaximizeBox
        SendMessage WM_SETREDRAW,True,,,ahk_id %hWindow%

        ;-- Maximize the window.  This command triggers the GUISize routine
        ;   which in turn, resizes the web browser control. The web browser
        ;   control is automatically redrawn because of the "Move" commands.
        gui Maximize

        ;-- Remove the WS_MAXIMIZEBOX style that was added earlier. This command
        ;   causes the content of the web browser control to disappear (yes,
        ;   again) in most cases.  To counteract this effect, WM_SETREDRAW is
        ;   sent before and after.
        SendMessage WM_SETREDRAW,False,,,ahk_id %hWindow%
        gui -MaximizeBox
        SendMessage WM_SETREDRAW,True,,,ahk_id %hWindow%

        ;-- If needed, remove the WS_SYSMENU style
        if not (l_Style & WS_SYSMENU)
            {
            SendMessage WM_SETREDRAW,False,,,ahk_id %hWindow%
            gui -SysMenu
            SendMessage WM_SETREDRAW,True,,,ahk_id %hWindow%
            }

        ;-- Reapply the styles and redraw the frame if needed
        ;   Note: This step is needed if the Desktop Window Manager is not
        ;   enabled.  Without it, changes to the title bar won't correctly
        ;   redraw to reflect the changes made.
        DllCall("SetWindowPos","ptr",hWindow,"ptr",0,"int",0,"int",0,"int",0,"int",0
        		,"int",0x27) ; SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER

        ;-- Restore DetectHiddenWindows
        DetectHiddenWindows %$DetectHiddenWindows%
        }
    }

;-- Sleep added to reduce the number of F11 calls that can be made consecutively
Sleep 150
return
#IfWinActive

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], boiler, Dom_Christo, guyzyl, kczx3, kunkel321, mikeyww, tank and 30 guests