Форум программистов, компьютерный форум, киберфорум
Наши страницы
Visual Basic
Войти
Регистрация
Восстановить пароль
 
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,862
Записей в блоге: 16
#1

Как установить фокус ввода на динамически созданный контрол Edit?

15.09.2015, 12:05. Просмотров 336. Ответов 4

Здравствуйте!

Создаю через CreateWindowEx контрол EDIT со стилем ES_MULTILINE.
Все работает нормально. Можно вводить текст, по нажатию ENTER - переход на новую строку.

НО, если добавить на форму стандартную кнопку, она получает "частичный" фокус ввода
и получается, что текст с клавиатуры вводится в EditBox, а нажатие ENTER - отправляется кнопке.

Как передать контролу EDIT полный фокус ввода при нажатии ЛКМ по нему?

Я пробовал получать оповещение WM_SETFOCUS, устанавливая затем фокус через функцию SetFocus или WM_NEXTDLGCTL, но это не помогло:

Кликните здесь для просмотра всего текста
frmmain.frm

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Option Explicit
 
Private Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExW" (ByVal dwExStyle As Long, ByVal lpClassName As Long, ByVal lpWindowName As Long, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
 
Private Const WS_EX_CLIENTEDGE  As Long = &H200&
Private Const WS_CHILD          As Long = &H40000000
Private Const WS_VISIBLE        As Long = &H10000000
Private Const ES_MULTILINE      As Long = 4&
Private Const ES_AUTOVSCROLL    As Long = &H40&
Private Const ES_NOHIDESEL      As Long = &H100&
Private Const ES_WANTRETURN     As Long = &H1000&
Private Const WM_GETTEXTLENGTH  As Long = &HE
Private Const WM_GETTEXT        As Long = &HD&
 
 
Private Sub Form_Load()
    Dim DefaultText As String
    DefaultText = "1 строка " & vbCrLf & vbCrLf & "2 строка."
    
    hWndEdit = CreateWindowEx(WS_EX_CLIENTEDGE, StrPtr("EDIT"), StrPtr(DefaultText), _
                               WS_CHILD Or WS_VISIBLE Or ES_MULTILINE Or ES_AUTOVSCROLL Or ES_NOHIDESEL Or ES_WANTRETURN, _
                               0&, 0&, Me.ScaleWidth / Screen.TwipsPerPixelX - 200, _
                               Me.ScaleHeight / Screen.TwipsPerPixelY, Me.hwnd, 0&, 0&, ByVal 0&)
                               
    lpPrevWndProc = SetWindowLong(hWndEdit, GWL_WNDPROC, AddressOf WndProc)
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
    SetWindowLong hWndEdit, GWL_WNDPROC, lpPrevWndProc
End Sub
 
Private Sub Command1_Click()
    Debug.Print "Hello!"
End Sub
modSubclassing.bas
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Option Explicit
 
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SetFocus Lib "user32.dll" (ByVal hwnd As Long) As Long
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function PostMessage Lib "user32.dll" Alias "SendMessageW" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
 
Public Const WM_SETFOCUS As Long = 7&
Public Const GWL_WNDPROC As Long = (-4)
Public Const WM_NEXTDLGCTL As Long = &H28&
 
Public lpPrevWndProc     As Long
Public hWndEdit          As Long
 
 
Public Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case uMsg
    Case WM_SETFOCUS
        'Dim oldHandle As Long
        'oldHandle = SetFocus(hWndEdit)
        'Debug.Print "WM_SETFOCUS Edit"
        'Debug.Print "Old handle = " & oldHandle
        'Debug.Print "New handle = " & hWndEdit
        
        PostMessage Form1.hwnd, WM_NEXTDLGCTL, hWndEdit, 1
        
    End Select
    WndProc = CallWindowProc(lpPrevWndProc, hwnd, uMsg, wParam, lParam)
End Function
0
Вложения
Тип файла: zip CreateWindow_TextBox.zip (2.5 Кб, 5 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.09.2015, 12:05
Ответы с готовыми решениями:

Как установить в Masked Edit св-ва для ввода даты/время?
Вот попытался в Masked Edit сделать форматированный ввод для поля таблицы БД...

Как сделать чтобы контрол не ловил фокус
У меня есть проблема некоторые контролы, например ActivBar2 ловят фокус и по...

Как динамически создать контрол в другом контроле-контейнере?
Вот пример создания Label на форме: Set NewLabel =...

Почему созданный контрол не садится на лист Excel
В чем может быть дело - созданный контрол нормально садится и работает на...

Как удалить динамически созданный контрол?
Допустим у меня есть массив чекбоксов. И мы отметили их как true; Если...

4
The trick
Модератор
7360 / 2579 / 754
Регистрация: 22.02.2013
Сообщений: 3,797
Записей в блоге: 76
15.09.2015, 19:56 #2
MSDN
When the multiline edit control is in a dialog box, the default response to pressing the ENTER key is to activate the default button. To use the ENTER key as a carriage return, use the ES_WANTRETURN style.
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,862
Записей в блоге: 16
15.09.2015, 20:43  [ТС] #3
Спасибо, но в коде выше этот стиль используется.

Кроме того, я пробовал этот код в ином проекте. Там поведение несколько иное: на форме есть кнопки.
Нажимаю на контрол EDIT. Кнопка ENTER производит перевод каретки. Нажимаю на кнопку, затем на EDIT. ENTER теперь активирует последнюю нажатую кнопку.
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,862
Записей в блоге: 16
19.09.2015, 22:56  [ТС] #4
"Решил" проблему удалением родных кнопок, и созданием их динамически через CreateWindowEx.
0
Dragokas
Эксперт WindowsАвтор FAQ
16969 / 7054 / 856
Регистрация: 25.12.2011
Сообщений: 10,862
Записей в блоге: 16
16.01.2016, 02:07  [ТС] #5
На форме 2 кнопки и таймер.

Почему не удается эмулировать TAB? (следующий контрол не получает фокус)

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Option Explicit
 
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
'Private Declare Function SetFocus2 Lib "user32" Alias "SetFocus" (ByVal hWnd As Long) As Long
 
Private Const WM_NEXTDLGCTL     As Long = &H28&
 
Private Sub Form_Load()
    Timer1.Interval = 1000
End Sub
 
Private Sub Timer1_Timer()
    SendMessage Me.hWnd, WM_NEXTDLGCTL, 0&, ByVal 0&
    Debug.Print "Worked"
    'Debug.Print "Old = " & SetFocus2(Command2.hWnd) & ". New = " & Command2.hWnd
End Sub
Добавлено через 2 минуты
lol, оказывается я этот способ уже пробовал.
Хотя ведь с родными кнопками должно было отработать...
0
16.01.2016, 02:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.01.2016, 02:07

Как удалить динамически созданный контрол?
public void button1_Click(object sender, EventArgs e) { ...

Как удалить динамически созданный пользовательский контрол?
При каждом нажатии на кнопку создается новый пользовательский контрол using...

Как установить в диалоге фокус на нужный контрол?
Подскажите, пожалуйста, новичку как установить в диалоге фокус на нужный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru