packrat Posted September 13, 2006 Posted September 13, 2006 How does the example code for "owner drawn" buttons under GuiRegisterMessage() have to be modified for two or more such customized buttons (rather than just one customized button)? In an attempt to experiment with (that is, learn how to handle) multiple customized buttons, I added another custom button and duplicated the MY_WM_COMMAND and MY_WM_DRAWITEM functions (adding the digits 1 and 2 to their names to represent the custom buttons 1 and 2), but all that seems to happen is that the Button2 data is duplicated for Button1's display (same colors, same displayed button names, etc.). This leads me to believe that somehow they're still sharing the same data somewhere, even though the MY_WM_DRAWITEM1/2 values of $sText, $nTextColor, and $nBackColor are different for the two custom buttons. I don't see or understand how to specify different button texts and colors unless there are multiple MY_WM_DRAWITEM functions. (However, I also have a hunch that having two sets of GUIRegisterMsg commands may be part of the problem.) Here's just the beginning portion of my modified code, showing the initial GUI setup: $hGUI = GUICreate("My Ownerdrawn Created Button", 300, 200) $nButton1 = GUICtrlCreateButton("", 90, 50, 120, 30) GUICtrlSetStyle($nButton1, BitOr($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)); Set the ownerdrawn flag $nButton2 = GUICtrlCreateButton("", 90, 95, 120, 30) GUICtrlSetStyle($nButton2, BitOr($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)); Set the ownerdrawn flag $nButton3 = GUICtrlCreateButton("Normal Button", 90, 140, 120, 30) GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND1") ; WM_DRAWITEM has to registered before showing GUI otherwise the initial drawing isn't done GUIRegisterMsg($WM_DRAWITEM, "MY_WM_DRAWITEM1") GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND2") ; WM_DRAWITEM has to registered before showing GUI otherwise the initial drawing isn't done GUIRegisterMsg($WM_DRAWITEM, "MY_WM_DRAWITEM2") GUISetState() MY_WM_COMMAND2 is a direct copy of MY_WM_COMMAND1, and MY_WM_DRAWITEM2 is a direct copy of MY_WM_DRAWITEM1 with the three variables I mentioned above having different values. The problem may be something very easy and obvious, but, without a lot of comments in the code, it's a bit challenging sometimes to figure out what's important to change and what should be left alone. Due to AutoIt's inability to change button backgrounds, etc., knowing how to handle multiple customized buttons in this manner is essential. Thanks in advance for any help and suggestions! Harvey
Richard Robertson Posted September 13, 2006 Posted September 13, 2006 Same function can draw both. Just check the object being referenced when the function is called. I'm sure there should be a way to.
GaryFrost Posted September 13, 2006 Posted September 13, 2006 http://www.autoitscript.com/forum/index.ph...c=25077&hl= SciTE for AutoItDirections for Submitting Standard UDFs Don't argue with an idiot; people watching may not be able to tell the difference.
packrat Posted September 14, 2006 Author Posted September 14, 2006 http://www.autoitscript.com/forum/index.ph...c=25077&hl= THANK YOU!! THANK YOU!! THANK YOU!! That works beautifully as far as I've been able to make it work so far. However, I can't seem to be able to make such a colored button work like a "normal" button with respect to activating it as a control having the focus via the Enter key or activating it via an Alt-keystroke combination. (I'm emulating a software vendor's dialog box as closely as I can--that's why all the "normality" of button activation is required.) Here's the code I've been working with, adapted as best I could with your _GuiCtrlCreateButton UDF: expandcollapse popupFunc GetAuthorization() Dim $WinHandle Dim $img ; control ID Dim $a Dim $Rtn ; ; set up the dialog box: $WinHandle = GUICreate ( "Please Enter Initials and Password" , 350, 200, 280, 250 ) ; GUISetBkColor( 0xFFFFFF ) ; white background for dialog box ; GUICtrlCreateLabel( "&Initials:", 100, 70, 65, 15 ) $txtbox1 = GUICtrlCreateInput( "", 168, 65, 108, 19, $WS_TABSTOP ) ; GUICtrlCreateLabel( "&Password:", 100, 94, 65, 15 ) $txtbox2 = GUICtrlCreateInput( "", 168, 89, 108, 19, BitOR( $WS_TABSTOP, $ES_PASSWORD ) ) ; $OkButton = _GuiCtrlCreateButton( "&OK", 111, 130, 49, 24, 0x000000, 0xFFFFFF ) ; $CancelButton = _GuiCtrlCreateButton("&Cancel", 168, 130, 71, 24, 0x000000, 0xFFFFFF ) ; GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") ; WM_DRAWITEM has to registered before showing GUI otherwise the initial drawing isn't done GUIRegisterMsg($WM_DRAWITEM, "MY_WM_DRAWITEM") ; GUICtrlSetState( $txtbox1, $GUI_FOCUS ) ; give focus to the first textbox ; GUISetState() ; display the dialog box ; $a = 0 While 1 $a = GUIGetMsg() Select Case $a = $GUI_EVENT_CLOSE ; Esc key or [X] exit button $authi = "" $authp = "" $Rtn = 0 ExitLoop ; Case $a = $CancelButton ;$authi = "" ;$authp = "" ;$Rtn = 0 ;ExitLoop Send("!c") ; force a mouseclick on "&Cancel" button ; Case $a = $txtbox1 GUICtrlSetState( $txtbox2, $GUI_FOCUS ) ; give focus to the password textbox ; Case $a = $txtbox2 GUICtrlSetState( $OkButton, $GUI_FOCUS ) ; give focus to the OK button ;GUICtrlSetBkColor( $OkButton, 0x669999 ) ; blue-green background for buttondown ; Case $a = $OkButton ;$authi = GUICtrlRead($txtbox1) ;$authp = GUICtrlRead($txtbox2) ;$Rtn = 1 ;ExitLoop Send("!o") ; force a mouseclick on "&OK" button EndSelect Wend ; GUIDelete( $WinHandle ) ; close the dialog box ; Return $Rtn ; value 1 = OK button chosen; value 0 = Esc/Exit/Cancel button chosen EndFunc ;==>GetAuthorization() Func Button_Click(ByRef $ctrl_id) Switch $ctrl_id Case $CancelButton $authi = "" $authp = "" $Rtn = 0 MsgBox(0,"",$Rtn & "'" & $authi & "'" & $authp & "'") ; Case $OkButton $authi = GUICtrlRead($txtbox1) $authp = GUICtrlRead($txtbox2) $Rtn = 1 MsgBox(0,"",$Rtn & "'" & $authi & "'" & $authp & "'") EndSwitch Return $Rtn ; value 1 = OK button chosen; value 0 = Esc/Exit/Cancel button chosen EndFunc ;==>Button_Click I left the code as it was, following my last experiment which attempted to "fake" a button click when either the Enter key was pressed (when the button had the focus) or else the combination Alt-o was pressed. I copied the button processing code in the "normal" control processing part of the GetAuthorization() function to the Button_Click function, but it didn't seem to make any difference. The MsgBoxes display when the buttons are clicked with the mouse, but in no other way (such as pressing Enter or Alt-o). Even more importantly, the values in each Button_Click case ($authi, $authp, $Rtn) don't seem to get set, passed, or anything. These values are absolutely essential to the ultimate use of the larger function. (The $authi and $authp variables are global; because of the Button_Click function, so are $OkButton, $CancelButton, $txtbox1, and $txtbox2.) Any further suggestions or help would be much appreciated! Thanks in advance! Harvey
packrat Posted September 14, 2006 Author Posted September 14, 2006 I think the code posted by Larry in the subject thread "Capturing the Enter-key of an Input-control" and the explanations and code given in the help file "GUI Reference - OnEvent Mode" may give the key to resolving my problem (that is, using an OnEvent approach rather than a MessageLoop approach). I'm going to attempt that, and, if it doesn't work, then I may be back with further questions. Thanks! Harvey
packrat Posted September 14, 2006 Author Posted September 14, 2006 Well, closer... but no cigar! Here's my attempt at using the OnEvent approach to accomplish my dialog box with custom buttons: expandcollapse popupGlobal $OkButton, $CancelButton, $txtbox1, $txtbox2, $WinHandle, $Rtn Global Const $DebugIt = 1 Func GetAuthorization() ; [15 Nov 2005; modified 8-9,13-14 Sep 2006] ; ; NOTE: $authi and $authp MUST be declared as global variables ; Opt("GUIOnEventMode", 1) ; replace default MessageLoop control processing with OnEvent control processing ; ;Dim $WinHandle Dim $img ; control ID ;Dim $txtbox1 ; control ID ;Dim $txtbox2 ; control ID ;Dim $OkButton ; control ID ;Dim $CancelButton ; control ID Dim $a Dim $Rtn ; ; set up the dialog box: $WinHandle = GUICreate ( "Please Enter Initials and Password" , 350, 200, 280, 250 ) GUISetOnEvent($GUI_EVENT_CLOSE, "_Terminate") ; GUISetBkColor( 0xFFFFFF ) ; white background for dialog box ; $img = GUICtrlCreatePic( "C:\QuestionMark.bmp", 16, 33, 28, 32 ) ; left, top, width, height -- these coordinates are relative to the dialog box, not the whole window ; GUICtrlCreateLabel( "&Initials:", 100, 70, 65, 15 ) $txtbox1 = GUICtrlCreateInput( "", 168, 65, 108, 19, $WS_TABSTOP ) GUICtrlSetOnEvent($txtbox1, "_MyInput") ; GUICtrlCreateLabel( "&Password:", 100, 94, 65, 15 ) $txtbox2 = GUICtrlCreateInput( "", 168, 89, 108, 19, BitOR( $WS_TABSTOP, $ES_PASSWORD ) ) GUICtrlSetOnEvent($txtbox2, "_MyInput") ; $OkButton = _GuiCtrlCreateButton( "&OK", 111, 130, 49, 24, 0x000000, 0xFFFFFF ) GUICtrlSetOnEvent($OkButton, "OKPressed") ; $CancelButton = _GuiCtrlCreateButton("&Cancel", 168, 130, 71, 24, 0x000000, 0xFFFFFF ) GUICtrlSetOnEvent($CancelButton, "CancelPressed") ; GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") ; WM_DRAWITEM has to registered before showing GUI otherwise the initial drawing isn't done GUIRegisterMsg($WM_DRAWITEM, "MY_WM_DRAWITEM") ; GUICtrlSetState( $txtbox1, $GUI_FOCUS ) ; give focus to the first textbox ; GUISetState() ; display the dialog box GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND2") ; Just idle around While 1 Sleep(10) WEnd ; END EndFunc ;==>GetAuthorization() Func _MyInput() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("_MyInput") ;---------------------------------------------------------------------------------------------- EndFunc ;==>_MyInput Func _Input_Changed($input) ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("Input Changed:" & GUICtrlRead($input)) ;---------------------------------------------------------------------------------------------- EndFunc ;==>_Input_Changed Func _Input_LostFocus() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("_Input_LostFocus") ;---------------------------------------------------------------------------------------------- EndFunc ;==>_Input_LostFocus Func _Input_GotFocus() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("_Input_GotFocus") ;---------------------------------------------------------------------------------------------- EndFunc ;==>_Input_GotFocus Func OKPressed() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("OK Pressed" & @LF & "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle) ;---------------------------------------------------------------------------------------------- $authi = GUICtrlRead($txtbox1) $authp = GUICtrlRead($txtbox2) $Rtn = 1 ;MsgBox(0,"",$Rtn & "'" & $authi & "'" & $authp & "'") _Terminate() EndFunc ;==>OKPressed Func CancelPressed() ;---------------------------------------------------------------------------------------------- If $DebugIt Then _DebugPrint("Cancel Pressed" & @LF & "ID=" & @GUI_CtrlId & " WinHandle=" & @GUI_WinHandle & " CtrlHandle=" & @GUI_CtrlHandle) ;---------------------------------------------------------------------------------------------- $authi = "" $authp = "" $Rtn = 0 ;MsgBox(0,"",$Rtn & "'" & $authi & "'" & $authp & "'") _Terminate() EndFunc ;==>OKPressed Func _Terminate() ; Esc key or [X] exit button ;Exit $authi = "" $authp = "" $Rtn = 0 ; ;MsgBox(0,"",$Rtn & "'" & $authi & "'" & $authp & "'") GUIDelete( $WinHandle ) ; close the dialog box ; Return $Rtn ; value 1 = OK button chosen; value 0 = Esc/Exit/Cancel button chosen ; Opt("GUIOnEventMode", 0) ; make MessageLoop control processing the default again EndFunc ;==>_Terminate Func Button_Click(ByRef $ctrl_id) Dim $Rtn ; Switch $ctrl_id Case $CancelButton $authi = "" $authp = "" $Rtn = 0 ;MsgBox(0,"",$Rtn & "xxx'" & $authi & "'" & $authp & "'") ; Case $OkButton $authi = GUICtrlRead($txtbox1) $authp = GUICtrlRead($txtbox2) $Rtn = 1 ;MsgBox(0,"",$Rtn & "xxx'" & $authi & "'" & $authp & "'") EndSwitch Return $Rtn ; value 1 = OK button chosen; value 0 = Esc/Exit/Cancel button chosen EndFunc ;==>Button_Click Func MY_WM_COMMAND2($hWnd, $msg, $wParam, $lParam) Local $nNotifyCode = _HiWord($wParam) Local $nID = _LoWord($wParam) Local $hCtrl = $lParam Local Const $EN_CHANGE = 0x300 Local Const $EN_KILLFOCUS = 0x200 Local Const $EN_SETFOCUS = 0x100 Switch $nID Case $txtbox1 Switch $nNotifyCode Case $EN_CHANGE _Input_Changed($txtbox1) Case $EN_SETFOCUS _Input_GotFocus() Case $EN_KILLFOCUS _Input_LostFocus() GUICtrlSetState( $txtbox2, $GUI_FOCUS ) ; give focus to the password textbox EndSwitch Case $txtbox2 Switch $nNotifyCode Case $EN_CHANGE _Input_Changed($txtbox2) Case $EN_SETFOCUS _Input_GotFocus() Case $EN_KILLFOCUS _Input_LostFocus() GUICtrlSetState( $OkButton, $GUI_FOCUS ) ; give focus to the OK button ;GUICtrlSetBkColor( $OkButton, 0x669999 ) ; blue-green background for button EndSwitch EndSwitch ; Proceed the default Autoit3 internal message commands. ; You also can complete let the line out. ; !!! But only 'Return' (without any value) will not proceed ; the default Autoit3-message in the future !!! Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_COMMAND2 #cs ;already exists in GuiButton.au3 code Func _DebugPrint($s_text) $s_text = StringReplace($s_text, @LF, @LF & "-->") ConsoleWrite("!===========================================================" & @LF & _ "+===========================================================" & @LF & _ "-->" & $s_text & @LF & _ "+===========================================================" & @LF) EndFunc ;==>_DebugPrint #ce Func _HiWord($x) Return BitShift($x, 16) EndFunc ;==>_HiWord Func _LoWord($x) Return BitAND($x, 0xFFFF) EndFunc ;==>_LoWord Unfortunately, it doesn't work right--at least in terms of keystrokes (mouseclicks seem to work fine). Here's my original version that DOES work right. (The only problem is that the dialog box I'm trying to emulate is all white rather than all gray.) expandcollapse popupFunc GetAuthorization() ; [15 Nov 2005; modified 8-9 Sep 2006] Dim $WinHandle Dim $txtbox1 ;control ID Dim $txtbox2 ;control ID Dim $OkButton ;control ID Dim $CancelButton ;control ID Dim $a Dim $Rtn ; ;set up the dialog box: $WinHandle = GUICreate ( "Please Enter Initials and Password" , 350, 200, 280, 250 ) GUICtrlCreateLabel( "&Initials:", 100, 70, 65, 15 ) ;left, top, width, height -- these coordinates are relative to the dialog box, not the whole window $txtbox1 = GUICtrlCreateInput ( "", 168, 65, 108, 19 ) GUICtrlCreateLabel( "&Password:", 100, 94, 65, 15 ) $txtbox2 = GUICtrlCreateInput ( "", 168, 89, 108, 19, $ES_PASSWORD ) $OkButton = GUICtrlCreateButton ("&OK", 111, 130, 49, 24 ) $CancelButton = GUICtrlCreateButton ("&Cancel", 168, 130, 71, 24 ) ; ;GUICtrlSetState( $OKButton, $GUI_DEFBUTTON ) ;OK button is the default button -- COMMENT OUT! GUICtrlSetState( $txtbox1, $GUI_FOCUS ) ;give focus to the first textbox ; GUISetState() ;display the dialog box ; $a = 0 While 1 $a = GUIGetMsg() Select Case $a = $GUI_EVENT_CLOSE ; Esc key or [X] exit button $authi = "" $authp = "" $Rtn = 0 ExitLoop Case $a = $CancelButton $authi = "" $authp = "" $Rtn = 0 ExitLoop Case $a = $txtbox1 GUICtrlSetState( $txtbox2, $GUI_FOCUS ) ; give focus to the password textbox Case $a = $txtbox2 GUICtrlSetState( $OkButton, $GUI_FOCUS ) ; give focus to the OK button ;GUICtrlSetBkColor( $OkButton, 0x669999 ) ; blue-green background for button Case $a = $OkButton $authi = GUICtrlRead($txtbox1) $authp = GUICtrlRead($txtbox2) $Rtn = 1 ExitLoop EndSelect Wend ; GUIDelete( $WinHandle ) ; Return $Rtn EndFunc Here are the specifications I wrote up for myself for how it had to work: ; NOTE: in this code, pressing the Enter key means different things, depending upon ; which control (field or button) has the focus: ; (1) Alt-O always submits data; Alt-C always cancels the dialog ; (2) Alt-I always goes to the "Initials" field; Alt-P always goes to the "Password" field ; (3) cursor in "Initials" field: Tab and Enter go to "Password" field; Shift-Tab goes to "Cancel" ; (4) cursor in "Password" field: Tab and Enter go to "OK" button; Shift-Tab goes to "Initials" ; (5) focus on "OK" button: Enter submits data; Tab goes to "Cancel" button; Shift-Tab goes to "Password" ; (6) focus on "Cancel" button: Enter cancels the dialog; Tab goes to "Initials"; Shift-Tab goes to "OK" [The only quirk which I hadn't fixed before moving on to customized buttons was that the Enter key didn't move from a textbox to the next control if the current textbox had no data entered in it.] The second version (MessageLoop approach) above works according to these specs, but the first version (OnEvent approach) does not--and I can't figure out why. Any and all help would be appreciated! Thanks! Harvey
packrat Posted September 14, 2006 Author Posted September 14, 2006 Addenda to my previous message: (1) I forgot to note that you have to include gafrost's UDF: #include "GuiButton.au3" (2) For testing, of course, you probably should add something to call the function: $a = GetAuthorization() (3) In the first version (OnEvent approach), the code responds to clicking. However, rather than exiting the function to the calling function (see addendum #2 above), it leaves the script in a "Script Paused" halted state, requiring manual intervention to exit--without any data/information being returned to the calling function. Basically, what I'm saying is that the clicking aspect only partially works--and the script as a whole does not work at all. Hope this extra info helps a bit! Harvey
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