Try
Code: Select all
rng.Para.SetLineSpacing(3, 400)
Works, thank you. I thought I had tried that already
haha, who needs documentation!teadrinker wrote: ↑29 May 2021, 15:30I didn't find any documentation about IText... interfaces for scripting either, so I just tried all possible variants.
Good to know!
Thanks. It covers some of the interfaces but not all, for example not iTextRange2 which has methods for RichEdit tables.malcev wrote: ↑29 May 2021, 18:41I found documentation here:
https://chromium.googlesource.com/chromium/deps/perl/+/refs/heads/main/c/i686-w64-mingw32/include/tom.h
I tried both the MiTeC tool and the Microsoft tool OLE COM Object Viewer (filename oleview.exe , I found it in folder C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86\ )malcev wrote: ↑29 May 2021, 18:41Also You can examine ole objects with different software.
For example with MiTeC OLE/COM Object Explorer
http://www.mitec.cz/Downloads/OLExp.zip
But tom header does not help.
Here is teadrinker's working COM Rich Edit code from above but I commented out the function call that opens WordPad, because irrelevant here, and added lines starting at ;######### start GetCellBorderWidths attempts #########. the InsertTable line works. After that the numbered items 1 2 3 4A 4B 4C 4D shows what I have tried without success and the comments show the error codes. I'm bad with COM code and have never attempted to use SafeArray before. I'm basically fumbling around
Code: Select all
#NoEnv
ComObjFromMyRichEdit()
;ComObjFromExternalRichEdit()
Esc:: ExitApp
ComObjFromMyRichEdit() {
hGui := CreateGui()
hRichEdit := CreateRichEdit(hGui, 300, 100, 400, 400) ; X Y W H
oWordPad := GetComFromMyRE(hRichEdit)
AddEventHandler( Func("EventHandler"), hGui, hRichEdit, oWordPad )
Actions(oWordPad)
}
ComObjFromExternalRichEdit() {
hRichEdit := GetRichEdit(720, 100) ; X Y
oWordPad := GetComFromExternalRE(hRichEdit)
Actions(oWordPad)
}
GetComFromMyRE(hRichEdit) {
static EM_GETOLEINTERFACE := 0x43C, VT_DISPATCH := 9, F_OWNVALUE := 1
, IID_ITextDocument2 := "{01C25500-4268-11D1-883A-3C8B00C10000}"
, IID_ITextDocument := "{8CC497C0-A1DF-11CE-8098-00AA0047BE5D}"
VarSetCapacity(buff, A_PtrSize, 0)
DllCall("SendMessage", Ptr, hRichEdit, UInt, EM_GETOLEINTERFACE, Ptr, 0, Ptr, &buff)
pITextDocument := ComObjQuery(pIRichEditOle := NumGet(buff), IID_ITextDocument2)
ObjRelease(pObj)
Return ITextDocument := ComObject(VT_DISPATCH, pITextDocument, F_OWNVALUE)
}
GetComFromExternalRE(hRichEdit) {
Return AccObjectFromWindow(hRichEdit, OBJID_NATIVEOM := -16)
}
AccObjectFromWindow(hWnd, idObject = 0) {
static IID_IDispatch := "{00020400-0000-0000-C000-000000000046}"
, IID_IAccessible := "{618736E0-3C3D-11CF-810C-00AA00389B71}"
, OBJID_NATIVEOM := 0xFFFFFFF0, VT_DISPATCH := 9, F_OWNVALUE := 1
, h := DllCall("LoadLibrary", Str, "oleacc", Ptr)
VarSetCapacity(IID, 16), idObject &= 0xFFFFFFFF
DllCall("ole32\CLSIDFromString", Str, idObject = OBJID_NATIVEOM ? IID_IDispatch : IID_IAccessible, Ptr, &IID)
if DllCall("oleacc\AccessibleObjectFromWindow", Ptr, hWnd, UInt, idObject, Ptr, &IID, PtrP, pAcc) = 0
Return ComObjEnwrap(VT_DISPATCH, pAcc, F_OWNVALUE)
}
Actions(ITextDocument) {
rng := ITextDocument.Range(0, 0)
;######### start GetCellBorderWidths attempts #########
;https://docs.microsoft.com/en-us/windows/win32/api/tom/nf-tom-itextrange2-inserttable
;"the borders are solid black with 0.5 point widths"
rng.InsertTable(3, 3 ,0) ;create 3x3 table
;https://docs.microsoft.com/en-us/windows/win32/api/tom/nn-tom-itextrow
;https://docs.microsoft.com/en-us/windows/win32/api/tom/nf-tom-itextrow-getcellborderwidths
;HRESULT GetCellBorderWidths(
; long *pduLeft,
; long *pduTop,
; long *pduRight,
; long *pduBottom
;);
; long = AHK "Int"
;1
;pduLeft := pduTop := pduRight := pduBottom := 0
;rng.Row.GetCellBorderWidths(pduLeft, pduTop, pduRight, pduBottom)
;"Error: 0x80020005 - Type mismatch."
;2
;pduLeft := pduTop := pduRight := pduBottom := 0
;rng.Row.GetCellBorderWidths(&pduLeft, &pduTop, &pduRight, &pduBottom)
;"Critical Error: Invalid memory read/write."
;3
;VarSetCapacity(pduLeft, 4, 0)
;VarSetCapacity(pduTop, 4, 0)
;VarSetCapacity(pduRight, 4, 0)
;VarSetCapacity(pduBottom, 4, 0)
;rng.Row.GetCellBorderWidths(&pduLeft, &pduTop, &pduRight, &pduBottom)
;"Critical Error: Invalid memory read/write."
;4 attempts with SafeArray
;https://www.autohotkey.com/docs/commands/ComObjArray.htm
;"Creates a SafeArray for use with COM"
;"ArrayObj := ComObjArray(VarType, Count1 , Count2, ... Count8)"
;https://www.autohotkey.com/docs/commands/ComObjType.htm
;"VT_UI2 := 0x12 ; 16-bit unsigned int"
;SafeArray := ComObjArray(VT_UI2 := 0x12, 4)
;4A
;rng.Row.GetCellBorderWidths(SafeArray)
;"Error: 0x80020005 - Type mismatch."
;4B
;rng.Row.GetCellBorderWidths(&SafeArray)
;"Error: 0x8002000E - Invalid number of parameters."
;4C
;rng.Row.GetCellBorderWidths(SafeArray.0, SafeArray.1, SafeArray.2, SafeArray.3)
;"Critical Error: Invalid memory read/write."
;4D
;rng.Row.GetCellBorderWidths(&SafeArray.0, &SafeArray.1, &SafeArray.2, &SafeArray.3)
;"Error: 0x80020005 - Type mismatch."
MsgBox % "end GetCellBorderWidths attempts"
ExitApp
;######### end GetCellBorderWidths attempts #########
rng.Font.Name := "Calibri"
rng.Font.Size := 24
rng.Text := "AutoHotkey forever!`n"
rng.MoveEnd(1, -10)
rng.Font.BackColor := 0xFF
rng.MoveEnd(1, 9)
rng.Start := 11
rng.Font.BackColor := 0xFF8844
rng.Font.ForeColor := 0xFFFFFF
rng.Font.Name := "Bradley Hand ITC"
rng.Start := ++rng.End
SetDefaultFont(rng)
rng.Text := "This is " . ComObjType(ITextDocument, "Name") . " implementation."
sel := ITextDocument.Selection
sel.Start := sel.End := rng.End
}
CreateGui() {
Gui, New, +hwndhGui
Gui, Margin, 0, 0
OnMessage(0x112, "WM_SYSCOMMAND")
Return hGui
}
WM_SYSCOMMAND(wp) {
if (wp = 0xF060) ; SC_CLOSE
ExitApp
}
CreateRichEdit(hGui, xGui, yGui, width, height) {
static hLbr := DllCall("LoadLibrary", Str, "Msftedit.dll", Ptr)
, _styles := { WS_VSCROLL: 0x200000, ES_SELECTIONBAR: 0x1000000
, ES_MULTILINE: 4, ES_AUTOVSCROLL: 0x40, ES_NOHIDESEL: 0x100
, ES_WANTRETURN: 0x1000, ES_SAVESEL: 0x8000 }, styles := 0
for k, v in _styles
styles |= v
Gui, %hGui%: Add, Custom, ClassRICHEDIT50W w%width% h%height% hwndhRichEdit +%styles%
GuiControl, Move, %hRichEdit%, w%width% h%height%
Gui, %hGui%: Show, x%xGui% y%yGui%, My WordPad
Return hRichEdit
}
AddEventHandler(funcObj, hGui, hRichEdit, ITextDocument) {
handler := funcObj.Bind(ITextDocument)
GuiControl, %hGui%: +g, %hRichEdit%, % handler
}
EventHandler(ITextDocument) {
if (A_EventInfo = 0x400) {
rng := ITextDocument.Range(0, 2)
( StrLen(rng.Text) = 1 && SetDefaultFont(ITextDocument) )
}
}
SetDefaultFont(obj) {
obj.Font.Size := 14
obj.Font.Name := "Calibri"
obj.Font.BackColor := 0xFFFFFF
obj.Font.ForeColor := 0xAA4400
}
GetRichEdit(x, y) {
if (x = "exit") {
Process, Close, %y%
Return
}
Run, wordpad,,, PID
WinWait, ahk_pid %PID%
OnExit( Func(A_ThisFunc).Bind("exit", PID) )
WinMove,,, x, y
ControlGet, hRichEdit, hwnd,, RICHEDIT50W1
Return hRichEdit
}
Code: Select all
msgbox % rng.Row.CellCount
Code: Select all
VarSetCapacity(var, 4, 0)
ComObject(0x4003, &var)
Thanks. I had missed the second usage pattern on the ComObjActive docs page. The code to get multiple values from the COM method call would go like this thenmalcev wrote: ↑01 Jun 2021, 11:11Function needs byref int.
You have to send it like thisCode: Select all
VarSetCapacity(var, 4, 0) ComObject(0x4003, &var)
Code: Select all
VarSetCapacity(pduLeft, 4, 0)
VarSetCapacity(pduTop, 4, 0)
VarSetCapacity(pduRight, 4, 0)
VarSetCapacity(pduBottom, 4, 0)
;https://www.autohotkey.com/docs/commands/ComObjActive.htm#ByRef
;https://www.autohotkey.com/docs/commands/ComObjType.htm#vt
; VT_BYREF := 0x4000 ; Pointer to another type of value
; VT_I4 := 3 ; 32-bit signed int
; VT_BYREF | VT_I4 = 0x4003
rng.Row.GetCellBorderWidths(ComObj(0x4003, &pduLeft)
, ComObj(0x4003, &pduTop)
, ComObj(0x4003, &pduRight)
, ComObj(0x4003, &pduBottom) )
I had assumed the GetCellBorderWidths could operate directly on a Row object (apply to all cells in that row) since it is a methods for ITextRow. But apparently not. I'm stumped on the extra step however. These give errorsmalcev wrote: ↑01 Jun 2021, 11:11How You can get width of cell borders if You dont have them?Code: Select all
msgbox % rng.Row.CellCount
Code: Select all
MsgBox % rng.Cells() ; "Error: 0x80004001 - Not implemented"
MsgBox % rng.row.Cells() ; "Error: 0x80020006 - Unknown name."
https://docs.microsoft.com/en-us/windows/win32/api/tom/nf-tom-itextrange2-getrowGets the row properties in the currently selected row.
My general goal was to learn how to to create and control Rich Edit tables with data and different styling (border weight, border color, ...) through COM. To move toward that goal I began experimenting with a few methods, to get a first grip on how to use them.
Code: Select all
rng.InsertTable(3, 3, 0) ;create 3x3 table
rng.SetIndex(tomTable := 15, 1, 0)
textRow := rng.Row
loop % textRow.CellCount
{
textRow.CellIndex := A_Index-1
textRow.CellWidth := 1000
textRow.SetCellBorderColors(123456,123456,123456,123456)
}
textRow.Apply(-1, tomRowApplyDefault := 0)
msgbox test
Users browsing this forum: Chunjee, Descolada, GroggyOtter, Mateusz53, moltenchees and 165 guests