Windows API Tutorials
Здесь есть возможность читать онлайн «Windows API Tutorials» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:Windows API Tutorials
- Автор:
- Жанр:
- Год:неизвестен
- ISBN:нет данных
- Рейтинг книги:3 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 60
- 1
- 2
- 3
- 4
- 5
Windows API Tutorials: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Windows API Tutorials»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Windows API Tutorials — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Windows API Tutorials», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
template
class SShellPtr{
public:
~SShellPtr () {
Free ();
_malloc-> Release();
}
T * weak operator->() { return _p; }
T const * operator->() const { return _p; }
operator T const * () const { return _p; }
T const & GetAccess () const { return *_p; }
protected:
SShellPtr () : _p (0) {
// Obtain malloc here, rather than
// in the destructor.
// Destructor must be fail-proof.
// Revisit: Would static IMalloc * _shellMalloc work?
if ( SHGetMalloc(& _malloc) == E_FAIL) throw Exception "Couldn't obtain Shell Malloc";
}
void Free () {
if (_p != 0) _malloc-> Free(_p);
_p = 0;
}
T * _p;
IMalloc * _malloc;
private:
SShellPtr (SShellPtr const & p) {}
void operator = (SShellPtr const & p) {}
};
Notice the same trick as before: the class SShellPtr is not directly usable. You have to subclass it and provide the appropriate constructor.
Notice also that I wasn't sure if _shellMalloc couldn't be made a static member of SShellPtr. The problem is that static members are initialized before WinMain. At that time, the whole COM system might be unstable. On the other hand, the documentation says that you can safely call another API, CoGetMalloc, before the call to CoInitialize. It doesn't say whether SHGetMalloc, which does almost the same thing, can also be called anytime in your program. Like in many other cases with badly designed/documented systems, only experiment can answer such questions. Feedbackwill be very welcome.
By the way, if you need a smart pointer that uses COM-specific malloc, the one obtained by calling CoGetMalloc, you can safely make its _malloc a static member and initialize it once in your program (here, SComMalloc::GetMalloc is static, too):
IMalloc * SComMalloc::_malloc = SComMalloc::GetMalloc ();
IMalloc * SComMalloc::GetMalloc() {
IMalloc * malloc = 0;
if ( CoGetMalloc(1, & malloc) == S_OK) return malloc;
else return 0;
}
That's all there is to know in order to start using Windows95 shell and its COM interfaces. Here's an example. Windows95 shell has this notion of a Desktop being the root of the "file" system. Did you notice how Windows95 applications let the user browse the file system starting at the desktop? This way you can, for instance, create files directly on your desktop, move between drives, browse a network drive, etc. It is, in effect, a poor man's Distributed File System (PMDFS). How can your application get access to PMDFS? Easy. For instance, let's write some code that will let the user pick a folder by browsing PMDFS. All we need to do is to get hold of the desktop, position ourselves with respect to it, start the built-in browser and retrieve the path that the user has chosen.
char path [MAX_PATH];
path [0] = '\0';
Desktop desktop;
ShPath browseRoot (desktop, unicodePath);
if (browseRoot.IsOK ()) {
FolderBrowser browser (hwnd, browseRoot, BIF_RETURNONLYFSDIRS, "Select folder of your choice");
if (browser.IsOK ()) {
strcpy (path, browser.GetPath ());
}
}
Let's start with the desktop object. It envelops the interface called IShellFolder. Notice how we conform to the First Rule of Acquisition — we allocate resources in the constructor by calling the API SHGetDesktopFolder. The smart interface pointer will take care of resource management (reference counting).
class Desktop: public SIfacePtr< IShellFolder> {
public:
Desktop () {
if ( SHGetDesktopFolder(& _p) != NOERROR) throw "HGetDesktopFolder failed";
}
};
Once we have the desktop, we have to create a special kind of path that is used by PMDFS. The class ShPath encapsulates this "path." It is constructed from a regular Unicode path (use mbstowcs to convert ASCII path to Unicode: int mbstowcs(wchar_t *wchar, const char *mbchar, size_t count)). The result of the conversion is a generalized path relative to the desktop. Notice that memory for the new path is allocated by the shell--we encapsulate it in SShellPtr to make sure it is correctly deallocated.
class ShPath: public SShellPtr {
public:
ShPath (SIfacePtr & folder, wchar_t * path) {
ULONG lenParsed = 0;
_hresult = folder-> ParseDisplayName(0, 0, path, & lenParsed, & _p, 0);
}
bool IsOK () const { return SUCCEEDED (_hresult); }
private:
HRESULT _hresult;
};
This shell path will become the root from which the browser will start its interaction with the user.
From the client code's point of view, the browser is the path chosen by the user. That's why it inherits from SShellPtr.
By the way, ITEMIDLIST is the official name for this generalized path . It is a list of, and I'm not making this up, SHITEMID's. I shall refrain from making any further comments or jokes about shell naming conventions.
class FolderBrowser: public SShellPtr {
public:
FolderBrowser(HWND hwndOwner, SShellPtr & root, UINT browseForWhat, char const *title);
char const * GetDisplayName () { return _displayName; }
char const * GetPath () { return _fullPath; }
bool IsOK() const { return _p != 0; };
private:
char _displayName [MAX_PATH];
char _fullPath [MAX_PATH];
BROWSEINFO _browseInfo;
};
FolderBrowser::FolderBrowser(HWND hwndOwner, SShellPtr & root, UINT browseForWhat, char const *title) {
_displayName [0] = '\0';
_fullPath [0] = '\0';
_browseInfo.hwndOwner = hwndOwner;
_browseInfo.pidlRoot = root;
_browseInfo.pszDisplayName = _displayName;
_browseInfo.lpszTitle = title;
_browseInfo.ulFlags = browseForWhat;
_browseInfo.lpfn = 0;
_browseInfo.lParam = 0;
_browseInfo.iImage = 0;
// Let the user do the browsing
_p = SHBrowseForFolder(& _browseInfo);
if (_p != 0) SHGetPathFromIDList(_p, _fullPath);
}
That's it! Isn't it simple?
Now, would you like to hear what I think about OLE?
What's Wrong with OLE?
The Insider's story
You might have heardor read critical opinions about OLE. Programmers mostly complain about the complex system of reference counting and the lack of support for inheritance. Microsoft evangelists counter this by saying that there is no other way, and that it's for your own good [1]. Interfaces, it is said, have to be refcounted, and there is a clever hack called aggregation(fondly called aggravation by OLE programmers) that provides the same functionality as inheritance. Maybe they are right, maybe the problem of interacting with run-time-loadable objects is so complex that there simply isn't any better way? On the other hand, maybe OLE has a fatal flaw that just keeps popping up all over the place.
Читать дальшеИнтервал:
Закладка:
Похожие книги на «Windows API Tutorials»
Представляем Вашему вниманию похожие книги на «Windows API Tutorials» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Windows API Tutorials» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.