Сообщений 25 Оценка 90 [+1/-0] Оценить |
Исходники библиотеки
Сайт проекта
На самом деле это довольно сложный вопрос. В начале (а прошёл уже год более или, скорее, менее активной работы) это был метод что-то доказать себе, нежели желание принести пользу. Не знаю, наверное, это болезнь всех, кто начинал на медленных машинах (80286), желание оптимизировать… Помню как мне слегка (и это не преуменьшение) не понравилась стандартная библиотека Borland Pascal 7.0, и я полностью переписал её всю (CRT, Graph, DOS + свои модули) на ассемблере. Ну вот, с тех пор и страдаю болезнью замены Run-Time Libraries :)
Начиналась писаться XWPL ещё на 6-й студии. Но потом плавно перетекла под седьмую. Правда, совместимость не потеряна. Если всё же что-то не скомпилируется на 6-й - сообщите, перепишу. Со временем библиотека обросла классами, функциями, и теперь стала довольно большой по размеру и, даже полезной. Кому она нужна? Я вот сейчас с её помощью пишу GUI приложения, сервисы, консольные пока не выйдут, но и это в планах. Но кроме оконных, она содержит, и кучу других, не менее полезных, классов. XWPL писалась так, чтобы при необходимости любой её класс или функцию можно было использовать независимо от остальных.
Подключите проект XWPL и добавьте в нужное место
#include "xwpl.h" |
Ну вот вроде и всё :) Да, для тех, кто не знает, можно указывать относительные пути:
#include "..\xwpl\xwpl.h" |
Названия структур - полностью из прописных букв. Между словами подчерк. Названия полей - каждое слово с прописной буквы, первое со строчной буквы.
typedef struct _STRUCT_NAME_TAG_ { TYPE memberName; } STRUCT_NAME, * LPC_STRUCT_NAME; |
Названия классов - каждое слово с прописной буквы с префиксом C_. Этот префикс продуман специально под технологию IntelliSence, чтобы, набрав его и нажав Ctrl+Пробел можно было получить названия всех классов. Использовать буквенные префиксы (вроде gl) не хотелось. Названия полей - каждое слово с прописной буквы, первое с строчной. Названия методов - каждое слово с прописной буквы. Исключение это методы обёртки вызовов функции SendMessage для оконных классов. Их названия начинаются с префикса sm_ и состоят только из строчных букв.
typedef class _CClassName_tag_ { public: TYPE memberName; private: RET_TYPE1 MemberFunction(PARAM_TYPE paramaterName); RET_TYPE2 sm_messagename(MESSAGE_PARAM_TYPE messageParamType); } C_ClassName, * LPC_ClassName; |
Отладочный макрос. Единственный параметр - истинное в нормальной ситуации выражение.
DEBUG_CHECK |
Макросы работы со строками. Конвертирование строк. C_Str соответствует классу C_StringA или C_StringW в зависимости от того ANSI или UNICODE сборка.
STR_A_TO_T STR_W_TO_T STR_T_TO_W STR_T_TO_A STR_A_TO_T_LEN STR_W_TO_T_LEN STR_T_TO_W_LEN STR_T_TO_A_LEN C_Str |
Функции для работы с памятью. Пока транслируются в Heap***. Но в будущем это должно измениться. Предполагается наличие собственного менеджера кучи.
memInitialize memFinalize memAlloc memRealloc memFree memSize |
Функции для работы со строками. Все перегружены и имеют ANSI и UNICODE версию. Функции конвертирования имеют четыре версии ANSI->ANSI, ANSI->UNICODE, UNICODE->ANSI, UNICODE->UNICODE. Большинство функций транслируются в вызовы функций API lstr***. В любом случае это вспомогательные функции (что видно по подчерку в начале названия) и в обычной практике рекомендуется использовать класс C_String.
_str_convert _str_convert_len _str_convert_len _str_convert_char _str_len _str_load _str_cat _str_copy _str_lower _str_upper _str_comp _str_compi |
Обёртки для объектов синхронизации.
C_Event C_Mutex C_Semaphore |
Обертка для работы с реестром.
C_Registry |
Класс типизированного буфера с автоматическим освобождением памяти.
C_AutoPtr |
Парсер математических выражений (пока в разработке). Используется стековый алгоритм Бауэра - Земельзона.
C_MathParser |
Шаблоны структур данных (пока в разработке).
C_Stack C_Queue C_HashElement C_SortedHash |
Шаблон строки (пока в разработке). Определены классы C_StringA и C_StringW для ANSI и UNICODE строк соответственно.
C_String |
Обёртки для соответствующих структур (есть проблемы с конструкторами C_Variant).
C_Variant C_SafeArray C_Decimal C_Currency |
Совместимые с OLE потоки для работы с файлами и pipe-ами.
C_StreamFile C_StreamFileMapping C_StreamPipe |
Классы для GDI графики.
C_Desktop C_DC C_Font |
Обёртки для меню и окна.
C_Menu C_Window |
Обёртки простых контролов.
C_Button C_ComboBox C_Edit C_ListBox C_Static C_RichEdit |
И продвинутых.
C_Animation C_ComboBoxEx C_DateTimePicker C_DragListBox C_FlatScrollBar C_ImageList C_IpAddress C_ListView C_Pager C_ProgressBar C_PropertySheet C_Rebar C_StatusBar C_Tab C_Toolbar C_Tooltip C_TreeView |
Обёртки диалогов открытия и сохранения файлов.
C_OpenFileName C_SaveFileName |
Обёртки для иконок в системном трее и Active Desktop (пока в разработке).
C_NotifyIcon C_ActiveDestop |
Окно с картой сообщений. Реализация сильно отличается от MFC-шной.
C_AdvancedWindow |
Классы для работы с сетью. Почему нет C_UdpSocket? Руки пока не дошли. C_TcpIpSocket кстати говоря, совместим с ISequentialStream.
CNetwork - уже созданный объект. По смыслу его не нужно больше чем один.
C_TcpIpSocket CNetwork |
Универсальное, не типизированное хранилище табличных данных. Тип указывается как параметр столбца в виде переменной типа VARTYPE (константы VT_***). Работа на уровне двоичных буферов.
C_DataColumn C_DataGrid |
ODBC интерфейс к базам данных. Результаты запросов (если есть) записываются в C_DataGrid.
C_ODBC C_ODBCConnection C_ODBCSQLStatement |
Обёртки для потоков, процессов и модулей. CApplication - уже созданный объект. По смыслу его не нужно больше чем один.
C_Thread C_Process C_Module CApplication |
ПРЕДУПРЕЖДЕНИЕ Библиотека XWPL использует свою версию CRT которая пока не поддерживает SEH/C++ exceptions, но я сейчас этим занят и вы можете помочь мне это реализовать. |
Для начала, надо сказать, что подключить XWPL к уже готовому проекту не очень просто. Входная процедура для вас XWPLMain. Переименуйте ваш WinMain в XWPLMain (параметры немного другие, но смысл сохранён) и решите много проблем. В любом случае я бы хотел начать с простого приложения ориентированного только на XWPL. Итак.
// #include "..\xwpl\xwpl.h" // Класс главного окна xwpl::C_AdvancedWindow CWindowMain; // Класс окна RichEdit в котором можно вводить текст xwpl::C_RichEdit CRichEdit; // Обработчик попытки закрытия окна LRESULT CALLBACK OnClose(HWND hWnd,WPARAM wParam,LPARAM lParam) { DestroyWindow(hWnd); PostQuitMessage(0); return 0; } // Обработчик попытки использовать контекстное меню LRESULT CALLBACK OnMenu(HWND hWnd,WPARAM wParam,LPARAM lParam) { // Local variables // Окно у которого фокус xwpl::C_Window CWindow(GetFocus()); // Code // послать окну у которого фокус соответствующее сообщение if (LOWORD(wParam) == STD_STRID_EDIT_CUT) { CWindow.sm_cut(); } if (LOWORD(wParam) == STD_STRID_EDIT_COPY) { CWindow.sm_copy(); } if (LOWORD(wParam) == STD_STRID_EDIT_PASTE) { CWindow.sm_paste(); } return 0; } // Обработчик события клика мышью на ссылке. Ссылкой становиться любой текст введённый в RichEdit // если он имеет нужный формат. Например http://xwpl.narod.ru LRESULT CALLBACK OnNotify(HWND hWnd,WPARAM wParam,LPARAM lParam) { // Класс автоматического рапределения памяти xwpl::C_AutoPtr<TCHAR,MAX_PATH> CLinkText; TEXTRANGE tr; // Если нужное действие (отпустили левую кнопку) if (((ENLINK *)lParam)->msg != WM_LBUTTONUP) { return 0; } // Получить текст ссылки tr.lpstrText = (LPTSTR)CLinkText; tr.chrg = ((ENLINK *)lParam)->chrg; xwpl::C_RichEdit CRichEdit(((ENLINK *)lParam)->nmhdr.hwndFrom); CRichEdit.sm_gettextrange(&tr); // И открыть в эксплорере ShellExecute(NULL,T("OPEN"),T("iexplore.exe"),(LPTSTR)CLinkText,NULL,SW_SHOW); return 0; } // int XWPLMain(HINSTANCE hInstance,C_Str CStrCommandLine,int nCmdShow) { // Пременная класса окна WNDCLASSEX wce; // Обнулить переменную ZeroMemory(&wce,sizeof(wce)); // Задний фон - обычный wce.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // Зарегистрировали класс. Имя класса создано автоматически. ATOM classAtom = CWindowMain.RegisterClass(&wce); // Начать регистрировать обработчики сообщений XWPL_MSGMAP_BEGIN(classAtom) // Зарегистрировать обработчики сообщений для оконного класса XWPL_MSGMAP_MESSAGE(OnClose,WM_CLOSE) XWPL_MSGMAP_MENU_ID(OnMenu,STD_STRID_EDIT_CUT); XWPL_MSGMAP_MENU_ID(OnMenu,STD_STRID_EDIT_COPY); XWPL_MSGMAP_MENU_ID(OnMenu,STD_STRID_EDIT_PASTE); XWPL_MSGMAP_NOTIFY_MESSAGE(OnNotify,EN_LINK); // Закончить регистрировать обработчики сообщений XWPL_MSGMAP_END // Создать окно CWindowMain.CreateAdvancedWindow(0,T("caption"),WS_CAPTION|WS_SIZEBOX|WS_SYSMENU,0,0,550,550,NULL); // Создать дочернее окно CRichEdit.CreateRichEdit(0,NULL,WS_CHILD|WS_BORDER|WS_VSCROLL|ES_MULTILINE,10,10,530,500,CWindowMain); // Показать дочернее окно CRichEdit.ShowWindow(SW_SHOWNORMAL); CRichEdit.UpdateWindow(); // Установить обработчик OLE запросов по умолчанию. Теперь в RichEdit можно вставлять картинки и другие объекты. CRichEdit.sm_setolecallback(XWPL_RICHEDIT_CALLBACK_DEFAULT); // Включить автоматическое распознавание адресов типа URL и преобразование их в ссылки CRichEdit.sm_autourldetect(TRUE); // Включить оповещение родительского окна прии операциях над ссылками. CRichEdit.sm_seteventmask(ENM_LINK); // Запустить главный цикл окна. Первы параметр типа ACCEL – клавишный ускоритель, // второй HWND окна с классом MDICLIENT или NULL если приложение не имеет MDI интерфейса. return xwpl::CApplication.RunMessageLoop(NULL,NULL); } // // end of file // |
Её нужно выделять и освобождать. Как? Просто!
// Выделили память, 100 байтов, изначально заполненных нулями. // Сколько реально выделилось памяти так, сразу, не известо. LPVOID lpPointer = memAlloc(100); // if (lpPointer == NULL) { // Если не выделилось... } // Но можно узнать вот так, меньше чем 100 (заказанный размер) в любом случае не выделится. UINT realSize = memSize(lpPointer); // А вот нам понадобилось ещё 150 байт, итого 250 байт. Остаток (последние 150 байт) инициализированы нулями. // Первые 100 имеют старые значения. LPVOID lpPointerNew = memRealloc(lpPointer,250); // Если не выделилось дополнительные 150 байт if (lpPointerNew == NULL) { // то } else { lpPointer = lpPointreNew; } // Ну и освободим память. memFree(lpPointer); // { // Локальная переменная, типизированный буфер. Первый параметр шаблона - тип содержимого // второй параметр – количество элементов. То есть в нашем случае реально выделенное // количество байт не меньше 1024*sizeof(TCHAR). Выделенная память инициализируется нулями. C_AutoPtr<TCHAR,1024> CStrPtr; // Если память не выделилась, то debug версия орёт об этом во всё горло, а release просто запишет NULL. // Есть два перегруженных оператора UINT и TYPE * возвращающие количество элементов и адрес блока памяти с данными. ZeroMemory(CStrPtr,CStrPtr); // Это лишнее – память и так обнулена // Возможности изменить количество выделенной памяти нельзя. // А память освободится здесь, в деструкторе, при выходе из зоны видимости. } |
Как вы уже успели заметить - здесь всё ещё в стадии разработки. Если кто хочет помочь - милости просим! Если есть замечания, дополнения, идеи, наработки, ну или если вы считаете, что здесь всё неправильно и можете это обосновать - пишите.
СОВЕТ Вы вполне можете использовать мой почтовый адрес в качестве простейшей поддержки. Если есть вопросы или проблемы пишите обязательно. Ваши письма – материал для улучшения библиотеки. |
В исходниках библиотеки есть файл changes.txt. В нём есть полезная информация.
Огромное спасибо всем тем, кто отвечал на мои вопросы с форумах. По информативности MSDN-у до RSDN-на еще плыть и плыть.
ПРЕДУПРЕЖДЕНИЕ Windows торговая марка Microsoft. IntelliSence тоже, наверное, кто-то зарегистрировал. Хотя XWPL и не является зарегистрированной торговой маркой, я всё же обижусь, если кто-то сознательно будет прикрываться этим именем. Ребята, давайте жить дружно. |
Сообщений 25 Оценка 90 [+1/-0] Оценить |