FaridAgl Posted September 18, 2012 Posted September 18, 2012 (edited) Firstly, here is the Subclass functions:Then, what I have done so far:#include "Subclass.au3" GUICreate('Subclass Test', 450, 200) GUICtrlCreateButton('Default', 10, 10, 100, 25) $TextBox = GUICtrlCreateInput('Hello world!', 10, 45, 250, 20) GUISetState() $hHandle = DllCallbackRegister('MY_SUBCLASSPROC', 'LRESULT', 'HWND;UINT;WPARAM;LPARAM;UINT_PTR;DWORD_PTR') If ($hHandle == 0) Then MsgBox(16, 'Subclass Test', 'Call to DllCallbackRegister failed.') Exit EndIf SetWindowSubclass(GUICtrlGetHandle($TextBox), DllCallbackGetPtr($hHandle), 0, 0) If (@error) Then MsgBox(16, 'Subclass Test', 'Call to SetWindowSubclass failed.') Exit EndIf While (True) Switch (GUIGetMsg()) Case -3 ;GUI_EVENT_CLOSE OnExit() EndSwitch WEnd Func MY_SUBCLASSPROC($hWnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData) ConsoleWrite($uMsg & @CRLF) DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) EndFunc Func OnExit() RemoveWindowSubclass(GUICtrlGetHandle($TextBox), DllCallbackGetPtr($hHandle), 0, 0) ;This must be called. If not, the scipt will remain running in taskbar, eating 1 cpu core. Exit EndFuncLooks like it's working but there are some problems, for example the Input control ($TextBox) gets freezed, however SUBCLASSPROC function gets the notifications of the control (Look at the console).I'm pretty sure I did all good, let me know if there is any problem in the code, maybe something that I forget to take care about.If we success in feaguring out the problem, we can write a GUICtrlRegisterMsg() function easily.Thanks in advance.Edit: Take a look over this article if you are interested to know what is it all about. Edited September 18, 2012 by D4RKON3 http://faridaghili.ir
FaridAgl Posted September 18, 2012 Author Posted September 18, 2012 (edited) After spenting some time on it, I have found another way to Subclassing a Window or Control.Here is the code:expandcollapse popupGUICreate('Subclass Test', 450, 200) $TextBox = GUICtrlCreateInput('Hello world!', 10, 10, 250, 20) GUISetState() $hHandle = DllCallbackRegister('MY_SUBCLASSPROC', 'LRESULT', 'HWND;UINT;WPARAM;LPARAM') If ($hHandle == 0) Then MsgBox(16, 'Subclass Test', 'Call to DllCallbackRegister failed.') Exit EndIf SetWindowLong(GUICtrlGetHandle($TextBox), -4, DllCallbackGetPtr($hHandle)) ;GWL_WNDPROC = -4 If (@error) Then MsgBox(16, 'Subclass Test', 'Call to SetWindowLong failed.') Exit EndIf While (True) Switch (GUIGetMsg()) Case -3 ;GUI_EVENT_CLOSE ;~ Exit ;Calling Exit won't close script, it will remain running in taskbar, eating 1 cpu core. ProcessClose(@AutoItPID) ;Just a way around EndSwitch WEnd Func MY_SUBCLASSPROC($hWnd, $uMsg, $wParam, $lParam) ConsoleWrite($uMsg & @CRLF) EndFunc Func SetWindowLong($hWnd, $nIndex, $dwNewLong) Local $lResult = DllCall('User32.dll', 'long', 'SetWindowLong', _ 'HWND', $hWnd, _ 'int', $nIndex, _ 'long', $dwNewLong) If (@error) Or ($lResult[0] == 0) Then Return SetError(1, 0, 0) Return SetError(0, 0, 1) EndFuncUnfortunately it has the same exact problem as SetWindowSubclass. Notifications of the control are sent to SUBCLASSPROC function but the control gets freezed!After some search on the forum I found this:I didn't read the whole thread, but in post #5, Yashied sayd: "No, DllCallbackRegister() kill the script.".I guess it's the problem here too.Edit: Reading post #12! Edited September 18, 2012 by D4RKON3 http://faridaghili.ir
PhoenixXL Posted September 18, 2012 Posted September 18, 2012 (edited) if you will block the code nothing gonna work#include <WinAPI.au3> ; Register callback function and obtain handle to _New_WndProc Global $___hNew_WndProc = DllCallbackRegister("_New_WndProc", "int", "hwnd;uint;wparam;lparam") ; Get pointer to _New_WndProc Global $___pNew_WndProc = DllCallbackGetPtr($___hNew_WndProc) GUICreate('Testing - Phoenix XL') Global $cEdit=GUICtrlCreateEdit('',10,10,100,100) Global $pOld_WndProc=_Edit_SubClass(GUICtrlGetHandle(-1),$___pNew_WndProc) GUISetState() Func _New_WndProc($hWnd, $iMsg, $wParam, $lParam) ; Get the Messages ConsoleWrite('Msg:'&$iMsg&@CR) ; Pass to the Original Window Procedure. Return _WinAPI_CallWindowProc($pOld_WndProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_New_WndProc Func _Edit_SubClass($hWnd, $pNew_WindowProc) Local $iRes = _WinAPI_SetWindowLong($hWnd, -4, $pNew_WindowProc) If @error Then Return SetError(1, 0, 0) If $iRes = 0 Then Return SetError(1, 0, 0) Return SetError(0, 0, $iRes) EndFunc ;==>_Edit_SubClass While GUIGetMsg()<>-3 Sleep(10) WEnd ; UnSubClass _Edit_SubClass(GUICtrlGetHandle($cEdit),$pOld_WndProc) ; Now free UDF created WndProc DllCallbackFree($___hNew_WndProc) ExitHope so this helpsEDIT: For better understanding have a look at my it uses the same concepts Edited September 18, 2012 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
FaridAgl Posted September 18, 2012 Author Posted September 18, 2012 (edited) Thank you, but did you noticed that the ConsoleWrite($uMsg & @CRLF) in the MY_SUBCLASSPROC function doesn't do anything, maybe MY_SUBCLASSPROC doesn't even get called!nvm, change:Global $pNewWndProc = DllCallbackRegister('_New_WndProc', 'int', 'HWND;UINT;WPARAM;LPARAM')ToDllCallbackRegister('MY_SUBCLASSPROC', 'int', 'HWND;UINT;WPARAM;LPARAM') Edited September 18, 2012 by D4RKON3 http://faridaghili.ir
FaridAgl Posted September 18, 2012 Author Posted September 18, 2012 But this: #include #include GUICreate('Subclass Test', 450, 200) $TextBox = GUICtrlCreateInput('Hello world!', 10, 10, 250, 20) Global $pNewWndProc = DllCallbackRegister('MY_SUBCLASSPROC', 'int', 'HWND;UINT;WPARAM;LPARAM') Global $pOldWndProc = _WinAPI_SetWindowLong(GUICtrlGetHandle(-1), -4, DllCallbackGetPtr($pNewWndProc)) GUISetState() While True Switch GUIGetMsg() Case -3 ;GUI_EVENT_CLOSE _WinAPI_SetWindowLong(GUICtrlGetHandle($TextBox), -4, $pOldWndProc) Exit EndSwitch WEnd Func MY_SUBCLASSPROC($hWnd, $uMsg, $wParam, $lParam) If $uMsg = $EN_CHANGE Then ConsoleWrite('***') Return _WinAPI_CallWindowProc($pOldWndProc, $hWnd, $uMsg, $wParam, $lParam) EndFunc Still doesn't work. Maybe I missed the point. http://faridaghili.ir
PhoenixXL Posted September 18, 2012 Posted September 18, 2012 (edited) looking as if you are beggining into Subclassing Bro, EN_CHANGE is a notification code and is posted to Window through WM_COMMAND message and not to the Window Procedure All the Best Edited September 18, 2012 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
PhoenixXL Posted September 18, 2012 Posted September 18, 2012 (edited) Hope this helps#include <WinAPI.au3> GUICreate('Testing - Phoenix XL') GUICtrlCreateEdit('',10,10,100,100) Global $cEdit=GUICtrlGetHandle(-1) GUIRegisterMsg(0x0111,'WM_COMMAND') GUISetState() Func WM_COMMAND($hWnd,$iMsg,$wParam,$lParam) Local $NotificationCode=_WinAPI_HiWord($wParam) Switch $lParam Case $cEdit Switch $NotificationCode Case 0x300 ;$EN_CHANGE ConsoleWrite('EN_CHANGE Encountered'&@CR) EndSwitch EndSwitch Return 'GUI_RUNDEFMSG' EndFunc While GUIGetMsg()<>-3 Sleep(10) WEnd Edited September 18, 2012 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
FaridAgl Posted September 18, 2012 Author Posted September 18, 2012 OK then, thank you again. May I ask about a list of $Msg(s) that can be catch by Subclassing? http://faridaghili.ir
PhoenixXL Posted September 18, 2012 Posted September 18, 2012 (edited) All the Windows Message Codes are posted to the Window ProcedureLike WM_CHAR, WM_ACTIVATE, WM_KILLFOCUS, WM_#Have a look at Windows Message Codes [Appendix]in the Help fileBr,Phoenix XL Edited September 18, 2012 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
PhoenixXL Posted September 18, 2012 Posted September 18, 2012 A simple example #include ; Register callback function and obtain handle to _New_WndProc Global $___hNew_WndProc = DllCallbackRegister("_New_WndProc", "int", "hwnd;uint;wparam;lparam") ; Get pointer to _New_WndProc Global $___pNew_WndProc = DllCallbackGetPtr($___hNew_WndProc) Global $hWnd_=GUICreate('Testing - Phoenix XL') GUICtrlCreateEdit('',10,10,100,100) Global $pOld_WndProc=_Edit_SubClass($hWnd_,$___pNew_WndProc) GUISetState() Func _New_WndProc($hWnd, $iMsg, $wParam, $lParam) ; Get the Messages ;0x0006 ==> WM_ACTIVATE if $iMsg=0x0006 Then ConsoleWrite('WM_ACTIVATE Encountered :)'&@CR) ; Pass to the Original Window Procedure. Return _WinAPI_CallWindowProc($pOld_WndProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>_New_WndProc Func _Edit_SubClass($hWnd, $pNew_WindowProc) Local $iRes = _WinAPI_SetWindowLong($hWnd, -4, $pNew_WindowProc) If @error Then Return SetError(1, 0, 0) If $iRes = 0 Then Return SetError(1, 0, 0) Return SetError(0, 0, $iRes) EndFunc ;==>_Edit_SubClass While GUIGetMsg()<>-3 Sleep(10) WEnd ; UnSubClass _Edit_SubClass($hWnd_,$pOld_WndProc) ; Now free UDF created WndProc DllCallbackFree($___hNew_WndProc) Exit Here we subclassed the GUI because WM_ACTIVATE is posted to the GUI and not to the Control(s) Feel free to ask if you have any Doubts My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
FaridAgl Posted September 18, 2012 Author Posted September 18, 2012 (edited) Good job, point taken. Thanks for the time you spent. BTW, any idea about why Subclass functions in the first post doesn't work? Edit: Subclassing only work for the window(s) that are created by the process that is calling SetWindowLong, am I right? Edited September 18, 2012 by D4RKON3 http://faridaghili.ir
PhoenixXL Posted September 19, 2012 Posted September 19, 2012 BTW, any idea about why Subclass functions in the first post doesn't work?yup, You have to return the Value of the Procedure orelse it wont work. This should work expandcollapse popupGUICreate('Subclass Test - Phoenix XL', 450, 200) GUICtrlCreateInput('Hello world!', 10, 45, 250, 20) $TextBox = GUICtrlGetHandle(-1) GUISetState() $hHandle = DllCallbackGetPtr(DllCallbackRegister('MY_SUBCLASSPROC', 'LRESULT', 'HWND;UINT;WPARAM;LPARAM;UINT_PTR;DWORD_PTR')) If ($hHandle == 0) Then MsgBox(16, 'Subclass Test', 'Call to DllCallbackRegister failed.') Exit EndIf SetWindowSubclass($TextBox, $hHandle, 0, 0) If (@error) Then MsgBox(16, 'Subclass Test', 'Call to SetWindowSubclass failed.') Exit EndIf While (True) Switch (GUIGetMsg()) Case -3 ;GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd RemoveWindowSubclass($TextBox, $hHandle, 0, 0) Exit Func MY_SUBCLASSPROC($hWnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData) ConsoleWrite($uMsg & @CRLF) Return DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) EndFunc Func SetWindowSubclass($hWnd, $pfnSubclass, $uIdSubclass, $dwRefData) Local $bResult = DllCall('Comctl32.dll', 'BOOL', 'SetWindowSubclass', _ 'HWND', $hWnd, _ 'ptr', $pfnSubclass, _ 'UINT_PTR', $uIdSubclass, _ 'DWORD_PTR', $dwRefData) If (@error) Or ($bResult[0] == 0) Then Return SetError(1, 0, 0) Return SetError(0, 0, 1) EndFunc Func GetWindowSubclass($hWnd, $pfnSubclass, $uIdSubclass, ByRef $dwRefData) Local $bResult = DllCall('Comctl32.dll', 'BOOL', 'GetWindowSubclass', _ 'HWND', $hWnd, _ 'ptr', $pfnSubclass, _ 'UINT_PTR', $uIdSubclass, _ 'DWORD_PTR*', 0) If (@error) Or ($bResult[0] == 0) Then Return SetError(1, 0, 0) $dwRefData = $bResult[4] Return SetError(0, 0, 1) EndFunc Func RemoveWindowSubclass($hWnd, $pfnSubclass, $uIdSubclass, $dwRefData) Local $bResult = DllCall('Comctl32.dll', 'BOOL', 'RemoveWindowSubclass', _ 'HWND', $hWnd, _ 'ptr', $pfnSubclass, _ 'UINT_PTR', $uIdSubclass) If (@error) Or ($bResult[0] == 0) Then Return SetError(1, 0, 0) Return SetError(0, 0, 1) EndFunc Func DefSubclassProc($hWnd, $uMsg, $wParam, $lParam) Local $aRet=DllCall('Comctl32.dll', 'LRESULT', 'DefSubclassProc', _ 'HWND', $hWnd, _ 'UINT', $uMsg, _ 'WPARAM', $wParam, _ 'LPARAM', $lParam) Return $aRet[0] EndFunc FaridAgl 1 My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
FaridAgl Posted September 19, 2012 Author Posted September 19, 2012 Absolutely true, thank you so much. http://faridaghili.ir
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