Sign in to follow this  
Followers 0
Artisan

Input control and WM_COMMAND [SOLVED]

4 posts in this topic

#1 ·  Posted (edited)

Hi all,

I've been studying WM_NOTIFY and WM_COMMAND for a hobby project I'm working on. At this point, I'm trying to capture the WM_COMMAND event that happens when the focus is on the Input control and the user presses the ENTER key. I know I could do this via _IsPressed(), but I'd really rather do everything from within WM_COMMAND and WM_NOTIFY. It just seems like better coding practice. Anyway, this is probably simpler than I think it is, but I'm really stuck.

I made a script that outputs WM_NOTIFY and WM_COMMAND events to the console as they happen. Here's my problem. When I press ENTER while the focus is on the Input control, this is the output I get:

==========================================================
Event: WM_COMMAND (unknown)
$hWnd: 0x00050408
$iMsg: 273 $WM_COMMAND: 273
$iwParam: 0x00000001 $iIDFrom: 1 $iCode: 0
$ilParam: 0x00000000
11:45:42:740
==========================================================

It looks like a command is coming from nowhere ($ilParam = 0) and doing nothing. Can anyone help me understand this? I've been all over the AutoIt Forums and MSDN and I'm still not understanding. I was expecting to see a key code for the ENTER key somewhere, or some kind of message like $WM_INPUT_CONFIRM or something.

Here's the script I wrote to get the output:

Global Const $tagNMHDR = "struct;hwnd hWndFrom;uint_ptr IDFrom;INT Code;endstruct", _
$WM_COMMAND = 0x0111, _
$WM_NOTIFY = 0x004E, _
$GUI_EVENT_CLOSE = -3, _
$GUI_RUNDEFMSG = 'GUI_RUNDEFMSG'

Global $gui = GUICreate("ComboBox Listener", 300, 300)
Global $combo = GUICtrlCreateCombo("", 10, 10)
GUICtrlSetData(-1, "Item 1|Item 2|Item 3|Item 4|Item 5|Item 6")
Global $input = GUICtrlCreateInput("", 10, 100)
Global $button = GUICtrlCreateButton("Test", 10, 200)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

Do
Until GUIGetMsg() == $GUI_EVENT_CLOSE

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR
$tNMHDR = DllStructCreate($tagNMHDR, $lParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")

Switch $hWndFrom
Case GUICtrlGetHandle($combo)
WM_Output("WM_NOTIFY", $iCode, "Combo")
Case GUICtrlGetHandle($input)
WM_Output("WM_NOTIFY", $iCode, "Input")
Case GUICtrlGetHandle($button)
WM_Output("WM_NOTIFY", $iCode, "Button")
Case $gui
WM_Output("WM_NOTIFY", $iCode, "GUI")
Case Else
WM_Output("WM_NOTIFY", $iCode, $hWndFrom)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg
Local $hWndFrom, $iIDFrom, $iCode
$hWndFrom = $ilParam
$iIDFrom = BitAND($iwParam, 0xFFFF)
$iCode = BitShift($iwParam, 16)
Switch $hWndFrom
Case GUICtrlGetHandle($combo)
WM_Output("WM_COMMAND", $iCode, "Combo")
Case GUICtrlGetHandle($input)
WM_Output("WM_COMMAND", $iCode, "Input")
Case GUICtrlGetHandle($button)
WM_Output("WM_COMMAND", $iCode, "Button")
Case $gui
WM_Output("WM_COMMAND", $iCode, "GUI")
Case Else
ConsoleWrite("==========================================================" & @LF)
ConsoleWrite("Event: WM_COMMAND (unknown)" & @LF)
ConsoleWrite("$hWnd: " & $hWnd & @LF)
ConsoleWrite("$iMsg: " & $iMsg & @TAB & "$WM_COMMAND: " & $WM_COMMAND & @LF)
ConsoleWrite("$iwParam: " & $iwParam & @TAB & "$iIDFrom: " & $iIDFrom & @TAB & "$iCode: " & $iCode & @LF)
ConsoleWrite("$ilParam: " & $ilParam & @LF)
ConsoleWrite(@HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @LF)
ConsoleWrite("==========================================================" & @LF & @LF)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc

Func WM_Output( $Event, $iCode, $Control )
ConsoleWrite("==========================================================" & @LF)
ConsoleWrite("Event: " & $Event & @LF)
ConsoleWrite("$iCode: " & $iCode & @LF)
ConsoleWrite("Control: " & $Control & @LF)
ConsoleWrite(@HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @LF)
ConsoleWrite("==========================================================" & @LF & @LF)
EndFunc
Edited by Artisan

Share this post


Link to post
Share on other sites



You can use it just like this:

$GUI_EVENT_CLOSE = -3

Global $gui = GUICreate("ComboBox Listener", 300, 300)
Global $combo = GUICtrlCreateCombo("", 10, 10)
GUICtrlSetData(-1, "Item 1|Item 2|Item 3|Item 4|Item 5|Item 6")
Global $input = GUICtrlCreateInput("", 10, 100)
Global $button = GUICtrlCreateButton("Test", 10, 200)
GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    If $msg = $input Then ConsoleWrite('Event from input control, value: ' & GUICtrlRead($input) & @CRLF)
WEnd

But this event is fired also when you change focus from input control to other control (and only when Enter is pressed on focused input control).

1 person likes this

Share this post


Link to post
Share on other sites

You may look here at example of WM_COMMAND for input control

Thanks. I've already got a decent handle on WM_COMMAND, so this wasn't quite what I was looking for. (I just wanted to know when the user finished inputting.)

You can use it just like this:

$GUI_EVENT_CLOSE = -3

Global $gui = GUICreate("ComboBox Listener", 300, 300)
Global $combo = GUICtrlCreateCombo("", 10, 10)
GUICtrlSetData(-1, "Item 1|Item 2|Item 3|Item 4|Item 5|Item 6")
Global $input = GUICtrlCreateInput("", 10, 100)
Global $button = GUICtrlCreateButton("Test", 10, 200)
GUISetState(@SW_SHOW)

While 1
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then ExitLoop
If $msg = $input Then ConsoleWrite('Event from input control, value: ' & GUICtrlRead($input) & @CRLF)
WEnd

But this event is fired also when you change focus from input control to other control (and only when Enter is pressed on focused input control).

That's PERFECT! ALso, *facepalm* for not thinking to try that myself. That's exactly what I needed.

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  
Followers 0

  • Similar Content

    • rootx
      Best way to play little video inside a Gui
      By rootx
      I would like to insert a video player inside the gui Autoit, preferably one with a free license such as Media Player Classic or VLC, I saw in the forum but I found examples of many years ago.
      Some examples links or advice would be much help
    • passwd
      Two images in one GUI control with ability to move image
      By passwd
      Hello. I'm trying to make a form with two pictures and one button. But pictures must overlap one another. First picture I'm getting from screenshot of another window, but second picture must be with alfa channel and positioning on that first image.
      Something like that:
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GDIPlus.au3> #include <ScreenCapture.au3> Global Const $AC_SRC_ALPHA = 1 $Form1_1 = GUICreate("Document", 701, 671, -1, -1) GUISetBkColor(0xFFFFFF) $Pic1 = GUICtrlCreatePic("", 8, 8, 409, 657) $Button1 = GUICtrlCreateButton("Take Picture", 424, 8, 161, 33) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 Generate() EndSwitch WEnd Func Generate() Local $hBMP, $hBitmap, $hGraphic, $WindowToCapture WinActivate("Notepad") $WindowToCapture = ControlGetHandle("Notepad", "", "[CLASS:Edit; INSTANCE:1]") $hBMP = _ScreenCapture_CaptureWnd ( '', $WindowToCapture,4,4,400,470,False) ; Initialize GDI+ library _GDIPlus_Startup() $PicHandle = GUICtrlGetHandle($Pic1) $myGuiHandle = ControlGetHandle("Document", "", $PicHandle) $TransparentButtonTest = GUICreate("", 0, 0, 390, 130, $WS_EX_MDICHILD, $WS_EX_LAYERED, $myGuiHandle) $hImageButton = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\2-f.png") SetBitMap($TransparentButtonTest, $hImageButton, 255) GUISetState() WinActivate("Document") ; Draw bitmap to GUI $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $hGraphic = _GDIPlus_GraphicsCreateFromHWND(GUICtrlGetHandle($Pic1)) _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 100) ; Clean up resources _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_BitmapDispose($hBitmap) _WinAPI_DeleteObject($hBMP) ; Shut down GDI+ library _GDIPlus_Shutdown() EndFunc Func SetBitmap($hGUI, $hImage, $iOpacity) Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hScrDC = _WinAPI_GetDC(0) $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage)) DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage)) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA) _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) EndFunc ;==>SetBitmap But the most interesting, that I need to move second picture(png FromFile) by draging it with mouse ontop of first image.
      Can you tell me what I have done wrong and maybe there is some easier ways to do this?
    • Trolleule
      Activate/Focus input control, which overlaps a listview
      By Trolleule
      Hi,
      iam not able to "activate" (the blue border of the edit control should be displayed) the created input control when clicking on a listview item. All i want is, when the edit control is created, it's active (blue border displayed) and you can directly write in it (cursor at the end), but i can't get it work. Can someone help?
      #include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <GuiImageList.au3> #include <WindowsConstants.au3> #include <GuiEdit.au3> #include <Misc.au3> Global $Debug_LV = False ; Check ClassName being passed to ListView functions, set to True and use a handle to another control to see it work Global $bChanged = False, $hDLL = DllOpen("user32.dll") Global $aClick_Info[2] Global $hListView, $hTmp_Edit Global $GUI, $hImage $GUI = GUICreate("(UDF Created) ListView Create", 400, 300) $hListView = _GUICtrlListView_Create($GUI, "", 2, 2, 394, 268) _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES)) GUISetState() GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; Load images $hImage = _GUIImageList_Create() _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0xFF0000, 16, 16)) _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0x00FF00, 16, 16)) _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0x0000FF, 16, 16)) _GUICtrlListView_SetImageList($hListView, $hImage, 1) ; Add columns _GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100) _GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100) _GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100) ; Add items _GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0) _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1) _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2) _GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1) _GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1) _GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2) ; Loop until user exits Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $iwParam Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo $hWndListView = $hListView If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndListView Switch $iCode Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button Local $iIndex, $iSubItem, $sTmp_Text, $aRect, $aPos $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam) $iIndex = DllStructGetData($tInfo, "Index") $iSubItem = DllStructGetData($tInfo, "SubItem") ; make sure user clicks on the listview & only the activate If $iIndex <> -1 And Not $bChanged Then $bChanged = True Local $iTimer = TimerInit() Local $iCounter = 1 Local $DOUBLE_CLICK_TIME_DELTA = 1200 While 1 If _IsPressed("01", $hDLL) Then $iCounter+=1 ConsoleWrite("_IsPressed - clicked." & @CRLF) ; Wait until key is released. While _IsPressed("01", $hDLL) WEnd ConsoleWrite("counter: " & $iCounter & " timer: " & TimerDiff($iTimer) & @CRLF) EndIf If $iCounter = 2 And TimerDiff($iTimer) < $DOUBLE_CLICK_TIME_DELTA Then ConsoleWrite("yes." & @CRLF) ExitLoop EndIf If TimerDiff($iTimer) > $DOUBLE_CLICK_TIME_DELTA Then ConsoleWrite("over." & @CRLF) $bChanged = False Return 1 EndIf WEnd GUICtrlDelete($hTmp_Edit) $aClick_Info[0] = $iIndex $aClick_Info[1] = $iSubItem ;~ GUISetAccelerators($aAccelKeys) $sTmp_Text = _GUICtrlListView_GetItemText($hWndListView, $iIndex, $iSubItem) ConsoleWrite("item: " & $iIndex & " subitem: " & $iSubItem & " text: " & $sTmp_Text & @CRLF) If $iSubItem = 0 Then $aRect = _GUICtrlListView_GetItemRect($hWndListView, $iIndex, 2) Else $aRect = _GUICtrlListView_GetSubItemRect($hWndListView, $iIndex, $iSubItem) EndIf $aPos = ControlGetPos("", "", $hWndListView) ConsoleWrite("Information :" & StringFormat("Item 2 Rectangle : [%d, %d, %d, %d]", $aRect[0]+ $aPos[0], $aRect[1]+ $aPos[1], $aRect[2], $aRect[3]) & @CRLF) $hTmp_Edit = GUICtrlCreateEdit($sTmp_Text, $aRect[0] + $aPos[0], $aRect[1] + $aPos[1], $aRect[2] - $aRect[0], $aRect[3] - $aRect[1], 0) GUICtrlSetState($hTmp_Edit, $GUI_FOCUS+$GUI_SHOW+$Gui_ontop) _GUICtrlEdit_SetSel(GUICtrlGetHandle($hTmp_Edit), 2, 15) EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY  
    • Wicked_Caty
      No carriage return in label
      By Wicked_Caty
      My program generates a huge lot of numbers that has to be displayed in a label. Usually there are around 100 thousand and 1 million numbers, so I obviously have certain problems with space. I get the data into the label, but it's all in one line and simply exceeds the label (by a couple of million pixels, but never mind that)... Of course it won't fit into a 200x200 big label either, but it'd look a lot nicer. I don't even need to scroll in it.
      The only thing in need is an automatic @CRLF at the border of the label.
      Something like the style $ES_MULTILINE for the input box.
      Here's the most important stuff from the GUI.
      Local $gui = GUICreate("Crypt", 630, 440) Local $in = GUICtrlCreateInput("", 10, 10, 300, 300, $ES_MULTILINE) ; need something like $ES_MULTILINE just one line later in this code Local $out = GUICtrlCreateLabel("", 320, 10, 300, 300) ; instead of "", please imagine a random number between 1e5 and 1e6 here please ; a lot of buttons that don't matter right now GUISetBkColor(0x111111, $gui) GUICtrlSetBkColor($in, 0xEEEEEE) GUICtrlSetBkColor($out, 0xEEEEEE) ; again a lot of button configuartion that's completely unnecessary right now GUICtrlSetColor($in, 0x111111) GUICtrlSetColor($out, 0x111111) ; same as before GUISetFont(13, 200, 0, "Candara", $gui) GUICtrlSetFont($in, 13, 200, 0, "Candara") GUICtrlSetFont($out, 13, 200, 0, "Candara") ; still configuation for the buttons Local $data0 = "" ; some unimportant variables GUISetState(@SW_SHOW, $gui) ; switch from GUIGetMsg() in an infinite while-loop Thanks!
    • Trolleule
      [Solved] Access TreeView Control of existing GUI
      By Trolleule
      Hey,
      i'm building a "Jump To" registry key function and trying to get access to the regedit treeview control like this:
      #include <GUIConstants.au3> #include <GuiTreeView.au3> #include <TreeViewConstants.au3> #include <SendMessage.au3> #include <WinAPI.au3> Global $h_item ShellExecute("regedit.exe") ;~ Local $pid = ProcessExists("regedit.exe") ;~ If $pid Then ;~ $h_tree = WinHandFromPID($pid, "[CLASS:RegEdit_RegEdit]") ;~ WinActivate("[CLASS:RegEdit_RegEdit]", "") ;~ EndIf WinWaitActive("[CLASS:RegEdit_RegEdit]", "") ;~ WinActivate("[CLASS:RegEdit_RegEdit]", "") ;~ WinSetState("[CLASS:RegEdit_RegEdit]", "", @SW_SHOW) ; activate ;~ WinSetState("[CLASS:RegEdit_RegEdit]", "", @SW_RESTORE) ; activate ;~ WinSetState("[CLASS:RegEdit_RegEdit]", "", @SW_RESTORE) ; activate $h_tree = WinGetHandle("[CLASS:RegEdit_RegEdit]", "") ;~ $ret = _WinAPI_ShowWindow($h_tree, @SW_RESTORE) $ctrl = ControlGetHandle($h_tree, "", "[CLASS:SysTreeView32]") ConsoleWrite("$h_tree: " & $h_tree & @CRLF) ConsoleWrite("$ctrl: " & $ctrl & @CRLF) $show = GUICtrlCreateButton("Show", 70, 180, 70, 20) Show() ;~ While 1 ;~ Sleep(200) ;~ WEnd Func Show() $result = "" _SendMessage($ctrl, $WM_SETFOCUS, 0, 0) If @error Then ConsoleWrite("error" & @CRLF) $h_item = _SendMessage($ctrl, $TVM_GETNEXTITEM, $TVGN_ROOT, 0) $split = StringSplit("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "\") For $i=1 To $split[0] ConsoleWrite("item bevor findkey: " & $h_item & @CRLF) $h_item = FindKey($h_item, $split[$i]) If $h_item = 0 Then Return _SendMessage($ctrl, $TVM_SELECTITEM, 0x0009, $h_item) ; expand tree _GUICtrlTreeView_Expand($ctrl, $h_item) Next MsgBox(0, "dsfsdf", "sdfsf") Exit EndFunc Func FindKey($hItemParent, $sKey) $h_item = _SendMessage($ctrl, $TVM_GETNEXTITEM, $TVGN_CHILD, $hItemParent) ConsoleWrite("child : " & $h_item & " key: " & $sKey & " parent: " & $hItemParent & " parent text: " & _GUICtrlTreeView_GetText($ctrl, $hItemParent) & @CRLF) While $h_item <> 0 Local $sItemText = _GUICtrlTreeView_GetText($ctrl, $h_item) ConsoleWrite("text : " & $sItemText & @CRLF) If $sItemText = $sKey Then Return $h_item $h_item = _SendMessage($ctrl, $TVM_GETNEXTITEM, $TVGN_NEXT, $h_item) ConsoleWrite("next : " & $h_item & @CRLF) WEnd ConsoleWrite("not found" & @CRLF) Return 0 EndFunc it's working, when i start regedit.exe within my app. But can't get it work when regedit.exe already open. Some ideas?