FireFox Posted February 19, 2014 Share Posted February 19, 2014 (edited) 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 : expandcollapse popup#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 February 19, 2014 by FireFox Link to comment Share on other sites More sharing options...
funkey Posted February 19, 2014 Share Posted February 19, 2014 (edited) Allways free the DLLCallBack. Func _Exit() DllCallbackFree($__hMs_BtnProc) Exit EndFunc ;==>_Exit Edit: Sometimes works, sometimes not No idea Edited February 19, 2014 by funkey Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
FireFox Posted February 19, 2014 Author Share Posted February 19, 2014 Allways free the DLLCallBack. I know, but I removed it as it's not a part of the bug. Link to comment Share on other sites More sharing options...
FaridAgl Posted February 19, 2014 Share Posted February 19, 2014 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: expandcollapse popup#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 http://faridaghili.ir Link to comment Share on other sites More sharing options...
FireFox Posted February 20, 2014 Author Share Posted February 20, 2014 You have changed the code and removed essential lines. Please have a look to the snipped I linked it's more evocative. Link to comment Share on other sites More sharing options...
FaridAgl Posted February 20, 2014 Share Posted February 20, 2014 Well, it wasn't about the code, I was showing you a better way of subclassing controls. Try to use it for subclassing and see if your problem got solved or not. http://msdn.microsoft.com/en-us/library/windows/desktop/bb773183(v=vs.85).aspx#subclassing_v6 http://faridaghili.ir Link to comment Share on other sites More sharing options...
FireFox Posted February 20, 2014 Author Share Posted February 20, 2014 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 Link to comment Share on other sites More sharing options...
LarsJ Posted March 7, 2014 Share Posted March 7, 2014 (edited) Try this (for 3.3.10 only):expandcollapse popup#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] EndFuncNice 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 March 7, 2014 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
FireFox Posted March 8, 2014 Author Share Posted March 8, 2014 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. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now