Jump to content
Sign in to follow this  
FireFox

Subclassing bug

Recommended Posts

FireFox

Hi,
 
I have an issue with the subclassing, it seems like the internal code is stuck in an infinite loop when the Exit statement is called.
 
I have removed as much lines of code as I could to make a reproducer but more the lines I removed and more the bug does not always occur.
 
So everything in the following script is needed for the bug to happend.
 
-If the GUI is deleted before the Exit statement there is no bug
 
Steps for the reproducer :
-Activate another window
-Click on the button "2"
-Click on the gui close button
 
And the script should be stuck (CPU to 25)

Here it is :

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIScrollBars.au3> ;_GUIScrollBars_ScrollWindow & Constants
#include <WinAPI.au3> ;_WinAPI_SetWindowLong
 
Opt("GUIOnEventMode", 1)
 
Global $__hMs_BtnProc = DllCallbackRegister("__BtnProc", "int", "hwnd;uint;wparam;lparam")
Global $__MSB_pBtnProc = DllCallbackGetPtr($__hMs_BtnProc), $__MSB_pPrevBtnProc = 0
 
Local $hGUI = GUICreate("MyGUI")
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
 
$btn1 = GUICtrlCreateButton("1", 250, 0, 80, 22)
$__MSB_pPrevBtnProc = _WinAPI_SetWindowLong(GUICtrlGetHandle($btn1), $GWL_WNDPROC, $__MSB_pBtnProc)
 
$btn2 = GUICtrlCreateButton("2", 250, 50, 80, 22)
_WinAPI_SetWindowLong(GUICtrlGetHandle($btn2), $GWL_WNDPROC, $__MSB_pBtnProc)
 
$hGUIChild = GUICreate("", 200, 200, 0, 0, $WS_CHILD, -1, $hGUI)
GUISetBkColor(0xFF0000)
 
GUISetState(@SW_SHOWNOACTIVATE, $hGUIChild)
GUISetState(@SW_SHOW, $hGUI)
 
While 1
    Sleep(10)
WEnd
 
Func _Exit()
    ;GUIDelete($hGUI)
    Exit
EndFunc   ;==>_Exit
 
Func __BtnProc($hWnd, $uMsg, $wParam, $lParam)
    Switch $uMsg
        Case $WM_LBUTTONDOWN
            _GUIScrollBars_ScrollWindow($hGUIChild, 0, -20)
    EndSwitch
 
    Return _WinAPI_CallWindowProc($__MSB_pPrevBtnProc, $hWnd, $uMsg, $wParam, $lParam)
EndFunc   ;==>__BtnProc

_

Also, please have a look to >this post. The issue is showed only by dragging a column header which is better for debuging.

Br, FireFox.

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
funkey

Allways free the DLLCallBack.

Func _Exit()
    DllCallbackFree($__hMs_BtnProc)
    Exit
EndFunc   ;==>_Exit

Edit: Sometimes works, sometimes not :(

No idea

Edited by funkey

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites
FireFox

Allways free the DLLCallBack.

I know, but I removed it as it's not a part of the bug.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
FaridAgl

To be honest, I didn't gave it a deep look, and to be more honest, I didn't noticed any bug, but I guess you may like to give it a try as well:

#include <WindowsConstants.au3>

Global $hCallback = DllCallbackRegister("SubclassProc", "LRESULT", "HWND;UINT;WPARAM;LPARAM;UINT_PTR;DWORD_PTR")

GUICreate("Subclassing", 640, 480)

Global $btn1 = GUICtrlCreateButton("Button", 25, 25, 100, 25)
SetWindowSubclass(GUICtrlGetHandle($btn1), $hCallback, $btn1, 0)

Global $btn2 = GUICtrlCreateButton("Button", 25, 75, 100, 25)
SetWindowSubclass(GUICtrlGetHandle($btn2), $hCallback, $btn2, 0)

GUISetState()

Do
Until (GUIGetMsg() = -3)

Func SubclassProc($hWnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData)
    Switch ($uMsg)
        Case $WM_LBUTTONDOWN
            ConsoleWrite("Control id: " & $uIdSubclass & @CRLF)
            ConsoleWrite("Message Id: " & "WM_LBUTTONDOWN" & @CRLF)

        Case $WM_LBUTTONUP
            ConsoleWrite("Control id: " & $uIdSubclass & @CRLF)
            ConsoleWrite("Message Id: " & "WM_LBUTTONUP" & @CRLF)

    EndSwitch

    Return DefSubclassProc($hWnd, $uMsg, $wParam, $lParam)
EndFunc

Func SetWindowSubclass($hWnd, ByRef $pfnSubclass, $uIdSubclass, $dwRefData)
    Return DllCall("comctl32.dll", "BOOL", "SetWindowSubclass", _
            "HWND", $hWnd, _
            "ptr", DllCallbackGetPtr($pfnSubclass), _
            "UINT_PTR", $uIdSubclass, _
            "DWORD_PTR", $dwRefData)[0]
EndFunc

Func DefSubclassProc($hWnd, $uMsg, $wParam, $lParam)
    Return DllCall("comctl32.dll", "LRESULT", "DefSubclassProc", _
            "HWND", $hWnd, _
            "UINT", $uMsg, _
            "WPARAM", $wParam, _
            "LPARAM", $lParam)[0]
EndFunc

Share this post


Link to post
Share on other sites
FireFox

You have changed the code and removed essential lines.

Please have a look to the snipped I linked it's more evocative.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
FireFox

The issue is still there and it's worse, if I click on a button and then I click somewhere else it's like I'm clicking on the button...

I commented out everything in the subclass function and it does not fix anything.

Attached the full script.

My_ScrollBars.au3


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
LarsJ

Try this (for 3.3.10 only):

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <HeaderConstants.au3>
#include <WinAPI.au3>

; The 0-based column to be disabled
Global $iFix_Col
Global $hOld_WndProc
; Get new WndProc hamdle and pointer
Global $hNew_WndProc = DllCallbackRegister("_New_LVHdr_Proc", "lresult", "hwnd;uint;wparam;lparam")
Global $pNew_WndProc = DllCallbackGetPtr($hNew_WndProc)
; To save old WndProc handle
Global $hOld_WndProc

_Main()

Func _Main()
    Local Const $hGUI = GUICreate("ListView Fix Column Width", 400, 300)
    
    Local Const $cListView = GUICtrlCreateListView("Column 0|Column 1|Column 2|Column 3", 10, 10, 380, 220)
    GUICtrlCreateListViewItem("0|1|2|3", $cListView)

    Global $hLVHdr = _GUICtrlListView_GetHeader($cListView)
    
    $cButton = GUICtrlCreateButton("Test", 10, 250, 80, 30)

    GUISetState()

    ; Prevent resizing of column 1
    $iFix_Col = 1

    ; Prevent drag resize
    GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")

    ; SubClass LV Header
    $hOld_WndProc = _WinAPI_SetWindowLong($hLVHdr, $GWL_WNDPROC, $pNew_WndProc)
    ConsoleWrite("Old proc: 0x" & Hex($hOld_WndProc, 8) & @CRLF)

    ; Loop until user exits
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
            Case $cButton
                ConsoleWrite("Pressed" & @CRLF)
        EndSwitch
    WEnd

    GUIDelete($hGUI)
EndFunc   ;==>_Main

Func _WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    ; Get details of message
    Local $tNMHEADER = DllStructCreate($tagNMHEADER, $lParam)
    ; Look for header resize code
    $iCode = DllStructGetData($tNMHEADER, "Code")
    Switch $iCode
        Case $HDN_BEGINTRACKW
            ; Now get column being resized
            Local $iCol = DllStructGetData($tNMHEADER, "Item")
            If $iCol = $iFix_Col Then
                ; Prevent resizing
                Return True
            Else
                ; Allow resizing
                Return False
            EndIf
    EndSwitch

EndFunc

Func _New_LVHdr_Proc($hWnd, $iMsg, $wParam, $lParam)

    Switch $iMsg
        Case $WM_SETCURSOR
            Return TRUE
    EndSwitch

    ; Now call previous WndProc and complete the chain
    ;Return _WinAPI_CallWindowProc($hOld_WndProc, $hWnd, $iMsg, $wParam, $lParam)
    Return CallWindowProc($hOld_WndProc, $hWnd, $iMsg, $wParam, $lParam)

EndFunc   ;==>_No_LVHdr_Resize

Func CallWindowProc($lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam)
  Return DllCall("user32.dll", "lresult", "CallWindowProc", "ptr", $lpPrevWndFunc, "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)[0]
EndFunc
Nice example Melba23.

I have not tested the other example by FireFox. I have tried, but the errors seem to be pretty random, and it makes it hard to draw any conclusions. Maybe I'm not testing properly. FireFox, can you do a test?

Edited by LarsJ

Share this post


Link to post
Share on other sites
FireFox

LarsJ,

The bug seems to be fixed, so it's directly related to the _WinAPI_CallWindowProc function.

If the DllCall result is not directly returned there's the issue, it may come from the variable declaration.

I'll make a track ticket.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.