// wcout является Unicode-эквивалентом cout.
wcout << L"Wallpaper path is:\n " << wszWallpaper << endl << endl;
} else {
cout << _T("GetWallpaper() failed.") << endl << endl;
}
// 5. Освобождаем интерфейс.
pIAD->Release();
} else {
cout << _T("CoCreateInstance() failed.") << endl << endl;
}
// 6. Разинициализируем библиотеку COM. В приложениях MFC этого не требуется –
// MFC делает это автоматически.
CoUninitialize();
В этом примере я использовал std::wcout для отображения строки Unicode wszWallpaper.
Использование COM-объекта, включающего несколько интерфейсов
Второй пример показывает, как можно использовать QueryInterface() для получения единственного интерфейса COM-объекта. В этом примере используется CO-класс Shell Link, содержащийся в оболочке, для создания ярлыка для файла "обоев", имя которого мы получили в предыдущем примере.
Программа состоит из следующих шагов:
1. Инициализация библиотеки COM.
2. Создание объекта COM, используемого для создания ярлыков, и получение интерфейса IShellLink.
3. Вызов метода SetPath() интерфейса IShellLink.
4. Вызов метода QueryInterface() объекта COM и получение интерфейса IPersistFile.
5. Вызов метода Save() интерфейса IPersistFile.
6. Освобождение интерфейсов.
7. Разинициализация библиотеки COM.
CString sWallpaper = wszWallpaper; // Конвертация пути к "обоям" в ANSI
IShellLink* pISL;
IPersistFile* pIPF;
// 1. Инициализация библиотеки COM (заставляем Windows загрузить библиотеки DLL). Обычно
// вам нужно делать это в функции InitInstance() или подобной ей. В MFC-приложениях
// можно также использовать функцию AfxOleInit().
CoInitialize(NULL);
// 2. Создание объекта COM с использованием CO-класса Shell Link, поставляемого оболочкой.
// 4-й параметр указывает на то, какой интерфейс нам нужен (IShellLink).
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pISL);
if (SUCCEEDED(hr)) {
// 3. Устанавливаем путь, на который будет указывать ярлык (к файлу "обоев").
hr = pISL->SetPath(sWallpaper);
if (SUCCEEDED(hr)) {
// 4. Получение второго интерфейса (IPersistFile) от объекта COM.
hr = pISL->QueryInterface(IID_IPersistFile, (void**)&pIPF);
if (SUCCEEDED(hr)) {
// 5. Вызов метода Save() для сохранения ярлыка в файл. Первый параметр
// является строкой Unicode.
hr = pIPF->Save(L"C:\\wallpaper.lnk", FALSE);
// 6a. Освобождение интерфейса IPersistFile.
pIPF->Release();
}
}
// 6b. Освобождение интерфейса IShellLink.
pISL->Release();
}
// Где-то здесь должен быть код для обработки ошибок.
// 7. Разинициализация библиотеки COM. В приложениях MFC этого делать
// не нужно, т.к. MFC справляется с этим сама.
CoUninitialize();
Литература
Essential COM , Don Box, ISBN 0-201-63446-5.
MFC Internals , George Shepherd and Scot Wingo, ISBN 0-201-40721-3.
Beginning ATL 3 COM Programming , Richard Grimes, ISBN 1-861001-20-7.
ВОПРОС-ОТВЕТ
Q. Как в Win9x и WinNT заблокировать клавиши WIN, Alt+Tab, Ctrl+Esc etc.?
Mike Krasnik
A 1Например так – в конструкторе главного окна приложения зарегистрировать HotKey:
m_HK = GlobalAddAtom("alttab"); // DWORD m_HK;
RegisterHotKey(GetSafeHwnd(), m_HK, MOD_ALT, VK_TAB);
а в деструкторе не забыть его разрегистрировать:
UnregisterHotKey(GetSafeHwnd(), m_HK);
так как никакого обработчика для этого HotKey мы не делаем, то соответственно и происходить по нажатию Alt-Tab ничего не будет.
Алексей Кирюшкин
A 2По материалам http://msdn.microsoft.com/msdnmag/issues/0700/Win32/Win320700.asp
В WinNT (начиная с Windows NTR 4.0 Service Pack 3) существует возможность использовать "low-level" hook на клавиатуру WH_ KEYBOARD_LL для отключения комбинаций Ctrl+Esc, Alt+Tab, Alt+Esc.
Для данной данной функии установлен лимит времени: Система возвращается в нормальное состояние через промежуток времени определяемый параметром LowLevelHooksTimeout в HKEY_CURRENT_USER\Control Panel\Desktop время указывается в милисекундах.
Владимир Згурский
A 3Это делается очень по-разному в различных системах от Microsoft.
В Windows 9x можно использовать трюк, опсанный в MSDN – вызвать функцию SystemParametersInfo с недокументированным параметром. В данном случае им можно пользоваться смело: Микрософт больше не будет вносить изменений в архитектуру Win9x. Чтобы отключить Alt+Tab, Ctrl+Alt+Del и т. д., нужно написать:
int prev;
SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &prev, 0);
Выполняя этот код, мы сообщаем системе, что работает скринсейвер. А когда он работает, переключение задач запрещено. Чтобы включить стандартные комбинации снова, используйте:
int prev;
SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &prev, 0);
Читать дальше