Конференция "Начинающим" » Как из RichEdit получить и засунуть текст в формате RTF? [D7]
 
  • Nikfel (10.07.10 22:37) [0]
    Подскажите, пожалуйста. Создаю RichEdit так:
    Var hRichDll: HINST;
       RichWnd : HWND;
    begin
    hRichDll := LoadLibrary('RICHED20.DLL');
    RichWnd := CreateWindowEx (WS_EX_STATICEDGE,'RichEdit20W','',
    WS_VISIBLE or WS_VSCROLL or WS_HSCROLL or WS_CHILD or ES_AUTOVSCROLL or  ES_WANTRETURN or ES_MULTILINE,
    0, 0,100, 100,hWin,0,Hinstance,nil);



    А вот как получить и засунуть текст в формате RTF в RichEdit? Заранее спасибо.
  • Юрий Зотов © (11.07.10 17:03) [1]
    Неиспользование VCL принципиально важно? Просто с VCL все это делается за полминуты.
  • Anatoly Podgoretsky © (11.07.10 17:09) [2]
    > Юрий Зотов  (11.07.2010 17:03:01)  [1]

    Может и важно, у него же RichEdit 3
  • Nikfel (11.07.10 21:44) [3]

    > Неиспользование VCL принципиально важно? Просто с VCL все
    > это делается за полминуты.

    Да с VCL это делать очень просто, но мне так не нравится. Без VCL гораздо удобнее для меня, но знаний пока маловато.
  • Германн © (12.07.10 01:37) [4]

    > Без VCL гораздо удобнее для меня, но знаний пока маловато.

    ???
  • Leonid Troyanovsky © (12.07.10 07:54) [5]

    > Nikfel   (10.07.10 22:37)  

    > А вот как получить и засунуть текст в формате RTF в RichEdit?

    EM_STREAMIN, msdn.

    > Без VCL гораздо удобнее для меня, но знаний пока маловато.

    Удобнее, конечно, но одеяло все время падает.

    --
    Regards, LVT.
  • Nikfel (14.07.10 22:14) [6]
    Открытие и сохранение файла:

    Program TextOpenSave;

    uses
     Windows,
     Messages,
     CommDlg;

    Var
    HWin, hRichDll: THandle;
    RichWND: THandle;
    ButtonWND:array[0..1] of THandle;
    { Сюда будет помещено значение оригинальной оконной процедуры класса Edit }
    OldProc: Pointer;

    const Capt = 'TextOpenSave';
         dllRich = 'RICHED20.DLL';
         c_myRichEdit = 'RichEdit20W';
         c_myClassRichEdit = 'RichEdit_';
         TopRich = 40;
         ID_FILE_OPEN = 10;
         ID_FILE_SAVE = 11;
         {$EXTERNALSYM EM_STREAMIN}
         EM_STREAMIN                         = WM_USER + 73;
         {$EXTERNALSYM EM_STREAMOUT}
         EM_STREAMOUT                        = WM_USER + 74;
         {$EXTERNALSYM SF_TEXT}
         SF_TEXT             = $0001;
         {$EXTERNALSYM SF_RTF}
         SF_RTF              = $0002;

    type
     TEditStreamCallBack = function (dwCookie: Longint; pbBuff: PByte;
       cb: Longint; var pcb: Longint): Longint; stdcall;

     {$EXTERNALSYM _editstream}
     _editstream = record
       dwCookie: Longint;
       dwError: Longint;
       pfnCallback: TEditStreamCallBack;
     end;
     TEditStream = _editstream;
     {$EXTERNALSYM EDITSTREAM}
     EDITSTREAM = _editstream;

    { Устанавливает для окна AWindow шрифт для контролов по умолчанию }
    Procedure SetDefFont(AWindow: THandle);
    Begin
    SendMessage(AWindow, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 1);
    End;

    { Модифицированная оконная процедура RichEdit }
    Function EditWinProc(HWin: THandle; Msg: Cardinal;
    WParam, LParam: Integer): Cardinal; Stdcall;
    Begin
    Case Msg Of
    WM_RBUTTONDOWN: messageBox(HWin,'Правая кнопка мыши','Нажата:',0);
    End;
    { Вызов оригинальной оконной процедуры }
    Result := CallWindowProc(OldProc,
    HWin, Msg, WParam, LParam);
    End;

    function OpenDlgProc(hdlg: HWND; uiMsg: UINT; WPARAM: wParam; LPARAM: lParam): UINT; stdcall;
    var
     pPnt: TPoint;
     dlgRect, prntRect: TRect;
    begin
     if uiMsg = WM_INITDIALOG then
       begin
         GetWindowRect(GetParent(hdlg), dlgRect);
         GetWindowRect(GetDesktopWindow, prntRect);
         pPnt.X := ((prntRect.Right - prntRect.Left) - (dlgRect.Right - dlgRect.Left)) div 2;
         pPnt.Y := ((prntRect.Bottom - prntRect.Top) - (dlgRect.Bottom - dlgRect.Top)) div 2;
         SetWindowPos(GetParent(hdlg), HWND_TOPMOST, pPnt.x, pPnt.y, 0, 0, SWP_NOSIZE or SWP_SHOWWINDOW);
       end;
     Result:= 0;
    end;

  • Nikfel (14.07.10 22:16) [7]
    // Функция OpenCallback для чтения rtf
    function OpenCallback(dwCookie: DWORD; pbBuff: PChar; cb: LongInt; pcb: pLongInt): DWORD; stdcall;
    begin
           // Выполняем чтение блока данных длиной cb байт
           pcb^ := _lread( HFILE(dwCookie), pbBuff, cb);
           if pcb^ < 0 then
                   pcb^ := 0;
           Result := 0;
    end;

    // Функция SaveCallback для записи rtf
    function SaveCallback(dwCookie: DWORD; pbBuff: PChar; cb: LongInt; pcb: pLongInt): DWORD; stdcall;
    begin
           // Выполняем чтение блока данных длиной cb байт
           pcb^ := _lwrite( HFILE(dwCookie), pbBuff, cb);
           if pcb^ < 0 then
                   pcb^ := 0;
           Result := 0;
    end;

    function AnsiUpperCase(const S: string): string;
    var Len: Integer;
    begin
     Len := Length(S);
     SetString(Result, PChar(S), Len);
     if Len > 0 then CharUpperBuffA(Pointer(Result), Len);
    end;

    { Оконная процедура главного окна }
    Function MainWinProc(HWin: THandle; Msg: Cardinal;
    WParam, LParam: Integer): Cardinal; Stdcall;
    Var
    TmpEdit: TWndClassEx;
    w,h: Integer;
    t:trect;
    ps:PAINTSTRUCT;
    pen,oldPen:hpen;
    ofn:OPENFILENAME;
    hFile:Thandle;
    ofs: OFSTRUCT;
    es: EDITSTREAM;
     procedure Line(DC_:HDC;x1,y1,x2,y2:integer);//для рисования линии
     begin
       MoveToEx(DC_,x1,y1,nil);
       LineTo(DC_,x2,y2);
     end;

     function getPath_:string;
     var s:string;
     i:integer;
     begin
       s:=Paramstr(0);
       i:=length(s);
       while i>0 do begin
         if s[i]='\' then begin
         delete(s,i+1,length(s)-i);
         result:=s;
         break;
         end;
         dec(i);
       end;
     end;
    Begin
    Case Msg Of
    { Здесь будет произведено создание дочерних окон }
    WM_CREATE:
    Begin
    { Начало суперклассинга }
    If Not GetClassInfoEx(hRichDll, c_myRichEdit, TmpEdit) Then Halt;
    { Запоминаем оконную процедуры для правильной работы окна }
    OldProc := TmpEdit.lpfnWndProc;
    { Модификация класса }
    TmpEdit.cbSize := SizeOf(TWndClassEx);
    TmpEdit.lpfnWndProc := @EditWinProc;
    TmpEdit.lpszClassName := c_myClassRichEdit;
    TmpEdit.hInstance := GetModuleHandle(NIL);
    { Регистрация класса }
    If RegisterClassEx(TmpEdit) = 0 Then Halt;
    { Подготовка массива }
    FillChar(RichWND, SizeOf(RichWND), 0);
    RichWND := CreateWindowEx(0, c_myClassRichEdit, '',
    WS_CHILD Or WS_VISIBLE Or ES_LEFT or WS_VSCROLL or WS_HSCROLL or ES_AUTOVSCROLL or  ES_WANTRETURN or ES_MULTILINE,
    10, TopRich, 470, 450, HWin, 0, HInstance, NIL);
    ButtonWnd[0]:=CreateWindowEx(0,'Button','Открыть',
    BS_PUSHBUTTON or WS_VISIBLE or WS_CHILD,//стиль кнопки
    10, 7, 75, 25, HWin, ID_FILE_OPEN, hInstance, nil );
    ButtonWnd[1]:=CreateWindowEx(0,'Button','Сохранить',
    BS_PUSHBUTTON or WS_VISIBLE or WS_CHILD,//стиль кнопки
    95, 7, 75, 25, HWin, ID_FILE_SAVE, hInstance, nil );

    SetDefFont(RichWND);
    SetDefFont(ButtonWnd[0]);
    SetDefFont(ButtonWnd[1]);
    SendMessage(RichWND, EM_LIMITTEXT, 2099999999, 0);//максимальная длина текста в RichEdit
    End;
    WM_SETFOCUS:begin
    SetFocus(RichWND);
    end;

  • Nikfel (14.07.10 22:17) [8]
    WM_SIZE:begin
     GetClientRect(HWin,t);
     MoveWindow(RichWND, 10,TopRich, t.Right-t.Left-20,t.Bottom-t.Top-TopRich-10,true);//изменяем размер RichEdit
    end;

    wm_Paint:begin
     GetClientRect(HWin,t);
     w:=t.Right-t.Left;
     h:=t.Bottom-t.Top;
     beginpaint(hWin,ps);//рисуем рамку вокруг RichEdit
       Pen:=CreatePen(PS_SOLID, 1, rgb(165,172,178));
       oldPen:=SelectObject(ps.hdc,pen);
       Line(ps.hdc, 10, TopRich-1, w-10, TopRich-1);
       Line(ps.hdc, 10, h-9, w-10, h-9);
       Line(ps.hdc, 9, TopRich-1, 9, h-8);
       Line(ps.hdc, w-10, TopRich-1, w-10, h-8);
       SelectObject(ps.hdc,Oldpen);
       DeleteObject(pen);
       ReleaseDC(hWin,ps.hdc);
     EndPaint(hWin, ps);
    end;

    WM_COMMAND:
       begin
        case LoWord(wParam) of
         ID_FILE_OPEN:begin
         ZeroMemory(@ofn, sizeof(OPENFILENAME));
           with ofn do
             begin
               lStructSize:=sizeof(OPENFILENAME);
               lpstrInitialDir:=pchar(getPath_);
               lpstrTitle:='Открыть';
               nMaxFile:=MAX_PATH;
               lpfnHook:=@OpenDlgProc;
               lpstrFile:=VirtualAlloc(nil, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);
               lpstrFilter:='*.*'+#0+'*.*'#0#0;
               Flags:=OFN_EXPLORER or OFN_CREATEPROMPT or OFN_FILEMUSTEXIST or
                OFN_HIDEREADONLY or OFN_PATHMUSTEXIST or OFN_ENABLEHOOK;
             end;

           if GetOpenFileName(ofn) then begin
           //Открытие файла
             hFile := OpenFile(ofn.lpstrFile, ofs, OF_READ);
             // Устанавливаем параметры функции обратного вызова, которая будет выполнять чтение
             es.dwCookie:=hFile;
             es.dwError:=0;
             es.pfnCallback:=@OpenCallback;

             SetWindowText(RichWND,'');

             if AnsiUpperCase(Copy(PChar(@ofn.lpstrFile[ofn.nFileExtension]), 1, 3)) = 'RTF' then
                                   SendMessage(RichWND, EM_STREAMIN, SF_RTF, LongInt(@es))
                           else
                                   SendMessage(RichWND, EM_STREAMIN, SF_TEXT, LongInt(@es));
             // Закрываем файл
             _lclose(hFile);
             // Сбрасываем признак изменения содержимого окна редактора текста
             SendMessage(RichWND, EM_SETMODIFY, 0, 0);
           end;
           VirtualFree(ofn.lpstrFile, 0, MEM_RELEASE);
         end;
         ID_FILE_SAVE:begin
           ZeroMemory(@ofn, sizeof(OPENFILENAME));
           with ofn do
             begin
               lStructSize:=sizeof(OPENFILENAME);
               lpstrInitialDir:=pchar(getPath_);
               lpstrTitle:='Сохранить';
               nMaxFile:=MAX_PATH;
               lpfnHook:=@OpenDlgProc;
               lpstrFile:=VirtualAlloc(nil, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);
               lpstrFilter:='*.*'+#0+'*.*'#0#0;
               Flags:=OFN_EXPLORER or OFN_CREATEPROMPT or OFN_FILEMUSTEXIST or
                OFN_HIDEREADONLY or OFN_PATHMUSTEXIST or OFN_ENABLEHOOK;
             end;
           if GetSaveFileName(ofn) then begin
           //Сохранение файла
             hFile := OpenFile(ofn.lpstrFile, ofs, OF_CREATE);
             // Устанавливаем параметры функции обратного вызова, которая будет выполнять чтение
             es.dwCookie:=hFile;
             es.dwError:=0;
             es.pfnCallback:=@SaveCallback;

             if AnsiUpperCase(Copy(PChar(@ofn.lpstrFile[ofn.nFileExtension]), 1, 3)) = 'RTF' then
                                   SendMessage(RichWND, EM_STREAMOUT, SF_RTF, LongInt(@es))
                           else
                                   SendMessage(RichWND, EM_STREAMOUT, SF_TEXT, LongInt(@es));
             // Закрываем файл
             _lclose(hFile);
             // Сбрасываем признак изменения содержимого окна редактора текста
             SendMessage(RichWND, EM_SETMODIFY, 0, 0);
           end;
           VirtualFree(ofn.lpstrFile, 0, MEM_RELEASE);
         end;
        end;
       end;

    WM_DESTROY:
    Begin
    { Уничтожение классов}
    UnregisterClass(c_myClassRichEdit, HInstance);
    { Выход для освобождения памяти }
    PostQuitMessage(0);
    End;
    End;
    { Обработка всех остальных сообщений по умолчанию }
    Result := DefWindowProc(HWin, Msg, WParam, LParam);
    End;

    Procedure WinMain;
    Var
    Msg: TMsg;
    { Оконный класс }
    WndClassEx: TWndClassEx;
    Begin
    { Подготовка структуры класса окна }
    ZeroMemory(@WndClassEx, SizeOf(WndClassEx));

    {************* Заполнение структуры нужными значениями ******************* }

    { Размер структуры }
    WndClassEx.cbSize := SizeOf(TWndClassEx);
    { Имя класса окна }
    WndClassEx.lpszClassName := 'SuperclassSampleWnd';
    { Стиль класса, не окна }
    WndClassEx.style := CS_VREDRAW Or CS_HREDRAW;
    { Дескриптор программы (для доступа к сегменту данных) }
    WndClassEx.hInstance := HInstance;
    { Адрес оконной процедуры }
    WndClassEx.lpfnWndProc := @MainWinProc;
    { Курсор }
    WndClassEx.hCursor := LoadCursor(0, IDC_ARROW);
    { Кисть для заполнения фона }
    WndClassEx.hbrBackground := COLOR_BTNFACE + 1;
    { Меню }
    WndClassEx.lpszMenuName := nil;

    { Регистрация оконного класса в Windows }
    If RegisterClassEx(WndClassEx) = 0 Then
    MessageBox(0, 'Невозможно зарегистрировать класс окна',
    'Ошибка', MB_OK Or MB_ICONHAND)
    Else
    Begin
    { Создание окна по зарегистрированному классу }
    hWin := CreateWindowEx(0, WndClassEx.lpszClassName,
    Capt,  WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_OVERLAPPEDWINDOW And Not WS_BORDER,
    Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), 500, 500, 0, 0,
    HInstance, NIL);

    If hWin = 0 Then
    MessageBox (0, 'Окно не создалось!',
    'Ошибка', MB_OK Or MB_ICONHAND)
    Else
    Begin
    { Показ окна }
    ShowWindow(hWin, SW_SHOWNORMAL);
    { Обновление окна }
    UpdateWindow(hWin);

    { Цикл обработки сообщений }
    While GetMessage(Msg, 0, 0, 0) Do
    Begin
    if msg.message=WM_KEYDOWN then begin
     if msg.wParam=VK_ESCAPE then break;//выходим по нажатию ESC
    end;
    TranslateMessage(Msg);
    DispatchMessage(Msg);
    End;
    DestroyWindow(RichWND);
    DestroyWindow(ButtonWnd[0]);
    DestroyWindow(ButtonWnd[1]);
    { Выход по прерыванию цикла }
    Halt(Msg.WParam);
    End;
    End;
    End;

    Begin
    hRichDll := LoadLibrary(dllRich);
    { Создание окна }
    WinMain;
    FreeLibrary(hRichDll);
    End.

  • Leonid Troyanovsky © (14.07.10 22:32) [9]

    > Nikfel   (14.07.10 22:14) [6]

    > Открытие и сохранение файла:

    Т.е., благодарностей не будет?

    --
    Regards, LVT.
  • Nikfel (14.07.10 22:41) [10]
    Leonid Troyanovsky, спасибо за подсказку. Вроде разобрался с этим, но  можно ли как-то перед сохранением зашифровать текст и тогда сохранить, а перед открытием произвести расшифровку и открыть? Как такое реализовать?
  • Leonid Troyanovsky © (14.07.10 22:49) [11]

    > Nikfel   (14.07.10 22:41) [10]

    > с этим, но  можно ли как-то перед сохранением зашифровать
    > текст и тогда сохранить, а перед открытием произвести расшифровку
    > и открыть? Как такое реализовать?

    http://groups.google.ru/group/fido7.ru.delphi.chainik/msg/b2fb08daf11406ff?hl=ru
    --
    Regards, LVT.
  • Nikfel (14.07.10 23:13) [12]

    > http://groups.google.ru/group/fido7.ru.delphi.chainik/msg/b2fb08daf11406ff?
    > hl=ru


    Такой вариант мне не понятен и я не хочу использовать uses Classes;

    Можно ли как-то в OpenCallback и SaveCallback прописать свой код шифровки?
  • Leonid Troyanovsky © (15.07.10 07:36) [13]

    > Nikfel   (14.07.10 23:13) [12]

    > Такой вариант мне не понятен и я не хочу использовать uses
    > Classes

    Мазохист? :)
    http://groups.google.ru/group/fido7.ru.delphi.chainik/msg/837239a40eb61173?hl=ru

    --
    Regards, LVT.
 
Конференция "Начинающим" » Как из RichEdit получить и засунуть текст в формате RTF? [D7]
Есть новые Нет новых   [134431   +13][b:0][p:0.012]