Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сохранение текста в файл из Richedit 
:(
    Опции темы
Tror
Дата 9.12.2005, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 29.4.2005
Где: Кишинёв

Репутация: нет
Всего: 4



я уже спрашивал на форуме как загрузить текст из файла в Richedit.
С этим вроде справился. Привожу код, может будут какие замечания.
Код

BOOL FileOpen()
{
    HANDLE            hFile;
    DWORD            dwFileSize;
    DWORD            dwBytesRead;
    LPVOID            lpvBuff;
    char            *cBuff;
    char            szTmpBuff[100];
    char            szWndTitle[100] = APP_TITLE;

    SendMessage(hEditWnd, WM_SETTEXT, NULL, (LPARAM)"");

    //
    //Задаём заголовок диалога открытия файла
    //
    ofn.lpstrTitle = "Opening File";

    //
    //Вызов стандартного диалога открытия файла
    //
    GetOpenFileName(&ofn);

    //
    //Попытка открытия файла
    //
    hFile = CreateFile(ofn.lpstrFile,
                        GENERIC_READ,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        (LPSECURITY_ATTRIBUTES) NULL,
                        OPEN_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL,
                        (HANDLE) NULL);

    //
    //Если файл удалось открыть...
    //
    if (hFile)
    {
        //
        //Определение размера файла
        //
        dwFileSize = GetFileSize(hFile, NULL);
        if (dwFileSize == INVALID_FILE_SIZE)
        {
            MessageBox(NULL, "Cant get file size", "Error", MB_OK | MB_ICONSTOP);
            return FALSE;
        }

        //
        //Выделение памяти для буфера
        //
        lpvBuff = VirtualAlloc(NULL, (SIZE_T)dwFileSize, MEM_COMMIT, PAGE_READWRITE);
        if (lpvBuff == NULL)
        {
            MessageBox(NULL, "Cant allocate enough memory for file opening", "Error", MB_OK | MB_ICONSTOP);
            return FALSE;
        }

        cBuff = (LPTSTR)lpvBuff;

        //
        //Получение имени файла и установка заголовка окна
        //
        GetFileTitle(ofn.lpstrFile, szTmpBuff, GetFileTitle(ofn.lpstrFile, NULL, 0));
        strcat(szWndTitle, "  --  ");
        strcat(szWndTitle, szTmpBuff);
        SendMessage(hMainWnd, (UINT)WM_SETTEXT, (WPARAM)NULL, (LPARAM)szWndTitle);

        //
        //Чтение из файла
        //
        SetFilePointer(hFile, 0, 0, FILE_BEGIN);
        ReadFile(hFile, cBuff,  dwFileSize, &dwBytesRead, NULL);
        //*(cBuff + dwBytesRead) = 0;
        SendMessage(hEditWnd, (UINT)EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)cBuff);

        //
        //Освобождение памяти
        //
        VirtualFree(lpvBuff, dwFileSize, MEM_RELEASE);

        //
        //Установка каретки в начало текста и флага модификации
        //
        SendMessage(hEditWnd, (UINT)EM_SETSEL, (WPARAM)0, (LPARAM)0);
        SendMessage(hEditWnd, EM_SETMODIFY, FALSE, 0);

        //
        //Закрытие файла
        //
        CloseHandle(hFile);
    }
    else
    {
        //
        //Вывод сообщения, если открытие файла невозможно
        //
        MessageBox(NULL, "Can't open file", "ERROR", MB_OK);
        return FALSE;
    }

    return TRUE;
}


а теперь, собственно, сабж
делаю так
Код

BOOL FileSave()
{
    HANDLE            hFile;
    GETTEXTLENGTHEX    gtl;
    DWORD            dwTextLength;
    DWORD            dwBytesWritten;
    LPVOID            lpvBuff;
    char            *cBuff;

    ofn.lpstrTitle = "Saving File";

    //
    //заполнение полей структуры GETTEXTLENGTHEX
    //
    gtl.codepage    = CP_ACP;
    gtl.flags        = GTL_NUMCHARS;

    GetSaveFileName(&ofn);

    hFile = CreateFile(ofn.lpstrFile,
                        GENERIC_WRITE,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        (LPSECURITY_ATTRIBUTES) NULL,
                        OPEN_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL,
                        (HANDLE) NULL);

    dwTextLength = SendMessage(hEditWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gtl, 0);

    lpvBuff = VirtualAlloc(NULL, dwTextLength, MEM_COMMIT, PAGE_READWRITE);
        if (lpvBuff == NULL)
        {
            MessageBox(NULL, "Cant allocate enough memory for file saving", "Error", MB_OK | MB_ICONSTOP);
            return FALSE;
        }

    cBuff = (LPTSTR)lpvBuff;

    SendMessage(hEditWnd, WM_GETTEXT, (WPARAM)(dwTextLength), (LPARAM)cBuff);
    WriteFile(hFile, cBuff, dwTextLength, &dwBytesWritten, NULL);

    //
    //Освобождение памяти
    //
    VirtualFree(lpvBuff, dwTextLength, MEM_RELEASE);

    CloseHandle(hFile);

    return TRUE;
}


тут 2 варианта:
если делаю так
Код

gtl.flags        = GTL_NUMCHARS;

то в сохранённом файле обрезается часть

если так
Код

gtl.flags        = GTL_NUMBYTES;

то в файл дописывается еще какие-то невидимые сиволы(отображаются квадратики)

что можете посоветовать?
Заранее благодарен

--------------------
Не говори всегда что знаешь, но знай всегда что говоришь. /Клавдий/============================================Кто может -- тот делает. Кто не может... тот получает сертификат MCSE ;)
PM MAIL ICQ   Вверх
Aleksandor
Дата 9.12.2005, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Практик
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 22.11.2005
Где: россия, зеленогра д

Репутация: 10
Всего: 12



Попробуй
gtl.flags= GTL_PRECISE;


--------------------
Call out Gouranga be happy!!!
Gouranga Gouranga Gouranga ....
That which brings the highest happiness!!
PM MAIL   Вверх
Fixin
Дата 9.12.2005, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Я ж в той теме статью давал, где рассказывается, как это делается методами, сообразными самому RichEdit`у.
PM MAIL ICQ   Вверх
Tror
Дата 11.12.2005, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 29.4.2005
Где: Кишинёв

Репутация: нет
Всего: 4



Fixin

Статью я читал, спасибо за интересный источник, но там написано следующее

Код

    //записываем полученный буфер в файл, размер переданного нам буфера в переменной cb
    pFile->Write(pbBuff,cb);
    //говорим RichEdit`у сколько мы обработали байтов
    *pcb=cb;
    //возвращаем ноль (у нас всё ОК)


а конкретнее обрати внимание на это
Цитата

размер переданного нам буфера в переменной cb

то есть мы сами должны передавать размер буфера в EditStreamCallback,
что я и хочу сделать, т.е. подсчитать кол-во байтов в тексте.
в этом то и заключается вся проблема
--------------------
Не говори всегда что знаешь, но знай всегда что говоришь. /Клавдий/============================================Кто может -- тот делает. Кто не может... тот получает сертификат MCSE ;)
PM MAIL ICQ   Вверх
Aleksandor
Дата 11.12.2005, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Практик
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 22.11.2005
Где: россия, зеленогра д

Репутация: 10
Всего: 12



Вот еще примерчик рабочего кода smile

Код

    GETTEXTLENGTHEX txtl;
    GETTEXTEX gtxt;
    HLOCAL hloc;
    LPCTSTR lpParts; 

                     txtl.codepage=CP_ACP;
     txtl.flags= GTL_PRECISE;
     text_size = SendMessage(hEditWnd, EM_GETTEXTLENGTHEX, (WPARAM)&txtl, 0);

    hloc = LocalAlloc(LHND, sizeof(TCHAR) * text_size); 
    lpParts = (LPCTSTR) LocalLock(hloc); 


    gtxt.cb=text_size;
    gtxt.codepage=CP_ACP; 
    gtxt.flags=GT_DEFAULT;
    gtxt.lpDefaultChar=NULL; gtxt.lpUsedDefChar=NULL;

    if (text_size>1) {

    SendMessage(hEditWnd, EM_GETTEXTEX, (WPARAM)&gtxt, (LPARAM)lpParts);  
    pPtr=(LPBYTE)lpParts;
// далее пишем в файл а адреса pPtr



--------------------
Call out Gouranga be happy!!!
Gouranga Gouranga Gouranga ....
That which brings the highest happiness!!
PM MAIL   Вверх
Fixin
Дата 11.12.2005, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Цитата(Tror @ 11.12.2005, 13:16)
то есть мы сами должны передавать размер буфера в EditStreamCallback,
Как раз нет. В этом и удобство того метода вывода - все делает сам RichEdit. Посмотри на тот же пример:
Код
DWORD CALLBACK MyOutFunction(
  DWORD dwCookie,      // то самое пользовательское значение которое мы указали в EDITSTREAM::dwCookie
  LPBYTE pbBuff,      // буфер с данными которые передает RichEdit
  LONG cb,            // размер буфера в байтах
  LONG *pcb           // указатель на переменную в которую следует
            записать сколько функция MyOutFunction успешно обработала байтов 
            из буфера pbBuff
)
{
    //в качестве dwCookie получаем указатель который мы установили в EDITSTREAM
    CFile* pFile=reinterpret_cast<CFile*>(dwCookie);
    //записываем полученный буфер в файл, размер переданного нам буфера в переменной cb
    pFile->Write(pbBuff,cb);
    //говорим RichEdit`у сколько мы обработали байтов
    *pcb=cb;
    //возвращаем ноль (у нас всё ОК)
    return 0;
}
Эту функцию, к стати, ты сам вызывать не должен -> не может "послать" параметр cb.

PM MAIL ICQ   Вверх
Guest
Дата 18.12.2005, 19:57 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Fixin, Aleksandor
Спасибо, всё получилось.
Сделал обоими методами. smile smile
  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0479 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.