Есть простая задача: создать progress bar control на главном окне подключив ConCtl32.dll динамически с помощью LoadLibrary().
В сети есть достаточно примеров линковки с ComCtl32.lib и вызовом InitCommonControlEx() через таблицу импорта. Эти примеры прекрасно работают.
Тем не менее, попытки сделать то же самое с помощью LoadLibrary() приводят к тому, что вызов InitCommonControlEx() как будто не регистрирует нужные классы окон, хотя сама функция возвращает TRUE.
Здравствуйте, Аноним, Вы писали:
А>Есть простая задача: создать progress bar control на главном окне подключив ConCtl32.dll динамически с помощью LoadLibrary().
А>В сети есть достаточно примеров линковки с ComCtl32.lib и вызовом InitCommonControlEx() через таблицу импорта. Эти примеры прекрасно работают.
А>Тем не менее, попытки сделать то же самое с помощью LoadLibrary() приводят к тому, что вызов InitCommonControlEx() как будто не регистрирует нужные классы окон, хотя сама функция возвращает TRUE.
Видимо, в манифесте должна быть ссылка на нужную версию common controls.
Имеется в виду вот это:
А>Может быть, есть что-то особенное, что нужно знать о таком способе использования ComCtl32.dll ?
Зачем вызывать инициализацию ДВАЖДЫ ?
InitCommonControls и InitCommonControlsEx взаимозаменяемы.
К тому же:
InitCommonControls function
Registers and initializes certain common control window classes. This function is obsolete. New applications should use the InitCommonControlsEx function.
Здравствуйте, okman, Вы писали:
O>Видимо, в манифесте должна быть ссылка на нужную версию common controls.
Гм. Добавление манифеста действительно приводит к тому, что классы регистрируются. Однако это не решает исходной проблемы, поскольку смысл использования LoadLibrary() с указанием полного пути к библиотеке именно в том, чтобы избежать манифестов и использовать ту версию библиотеки, которая нашлась в системе.
Может быть, есть способ написать манифест так, чтобы ComCtrl32.dll версии 6 использовалась только тогда, когда она доступна в системе, а в остальных случаях использовалась версия 5? Это решило бы дело.
Здравствуйте, MasterZiv, Вы писали:
MZ>Зачем вызывать инициализацию ДВАЖДЫ ? MZ>InitCommonControls и InitCommonControlsEx взаимозаменяемы.
1) Я так понимаю, что это не имеет отношения к исходному вопросу?
2) Вызов InitCommonControls() добавлен "на всякий случай", исходя из того, что во времена до InitCommonControlsEx() именно вызов InitCommonControls() обеспечивал инициализацию библиотеки.
3) InitCommonControls() конечно же не заменяет InitCommonControlsEx().
Здравствуйте, rtiuni, Вы писали:
R>Может быть, есть способ написать манифест так, чтобы ComCtrl32.dll версии 6 использовалась только тогда, когда она доступна в системе, а в остальных случаях использовалась версия 5? Это решило бы дело.
А в каких системах, например, отсутствует шестая версия comctl32.dll ?
Ну а что Вас смущает ?
Если верить приведенной таблице "версия comctl32.dll — релиз Windows/IE", шестая
comctl32.dll есть в Windows XP, начиная с RTM-версии.
Здравствуйте, rtiuni, Вы писали:
R>2) Вызов InitCommonControls() добавлен "на всякий случай", исходя из того, что во времена до InitCommonControlsEx() именно вызов InitCommonControls() обеспечивал инициализацию библиотеки.
InitCommonControls ничего не инициализировала вообще. Ее код состоял из одной команды ret. Просто вызов этой функции приводил к тому, что commctl32 оказывалась в списке импорта EXE и неявно загружалась при старте процесса. Иначе она могла бы и не загрузиться при старте процесса, а потом (намного позже) не создался бы диалог с common controls — их классы именно commctl32 регистрирует.
Здравствуйте, okman, Вы писали:
O>Ну а что Вас смущает ? O>Если верить приведенной таблице "версия comctl32.dll — релиз Windows/IE", шестая O>comctl32.dll есть в Windows XP, начиная с RTM-версии.
Упс. А я прочитал таблицу так, что в XP может быть только пятая версия. Спасибо.
Здравствуйте, Pavel Dvorkin, Вы писали:
R>>2) Вызов InitCommonControls() добавлен "на всякий случай", исходя из того, что во времена до InitCommonControlsEx() именно вызов InitCommonControls() обеспечивал инициализацию библиотеки.
PD>InitCommonControls ничего не инициализировала вообще. Ее код состоял из одной команды ret. Просто вызов этой функции приводил к тому, что commctl32 оказывалась в списке импорта EXE и неявно загружалась при старте процесса. Иначе она могла бы и не загрузиться при старте процесса, а потом (намного позже) не создался бы диалог с common controls — их классы именно commctl32 регистрирует.
Да, InitCommonControls() была и остается пустой, но ее вызов приводил не просто к импорту ComCtl32.dll, а к ее фактической загрузке в момент самого вызова, что означает вызов DllMain() и регистрацию классов ICC_WIN95_CLASSES. Так что не путайте, пожалуйста, себя и других.
Здравствуйте, okman, Вы писали:
R>>Упс. А я прочитал таблицу так, что в XP может быть только пятая версия. Спасибо.
O>В любом случае стоит проверить. Хотя Windows XP без SP еще попробуй достать...
Вот именно. Мой экземпляр уже включает SP2, поэтому сам проверить не могу.
Здравствуйте, rtiuni, Вы писали:
PD>>InitCommonControls ничего не инициализировала вообще. Ее код состоял из одной команды ret. Просто вызов этой функции приводил к тому, что commctl32 оказывалась в списке импорта EXE и неявно загружалась при старте процесса. Иначе она могла бы и не загрузиться при старте процесса, а потом (намного позже) не создался бы диалог с common controls — их классы именно commctl32 регистрирует.
R>Да, InitCommonControls() была и остается пустой, но ее вызов приводил не просто к импорту ComCtl32.dll, а к ее фактической загрузке в момент самого вызова, что означает вызов DllMain() и регистрацию классов ICC_WIN95_CLASSES. Так что не путайте, пожалуйста, себя и других.
Никого я не путаю. То, что в результате загрзузки DLL вызовется DLLMain — полагаю, всем здесь хорошо известно. Косвенно я об этом сказал — "их классы именно commctl32 регистрирует". Естетсвенно, DLLMain их в конечном счете и регистрирует — больше просто некому.