Archive: Set Focus to a Field


Set Focus to a Field
I'm trying to use the function on the wiki Set Focus to a Control but there is only an abstract function call syntax and no tangible working example and I'm having a hard time figuring out how to call it.

Can someone please help and give me a real simple example that would set the focus to the first text field in a custom dialog? Better yet, add it to the wiki too?

Thanks in advance.


It is quite simple really.

Page Custom ShowCustom1

Var HWND

Function .onInit
!insertmacro MUI_INSTALLOPTIONS_EXTRACT "ioFile.ini"
FunctionEnd

Function ShowCustom1

!insertmacro MUI_HEADERTEXT "blah" "blah"

!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "ioFile.ini"
Pop $HWND ;HWND (handle) of dialog

Push "$PLUGINSDIR\ioFile.ini" ;Page .ini file where the field can be found.
Push "$HWND" ;Page handle you got when reserving the page.
Push "1" ;Field number to set focus.
Call SetFocus

!insertmacro MUI_INSTALLOPTIONS_SHOW

FunctionEnd


-Stu

From version 2.24 InstallOptions has native FOCUS flag


NSIS version 2.24 is still to be released :)

InstallOptions will be v2.45 then.


SetFocus is not working can anyone tell me why?


Page custom organisation_id_pre organisation_id_leave

function organisation_id_pre
strcmp $ALREADY_INSTALLED "YES" 0 +2
abort
!insertmacro MUI_HEADER_TEXT "Required Information" "Please enter following required information"
InstallOptions::Dialog "$PLUGINSDIR\Organisation_id.ini"
Pop $HWND_org_id
functionend



function organisation_id_leave
ReadINIStr $0 "$PLUGINSDIR\Organisation_id.ini" 'Field 2' "State" ;l$ip_addr "$PLUGINSDIR\Organisation_id.ini" 'Field 4' "State"
ReadINIStr $1 "$PLUGINSDIR\Organisation_id.ini" 'Field 3' "State"
ReadINIStr $2 "$PLUGINSDIR\Organisation_id.ini" 'Field 4' "State"
ReadINIStr $3 "$PLUGINSDIR\Organisation_id.ini" 'Field 5' "State"

${If} $0 > '255'
messagebox mb_ok "IP address not valid from IP field 1"
Push "$PLUGINSDIR\Organisation_id.ini" ;Page .ini file where the field can be found.
Push "$HWND_org_id" ;Page handle you got when reserving the page.
Push "2" ;Field number to set focus.
Call SetFocus
!insertmacro MUI_INSTALLOPTIONS_SHOW
; WriteINIStr "$PLUGINSDIR\Organisation_id.ini" 'Field 2' 'Flags' 'FOCUS'
; FlushINI $TEMP\something.ini
; !insertmacro MUI_INSTALLOPTIONS_READ $R1 "$PLUGINSDIR\Organisation_id.ini" "Field 2" "HWND"
; SendMessage $R1 ${WM_SETFOCUS} 0 0
; SendMessage $R1 ${WM_SETTEXT} 0 "STR:8080"
; abort
${EndIf}


Don't call MUI_INSTALLOPTIONS_SHOW in the leave function. That should only be called in the page callback function (organistaion_id_pre in your case).


If i dont display the page again how the chages will get reflect in UI ?


If you call Abort, the page isn't left. If you call InstallOptions again, you just create another page with the old settings and will create trouble when the pages are destroyed.


Then what i should i do to reflect the changes


As I said, call Abort.

Function leave
Abort # in case leaving the page should be stopped...
FunctionEnd

I was able to use this thread to set focus to a known field number, but how do I focus the next button?


!include WinMessages.nsh
#...
GetDlgItem $0 $HWNDPARENT 1
SendMessage $HWNDPARENT ${WM_NEXTDLGCTL} $0 1

tried a few things, but where in this logic would that go, i've commented out what I have my hacky SetFocus to remove focus from the text object that I have in there:


!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "eula.ini"

Pop $HWND ;HWND of dialog

; this removes the focus from the text field on my custom
; form so that pressing enter continues the install flow.
;Push "eula.ini"found.
;Push "$HWND"
;Push "7" ; this is a custom label
;Call SetFocus

Call SetOtherGoodies ;

; Now show the dialog
!insertmacro MUI_INSTALLOPTIONS_SHOW

Ah, you want the focus to go there right away. I don't think that'd be possible without modifying InstallOptions. But why do it? Since the next button is the default button, it'd still go to the next page when you hit enter.


that's just it, it doesn't I have call just after the Pop to:

!insertmacro MUI_INSTALLOPTIONS_READ $DLGITEM "eula.ini" "Field 4" "HWND"
SetCtlColors $DLGITEM 0x000000 0xFFFFFF

Field 4 is my text box, focus is put there and pressing enter doesn't work.


Have you tried using the FOCUS flag instead?


that's another one, where does the focus flag go for the next button? been trying to do searches here in the forums for about 15-20 minutes, but no examples of where to use the focus flags, etc. pardon my moronic ways...


Not for the Next button, for the control you want focus for. Without any settings, the first control should receive focus and the Next button should still be the default button, so pressing enter should still go to the next page.

There is no setting to set focus to the Next button, because there shouldn't be any need to do that.


how do I set the focus flag to one of my controls?


Just add Flags=FOCUS in the INI file.


ok, I had tried that on the label and link controls just to get the focus off of the text control, but I have to see what's up. thanks.


It won't work on those controls. It knows which controls can receive focus and will ignore the flag if they can't. But weren't you saying you wanted the focus on the Next button rather than off it?


yeah, but if I can get the focus off the text control (as I have done with the SetFocus function) then the Next button will behave like the default button and continue when pressing enter.


It should behave that way with or without focus.

How about you attach an example? I'm starting to get confused about what exactly happens and what exactly you want.


here's a stripped version of what I'm trying to do, thanks.


What's the BackButton plug-in?


oops just remove that puppy


Ah, you didn't mention it's a multiline text field. It might have the same bug as with the richedit control where it eats up Enter and Escape even though it doesn't have the ES_WANTRETURN style. Instead of leaving them be, it acts on the dialog manager's behalf and sends WM_COMMAND to IDOK or WM_CLOSE to its parent dialog. But its parent dialog is just a internal dialog which doesn't handle this. Unlike richedit, edit controls don't have EN_MSGFILTER so if it's really the case, it'd require subclassing.


ok, I'll stick with my SetFocus hack for now, thanks.


Raymond Chen confirms this is the same bug as with the Rich Edit control. His post also links to another post stating the solution, similar to what Sunjammer used for the RichEdit. I need to think how this can be implemented for nsDialogs as you obviously do want the controls eat the Enter key in some cases.