Это случай магии VB, который несовместим с манифестами. Проблема связана с поведением VB со ссылками на элементы управления пользователя. Даже если вы сильно Dim переменной As UserControl
, доступ к методам / свойствам по этой ссылке имеет позднюю привязку! VB создает класс расширения в каждом элементе управления, на который ссылаются, для предоставления общих методов (таких как SetFocus, Move и т. Д.), Поэтому, когда вы что-то делаете Dim As UserControl
, это компилируется не как ссылка на UserControl
в библиотеке элементов управления, а VBControlExtender
унаследованный класс, в любом случае автоматически сгенерированная оболочка на UserControl
.
То, что я делаю с тех пор, как обнаружил главу о пользовательских элементах управления в Книга Curland Advanced Visual Basic 6 , заключается в создании настраиваемой библиотеки типов Direct User Controls
, которая заставляет VB не использовать оболочки. В основном это выглядит так:
[
uuid(GUIDHERE-0000-1111-2222-2B5E1A72D6BF),
version(1.0),
helpstring("Direct User Controls Typelib 1.0")
]
library <<mytypelib>>
{
importlib("stdole2.tlb");
importlib("C:\\WINDOWS\\system32\\COMCTL32.ocx");
importlib("C:\\WINDOWS\\system32\\COMCT232.ocx");
importlib("C:\\WINDOWS\\system32\\shdocvw.dll");
...
typedef [public] ComctlLib.ImageList DirectImageList;
typedef [public] ComctlLib.ListView DirectListView;
typedef [public] ComctlLib.ProgressBar DirectProgressBar;
typedef [public] ComctlLib.Slider DirectSlider;
typedef [public] ComctlLib.StatusBar DirectStatusBar;
typedef [public] ComctlLib.TabStrip DirectTabStrip;
typedef [public] ComctlLib.Toolbar DirectToolbar;
typedef [public] ComctlLib.TreeView DirectTreeView;
typedef [public] ComCtl2.Animation DirectAnimation;
typedef [public] ComCtl2.UpDown DirectUpDown;
typedef [public] SHDocVw.WebBrowser DirectWebBrowser;
...
}
В моих проектах хранятся "прямые" ссылки, вызывающие методы с ранним определением. Я использую Controls.Add
, как это
Dim oCtl As DirectXxx
Set oCtl = pvCastVBControlExtender(Controls.Add(PROGID_Xxx, sName)).Object
где помощник по кастингу что-то вроде этого
Private Function pvCastVBControlExtender(oCtl As VBControlExtender) As VBControlExtender
Set pvCastVBControlExtender = oCtl
End Function
Этот фрагмент работает, как и ожидалось, в трех случаях: во VBIDE, с зарегистрированными элементами управления и с элементами управления без регистрации.