Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) Использование RICHTEXT.RichtextCtrl для редактирования программно DOC? (число прочтений - 11905 )
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
09. Декабря 2011 :: 12:21
Печать  
Надо из 1С формировать печатную форму Договора. Юристы пишут договора в DOC-формате. Этот файл посредством RICHTEXT.RichtextCtrl  можно открыть на просмотр (сохранив перед этим в формате trf), но как в нем поменять некоторые символы?
Т.е. Например в DOC-файле написано $НомерДоговора$ Его надо заменить на значение НомерДок текущего документа.
Можно напрямую редактировать 16-ричные значения букв, но хотелось бы как то более поизящнее. Может есть у кого наработки в этой области?
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #1 - 09. Декабря 2011 :: 12:39
Печать  
Если у кого есть наработки - поделитесь пожалуйста примерами (Создать и загрузить файл удалось, а вот как выполнить замену нужного текста?). Спасибо.
  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #2 - 09. Декабря 2011 :: 13:05
Печать  
MSDN не предлагать?  Круглые глаза

Do While RichTextBox1.Find("123") >= 0
    RichTextBox1.SelectedText = "456"
Loop

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #3 - 09. Декабря 2011 :: 13:24
Печать  
Спасибо, MSDN только дал результаты для NET, если у вас есть прамая ссылка на старую версию - дайте плиз. Спасибо.
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #4 - 09. Декабря 2011 :: 13:28
Печать  
Делаю так:
Код
Выбрать все
АФ = СоздатьОбъект("АктивИкс");
	АФ.УстановитьАтрибут(Форма, "ActX");
	Контрол = АФ.СоздатьЭУ("RICHTEXT.RichtextCtrl");
	Контрол.BorderStyle = 1;
	//Контрол.DisableNoScroll = 10;
	//Контрол.ScrollBars = 3;
	Контрол.AutoVerbMenu = 1;
	Контрол.LoadFile("D:\1Cv77\SQL\doc\dogovor_dil_2011.rtf",0);
	АФ.УстановитьФокус();

	Пока Контрол.Find("$") >= 0 Цикл
		Контрол.SelectedText = "456"
	КонецЦикла;
 


И ничего не меняется. На вызов "Контрол.Refresh();" - пишет ошибку: Поле агрегатного объекта не обнаружено (Refresh)

Или как можно NET-овскую библиотеку использовать как ActiveX?
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #5 - 09. Декабря 2011 :: 13:55
Печать  
Уже перепробовал все что можно, Контрол.Find("$") всегда возвращает -1.
  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #6 - 09. Декабря 2011 :: 14:03
Печать  
А, ты про этот RichText..

Контрол.SelText = "456"
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #7 - 09. Декабря 2011 :: 14:05
Печать  
pvase писал(а) 09. Декабря 2011 :: 13:55:
Уже перепробовал все что можно, Контрол.Find("$") всегда возвращает -1.

А это интереснее. Выложи тестовую обработку.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #8 - 09. Декабря 2011 :: 14:16
Печать  
berezdetsky писал(а) 09. Декабря 2011 :: 14:05:
А это интереснее. Выложи тестовую обработку.


Выкладываю, в обработке надо подправить ссылку на открытие файла rtf.
  

RichtextCtrl_001.zip ( 19 KB | Загрузки )
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #9 - 09. Декабря 2011 :: 14:23
Печать  
pvase писал(а) 09. Декабря 2011 :: 14:16:
Выкладываю, в обработке надо подправить ссылку на открытие файла rtf.

Ok, на выходных посмотрю.

pvase писал(а) 09. Декабря 2011 :: 13:24:
Спасибо, MSDN только дал результаты для NET, если у вас есть прамая ссылка на старую версию - дайте плиз. Спасибо.

  

rtfbox98.zip ( 75 KB | Загрузки )

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #10 - 09. Декабря 2011 :: 21:23
Печать  
Посмотрел. В доработанном мной (на предмет multilevel undo) RichtextCtrl (устанавливается с qryConsole) поиск поломан. В оригинальном (приложен в архиве) поиск работает, но только с нерусскими буквами.  Ужас

Человеческий поиск (EM_FINDTEXT) ищет всё в обоих случаях. Пример поиска на VB:
Код
Выбрать все
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Type CHARRANGE
    cpMin As Long
    cpMax As Long
End Type

Private Type FINDTEXT
    chrg As CHARRANGE
    lpstrText As String
End Type

Const WM_USER = &H400
Const EM_FINDTEXT = WM_USER + 56

Const FR_DOWN = &H1
Const FR_WHOLEWORD = &H2
Const FR_MATCHCASE = &H4

Private Sub Command1_Click()
    Dim cr As CHARRANGE
    cr.cpMin = 0
    cr.cpMax = -1

    Dim ft As FINDTEXT
    ft.chrg = cr
    ft.lpstrText = Text1.Text

    With RichTextBox1
	  .SelStart = SendMessage(.hwnd, EM_FINDTEXT, FR_DOWN, ft)
	  .SelLength = Len(Text1.Text)
	  .SelText = Text2.Text
    End With
End Sub

Private Sub Form_Load()
    RichTextBox1.LoadFile "Z:\pvase\RichtextCtrl_001\test.rtf"
End Sub
 



Для поиска русских букв должна быть включена русская раскладка клавиатуры.
Если чё:
Код
Выбрать все
Private Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal flags As Long) As Long
Private Const kb_lay_ru As Long = 68748313

...

ActivateKeyboardLayout kb_lay_ru, 0
 



В общем, стоит написать обёртку, чтобы всё это спрятать. А если писать обёртку - интереснее использовать дотнетовский контрол.  Круглые глаза Так что, если ты дочитал это до конца - забудь всё, что прочитал и..
  

richtx32.zip ( 93 KB | Загрузки )

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #11 - 11. Декабря 2011 :: 13:40
Печать  
Спасибо большое. Но что то не получается. Скачал файл из последнего поста, установил, но ситуация не изменилась, поиск все так же не работает даже при включенной русской раскладке клавиатуры. По поводу net - к сожалению не разбирался как он работает и как из него делать com-объекты.
  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #12 - 11. Декабря 2011 :: 15:05
Печать  
Скачал файл - это хорошо. Неплохо бы ещё текст прочитать..  Подмигивание

Чтобы этот код ободинэсить, нужно контрол завернуть в обёртку и добавить методы поиска/замены. Пример такой обёртки: http://www.1cpp.ru/forum/YaBB.pl?num=1157967835/71#71
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #13 - 12. Декабря 2011 :: 06:56
Печать  
berezdetsky писал(а) 11. Декабря 2011 :: 15:05:
Скачал файл - это хорошо. Неплохо бы ещё текст прочитать..  Подмигивание

Чтобы этот код ободинэсить, нужно контрол завернуть в обёртку и добавить методы поиска/замены. Пример такой обёртки: http://www.1cpp.ru/forum/YaBB.pl?num=1157967835/71#71


Еще раз большое спасибо. Разбираюсь с примером.
  
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #14 - 12. Декабря 2011 :: 09:25
Печать  
Установил WS 2010 Express, что не хочет открывать проект.
Также есть вопрос, можно ли как то сделать перенаправление всех остальных методов не описывая их в компилируемом объекте? Например интересует SaveFile и LoadFile? Или надо все эти методы описывать и перенаправлять?
  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #15 - 12. Декабря 2011 :: 10:22
Печать  
Проект на VB 6.0.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #16 - 15. Декабря 2011 :: 12:45
Печать  
Еще раз большое спасибо, получилось, Добавил метод:
Код
Выбрать все
' TextReplace - Замена
Public Sub TextReplace(ByVal bstrString As String, bstrString2 As String)
    Dim cr As CHARRANGE
    cr.cpMin = 0
    cr.cpMax = -1

    Dim ft As FindText
    ft.chrg = cr
    ft.lpstrText = bstrString

    ActivateKeyboardLayout kb_lay_ru, 0

    With RichTextBox1
	.SelStart = SendMessage2(.hwnd, EM_FINDTEXT, FR_DOWN, ft)
	.SelLength = Len(bstrString)
	.SelText = bstrString2
    End With
    RichTextBox1.Refresh
End Sub
 


и вызываю его, а вот поиск по этому же принципу не удалось сделать, не могу никак понять как вернуть из глобальной функции переменную.

И печать не удается сделать, никак не пойму как получить первый параметр для SelPrint, в MSDN вот что пишут:
Цитата:
This example prints the formatted text in a RichTextBox control. To try this example, put a RichTextBox control, a CommonDialog control, and a CommandButton control on a form. Paste this code into the Click event of the CommandButton control. Then run the example.
Private Sub Command1_Click()
   CommonDialog1.Flags = cdlPDReturnDC + cdlPDNoPageNums
   If RichTextBox1.SelLength = 0 Then
     CommonDialog1.Flags = CommonDialog1.Flags + cdlPDAllPages
   Else
     CommonDialog1.Flags = CommonDialog1.Flags + cdlPDSelection
   End If
   CommonDialog1.ShowPrinter
   Printer.Print ""
   RichTextBox1.SelPrint CommonDialog1.hDC
End Sub


но как при этом это подключить в ActiveX?
  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #17 - 15. Декабря 2011 :: 17:36
Печать  
pvase писал(а) 15. Декабря 2011 :: 12:45:
а вот поиск по этому же принципу не удалось сделать, не могу никак понять как вернуть из глобальной функции переменную.

А в чём проблема?

pvase писал(а) 15. Декабря 2011 :: 12:45:
И печать не удается сделать, никак не пойму как получить первый параметр для SelPrint, в MSDN вот что пишут:
...
но как при этом это подключить в ActiveX?

Нужно подключить диалог выбора принтера или печатать на заранее известный принтер? Если второе, то контекст устройства обычно получают функцией CreateIC.

Код
Выбрать все
Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32

Private Type DEVMODE
	  dmDeviceName As String * CCHDEVICENAME
	  dmSpecVersion As Integer
	  dmDriverVersion As Integer
	  dmSize As Integer
	  dmDriverExtra As Integer
	  dmFields As Long
	  dmOrientation As Integer
	  dmPaperSize As Integer
	  dmPaperLength As Integer
	  dmPaperWidth As Integer
	  dmScale As Integer
	  dmCopies As Integer
	  dmDefaultSource As Integer
	  dmPrintQuality As Integer
	  dmColor As Integer
	  dmDuplex As Integer
	  dmYResolution As Integer
	  dmTTOption As Integer
	  dmCollate As Integer
	  dmFormName As String * CCHFORMNAME
	  dmUnusedPadding As Integer
	  dmBitsPerPel As Long
	  dmPelsWidth As Long
	  dmPelsHeight As Long
	  dmDisplayFlags As Long
	  dmDisplayFrequency As Long
End Type

Private Declare Function CreateIC Lib "gdi32" Alias "CreateICA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As DEVMODE) As Long 

  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #18 - 05. Января 2012 :: 09:34
Печать  
berezdetsky писал(а) 15. Декабря 2011 :: 17:36:
Нужно подключить диалог выбора принтера или печатать на заранее известный принтер? Если второе, то контекст устройства обычно получают функцией CreateIC.

Код
Выбрать все
Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32

Private Type DEVMODE
	  dmDeviceName As String * CCHDEVICENAME
	  dmSpecVersion As Integer
	  dmDriverVersion As Integer
	  dmSize As Integer
	  dmDriverExtra As Integer
	  dmFields As Long
	  dmOrientation As Integer
	  dmPaperSize As Integer
	  dmPaperLength As Integer
	  dmPaperWidth As Integer
	  dmScale As Integer
	  dmCopies As Integer
	  dmDefaultSource As Integer
	  dmPrintQuality As Integer
	  dmColor As Integer
	  dmDuplex As Integer
	  dmYResolution As Integer
	  dmTTOption As Integer
	  dmCollate As Integer
	  dmFormName As String * CCHFORMNAME
	  dmUnusedPadding As Integer
	  dmBitsPerPel As Long
	  dmPelsWidth As Long
	  dmPelsHeight As Long
	  dmDisplayFlags As Long
	  dmDisplayFrequency As Long
End Type

Private Declare Function CreateIC Lib "gdi32" Alias "CreateICA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As DEVMODE) As Long 



Спасибо сделал. Но почему то при вызове метода SelPrint пишет: RichtextCtrl: Invalid HDC
.
Вот что сделал в OCX:
Код
Выбрать все
Public Sub DocPrint(ByVal lpszDriver As String, lpszDevice As String)
    Dim pr As DEVMODE
    Dim hInfoDC As Long
  
    hInfoDC = CreateIC(lpszDriver, lpszDevice, 0, pr)
    RichTextBox1.SelPrint (hInfoDC)
    RichTextBox1.Refresh
End Sub
 



Вот так вызываю из 1С:
Код
Выбрать все
Контрол.DocPrint(0,ТекПринтер);
 


где ТекПринтер - название принтера.
  
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Использование RICHTEXT.RichtextCtrl для редактирования программно DOC?
Ответ #19 - 05. Января 2012 :: 18:52
Печать  
SelPrint не печатает текст, а отправляет форматированный текст на устройство, которое может его напечатать. В общем случае рендерить текст придётся самому. Пример для принтера по-умолчанию, по мотивам MSDN:

Код
Выбрать все
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type CharRange
    cpMin As Long ' First character of range (0 for start of doc)
    cpMax As Long ' Last character of range (-1 for end of doc)
End Type

Private Type FormatRange
    hdc As Long ' Actual DC to draw on
    hdcTarget As Long ' Target DC for determining text formatting
    rc As RECT ' Region of the DC to draw to (in twips)
    rcPage As RECT ' Region of the entire DC (page size) (in twips)
    chrg As CharRange ' Range of text to draw (see above declaration)
End Type

Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY = 90
Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113
Private Const WM_USER As Long = &H400
Private Const EM_FORMATRANGE As Long = WM_USER + 57
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Public Sub PrintRTF(RTF As RichTextBox, LeftMarginWidth As Long, TopMarginHeight, RightMarginWidth, BottomMarginHeight)
    Dim LeftOffset As Long, TopOffset As Long
    Dim LeftMargin As Long, TopMargin As Long
    Dim RightMargin As Long, BottomMargin As Long
    Dim fr As FormatRange
    Dim rcDrawTo As RECT
    Dim rcPage As RECT
    Dim TextLength As Long
    Dim NextCharPosition As Long
    Dim r As Long

    ' Start a print job to get a valid Printer.hDC
    Printer.Print Space(1)
    Printer.ScaleMode = vbTwips

    ' Get the offsett to the printable area on the page in twips
    ' some code here
    LeftOffset = GetDeviceCaps(Printer.hdc, PHYSICALOFFSETX) / GetDeviceCaps(Printer.hdc, LOGPIXELSX) * 1440
    TopOffset = GetDeviceCaps(Printer.hdc, PHYSICALOFFSETY) / GetDeviceCaps(Printer.hdc, LOGPIXELSY) * 1440

    ' Calculate the Left, Top, Right, and Bottom margins
    ' some code here
    LeftMargin = LeftMarginWidth - LeftOffset
    TopMargin = TopMarginHeight - TopOffset
    RightMargin = (Printer.Width - RightMarginWidth) - LeftOffset
    BottomMargin = (Printer.Height - BottomMarginHeight) - TopOffset

    ' Set printable area rect
    ' some code here
    rcPage.Left = 0
    rcPage.Top = 0
    rcPage.Right = Printer.ScaleWidth
    rcPage.Bottom = Printer.ScaleHeight

    ' Set rect in which to print (relative to printable area)
    ' some code here
    rcDrawTo.Left = LeftMargin
    rcDrawTo.Top = TopMargin
    rcDrawTo.Right = RightMargin
    rcDrawTo.Bottom = BottomMargin

    ' Set up the print instructions
    fr.hdc = Printer.hdc ' Use the same DC for measuring and rendering
    fr.hdcTarget = Printer.hdc ' Point at printer hDC
    fr.rc = rcDrawTo ' Indicate the area on page to draw to
    fr.rcPage = rcPage ' Indicate entire size of page
    fr.chrg.cpMin = 0 ' Indicate start of text through
    fr.chrg.cpMax = -1 ' end of the text

    ' Get length of text in RTF
    TextLength = Len(RTF.Text)

    ' Loop printing each page until done
    Do
	  ' Print the page by sending EM_FORMATRANGE message
	  NextCharPosition = SendMessage(RTF.hWnd, EM_FORMATRANGE, True, fr)
	  If NextCharPosition >= TextLength Then Exit Do 'If done then exit
	  fr.chrg.cpMin = NextCharPosition ' Starting position for next page
	  Printer.NewPage ' Move on to next page
	  Printer.Print Space(1) ' Re-initialize hDC
	  fr.hdc = Printer.hdc
	  fr.hdcTarget = Printer.hdc
    Loop

    ' Commit the print job
    Printer.EndDoc

    ' Allow the RTF to free up memory
    r = SendMessage(RTF.hWnd, EM_FORMATRANGE, False, 0&)
End Sub

Private Sub Command1_Click()
    PrintRTF Me.RichTextBox1, 1440, 1440, 1440, 1440
End Sub
 



HOWTO: Use Built-In Printing Features from a Rich Edit Control
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать