Hello there,
this is in application of jgr's API signature of the internal text finder,
http://www.theswamp.org/index.php?topic=31886.msg388707#msg388707 (many thx!).
Command acquires a search string and an optional selection set and sets the implied selection accordingly, either with the found text object or with the parent object if it's an attribute in a block or a text in a dimension.
What would be required to extend that to nested text in blocks or xrefs? Phrased differently, what does the prepackaged FIND command do?
Have fun, Thorsten
module FindSelectCommand
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.Runtime
open System.Runtime.InteropServices
type acApp = Autodesk.AutoCAD.ApplicationServices.Application
type AC_SRCH =
| AC_SRCH_BLOCK = 0x01uy
| AC_SRCH_DIM_TEXT = 0x02uy
| AC_SRCH_TEXT = 0x04uy
| AC_SRCH_LINK_DESC = 0x08uy
| AC_SRCH_LINK_URL = 0x10uy
| AC_SRCH_MATCH_CASE = 0x20uy
| AC_SRCH_WHOLE_WORD = 0x40uy
| AC_SRCH_DEFAULT = 0x1Fuy
[<DllImport(
"acdb18.dll",
CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Unicode,
EntryPoint ="?acdbTextFind@@YA_NPAVAcDbDatabase@@AAV?$AcArray@VAcDbObjectId@@V?$AcArrayMemCopyReallocator@VAcDbObjectId@@@@@@PB_W2EABV2@@Z")>]
let acdbTextFind
( pDb: nativeint,
resultSet: nativeint,
[<In;MarshalAs(UnmanagedType.LPWStr)>] findString: string,
[<In;MarshalAs(UnmanagedType.LPWStr)>] replaceString: string,
searchOptions: AC_SRCH,
selSet: nativeint ) = false
[<CommandMethod "FindSelect">]
let findSelect() =
let doc = acApp.DocumentManager.MdiActiveDocument
let db = doc.Database
let ed = doc.Editor
let pstrr =
new PromptStringOptions(
"\nSearch for: ",
AllowSpaces = true )
|> ed.GetString
if pstrr.Status = PromptStatus.OK then
let psr = ed.GetSelection()
let psr =
if psr.Status <> PromptStatus.Error then psr
else ed.SelectAll()
if psr.Status = PromptStatus.OK then
use oidIn = new ObjectIdCollection(psr.Value.GetObjectIds())
use oidOut = new ObjectIdCollection()
let ret =
acdbTextFind(
db.UnmanagedObject,
oidOut.UnmanagedObject,
pstrr.StringResult,
null,
AC_SRCH.AC_SRCH_DEFAULT,
oidIn.UnmanagedObject )
if ret then
use tr = db.TransactionManager.StartTransaction()
let rec objInCurrentSpace (oid: ObjectId) =
let dbo = tr.GetObject(oid, OpenMode.ForRead)
let ownerId = dbo.OwnerId
if ownerId = db.CurrentSpaceId then Some oid
elif ownerId.IsNull then None
else objInCurrentSpace ownerId
let sSet =
oidOut
|> Seq.cast<_>
|> Seq.choose objInCurrentSpace
|> Seq.toArray
|> SelectionSet.FromObjectIds
ed.SetImpliedSelection sSet
ed.WriteMessage(
"\n{0} found, {1} selected. ", oidOut.Count, sSet.Count )
tr.Commit()