[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]

[MD:7263] Meadow OLE automation Implementation



ほりぐちです. しばらく死んでましたがふと思い立って Meadow に OLE
Automation を突っ込んでみました. (できたからなんだという話もありま
すが..)

 今のところ後につけるような elisp が動いています.

 動作自体は ruby の win32ole のサンプルと同じ..だと思います. 長期
 /高負荷時のの動作の検証はあまり行っていません.

 Meadow の既存コードへのインパクトについてはメインスレッドで処理す
るプライベートメッセージがひとつ追加になっただけです. なので OLE
モジュールの初期化をしなければ既存部分への動作への影響はまったく影
響はありません.

 特に問題がなければこれをリポジトリに入れてしまおうと思っています
がどうでしょうか.

# インタフェースの仕様についての突っ込みも歓迎です.

##  他に機能増強ネタとしては, WaitForMultipleObject や select をマ
## ルチスレッドで行うことでソケット 64 個制限を乗り越えるというの
## があります. これで起動できるプロセス数を現状の30個程度より増や
## すことができるようになると思います.

-- 
ほりぐちきょうたろう

=== mw32ole の利用例

;;=excel1====================================================
(defun oletest-excel1 ()
  "Create graph on excel."
  (unwind-protect
      (let (application workbook worksheet range)
	(setq application (or (mw32-ole-connect "excel.application")
			      (mw32-ole-create "excel.application")))
	(mw32-ole-putprop application "visible" t)
	(setq workbook (mw32-ole-execute
			(mw32-ole-getprop application "Workbooks")
			"Add"))
	(setq worksheet (mw32-ole-execute workbook "Worksheets" 1))
	(mw32-ole-putprop
	 (mw32-ole-execute worksheet "Range" "A1:D1")
	 "value"  ["North" "South" "East" "West"])
	(mw32-ole-putprop (mw32-ole-execute worksheet "Range" "A2:B2")
			  "value"  [5.2 10])
	(mw32-ole-putprop (mw32-ole-execute worksheet "Range" "C2")
			  "value" 8)
	(mw32-ole-putprop (mw32-ole-execute worksheet "Range" "D2")
			  "value"  20)

	(setq range (mw32-ole-execute worksheet "Range""A1:D2"))
	(mw32-ole-execute range "Select")
	(setq chart (mw32-ole-execute (mw32-ole-getprop workbook "Charts")
				      "Add"))

	(mw32-ole-putprop workbook "saved" t)
	(sleep-for 4)

	(mw32-ole-execute
	 (mw32-ole-getprop application "ActiveWorkbook")
	 "Close" 0)
	(mw32-ole-execute application "Quit"))
    (mw32-ole-cleanup-objects)))

;;=excel2====================================================
(defun oletest-excel2 ()
  "Create graph on excel and rotate it."
  (unwind-protect
      (let ((chartypeval -4100)
	    excel workbook excelchart)
	(setq excel (or (mw32-ole-connect "excel.application")
			(mw32-ole-create "excel.application")))
      
	(mw32-ole-putprop excel "visible" t)
	(setq workbook
	      (mw32-ole-execute (mw32-ole-getprop excel "Workbooks") "Add"))
	(mw32-ole-putprop (mw32-ole-execute excel "Range" "a1") "value" 3)
	(mw32-ole-putprop (mw32-ole-execute excel "Range" "a2") "value" 2)
	(mw32-ole-putprop (mw32-ole-execute excel "Range" "a3") "value" 1)
	(mw32-ole-execute (mw32-ole-execute excel "Range" "a1:a3") "Select")
	(setq excelchart
	      (mw32-ole-execute (mw32-ole-getprop excel "Charts") "Add"))
	(mw32-ole-putprop excelchart "Type" chartypeval)
      
	(let ((i 30))
	  (while (<= i 180)
	    (mw32-ole-putprop excelchart "rotation" i)
	    (setq i (+ i 10))
	    (sleep-for 0.5)))
	(mw32-ole-putprop workbook "saved" t)
	(sleep-for 4)
      
	(mw32-ole-execute (mw32-ole-getprop excel "ActiveWorkbook") "close" 0)
	(mw32-ole-execute excel "quit"))
    (mw32-ole-cleanup-objects)))

;;=excel3====================================================
(defun oletest-excel3 ()
  "Insert worksheet on excel."
  (unwind-protect
      (let (application workbook sheet sheetS strs)
	(setq application (or (mw32-ole-connect "excel.application")
			      (mw32-ole-create "excel.application")))
	(mw32-ole-putprop application "visible" t)
	(setq workbook (mw32-ole-execute
			(mw32-ole-getprop application "Workbooks")
			"Add"))
	(setq sheet (mw32-ole-execute workbook "Worksheets" 1))
	(setq sheetS (mw32-ole-getprop workbook "Worksheets"))
	(setq
	 strs
	 (cons (format "The number of sheets is %d"
		       (mw32-ole-getprop sheetS "count"))
	       (cons 
		(format "Now add 2 sheets after of %s"
			(mw32-ole-getprop sheet "name"))
		nil)))
	(mw32-ole-execute sheetS "add" '(count . 2) (cons 'after sheet))
	(mw32-ole-putprop workbook "saved" t)

	(setq strs
	      (append strs
		      (list (format "The number of sheets is %d"
				    (mw32-ole-getprop sheetS "count"))))))
    (mw32-ole-cleanup-objects)))

;;=ie constants load =====================================
(defun oletest-ieconst ()
  "Load OLE constants as alist."
  (unwind-protect
      (mw32-ole-load-constant
       (mw32-ole-create "InternetExplorer.Application"))
    (mw32-ole-cleanup-objects)))

	    
;;=ie navigation and event processing ====================
(defun oletest-ienavi (&optional url)
  "Internet Explorer navigation."
  (if (null url) (setq url "http://www.meadowy.org/meadow"))
  (put 'global 'url url)
  (put 'global 'state 0)
  (let (ev)
    (put 'global
	 'ie (mw32-ole-create "InternetExplorer.Application"))
    (mw32-ole-putprop (get 'global 'ie) "visible" t)
    (mw32-ole-execute (get 'global 'ie) "gohome")
    (setq ev (mw32-ole-create-eventsink (get 'global 'ie) "DWebBrowserEvents"))
    (mw32-ole-set-event-handler
     ev '(lambda (event &rest args)
	   (cond
	    ((and (eq event 'NavigateComplete)
		  (eq 0 (get 'global 'state)))
	     (put 'global 'state 1)
	     (message (format "Hop to \"%s\" from \"%s\""
			      (get 'global 'url)
			      (car args)))
	     (mw32-ole-execute (get 'global 'ie) "navigate"
			       (get 'global 'url)))
	    ((eq event 'NavigateComplete)
	     (message (format "Navigate completed : \"%s\""(car args))))
	    ((eq event 'Quit)
	     (message "Internet Explorer quited"))
	    ((eq event 'BeforeNavigate)
	     (message (format "IE: Navigate \"%s\"" (car args))))))
     '(Quit NavigateComplete BeforeNavigate)))
  nil)
  

;;=== wsh ====================================================
(defun oletest-dirs (&optional dir)
  (unwind-protect
      (let ((folder (mw32-ole-execute
		     (mw32-ole-create "Scripting.FileSystemObject")
		     "GetFolder" (or dir ".")))
	    subfolders files)
	(cons
	 (cons 'directories
	       (mw32-ole-mapcar
		'(lambda (a) (mw32-ole-getprop a "name"))
		(mw32-ole-enumerator (mw32-ole-getprop folder "SubFolders"))))
	 (cons 'files
	       (mw32-ole-mapcar
		'(lambda (a) (mw32-ole-getprop a "name"))
		(mw32-ole-enumerator (mw32-ole-getprop folder "Files"))	))))
    (mw32-ole-cleanup-objects)))
===============================
mw32-ole-cleanup-objects
(mw32-ole-cleanup-objects &optional discard)

Release recorded IDispatch objects since last `mw32-ole-record-start',
and go up the nest level.
If discard is not nil, no objects are released and simply go up the nest level.
Returns the cons of the number of the released objects and new nest level.

==========
mw32-ole-clsid
(mw32-ole-clsid progid)

Get class id of progid.
Class is a vector consists of three integer and one vector of 8 integers.
Eash element corresponds with CLSID's member Data1, Data2, Data3, and Data4.

==========
mw32-ole-connect
(mw32-ole-connect progid)

Connect to existing OLE instance indicated with progid.
Returns OLE IDispatch object if succeed, and returns nil if no instance
exists.

==========
mw32-ole-create
(mw32-ole-create progid)

Create new OLE instance for progid.
Returns OLE IDispatch object if succeed.

==========
mw32-ole-create-eventsink
(mw32-ole-create-eventsink idispatch typename)

Create EventSink object for interface typename of idispatch.

==========
mw32-ole-dump-objects
(mw32-ole-dump-objects)

Dump all interface objects in record.

==========
mw32-ole-enumerator
(mw32-ole-enumerator idispatch)

Get Enumerator for collection object IDISPACH.

==========
mw32-ole-execute
(mw32-ole-execute idispatch method &rest parameters)

Excecuting method of IDispatch interface.
The first argument idispatch is IDispatch object returned by
`mw32-ole-connect' or `mw32-ole-create'.
The second argument method is the name of the method to invoke.
The REST are the parameters of method. The format of parameters is
simple value or cons of name and value where the name is string or symbol.
Returns the result of method.

==========
mw32-ole-getprop
(mw32-ole-getprop idispatch member)

Get property of the IDispatch.
The first argument idispatch is an obect returned by `mw32-ole-create' or
`mw32-ole-connect'.
The second argument member is the name of the member to get property of.
Returns the value of the property.

[back]

==========
mw32-ole-init
(mw32-ole-init)

Initialize OLE facility.
Returns t if intialize successed.

==========
mw32-ole-invoke
(mw32-ole-invoke idispatch interface context &rest parameters)

Primitive IDispatch invoke function.
The first argument idispatch is an obect returned by `mw32-ole-create' or
`mw32-ole-connect'.
The second argument interface is name of the interface to invoke in symbol
or string.
The third argument context of invoke. 'DISPATCH_METHOD,
'DISPATCH_PROPERTYGET, 'DISPATCH_PROPERTYPUT can be specified.
parameters are the parameters to pass target, that are simple values or
conses of the paramter name and the value, where the name is a symbol
or string.

==========
mw32-ole-load-constant
(mw32-ole-load-constant idispatch)

Load constant for idispatch.

==========
mw32-ole-mapc
(mw32-ole-load-constant idispatch)

Load constant for idispatch.

==========
mw32-ole-mapcar
(mw32-ole-mapcar function enumuerator)

Apply function to each element of ENUMERTOR, and make a list of the results.
The result is a list just as long as the number of te elements of ENUMERATOR.
All interface objects passed to function are released before exiting.

==========
mw32-ole-putprop
(mw32-ole-putprop idispatch member value)

Put property value of the IDispatch.
The first argument idispatch is an obect returned by `mw32-ole-create' or
`mw32-ole-connect'.
The second argument member is the name of the member to put property of.
The third argument is the value to be set.
Returns the value of the property.

==========
mw32-ole-record-start
(mw32-ole-record-start)

Start recording IDispatch object creation.
`mw32-ole-unwind-record' can release recorded objects.
Recording of object creation can be nested. `mw32-ole-unwind-record'
releases mostinner records and go upward in the  nest levels.
If the record released was the toplevel, simply emtpy the record and stay
in the top level.
Returns the new nest level of recording.

==========
mw32-ole-release
(mw32-ole-release iobj)

Release the OLE Interface object.

==========
mw32-ole-set-event-handler
(mw32-ole-set-event-handler ieventsink function &optional filter
queue-len)

Set event handler function to ieventsink.
If function is nil, unset existing event handler. If not nil, unset existing
handler and set it.
Optional third parameter filter is a list of the names of the events to be
caught. This reduces internal communication to handle events.
Optional fourth queue-len is event queue length. If event queue is flooded,
event handling is stoped and the event handler is removed.

==========
mw32-ole-uninit
(mw32-ole-uninit)

Release all existing IDispatch objects and unnitialize OLE facility.
Returns the number of the objects released.
=======