{"size": 2723, "ext": "scrbl", "max_stars_repo_path": "pkgs/racket-doc/scribblings/foreign/active-x.scrbl", "max_stars_repo_name": "lkh01/racket", "max_stars_repo_stars_event_min_datetime": "2018-07-29T04:13:52.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-14T16:11:17.000Z", "max_issues_repo_path": "pkgs/racket-doc/scribblings/foreign/active-x.scrbl", "max_issues_repo_name": "lkh01/racket", "max_issues_repo_issues_event_min_datetime": "2017-08-25T20:26:37.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-26T17:48:40.000Z", "max_forks_repo_path": "pkgs/racket-doc/scribblings/foreign/active-x.scrbl", "max_forks_repo_name": "lkh01/racket", "max_forks_repo_forks_event_min_datetime": "2016-04-25T11:47:57.000Z", "max_forks_repo_forks_event_max_datetime": "2017-05-09T14:52:48.000Z"}
{"max_stars_count": 10, "max_issues_count": 15, "max_forks_count": 3, "avg_line_length": 34.0375, "max_line_length": 73, "alphanum_fraction": 0.5670216673}
#lang scribble/doc
@(require scribble/manual
          "com-common.rkt"
          (for-label racket/base
                     ffi/unsafe/com
                     xml))

@title[#:tag "active-x"]{ActiveX Controls}

An ActiveX control is a COM object that needs a container to manage
its graphical representation. Although @racketmodname[ffi/com] does
not provide direct support for ActiveX controls, you can use
@racketmodname[ffi/com] to drive Internet Explorer as an ActiveX
container.

The following code demonstrates using Internet Explorer to instantiate
the ``Sysmon'' ActiveX control that is included with Windows.

@codeblock{
#lang racket
(require ffi/com
	 xml)

;; The control we want to run:
(define control-progid "Sysmon")

;; Start IE:
(define ie (com-create-instance "InternetExplorer.Application.1"))

;; Set up an event callback so that we know when the initial document
;; is ready:
(define ex (com-make-event-executor))
(void (thread (lambda () (let loop () ((sync ex)) (loop)))))
(define ready (make-semaphore))
(com-register-event-callback ie "DocumentComplete" 
                             (lambda (doc url) (semaphore-post ready)) 
                             ex)

;; Navigate to get an initial document:
(com-invoke ie "Navigate" "about:blank")
(define READYSTATE_COMPLETE 4)
(unless (= (com-get-property ie "READYSTATE") READYSTATE_COMPLETE)
  (semaphore-wait ready))
(define doc (com-get-property ie "Document"))

;; Install HTML to show the ActiveX control:
(com-invoke doc "write"
            (xexpr->string
             `(html
               (head (title "Demo"))
               (body
                (object ((class "object")
                         (CLASSID ,(format 
                                    "CLSID:~a"
                                    (let ([s (guid->string 
                                              (progid->clsid 
                                               control-progid))])
                                      ;; must remove curly braces:
                                      (define len 
                                        (string-length s))
                                      (substring s 1 (sub1 len)))))))))))

;; Configure the IE window and show it:
(com-set-property! ie "MenuBar" #f)
(com-set-property! ie "ToolBar" 0)
(com-set-property! ie "StatusBar" #f)
(com-set-property! ie "Visible" #t)

;; Extract the ActiveX control from the IE document:
(define ctl (com-get-property 
	     (com-invoke (com-invoke doc "getElementsByTagName" "object") 
                         "item" 
                         0)
	     "object"))

;; At this point, `ctl' is the ActiveX control;
;; demonstrate by getting a list of method names:
(com-methods ctl)
}
