void CAdvBar::Initialize() {
CRect rc;
SetHeight(CONTROL_HEIGHT + 8); // устанавливаем нужную толщину тулбара
// превращаем кнопку в сепаратор нужных размеров
// (IDC_COMBO - ID кнопки)
SetButtonInfo(CONTROL_INDEX, IDC_COMBO, TBBS_SEPARATOR, CONTROL_WIDTH);
GetItemRect (CONTROL_INDEX, rc); // получаем координаты сепаратора
// теперь создаем комбобокс.
// не забывайте, что для этого контрола при создании указывается
// его высота В РАЗВЕРНУТОМ ВИДЕ, именно поэтому
// мы к ней прибавляем еще 100 пикселов.
rc.bottom += 100;
m_ComboBox.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | CBS_AUTOHSCROLL | CBS_DROPDOWN, rc, this, IDC_COMBO);
// настраиваем контрол
m_ComboBox.AddString("Строка 1");
m_ComboBox.AddString("Строка 2");
m_ComboBox.SetCurSel(0);
}
В данном случае еще могу порекомендовать в комбобоксе изменить шрифт на пропорциональный.
Вот, теперь все, что осталось сделать – в CMainFrame::OnCreate() после создания тулбара вызвать Initialize().
Взаимодейстиве с контролом, размещенным на тулбаре, происходит через соответствующий член класса и/или посредством сообщений.
ВОПРОС-ОТВЕТ
Из ответов, содержащих одинаковое решение, я выбрал лучшие (с моей точки зрения). Большая просьба: не нужно присылать мне целые проекты и большие куски кода. Лучше объясните ваше решение словами.
Q.Как просканировать LAN на предмет создания поименного списка машин, чтобы затем можно было изпользовать результат в ListBox'e? Пробовал использовать для этой цели SHBrowseForFolder() и связанные ф-ции с установленным флагом CIDL_NETWORK, но открывающееся окно для выбора узла и необходимость "раскрывать плюсики" в локальных группах меня не устраивает. Если можно, в API без MFC.
DevXarT
A 1Необходимо подключить заголовочные файлы
#include
#include
#include
и библиотеку NetAPI, в диалоге "Project Settings" на странице "Link" в поле "Object/library modules:" вписать netapi32.lib
Далее, например так:
LPSERVER_INFO_100 pServerEnum;
DWORD dwResult, dwRead, dwTotal;
dwResult = ::NetServerEnum(NULL, 100, (BYTE**)&pServerEnum, -1, &dwRead, &dwTotal, SV_TYPE_ALL, NULL, 0);
if (dwResult == NERR_Success) {
for (DWORD i=0; i
m_wndListBox.AddString(CString((LPCWSTR)pServerEnum[i].sv100_name));
}
}
Причем, используя SERVER_INFO_101 можно получить более подробную информацию (например тип и версию операционной системы), а комбинируя различные флаги в седьмом параметре NetServerEnum можно выбирать компьютеры по определенному признаку (например, только SQL-серверы или Terminal Server).
Недостаток такого способа в том, что он получает список хостов от мастер-браузера. Таким образом в этом списке присутствуют только хосты, в настоящий момент присутствующие в сети. А поскольку мастер-браузер обновляет эту информацию с периодичностью около 15 минут, список может быть не актуален на данный момент. Кроме того в нем отсутствуют "скрытые" хосты (например командой net config server /hidden:yes ).
А вот мой вопрос… Многие утилиты Windows NT Server (regedt32, Windows NT Diagnostics, Event Viewer, Perfomance Monitor, Shutdown Manager) имеют диалог "Select Computer". Наверняка он в системе "стандартный". Что-то типа SHBrowseForFolder. Может кто знает, где его найти, как вызвать?
Андрей
A 2Ответ кроется в группе функций с префиксом ::WNetXXX:
WNetOpenEnum(RESOURCE_CONTEXT, RESOURCETYPE_ANY, 0, NULL, &handleEnum) – открыть нумерацию локальных доменов верхнего уровня (включая узел Entire Network, эквиалентно выбору Network Neighbourhoods в Explorer), четвертый параметр имеет тип LPNETRESOURCE, где NETRESOURCE – структура, описывающая узел;
WNetOpenEnum(RESOURCEUSAGE_CONTAINER, RESOURCETYPE_ANY, 0, pNetCurrent, &handleEnum) – открыть нумерацию ресурсов узла (шаринги, локальные домены следующего уровня, принтеры, см. флажки в МСДН);
WNetEnumResource(handleEnum, &dwCounter, pNetResource, &dwBufferSize) – получить список ресурсов узла, handleEnum получается предыдущей ф-цией.
…я бы не советовал заполнять листбокс всеми именами машин за раз, процесс этот может быть довольно длительным во времени (порядка минуты); если сеть достаточно велика (от 30-50 машин), лучше использовать дерево.
James Nicolas Borodco
A 3Список машин, их имена, имена провайдера, тип подключения и т.д. имеется в реестре. Смотри ключи:
HKEY_CURRENT_USER\Network
HKEY_CURRENT_USER\Network\Recent
Функции для работы с реестром имеются, ищи в MSDN Library, например, RegOpenKeyEx, RegQueryInfoKey. Там же в MSDN Library имеются и примеры работы с реестром (в обзорах, конечно).
Виктор Никитенко
К сведению: Не во всех системах есть такие ключи реестра. В Windows NT/2000, например, их нет.
Хочу поблагодарить всех, кто откликнулся и прислал ответ на вопрос. Если хотите чтобы ваш ответ был опубликован – постарайтесь, чтобы он был лучше других! Напоминаю, что только вопросы от авторов опубликованныхответов и материалов имеют в дальнейшем приоритет. (Вопросы, естественно, должны быть по программированию).
Читать дальше