2009-05-14 2 views
2

У меня есть COM-видимый способ, который выглядит примерно следующим:Проблемы прохождения в UserControl в качестве параметра в VB6

Public Sub SomeMethod(someControl as Object) 
On Error Goto ErrHandler  

Dim someSpecificControl as SpecificControl 

    MsgBox TypeOf someControl is Control 
    MsgBox TypeOf someControl is SpecificControl 

    On Error Resume Next 
    Set someSpecificControl = someControl 
    On Error Goto ErrHandler 
    if someSpecificControl is Nothing then 
     Exit Sub 
    end if 

    ' do stuff to the control 

End Sub 

Другие компоненты будут вызывать этот метод (т.е. через COM) и передать в управление типа SpecificControl.

Моя проблема заключается в том, что при запуске через отладчик параметризованный элемент управления, похоже, не имеет правильного типа, то есть он выходит из подпрограммы после сбоя «cast», когда я ожидал, что это не так.

Использование TypeOf Я проверил, что параметризованный объект имеет тип Control (как указано выше), но я не могу понять, почему он был передан - по-видимому - неправильно. Кажется, он ведет себя корректно, когда запускается за пределами отладчика, но я не могу быть уверен (отсюда этот вопрос).

Может ли кто-нибудь пролить свет на это? Может ли контроль быть каким-то образом поврежден в процессе боксирования-распаковки? Есть ли лучший способ сделать это?

Edit: я использовал TypeName как предложил Крис Эриксон и получил некоторые интересные результаты:

MsgBox TypeName(someControl) 
MsgBox "someControl is of type SpecificControl: " & TypeOf someControl is SpecificControl 
MsgBox "someControl is of type UserControl: " & TypeOf someControl is UserControl 
MsgBox "someControl is of type Control: " & TypeOf someControl is Control 

я получаю:

SpecificControl 
someControl is of type SpecificControl: False 
someControl is of type UserControl: False 
someControl is of type Control: True 

Я думаю, единственный способ, которым я есть вокруг этого, чтобы избежать прохождения в UserControl в качестве параметра.

ответ

1

Я не знаю, почему это происходит, но я знаю, что UserControl - это полумагия в VB6. Если вы передаете UserControl в функцию по его фактическому типу, он теряет весь свой базовый класс UserControl (я знаю, VB6 не имеет наследования, но при создании UserControl вы ожидаете определенные функции).

Так что, если вы

Private Sub AdjustControlProperties(oControl as MyUserControl) 
... 
End Sub 

После того, как управление покидает вашу вашу подпрограмму, он будет вести себя как контроль, а не как UserControl (не будет иметь доступа к свойствам UserControl больше, и пытается получить доступ к ним будет вызывают ошибку). Очень странная ошибка в VB6, и одна из них вызвала много усилий по вытягиванию волос.

Private Sub AdjustControlProperties(oControl as Object) 
... 
End Sub 

И все в порядке. Я предполагаю, что вы правы, а UserControls в коробке, unboxed как не ControlControls Control. Единственное решение типа проверки, является использование

TypeName() 

знать, какого типа это, так как это не повреждаются.

+0

Наверное, лучше, чем я стараюсь избегать передачи элемента управления в качестве параметра в первую очередь. Благодаря! – jpoh

1

Я использую VBControlExtender в качестве параметра типа

Public Sub SomeMethod(someControl as VBControlExtender)

тогда я получаю ссылки как этот

Dim someSpecificControl as SpecificControl 
Dim someSpecificControlExt as VBControlExtender 

Set someSpecificControl = someControl.object 
Set someSpecificControlExt = someControl

Затем используйте someSpecificControlExt для доступа Left, TabIndex, TabStop, Name, Move и т.д.свойства расширителя и someSpecificControl для доступа к определенным методам/свойствам моего пользовательского элемента управления.

FYI, поведение вашего кода зависит от того, реализован ли пользовательский элемент управления в текущем проекте или указан в ocx. Я использую Matt Curlands direct user control access hack тоже, что позволяет мне сделать это

Dim someSpecificControl as DirectSpecificControl

так что someSpecificControl реквизита/методы доступны в начале переплете.

Это, как я получаю someSpecificControlExt (экстендер) из-под контроля:

Public Function GetExtendedControl(oCtl As IUnknown) As VBControlExtender 
    Dim pOleObject  As IOleObject 
    Dim pOleControlSite As IOleControlSite 

    On Error Resume Next 
    Set pOleObject = oCtl 
    Set pOleControlSite = pOleObject.GetClientSite 
    Set GetExtendedControl = pOleControlSite.GetExtendedControl 
    On Error GoTo 0 
End Function

Это, как я получаю внутренний UserControl контроля пользователя VB6:

Public Function GetUserControl(oObj As Object) As UserControl 
    Dim pControl  As UserControl 

    Call CopyMemory(pControl, ObjPtr(oObj), 4) 
    Set GetUserControl = pControl 
    Call CopyMemory(pControl, 0&, 4) 
End Function

Эталонные GetUserControl возвращается имеет очень странное изображение of QueryInterface - кажется UserControl Интерфейс специально причислен к E_NOTIMPLEMENTED.

Смежные вопросы