Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/27/2016 in all areas

  1. Finally we can implement the subclassing functions in a small UDF: Save as Subclassing.au3: #include-once #include <GuiComboBox.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> ; Register message handler callback function Global $pMsgHandler = DllCallbackGetPtr( DllCallbackRegister( "MsgHandler", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) Func SubclassingInit( $hParent, $hCombo ) ; Register message handler based on subclassing _WinAPI_SetWindowSubclass( $hParent, $pMsgHandler, 1000, $hCombo ) ; $iSubclassId = 1000, $pData = $hCombo EndFunc Func SubclassingExit( $hParent ) _WinAPI_RemoveWindowSubclass( $hParent, $pMsgHandler, 1000 ) ; Unregister message handler EndFunc ; Message handler based on subclassing Func MsgHandler( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $hCombo ) ; $pData = $hCombo If $iMsg <> $WM_COMMAND Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] ; Now it's a WM_COMMAND message handler (all other messages are filtered away in the line above) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $hCombo ; $pData = $hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "MsgHandler: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "MsgHandler: $CBN_DBLCLK (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "MsgHandler: $CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "MsgHandler: $CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "MsgHandler: $CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "MsgHandler: $CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "MsgHandler: $CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "MsgHandler: $CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "MsgHandler: $CBN_SELENDOK (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "MsgHandler: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) Return 1 EndSwitch EndSwitch ; Call next function in subclass chain (this forwards WM_COMMAND messages to main GUI (other messages are already forwarded)) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $hWnd, $iMsg, $iSubclassId EndFunc #include <GUIConstantsEx.au3> #include "Subclassing.au3" Global $g_hCombo Example() Func Example() ; Create GUI Local $hGui = GUICreate("(UDF) ComboBox Create", 400, 300) Local $idButton = GUICtrlCreateButton( "Turn subclassing off", 2, 2, 396, 25 ), $bsubclassingEnabled = True GUICtrlSetBkColor( $idButton, 0xCCFFCC ) $g_hCombo = _GUICtrlComboBox_Create($hGui, "", 2, 40, 396, 296) ; Add files _GUICtrlComboBox_BeginUpdate($g_hCombo) _GUICtrlComboBox_AddDir($g_hCombo, "", $DDL_DRIVES, False) _GUICtrlComboBox_EndUpdate($g_hCombo) ; Register message handler based on subclassing SubclassingInit( $hGui, $g_hCombo ) ; Register WM_COMMAND message handler GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Show GUI GUISetState(@SW_SHOW) ; Message loop While 1 Switch GUIGetMsg() Case $idButton If $bsubclassingEnabled Then GUICtrlSetBkColor( $idButton, 0xFFCCCC ) GUICtrlSetData( $idButton, "Turn subclassing on" ) SubclassingExit( $hGui ) ; Unregister message handler Else GUICtrlSetBkColor( $idButton, 0xCCFFCC ) GUICtrlSetData( $idButton, "Turn subclassing off" ) SubclassingInit( $hGui, $g_hCombo ) ; Register message handler EndIf $bsubclassingEnabled = Not $bsubclassingEnabled Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup GUIRegisterMsg($WM_COMMAND, "") ; Unregister WM_COMMAND message handler SubclassingExit( $hGui ) ; Unregister message handler GUIDelete() EndFunc ; WM_COMMAND message handler Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "WM_COMMAND: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "WM_COMMAND: $CBN_DBLCLK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "WM_COMMAND: $CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "WM_COMMAND: $CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "WM_COMMAND: $CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "WM_COMMAND: $CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "WM_COMMAND: $CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "WM_COMMAND: $CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "WM_COMMAND: $CBN_SELENDOK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "WM_COMMAND: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg EndFunc
    3 points
  2. Now we can try to implement both methods in the same script: #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> Global $g_hCombo Example() Func Example() ; Create GUI Local $hGui = GUICreate("(UDF) ComboBox Create", 400, 300) $g_hCombo = _GUICtrlComboBox_Create($hGui, "", 2, 2, 396, 296) ; Add files _GUICtrlComboBox_BeginUpdate($g_hCombo) _GUICtrlComboBox_AddDir($g_hCombo, "", $DDL_DRIVES, False) _GUICtrlComboBox_EndUpdate($g_hCombo) ; Register message handler based on subclassing Local $pMsgHandler = DllCallbackGetPtr( DllCallbackRegister( "MsgHandler", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) _WinAPI_SetWindowSubclass( $hGui, $pMsgHandler, 1000, 0 ) ; $iSubclassId = 1000, $pData = 0 ; Register WM_COMMAND message handler GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Show GUI GUISetState(@SW_SHOW) ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup GUIRegisterMsg($WM_COMMAND, "") ; Unregister WM_COMMAND message handler _WinAPI_RemoveWindowSubclass( $hGui, $pMsgHandler, 1000 ) ; Unregister message handler GUIDelete() EndFunc ; Message handler based on subclassing Func MsgHandler( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) If $iMsg <> $WM_COMMAND Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] ; Now it's a WM_COMMAND message handler (all other messages are filtered away in the line above) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "MsgHandler: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "MsgHandler: $CBN_DBLCLK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "MsgHandler: $CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "MsgHandler: $CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "MsgHandler: $CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "MsgHandler: $CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "MsgHandler: $CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "MsgHandler: $CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "MsgHandler: $CBN_SELENDOK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "MsgHandler: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value EndSwitch EndSwitch ; Call next function in subclass chain (this forwards WM_COMMAND messages to main GUI (other messages are already forwarded)) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $hWnd, $iMsg, $iSubclassId, $pData EndFunc ; WM_COMMAND message handler Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "WM_COMMAND: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "WM_COMMAND: $CBN_DBLCLK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "WM_COMMAND: $CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "WM_COMMAND: $CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "WM_COMMAND: $CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "WM_COMMAND: $CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "WM_COMMAND: $CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "WM_COMMAND: $CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "WM_COMMAND: $CBN_SELENDOK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "WM_COMMAND: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg EndFunc And we can add a button to turn subclassing on/off on the fly: #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> Global $g_hCombo Example() Func Example() ; Create GUI Local $hGui = GUICreate("(UDF) ComboBox Create", 400, 300) Local $idButton = GUICtrlCreateButton( "Turn subclassing off", 2, 2, 396, 25 ), $bsubclassingEnabled = True GUICtrlSetBkColor( $idButton, 0xCCFFCC ) $g_hCombo = _GUICtrlComboBox_Create($hGui, "", 2, 40, 396, 296) ; Add files _GUICtrlComboBox_BeginUpdate($g_hCombo) _GUICtrlComboBox_AddDir($g_hCombo, "", $DDL_DRIVES, False) _GUICtrlComboBox_EndUpdate($g_hCombo) ; Register message handler based on subclassing Local $pMsgHandler = DllCallbackGetPtr( DllCallbackRegister( "MsgHandler", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) _WinAPI_SetWindowSubclass( $hGui, $pMsgHandler, 1000, 0 ) ; $iSubclassId = 1000, $pData = 0 ; Register WM_COMMAND message handler GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Show GUI GUISetState(@SW_SHOW) ; Message loop While 1 Switch GUIGetMsg() Case $idButton If $bsubclassingEnabled Then GUICtrlSetBkColor( $idButton, 0xFFCCCC ) GUICtrlSetData( $idButton, "Turn subclassing on" ) _WinAPI_RemoveWindowSubclass( $hGui, $pMsgHandler, 1000 ) ; Unregister message handler Else GUICtrlSetBkColor( $idButton, 0xCCFFCC ) GUICtrlSetData( $idButton, "Turn subclassing off" ) _WinAPI_SetWindowSubclass( $hGui, $pMsgHandler, 1000, 0 ) ; $iSubclassId = 1000, $pData = 0 EndIf $bsubclassingEnabled = Not $bsubclassingEnabled Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup GUIRegisterMsg($WM_COMMAND, "") ; Unregister WM_COMMAND message handler _WinAPI_RemoveWindowSubclass( $hGui, $pMsgHandler, 1000 ) ; Unregister message handler GUIDelete() EndFunc ; Message handler based on subclassing Func MsgHandler( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) If $iMsg <> $WM_COMMAND Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] ; Now it's a WM_COMMAND message handler (all other messages are filtered away in the line above) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "MsgHandler: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "MsgHandler: $CBN_DBLCLK (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "MsgHandler: $CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "MsgHandler: $CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "MsgHandler: $CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "MsgHandler: $CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "MsgHandler: $CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "MsgHandler: $CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "MsgHandler: $CBN_SELENDOK (" & $iCount & ")" & @CRLF ) Return 1 Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "MsgHandler: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) Return 1 EndSwitch EndSwitch ; Call next function in subclass chain (this forwards WM_COMMAND messages to main GUI (other messages are already forwarded)) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $hWnd, $iMsg, $iSubclassId, $pData EndFunc ; WM_COMMAND message handler Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "WM_COMMAND: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "WM_COMMAND: $CBN_DBLCLK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "WM_COMMAND: $CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "WM_COMMAND: $CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "WM_COMMAND: $CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "WM_COMMAND: $CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "WM_COMMAND: $CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "WM_COMMAND: $CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "WM_COMMAND: $CBN_SELENDOK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "WM_COMMAND: $CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg EndFunc Note that I've replaced "; no return value" with "Return 1" in MsgHandler function.
    3 points
  3. kcvinu, I'll answer your 2nd doubt (post 21) first. The four points you have listet, is the technique used for the old approach based on SetWindowLong function. Subclassing based on the new function SetWindowSubclass is much easier. You more or less use the same technique as you use to create a message handler with GUIRegisterMsg. This is a slightly modified version of the example for _GUICtrlComboBox_Create in the help file: #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $g_hCombo Example() Func Example() ; Create GUI Local $hGui = GUICreate("(UDF) ComboBox Create", 400, 300) $g_hCombo = _GUICtrlComboBox_Create($hGui, "", 2, 2, 396, 296) ; Add files _GUICtrlComboBox_BeginUpdate($g_hCombo) _GUICtrlComboBox_AddDir($g_hCombo, "", $DDL_DRIVES, False) _GUICtrlComboBox_EndUpdate($g_hCombo) ; Register WM_COMMAND message handler GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; Show GUI GUISetState(@SW_SHOW) ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup GUIRegisterMsg($WM_COMMAND, "") ; Unregister WM_COMMAND message handler GUIDelete() EndFunc ; WM_COMMAND message handler Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "$CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "$CBN_DBLCLK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "$CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "$CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "$CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "$CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "$CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "$CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "$CBN_SELENDOK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "$CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg EndFunc And this is the same WM_COMMAND message handler implemented through SetWindowSubclass: #include <GuiComboBox.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIShellEx.au3> Global $g_hCombo Example() Func Example() ; Create GUI Local $hGui = GUICreate("(UDF) ComboBox Create", 400, 300) $g_hCombo = _GUICtrlComboBox_Create($hGui, "", 2, 2, 396, 296) ; Add files _GUICtrlComboBox_BeginUpdate($g_hCombo) _GUICtrlComboBox_AddDir($g_hCombo, "", $DDL_DRIVES, False) _GUICtrlComboBox_EndUpdate($g_hCombo) ; Register message handler based on subclassing Local $pMsgHandler = DllCallbackGetPtr( DllCallbackRegister( "MsgHandler", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) _WinAPI_SetWindowSubclass( $hGui, $pMsgHandler, 1000, 0 ) ; $iSubclassId = 1000, $pData = 0 ; Show GUI GUISetState(@SW_SHOW) ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup _WinAPI_RemoveWindowSubclass( $hGui, $pMsgHandler, 1000 ) ; Unregister message handler GUIDelete() EndFunc ; Message handler based on subclassing Func MsgHandler( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData ) If $iMsg <> $WM_COMMAND Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] ; Now it's a WM_COMMAND message handler (all other messages are filtered away in the line above) Local static $iCount = 0 Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; Hi Word $iCount += 1 Switch $hWndFrom Case $g_hCombo Switch $iCode Case $CBN_CLOSEUP ; Sent when the list box of a combo box has been closed ConsoleWrite( "$CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DBLCLK ; Sent when the user double-clicks a string in the list box of a combo box ConsoleWrite( "$CBN_DBLCLK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_DROPDOWN ; Sent when the list box of a combo box is about to be made visible ConsoleWrite( "$CBN_DROPDOWN (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITCHANGE ; Sent after the user has taken an action that may have altered the text in the edit control portion of a combo box ConsoleWrite( "$CBN_EDITCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_EDITUPDATE ; Sent when the edit control portion of a combo box is about to display altered text ConsoleWrite( "$CBN_EDITUPDATE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_KILLFOCUS ; Sent when a combo box loses the keyboard focus ConsoleWrite( "$CBN_KILLFOCUS (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELCHANGE ; Sent when the user changes the current selection in the list box of a combo box ConsoleWrite( "$CBN_SELCHANGE (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDCANCEL ; Sent when the user selects an item, but then selects another control or closes the dialog box ConsoleWrite( "$CBN_SELENDCANCEL (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SELENDOK ; Sent when the user selects a list item, or selects an item and then closes the list ConsoleWrite( "$CBN_SELENDOK (" & $iCount & ")" & @CRLF ) ; no return value Case $CBN_SETFOCUS ; Sent when a combo box receives the keyboard focus ConsoleWrite( "$CBN_CLOSEUP (" & $iCount & ")" & @CRLF ) ; no return value EndSwitch EndSwitch ; Call next function in subclass chain (this forwards WM_COMMAND messages to main GUI (other messages are already forwarded)) Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0] #forceref $hWnd, $iMsg, $iSubclassId, $pData EndFunc Note that the entire GUI is subclassed. Enter some text in the edit box to generate a lot of WM_COMMAND messages. Note also that the two code sections are almost identical. These lines ; Register message handler based on subclassing Local $pMsgHandler = DllCallbackGetPtr( DllCallbackRegister( "MsgHandler", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) ) _WinAPI_SetWindowSubclass( $hGui, $pMsgHandler, 1000, 0 ) ; $iSubclassId = 1000, $pData = 0 replaces these lines: ; Register WM_COMMAND message handler GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") This line _WinAPI_RemoveWindowSubclass( $hGui, $pMsgHandler, 1000 ) ; Unregister message handler replaces this line: GUIRegisterMsg($WM_COMMAND, "") ; Unregister WM_COMMAND message handler The two message handler functions are more or less identical. In this simple case the message handler based on GUIRegisterMsg is much much better than the message handler based on SetWindowSubclass. Why is the first implementation so much better? This is important to know. Schematically the message flow looks like this in the two situations. GUIRegisterMsg to the left and subclassing to the right:
    3 points
  4. Melba23

    compile for .exe

    rodiney, It is probably advantageous to combine all the functions into a single script file. You could use the interpreter within a single compiled file to run the other scripts, but there could well be a significant performance penalty were you to do so - even if you were to compile the other scripts to .a3x format. M23
    1 point
  5. alexs-9999

    loading file on RDP

    I had sex sorry what that I gone
    1 point
  6. Melba23

    GUICtrl RichEdit

    rodiney, Just apply the "ReadOnly" style when you create the RichEdit control - look in the help file on the _GUICtrlRichEdit_Create page to see how to do it. M23
    1 point
  7. mLipok

    Can't get span ID from IE

    Welcome to the forum. Please post URL to the site or if you can't try to inspect that item but put here some wider part of HTML snippet. btw. Use code tags I mean <> icon on forum editor toolbar.
    1 point
  8. AutoBert

    GUICtrl RichEdit

    Please post your script or a small runable reproducer.
    1 point
  9. Yes, You can create a single callback function for a group of checkboxes. And then you can use the control handle to separate messages from different controls, if you need that. This is exactly the same as you would do in a message handler created with GUIRegisterMsg. Notifications from a checkbox are send as WM_COMMAND messages. Now we have a checkbox, a combobox and an edit control which all sends notifications as WM_COMMAND messages. With GUIRegisterMsg you can only create one big function to handle all these WM_COMMAND messages. It's all mixed together in one big hotchpotch, if one can put it like that. With subclassing you can create three small functions which all can handle WM_COMMAND messages. A small function to handle WM_COMMAND messages from the checkbox or a group of checkboxes. A small function to handle WM_COMMAND messages from the combobox or a group of comboboxes. And a small function to handle WM_COMMAND messages from the edit control or a group of edit controls. This is one of the major advantages of subclassing.
    1 point
  10. This is a few comments to the code in post 19. I added this code based on SetWindowSubclass as an alternative to the GUIRegisterMsg function which was proposed as a solution in one of the previous posts. As you probably already know, there are several issues related to GUIRegisterMsg: A message handler created with GUIRegisterMsg is a very global message handler. All WM_COMMAND messages in the entire GUI will result in a call of the WM_COMMAND function. If you add an edit control (which generates WM_COMMAND messages) to the GUI and updates the text, the WM_COMMAND function will be called. Although only the first 4-5 lines of the function is executed because the control handle doesn't fit, it can still easily lead to performance issues. GUIRegisterMsg can only register one message handler at a time for the same message type. If you have a GUI that contains a combo box and an edit control, it would be nice to be able to define a WM_COMMAND message handler for each of the controls. Because you can only define one WM_COMMAND message handler, you need to add control structures to the WM_COMMAND function to separate messages from the controls. You end up with a message handler, that contains really many code lines. Especially because you can only register one GUIRegisterMsg message handler at a time for the same message type, it's often difficult to use message handlers in UDFs. This seems to restrict the creation of UDFs a little bit. SetWindowSubclass and the associated funtions GetWindowSubclass, RemoveWindowSubclass and DefSubclassProc (all coded in WinAPIShellEx.au3) is an effective solution to all of these issues. That's just a matter of using the functions properly. The benefits of using subclassing instead of a GUIRegisterMsg created message handler are: If you create the combo box in a child window as is done in the example and subclass the child window, you can effectively limit the message handling to include messages from the combo box only. You can easily create another callback function (message handler) to handle WM_COMMAND messages from eg. an edit control. You can even create different callback functions for different combo boxes. Depending on the return value in the callback function, you can decide whether the WM_COMMAND notification is forwarded to another message handler. In the example the return value is 1 for all WM_COMMAND notifications, which prevents the notifications from being forwarded. It's easy to implement a message handler based on subclassing in a UDF. The user can create her own message handler with GUIRegisterMsg completely as usual. The function SetWindowLong should not be used for subclassing. MicroSoft themselves have documented the reasons. I'll come back with an answer to your questions in post 21.
    1 point
  11. Hello, great work. I ran into a problem while using this UDF Here is the Code.... $Connection = _Start_Connection(@ScriptDir & "\Test.accdb;") $InsertData = _Insert_Data("INSERT INTO Table1([Col1], [Col2], [Col3]) VALUES ('AutoIt', 'Coding is Fun', 'AutoIt Rocks');") $GetData = _Get_Records("SELECT [Col1],[Col2] FROM Table1 WHERE Col3 = 'AutoIt Stone' ;") msgbox(0,'',ubound($GetData)) $GetData = _Get_Records("SELECT [Col1],[Col2] FROM Table1 WHERE Col3 = 'AutoIt Rocks' ;") msgbox(0,'',ubound($GetData)) _Close_Connection() Basically I want to modify the Where clause to accept other conditions but I got an error the second time I ran _Get_Records(). Error message "ADODB COM Error err.description is: Operation is not allowed when the ojbect is open." How do I close the object when _Get_Records() returns nothing? Anybody know how to fix this without using _Close_Connection() and _Start_Connection() again....
    1 point
×
×
  • Create New...