Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Visual C++ - расширенное программирование Недокументированные функции (часть 0)


Информационный Канал Subscribe.Ru

Visual C++ - расширенное программирование

Выпуск № 14
Cайт : SoftMaker.com.ru
Архив рассылки : SoftMaker.com.ru
Количество подписчиков : 5009
В этом выпуске
От автора

Здравствуйте уважаемые подписчики !

Прежде всего я искренне поздравляю всех вас

С Новым Годом !

Хочу пожелать вам в новом году счастья и творческих успехов !


Как всегда, Вы можете отправить свои пожелания по поводу рассылки и сайта по этому адресу.
Если Вы хотите опубликовать свою статью, исходники, либо создать и вести какой либо раздел в этой рассылке - также пишите мне.

Напомню, что вы можете задавать свои вопросы по C и C++ в рассылке C/C++ Вопрос Ответ.
Также вы можете оперативно обсуждать вопросы программирования в дискуссионном листе Программирование. Форум !!!.

С уважением, Вахтуров Виктор.

Exceptional MFC

Недокументированные функции (часть 0)

Вместо вступления

Сегодня буду краток (раз уж рассылка выходит почти сразу после новогоднего праздника, не буду обременять вас, дорогие подписчики, ни пространным вступлением, ни длинным выпуском.
Тема сегодняшнего выпуска - недокументированные функции. Недокументированные функции, которые входят в библиотеку MFC. Под "недокументированностью" здесь я подразумеваю те факты, что эти функции не описаны в документации Microsoft (конкретно - в MSDN). Здесь немного оговорюсь - в поиске по MSDN можно найти упоминания некоторых из этих функций, но не в контексте документации, а обычно в плане описания багов MFC. Не удалось мне найти упоминания о большинстве этих функций и в поисковиках.
Также замечу, что здесь, конечно же описывается совсем не полный перечень функций, которые могут быть полезны, но недокументированы. Я просто взял несколько интересных функций из своих "загашников" и "задокументировал" :) их здесь. Использовать или не использовать эти функции - дело ваше. Однако, на мой взгляд, многие из них достойны внимания (некоторые я сам интенсивно использую в своих проектах - они просто избавляют от необходимости писать такие же, но свои). Думаю также, я продолжу эту тему в следующих выпусках).

И напоследок - все что здесь описано я "нашел" в исходниках MFC (которые любезно поставляются Microsoft). Так что господа, читайте исходный код !

Работа с окнами

Согласитесь, нижеследующие функции достаточно актуальны в ряде случаев.

Функция AfxGetParentOwner
Декларирована AFXIMPL.H
Реализована WINCORE.CPP

Прототип

HWND AFXAPI AfxGetParentOwner(HWND hWnd);

Комментарии

Если выполнен сабклассинг окна hWnd библиотекой MFC, то возвращается Owner-окно MFC (при помощи CWnd::GetOwner). Если нет, то если окно является дочерним другому, возвращается его родитель (::GetParent(hWnd)), иначе - его хозяин (::GetWindow(hWnd, GW_OWNER)).

Здесь немного поясню. Дело в том, что в Windows отношение Owner-Owned могут иметь только overlapped или pop-up окна (такие как окна-рамки SDI или MDI интерфейса или диалоги). Дочерние (имеющие стиль WS_CHILD) окна имеют родительское окно (они располагаются в клиентской области родительского окна), которое должно быть указано в качестве параметра hWndParent при создании функцией CreateWindow или CreateWindowEx.

Однако, если создавать overlapped или pop-up окно (со стилем WS_OVERLAPPED или WS_POPUP) и передать в качестве параметра hWndParent дескриптор другого overlapped или pop-up окна, второе окно станет владельцем (Owner) первого. Особенности Owned (имеющих владельца) окон таковы:
  • Окно, имеющее владельца всегда находится над окном-владельцем в z-порядке.
  • Система автоматически уничтожает "подчиненные" окна, когда уничтожается их владелец.
  • "Подчиненное" окно скрывается, когда его владелец минимизируется.
MFC вводит свою иерархию Owned-окон, инкапсулируя переменную компоненту m_hWndOwner в классе CWnd. Функции-члены класса CWnd SetOwner и GetOwner устанавливают и возвращают соответственно значение m_hWndOwner. Таким образом, в терминах MFC, отношение "владелец-подчиненное" применимы и к дочерним окнам. И такая структура достаточно часто используется в MFC (например, при установке текста строки состояния панелями инструментов (toolbars) - см. CControlBar::SetStatusText).

Таким образом данная функция предоставляет механизм для перемещения вниз по иерархии окон, связанных отношениями разного типа (Parent-Child и Owner-Owned), для части из которых может быть осуществлен сабклассинг библиотекой MFC, а для части - нет.


Функция AfxIsDescendant
Декларирована AFXIMPL.H
Реализована WINFRM.CPP

Прототип

BOOL AFXAPI AfxIsDescendant(HWND hWndParent, HWND hWndChild);

Комментарии

Возвращает TRUE, если окно hWndChild является потомком (даже не прямым (!)) окна hWndParent, и FALSE в противном случае.

Это достаточно полезная функция. Очень может пригодится, например, при определении, имеет ли какой либо потомок окна фокус. Например, я иногда использую следующую функцию для нахождения активного потомка некоторого окна в иерархии окон MFC:
CWnd *GetActiveChild(CWnd *pWnd)
{
   ASSERT(pWnd != NULL);

   if(pWnd != NULL)
   {
      CWnd *pFocusedWnd = CWnd::GetFocus();

      if(pFocusedWnd != NULL)
      {
         if(AfxIsDescendant(pWnd->GetSafeHwnd(), pFocusedWnd->GetSafeHwnd()))
            return pFocusedWnd;
      }

      CFrameWnd *pFrameWnd = pWnd->GetParentFrame();

      if(pFrameWnd != NULL)
      {
         CView *pView = pFrameWnd->GetActiveView();

         if(pView != NULL)
         {
            if(AfxIsDescendant(pWnd->GetSafeHwnd(), pView->GetSafeHwnd()))
               return pView;
         }
      }
   }

   return NULL;
}


Функция _AfxChildWindowFromPoint
Декларирована AFXIMPL.H
Реализована WINUTIL.CPP

Прототип

HWND AFXAPI _AfxChildWindowFromPoint(HWND hWnd, POINT pt);

Комментарии

Находит дочернее окно, в которое "попадает" точка pt.

hWnd - дескриптор одна, среди дочерних окон которого ведется поиск.
pt - точка (в координатах клиентской области), которая должна "попасть" в окно.


Работа с именами файлов и каталогов

Функция AfxFullPath
Декларирована AFXIMPL.H
Реализована FILECORE.CPP

Прототип

BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);

Комментарии

Возвращает полный путь к файлу (копирует результат в буфер, указанный lpszPathOut; минимаьлный объем буфера должен быть равен _MAX_PATH) по относительному пути к нему (lpszFileIn).


Функция AfxGetRoot
Декларирована AFXIMPL.H
Реализована FILECORE.CPP

Прототип

void AFXAPI AfxGetRoot(LPCTSTR lpszPath, CString& strRoot);

Комментарии

Определяет корневой каталог тома вида: x:\ или \\server\share\ для заданного строкой пути lpszPath ресурса.


Функция AfxComparePath
Декларирована AFXIMPL.H
Реализована FILECORE.CPP

Прототип

BOOL AFXAPI AfxComparePath(LPCTSTR lpszPath1, LPCTSTR lpszPath2);

Комментарии

Проверяет "идентичность" переданных путей.


Функция AfxGetFileTitle
Декларирована AFXIMPL.H
Реализована FILECORE.CPP

Прототип

UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax);

Комментарии

Выделяет имя файла из переданной строки-пути (lpszPathName), копируя его в буфер, на который указывает lpszTitle. Минимальная длина буфера должна быть равна _MAX_FNAME.


Функция AfxGetModuleShortFileName
Декларирована AFXPRIV.H
Реализована FILECORE.CPP

Прототип

void AFXAPI AfxGetModuleShortFileName(HINSTANCE hInst, CString& strShortName);

Комментарии

Возвращает имя файла модуля, соответствующего дескриптору hInst. Значение возвращается в переданную по ссылке strShortName строку.


Функция AfxResolveShortcut
Декларирована AFXIMPL.H
Реализована FILECORE.CPP

Прототип

BOOL AFXAPI AfxResolveShortcut(CWnd* pWnd, LPCTSTR pszShortcutFile, LPTSTR pszPath, int cchPath);

Комментарии

"Разрешает" ярлык.
Это подразумевает, что если есть некоторый файл ярлыка (например, C:\shortcut.lnk), ссылающийся на другой файл (например, d:\exec.exe), то функция возвратит путь к файлу, на который ссылается ярлык (в данном случае - "d:\exec.exe") в строку pszPath
Также работает "многоуровневое" разрешение (когда ярлык ссылается на ярлык, и.т.д.).


Для отладки

Функция AfxIsValidAddress
Декларирована AFX.H
Реализована VALIDADD.CPP

Прототип

BOOL AFXAPI AfxIsValidAddress(const void* lp, UINT nBytes, BOOL bReadWrite = TRUE);

Комментарии

Проверяет блок памяти, объемом nBytes, указанный lp на доступность для чтения (или, если bReadWrite = TRUE, то - чтения/записи).


Функция AfxIsValidString
Декларирована AFX.H
Реализована VALIDADD.CPP

Прототип

BOOL AFXAPI AfxIsValidString(LPCWSTR lpsz, int nLength = -1);

Комментарии

Проверяет корректность указателя на юникод-строку.


Функция AfxIsValidString
Декларирована AFX.H
Реализована VALIDADD.CPP

Прототип

BOOL AFXAPI AfxIsValidString(LPCSTR lpsz, int nLength = -1);

Комментарии

Проверяет корректность указателя на ASCII-строку.


Функция AfxDumpMemoryLeaks
Декларирована AFX.H
Реализована AFXMEM.CPP

Прототип

BOOL AFXAPI AfxDumpMemoryLeaks();

Комментарии

Выводит отладочную информацию об утечках памяти (утечками памяти считаются неосвобожденные с момента старта приложения блоки памяти). В Debug-версии приложения эта функция - просто обертка для _CrtDumpMemoryLeaks. Эта функция приведена здесь больше для ознакомления, поскольку _CrtDumpMemoryLeaks вызывается явно отладочной версией ядра MFC при завершении приложения.


Функция AfxIsMemoryBlock
Декларирована AFX.H
Реализована AFXMEM.CPP

Прототип

BOOL AFXAPI AfxIsMemoryBlock(const void* p, UINT nBytes, LONG* plRequestNumber = NULL);

Комментарии

Проверяет корректность блока памяти.
В Debug-версии приложения эта функция - обертка для _CrtIsMemoryBlock. Возвращает TRUE, если указанный блок выделен в локальной куче приложения, имеет указанный в nBytes объем и имеет корректный отладочный идентификатор типа блока в куче, иначе - FALSE. Если передан параметр plRequestNumber, в переменную по этому адресу будет записан номер блока в куче.

Пример использования:
long nBlockNumber = 0;

int *p = new int[1024];

BOOL bIsValidBlock = AfxIsMemoryBlock(p, 4096, &nBlockNumber);

TRACE("bIsValidBlock = %d  nBlockNumber = %d", bIsValidBlock, nBlockNumber);

delete p;

Примечание.

Функция только для отладки ! В Release-конфигурации вместо функции просто определен макрос:

#define AfxIsMemoryBlock(p, nBytes) TRUE


Функция AfxCheckMemory
Декларирована AFX.H
Реализована AFXMEM.CPP

Прототип

BOOL AFXAPI AfxCheckMemory();

Комментарии

Проверяет целостность блоков памяти, выделенных в отладочной куче (только для отладочных версий). Возвращает TRUE, если с памятью "все в порядке", FALSE - в противном случае (в этом случае также выводится диагностическая информация). В Debug-версии приложения эта функция - обертка для _CrtCheckMemory.

Пример использования:
int *p = new int[16];
   
p = new int[16];

p[16] = 0;

AfxCheckMemory();

Примечание.

Функция только для отладки ! В Release-конфигурации вместо функции просто определен макрос:

#define AfxCheckMemory() TRUE

Книги по C++, Visual C++, MFC
Программирование на Microsoft Visual C++ 6.0 для профессионалов
Программирование на Microsoft Visual C++ 6.0 для профессионалов (+ CD ROM)

Автор: Д. Круглински, С. Уингоу, Д.Шеферд

Эта книга - настоящая "библия" программирования на Microsoft Visual C++ 6.0 с применением библиотеки классов MFC. Ориентирована на профессиональных программистов, владеющих языком С, имеющих представление о С++ и приступающих к разработке 32-х разрядных приложений для Microsoft Windows 95/98/NT/2000/XP.

В книге рассмотрены разработка приложений для новейших 32-х разрядных операционных систем (обработка событий, управление памятью, печать, GDI, DIB, SDI/MDI, ActiveX, COM, ATL, последние расширения COM), поддержка баз данных, программирование для Интернета с использованием Windows Sockets, MFC WinInet и ISAPI.

Прилагаемый к книге компакт-диск содержит образцы кода и дополнительное программное обеспечение.

Страница книги на Озоне
Язык программирования C++. Специальное издание
Язык программирования C++. Специальное издание

Автор: Бьерн Страуструп

Книга написана Бьерном Страуструпом - автором языка программирования C++ - и является каноническим изложением возможностей этого языка. Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный объектно-ориентированный подход к созданию программных продуктов.

Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++.

Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие. Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток.

Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка "из первых рук".

Страница книги на Озоне
Рассылки и дискуссионные листы компьютерной тематики
Рассылки
C/C++ Вопрос-Ответ

Это - интерактивная рассылка !
Здесь Вы можете задать свой вопрос по программированию на C и C++, а также ответить на вопросы других подписчиков.

Дискуссионные листы
Программирование. Форум !!!

Самый популярный дискуссионный лист по программированию на subscribe.ru, существующий с момента открытия сервиса дискуссионных листов !

Задайте здесь любой вопрос по программированию - и Вы получите ответ. Участвуйте в оживленных дискуссиях, обсуждайте интересные темы. Давайте ответы сами. Ведь это форум !!! Здесь просто интересно ! Присоединяйтесь !

Вебстроительство. Форум !!!

В дискуссионном листе ведется обсуждение различных аспектов создания сайтов - написание скриптов, использование, настройка портальных движков, и многое другое. Присоединяйтесь !

Поисковые системы. Форум !!!

Этот дискуссионный лист посвящен обсуждению поиковых систем, методов индексации сайтов поисковиками, способам оптимизации сайта под поисковые системы.

Хостинг. Обзоры и обсуждения платного и бесплатного хостинга.

Вы ищете хостинг (платный, бесплатный) ? Хотите спросить совета в выборе ? Можете обсудить это здесь. Поделитесь советом, если знаете. Или узнайте больше. Все о хостинге.


Всего доброго. До встречи в следующем номере.

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.qandacpp
Отписаться

В избранное