Как обратится к форме по Hwnd

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
xfolder
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 133
Зарегистрирован: 22.07.2002 (Пн) 18:57
Откуда: United Kingdom

Как обратится к форме по Hwnd

Сообщение xfolder » 01.05.2005 (Вс) 4:14

делаю глобальный обработчик ввода данных в textbox, функция находится в модуле. все хорошо но проблема в том как из той функции обратится к форме*

я передаю hwnd окна которое обратилось и имя контрола. задача найти окно и обратится к контролу по его имени.

кстати можно ли внутри обработчика события запросить имя контрола???

Private Sub email_KeyUp(KeyCode As Integer, Shift As Integer)

control_name=???

End Sub

FaKk2
El rebelde gurú
El rebelde gurú
Аватара пользователя
 
Сообщения: 2031
Зарегистрирован: 09.03.2003 (Вс) 22:10
Откуда: Los Angeles

Сообщение FaKk2 » 01.05.2005 (Вс) 4:53

xfolder

Так как форма твоя, думаю тебе будет проще передать в функцию ссылку на контрол, например так:

Код: Выделить всё


Public SomeFunc(ByRef SrcControl as Object)

'...
'Обращаешься так: SrcControl.Name
End Function


Насчет обработчика события... По определению обработчик события вызывается, чтобы обработать событие относящееся к контролу.

Если у тебя массив контролов, то тогда в обработчик посылается индекс контрола вызвавшего событие, например:

Код: Выделить всё

Private Sub cmdTest_Click(Index As Integer)

Msgbox "Нажата кнопка номер " & Index + 1 & " ! "

End Sub
Для получения ответа надо продемонстрировать качества, позволяющие стать компетентным — внимательность, вдумчивость, наблюдательность, желание активно участвовать в выработке решения.

xfolder
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 133
Зарегистрирован: 22.07.2002 (Пн) 18:57
Откуда: United Kingdom

Сообщение xfolder » 01.05.2005 (Вс) 18:53

как принимать эт понятно, я бы посылал полное имя контрола типа myform.text1 но задача в том чтобы это автоматизировать, передачу данных о вызываемым контроле.

у меня проекте более 200 textboxes, вот и ищу как автоматом передавать данные

CheckContent (FieldType,ControlPath,MaxSymbols)

CheckContent (TextOnly,Myform.text1, 20)

а пока приходится вот так

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 02.05.2005 (Пн) 2:02

1. Каждая форма существует в глобальной коллекции Forms. След-но, можно перебрать все экземпляры форм в проекте через For Each ... Next.
2. У каждой формы есть коллекция Controls. След-но, на каждой форме можно перебрать все контролы через, повторюсь, For Each ... Next.
3. В VB есть такая прикольная штука - TypeOf. Работает примерно так:
Код: Выделить всё
Dim V as Control
For Each V in Me.Controls
  if TypeOf V Is Textbox then
    ' Do some useful things
  elseif TypeOf V Is OptionButton then
    ' Just an example...
  End If
Next V

Используя подобный подход, можно довольно неплохо управляться с программой, в общем случае непостоянной в плане GUI.

xfolder
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 133
Зарегистрирован: 22.07.2002 (Пн) 18:57
Откуда: United Kingdom

Сообщение xfolder » 02.05.2005 (Пн) 16:36

Ennor писал(а):1. Каждая форма существует в глобальной коллекции Forms. След-но, можно перебрать все экземпляры форм в проекте через For Each ... Next.
2. У каждой формы есть коллекция Controls. След-но, на каждой форме можно перебрать все контролы через, повторюсь, For Each ... Next.
3. В VB есть такая прикольная штука - TypeOf. Работает примерно так:
Код: Выделить всё
Dim V as Control
For Each V in Me.Controls
  if TypeOf V Is Textbox then
    ' Do some useful things
  elseif TypeOf V Is OptionButton then
    ' Just an example...
  End If
Next V

Используя подобный подход, можно довольно неплохо управляться с программой, в общем случае непостоянной в плане GUI.



так это и так ясно, только это самый медленный способ перебирать коллекции.
Я ищу чтото более быстрое. к сожалению не силен в API, но наверняка чтото должно там быть чтобы можно было обратится к обьекту по hwnd не перебирая все формы

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 03.05.2005 (Вт) 15:08

xfolder писал(а):так это и так ясно, только это самый медленный способ перебирать коллекции.

Че??? Сам-то понял, что сказал? For Each ... Next - это самый быстрый способ перебора коллекций.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 03.05.2005 (Вт) 15:23

2 xfolder
Объект Form - он внутренний, VBшный, плучить на него ссылку по hwnd ну никак нельзя (соответственно и его деток).
Предлагаю навесить на все текстбоксы единую оконную процедуру и уже в ней обрабатывать все возможные события.
Лучший способ понять что-то самому — объяснить это другому.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 03.05.2005 (Вт) 16:44

В общем, чтобы не мучаться:
В модуле
Код: Выделить всё

Private 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 PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = -4
Public Const WM_USER = &H400

Public PrevTextBoxProcs() As Long

Public Function TextBoxProc(ByVal hwnd As Long, ByVal message As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Static ArrIndex As Long
    Select Case message
        Case WM_USER + 1
            ArrIndex = wParam
        Case Else
            'здесь обрабатываешь остальные события
    End Select
    If ArrIndex = 0 Then
        TextBoxProc = 0
        Exit Function
    End If
    TextBoxProc = CallWindowProc(PrevTextBoxProcs(ArrIndex), hwnd, message, wParam, lParam)
End Function

В форме:
Код: Выделить всё

Private Sub Form_Load()
Dim c As Control
Dim x As Long
    x = 1
    For Each c In Me.Controls
        If TypeOf c Is TextBox Then
            ReDim Preserve PrevTextBoxProcs(x)
            PrevTextBoxProcs(x) = SetWindowLong(c.hwnd, GWL_WNDPROC, AddressOf TextBoxProc)
            PostMessage c.hwnd, WM_USER + 1, x, 0
            x = x + 1
        End If
    Next c
End Sub

Private Sub Form_Unload(Cancel As Integer)
Dim c As Control
Dim x As Long
    x = 1
    For Each c In Me.Controls
        If TypeOf c Is TextBox Then
            SetWindowLong c.hwnd, GWL_WNDPROC, PrevTextBoxProcs(x)
            x = x + 1
        End If
    Next c
End Sub
Лучший способ понять что-то самому — объяснить это другому.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: SemrushBot и гости: 160

    TopList  
cron