FAQ:WinAPI, VCPP Part 3 — различия между версиями
RXL (обсуждение | вклад) м |
RXL (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
===Что означают сообщения, которые студия выводит при компиляции, вроде таких: Loaded 'C:\WINDOWS\SYSTEM\WSOCK32.DLL', no matching symbolic information found?=== | ===Что означают сообщения, которые студия выводит при компиляции, вроде таких: Loaded 'C:\WINDOWS\SYSTEM\WSOCK32.DLL', no matching symbolic information found?=== | ||
Версия 15:37, 3 октября 2009
Содержание
- 1 Что означают сообщения, которые студия выводит при компиляции, вроде таких: Loaded 'C:\WINDOWS\SYSTEM\WSOCK32.DLL', no matching symbolic information found?
- 2 Как обработать сообщения, которые приходят к элементу управления?
- 3 Как настроить количество пробелов в табуляции?
- 4 Как автоматически расставить отступы?
- 5 Поиск границ блока.
- 6 Вертикальное выделение текста.
- 7 Как узнать количество установленных в CListCtrl столбцов?
- 8 Как получить иконку приложения?
- 9 Как в CString можно найти или вырезать часть строки?
- 10 Как отобразить на элементах управления промежуточные результаты длительных вычислений?
- 11 Я написал DLL, которую используют несколько приложений. Всё работает, но когда происходит очередной вызов функции из DLL, почему то, данные в функции обнуляются. С чем это связано?
- 12 Как открыть проекцию файла в память и как с ней работать?
- 13 Как в MFC Grid control отобразить картинку в ячейке?
- 14 Как при помощи IPicture отобразить картинку из файла?
- 15 Как позволить пользователю начать ввод новой строки в многострочном поле редактирования?
- 16 Как выводят картинку-логотип (splash screen) при запуске программы?
- 17 Как сделать, чтобы при выпадении списка у ComboBox была не одна строка, а больше? Вроде все свойства покрутил, не помогает: вместо выпадающего списка - одна строка и скролл.
- 18 VC++.NET. На форму установил ActiveX ListView. Как объявить класс и переменную для этого элемента?
- 19 Как работать с буфером обмена (Clipboard)?
- 20 Как получить полный путь к экзешнику из самой программы?
- 21 Каким способом exe файл может заменить самого себя?
- 22 Как производится конвертация из кодировки UTF8 в 1251 и наоборот?
- 23 Как работать с базой данных Access из программы на VC.net?
Что означают сообщения, которые студия выводит при компиляции, вроде таких: Loaded 'C:\WINDOWS\SYSTEM\WSOCK32.DLL', no matching symbolic information found?
Это строка говорит о том, что студия не смогла найти отладочные символы для WSOCK32.DLL. В этом нет ничего страшного. Просто, при наличии отладочных символов в процессе отладки, можно получить доступ к именам функции из системных DLL. Например, вместо KERNEL32! 0x77E8B184() увидим KERNEL32!CreateThread.
Как обработать сообщения, которые приходят к элементу управления?
Скажем, нужно обработать сообщения, приходящие к элементу класса CEdit. Нужно произвести от CEdit свой класс и в виртуальной процедуре класса WindowProc перехватить нужные сообщения.
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam );
Пример. Полностью выключаем, скажем, обработку сообщения WM_CHAR.
LRESULT CMyEdit::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CHAR: { return 0; } break; } return CEdit::WindowProc(message, wParam, lParam); }
Чтобы связать экземпляр класса с элементом управления на форме, добавьте визардом для элемента управления переменную класса (выбрав не Value, а Control).
Как настроить количество пробелов в табуляции?
Есть пара способов:
- Tools->Options->Tabs->Insert Spaces
- Правой кнопкой мыши щёлкнуть по тексту, в контекстном меню выбрать properties.
Как автоматически расставить отступы?
Нужно в студии выделить текст для форматирования и нажать Alt+F8.
Ещё есть программа Artistic Style ( http://sourceforge.net/projects/astyle/ ), которая занимается переформатированием кода.
Поиск границ блока.
Сочетание клавиш CTRL+"}" ищет парную фигурную скобку в тексте и переходит к ней.
Вертикальное выделение текста.
Если удерживать клавишу Alt, а затем начать выделять текст мышкой, то область выделения принимает форму прямоугольника, что позволяет выделять вертикальные фрагменты текста.
Как узнать количество установленных в CListCtrl столбцов?
Пример:
// указатель на переменную-элемент управления CListCtrl* pL = ...; // получаем количество столбцов int count = pL->GetHeaderCtrl()->GetItemCount();
Как получить иконку приложения?
Если приложение запущено, то нужно найти его главное окно и послать ему сообщение WM_GETICON.
// функция возвращант хендл иконки LRESULT SendMessage(hWnd, WM_GETICON, wParam, 0); // hWnd == хендл окна приложения // wParam == // 1)==ICON_BIG - получить большую иконку // 2)==ICON_SMALL - получить маленькую иконку // 3)==ICON_SMALL2 - получить маленькую иконку, если она определена // в приложении. Если её нет, то маленькую иконку, // сгенерированную системой из большой иконки
Как в CString можно найти или вырезать часть строки?
Это можно сделать при помощи методов класса CString:
// вырезает кусок строки CString Mid(int nFirst) const; CString Mid(int nFirst, int nCount) const; // возвращает кусок строки (сначала или с конца) CString Left(int nCount) const; CString Right(int nCount) const; // возвращает начальный кусок строки, в котором есть только // символы из набора, представленного в lpszCharSet CString SpanIncluding(LPCTSTR lpszCharSet) const; // возвращает начальный кусок строки, в котором нет // символов из набора, представленного в lpszCharSet CString SpanExcluding(LPCTSTR lpszCharSet) const; // убирает "пробелоподобные" символы из самого начала строки. // то есть - пробел, табуляцию (\t), возврат каретки, перевод строки (/r/n) void TrimLeft(); // убирает все повторы символа из самого начала строки void TrimLeft(TCHAR chTarget); // убирает из самого начала строки все символа из набора lpszTargets void TrimLeft(LPCTSTR lpszTargets); void TrimRight(); void TrimRight(TCHAR chTarget); void TrimRight(LPCTSTR lpszTargets); // поиск в строке int Find(TCHAR ch) const; int Find(LPCTSTR lpszSub) const; int Find(TCHAR ch, int nStart) const; int Find(LPCTSTR pstr, int nStart) const; // поиск, начиная с конца int ReverseFind(TCHAR ch) const; // поиск позиции первого символа, одного из набора, // представленного в lpszCharSet int FindOneOf(LPCTSTR lpszCharSet) const;
Как отобразить на элементах управления промежуточные результаты длительных вычислений?
В общем случае это делается принудительной перерисовкой нужного окна путём объявления этого окна невалидным.
pWnd->Invalidate(0);
Затем непосредственной отсылки в оконную процедуру сообщения WM_PAINT.
pWnd->UpdateWindow();
Пример:
CWnd* pWnd = ...; // окно, которое надо перерисовывать for (int i = 0; i < 10000; i++) { // меняется содержимое окна // ... // немедленная перерисовка pWnd->Invalidate(0); pWnd->UpdateWindow(); }
Также можно также просто вызвать метод RedrawWindow() с параметрами по умолчанию.
Я написал DLL, которую используют несколько приложений. Всё работает, но когда происходит очередной вызов функции из DLL, почему то, данные в функции обнуляются. С чем это связано?
Переменные и массивы в DLL, содержимое которых должно использоваться несколькими процессами, должны объявляться статическими. Статическая переменная или массив инициализируются только один раз в момент загрузки DLL.
Пример:
DWORD calltest() { // будет выполнено только при первом вызове static DWORD callcount = 0; static DWORD str[1000] = {0}; // будет выполняться каждый раз callcount++; return callcount; }
Как открыть проекцию файла в память и как с ней работать?
Создание проекции:
HANDLE CreateFileMapping( HANDLE hFile, // хендл уже открытого файла LPSECURITY_ATTRIBUTES lpAttributes, DWORD flProtect, // способ открытия проекции DWORD dwMaximumSizeHigh, // размер файла (старшие 4 байта, обычно - 0) DWORD dwMaximumSizeLow, // размер файла (младшие 4 байта) LPCTSTR lpName );
Доступ к созданной проекции производится процедурой:
LPVOID MapViewOfFile( HANDLE hFileMappingObject, // хендл проекции DWORD dwDesiredAccess, // способ работы с проекцией DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, // смещение от начала файла (младшие 4 байта) SIZE_T dwNumberOfBytesToMap // длина в байтах (если 0 - то весь файл) );
Далее с файлом можно работать как с обычным массивом в памяти.
После работы с проекцией, её надо освободить.
BOOL UnmapViewOfFile( LPCVOID lpBaseAddress // адрес, который вернула процедура MapViewOfFile );
Пример:
HANDLE hFile = ...; // хендл уже открытого файла DWORD dwdFileLen = ...; // размер открытого файла HANDLE hMapFile = 0; // хендл для проекции // создаём проекцию "только для чтения" hMapFile = ::CreateFileMapping(hFile, 0, PAGE_READONLY, 0, dwdFileLen, 0); // хендл hFile можно закрыть уже здесь, в принципе, // но мы сделаем это позже // получаем доступ к проекции (тоже только для чтения) BYTE* pbyFile = (BYTE*)::MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); /////////////////// // тут работаем с массивом pbyFile[dwdFileLen] как с обычным, // только не забываем, что он открыт только для чтения // ... // ... // ... /////////////////// // отключаем файл данных от адресного пространства UnmapViewOfFile(pbyFile); // освобождаем хендл проекции CloseHandle(hMapFile) // освобождаем хендл открытого файла CloseHandle(hFile);
Как в MFC Grid control отобразить картинку в ячейке?
Нужно создать список изображений (CImageList), затем передать указатель на список в таблицу. Поскольку элемент управления лишь копирует указатель, список должен создаваться динамически, либо быть членом класса, экземпляр которого существует всё время работы таблицы.
CImageList m_ImageList; CGridCtrL m_Grid1; // ... // неким образом создаётся список m_ImageList.Create(...); // ... //вставляем в элемент управления m_Grid1.SetImageList(&m_ImageList);
Как при помощи IPicture отобразить картинку из файла?
Пример - несложная функция, отображающая картинку из файла. Поддерживаются форматы BMP, GIF, JPEG, PNG, TIFF, EMF.
#include "atlconv.h" #define HandleIsValid(H) (H != (HANDLE) - 1 && H != (HANDLE)0) // *pDestDC - CDC, на который предполагается вывод картинки // pchzFilePath - путь к файлу // pWid - (возвращает) ширина картинки // pHig - (возвращает) высота картинки bool DrawBitmapFromFile(CDC* pDestDC, const char* pchzFilePath, int *pWid = 0, int *pHig = 0) { bool result = false; if (pWid) *pWid = 0; if (pHig) *pHig = 0; int Wid = 0; int Hig = 0; IPicture* pPic = 0; try { IPicture* ptmpPic = 0; USES_CONVERSION; HRESULT hr; CString txt = pchzFilePath; hr = ::OleLoadPicturePath( const_cast<LPOLESTR>(T2COLE(txt)), 0, 0, 0, IID_IPicture, reinterpret_cast<void **>(&ptmpPic) ); if (hr == S_OK && ptmpPic) { pPic = ptmpPic; } else { throw 0; } OLE_XPOS_HIMETRIC cxSrc; OLE_YPOS_HIMETRIC cySrc; if (S_OK != pPic->get_Width(&cxSrc)) { throw 0; } if (S_OK != pPic->get_Height(&cySrc)) { throw 0; } Wid = cxSrc / 26; Hig = cySrc / 26; // рисуем if (S_OK != pPic->Render(pDestDC->GetSafeHdc(), 0, Hig, Wid, -Hig, 0, 0, cxSrc, cySrc, 0)) { throw 0; } } catch (...) { result = false; } if (pPic) { pPic->Release(); pPic = 0; } if (pWid) { *pWid = Wid; } if (pHig) { *pHig = Hig; } return result; }
Как позволить пользователю начать ввод новой строки в многострочном поле редактирования?
Нужно в редакторе ресурсов поставить для свойств окошка CEdit галочку "WantReturn" или добавить стиль ES_WANTRETURN при создании CEdit элемента управления динамически. Тогда при нажатии Enter в поле редактирования будет вводиться новая строка.
Как выводят картинку-логотип (splash screen) при запуске программы?
Для этого используется класс, производный от CDialog. Этот диалог после создания показывает себя на экран, выводя на себя рисунок. Также запускает таймер, по срабатывани которого диалог гасится. Создаётся диалог в процедуре InitInstance приложения.
В VC6++ также есть уже готовый компонент: Project->Add To Project -> Components and Controls->(в папке "Visual C++ Components" есть SplashScreen.).
Как сделать, чтобы при выпадении списка у ComboBox была не одна строка, а больше? Вроде все свойства покрутил, не помогает: вместо выпадающего списка - одна строка и скролл.
В редакторе ресурсов надо щелкнуть в комбобоксе на треугольнике - появляется рамка для растягивания вниз - размер выпадающего списка.
VC++.NET. На форму установил ActiveX ListView. Как объявить класс и переменную для этого элемента?
Щёлкнуть правой кнопкой мыши на элементе, в меню - add variable или add class.
Как работать с буфером обмена (Clipboard)?
Копирование в буфер обмена.
Алгоритм:
- Готовим данные
- Выделяем память из кучи, вызывая GlobalAlloc()
- Получаем указатель на выделенную память, вызывая GlobalLock()
- Заполняем данные
- Освобождаем указатель, вызывая GlobalUnlock();
- Открываем буфер обмена, вызывая OpenClipboard();
- Очищаем буфер, вызывая EmptyClipboard();
- Вызываем SetClipboardData() один раз для каждого формата вставляемых данных (имеется в виду - если одни и те же данные представлены в разных форматах, и приложение может эти форматы создать)
- Закрываем буфер, вызывая CloseClipboard();
- ВЫЗЫВАТЬ GlobalFree() НЕ НУЖНО, в этом случае это предоставлено системе
Скажем, хотим поместить в буфер обмена текст.
// готовим данные // выделяем из кучи память для данных HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE,10); if (!hglbCopy) return; // получаем указатель void* lpStr = GlobalLock(hglbCopy); if (!lpStr) return; // заполняем данные strcpy((char*)lpStr, "my text"); // освобождаем указатель GlobalUnlock(hglbCopy); lpStr = 0; // открываем буфер обмена OpenClipboard(); // очищаем EmptyClipboard(); // текстовый формат SetClipboardData(CF_TEXT, hglbCopy); // закрываем буфер CloseClipboard();
Извлечение из буфера обмена.
Алгоритм:
- Проверяем, что поддерживается нужный формат данных, вызывая IsClipboardFormatAvailable()
- Открываем буфер обмена, вызывая OpenClipboard();
- Достаём данные
- Получаем из буфера хендл требуемого формата, вызывая GetClipboardData()
- Получаем указатель на выделенную память, вызывая GlobalLock()
- Работаем с данными
- Освобождаем указатель, вызывая GlobalUnlock();
- Закрываем буфер, вызывая CloseClipboard();
Скажем, хотим извлечь из буфера обмена текст.
// Проверяем, что поддерживается нужный формат данных, if (!IsClipboardFormatAvailable(CF_TEXT)) return; // открываем буфер обмена OpenClipboard(); // достаём данные // текстовый формат HANDLE hglbCopy = GetClipboardData(CF_TEXT); if (!hglbCopy) return; // получаем указатель void* lpStr = GlobalLock(hglbCopy); if (!lpStr) return; // читаем данные char data[10]; memmove(data, lpStr, sizeof(data)); // освобождаем указатель GlobalUnlock(hglbCopy); lpStr = 0; // закрываем буфер CloseClipboard();
Как получить полный путь к экзешнику из самой программы?
Можно прочитать параметры командной строки - в командную строку первым параметром система всегда передаёт заключённый в кавычки полный путь к файлу запущенной программы. Достаём путь следующим образом:
BOOL CMyApp::InitInstance() { // добыча полного имени экзешника CString csFullExeName; { CString csAppName = GetCommandLine(); csAppName.Delete(0, 1); csAppName.Replace('\"', '\0'); csFullExeName = (const char*)csAppName; } // теперь csFullExeName содержит искомый путь //... //... }
Каким способом exe файл может заменить самого себя?
К примеру, программа должна обновляется через Internet и хочет обновить свой exe-файл. Но так как он в данный момент запущен, это будет, естественно, невозможно сделать напрямую. Один из способов - сделать копию экзешника и из него обновиться
// путь к старому файлу #define def_exeNAMEup "c:\\myprog_toupdate.exe" // путь к новому файлу (уже "скачали":) ) #define def_exeNAMEdnld "c:\\myprog_downloaded.exe" #define def_keyUdate "/update" void CTESTFAQApp::UpdateItself() { // добыча полного имени экзешника CString csFullExeName; { CString csAppName = GetCommandLine(); csAppName.Delete(0,1); csAppName.Replace('\"', '\0'); csFullExeName = (const char*)csAppName; } // теперь csFullExeName - содержит искомый путь // делаем копию экзешника с другим именем CopyFile(csFullExeName, def_exeNAMEup, 0); // передаём в параметры нового процесса ключ и путь к текущему файлу CString csParams = def_keyUdate; csParams += " "; csParams += csFullExeName; // запускаем копию STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (CreateProcess(def_exeNAMEup, def_keyUdate, 0, 0, 0, 0, 0, 0, &si, &pi)) { // завершаем текущий процесс ExitFromMyApp(); } } void CTESTFAQApp::ExitFromMyApp() { exit(0); } BOOL CTESTFAQApp::InitInstance() { // смотрим, не запущено ли для апдейта? CString txt; txt = m_lpCmdLine; if (txt.Find(def_keyUdate) == 0) { // делаем айдейт txt.Replace(def_keyUdate, ""); txt.TrimLeft(); CString csFullExeName = txt; // берём откуда то уже скачанный файл обновления // ... CString csFull_Downloaded_ExeName = def_exeNAMEdnld; // копируем файл (обновляем старый то есть) CopyFile(csFull_Downloaded_ExeName, csFullExeName, 0); // запускаем обновлённого мученника STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (CreateProcess(csFullExeName, 0, 0, 0, 0, 0, 0, 0, &si, &pi)) ExitFromMyApp(); } // ... // ... }
Как производится конвертация из кодировки UTF8 в 1251 и наоборот?
Можно перевести строку из UTF8 в Unicode, затем из Unicode в 1251
Ниже приведена структура, содержащая процедуры перекодирования, а также процедуру с примером использования.
// описание структуры struct coder { // utf8->unicode static wchar_t* utf8_to_unicode__dontForgetDeleteArr(const char *utf8_string) { wchar_t* pRes = 0; int res_len = 0; // тест на возможность преобразования res_len = MultiByteToWideChar(CP_UTF8, 0, utf8_string, -1, 0, 0); if (!res_len) { return 0; } // выделяем память pRes = new wchar_t[res_len]; if (!pRes) { return 0; } // преобразование if (!MultiByteToWideChar(CP_UTF8, 0, utf8_string, -1, pRes, res_len)) { delete[] pRes; return 0; } return pRes; } // unicode->1251 static char * unicode_to_1251__dontForgetDeleteArr(const wchar_t *unicode_string) { char* pRes = 0; int res_len = 0; // тест на возможность преобразования res_len = WideCharToMultiByte(1251, 0, unicode_string, -1, 0, 0, 0, 0); if (!res_len) { return 0; } // выделяем память pRes = new char[res_len]; if (!pRes) { return 0; } // преобразование if (!WideCharToMultiByte(1251, 0, unicode_string, -1, pRes, res_len, 0, 0)) { delete[] pRes; return 0; } return pRes; } // процедура с примером static void Example() { wchar_t* unicode_string = 0; char* cp1251_string = 0; // исходный текст char utf8_string[] = "UTF-8 + русский текст"; for (;;) { unicode_string = utf8_to_unicode__dontForgetDeleteArr(utf8_string); if (!unicode_string) { AfxMessageBox("Не удалось конвертировать в unicode!"); break; } cp1251_string = unicode_to_1251__dontForgetDeleteArr(unicode_string); if (!cp1251_string) { AfxMessageBox("Не удалось конвертировать из unicode!"); break; } break; } // cp1251_string - результат AfxMessageBox(cp1251_string); // не забываем удалить массивы if (unicode_string) { delete[] unicode_string; unicode_string = 0; } if (cp1251_string) { delete[] cp1251_string; cp1251_string = 0; } } }; // вызов примера coder::Example();
Как работать с базой данных Access из программы на VC.net?
Проще всего подключить ADO компоненты и сделать все на них.
Компоненты ADO (ADODC,DATAGRID и т.п.) это ActiveX.
В редакторе ресурсов, во всплывающем меню, есть Insert ActiveX Control -> открывается список всех компонент, зарегистрированных на машине. Нужно найти компоненты (Это компоненты от MS и они помечены (OLEDB)) и вставить их в диалог. Для того что бы иметь возможность управлять ими, нужно импортировать обертки для них, это делается при помощи ClassWizard, там есть импорт->класс->указать файл с компонентой (OSX). Появляется список всех классов, объявленных внутри.
Расставляем нужные галочки, нажимаем ОК.