Lisp HUG Maillist Archive

Problem with com:invoke-dispatch-method

Hello All,

I'm having a problem and I hope someone can help me.  I'm trying to
interact with the WebBrowser ActiveX control in a similar fashion to
the html-viewer.lisp sample that ships with LWW.  I am able to call
almost all the methods I need with com:invoke-dispatch-method. 
However, I have a requirement to be able to print from the control. 
In order to do this, I need to call the ExecWB method and pass in some
parameters (see
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/Objects/WebBrowser.asp).
  It takes 4 parameters - an OLECMDID, an OLECMDEXECOPT, a Variant,
and a Variant.  In the case of printing, you use OLECMDID with a value
of IDM_PRINT (http://msdn.microsoft.com/workshop/browser/mshtml/reference/constants/idm_print.asp)
and away you go (the last 2 parameters are optional).

I have tried adding a Print button to the html-viewer.lisp sample and
a corresponding callback function that looks like this:

(defun html-viewer-demo-print (self)
  (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
                              "ExecWB"
                              27 ; IDM_PRINT
                              1 ; OLECMDEXECOPT_PROMPTUSER))

But I get an error:

Missing value for in/out arg 3.

I try supplying all 4 parameters with a function that looks like this:

(defun html-viewer-demo-print (self)
  (let ((temp nil)
        (temp2 nil))
    (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
                                "ExecWB"
                                27 ; IDM_PRINT
                                1 ; OLECMDEXECOPT_PROMPTUSER
                                temp
                                temp2)))

But I get an error:

#<Pointer to type COM:VARIANT = #x008C0108> is not of type CONS.

I've tried various versions of this with temp and temp2 having values
made by make-lisp-variant, fli:allocate-foreign-object, arrays, lists
and I haven't been able to get past the "Pointer to type..." error.  I
feel like I'm just missing it somehow.

Can someone please help?  I've included a patch below with my changes
to html-viewer.lisp.

Thanks!
Tom

------

--- orig/html-viewer.lisp       2006-01-01 15:34:16.111235200 -0600
+++ print-test/html-viewer.lisp 2006-01-01 15:20:16.564025600 -0600
@@ -32,10 +32,14 @@
    (go-button capi:push-button
               :text "Go"
               :callback 'html-viewer-demo-go
-              :callback-type :interface))
+              :callback-type :interface)
+   (print-button capi:push-button
+                 :text "Print"
+                 :callback 'html-viewer-demo-print
+                 :callback-type :interface))
   (:layouts
    (controls-layout capi:row-layout
-                    '(address go-button))
+                    '(address go-button print-button))
    (main-layout capi:column-layout
                 '(controls-layout html-pane)))
   (:default-initargs
@@ -54,6 +58,16 @@
                               (capi:text-input-pane-text
                                (slot-value self 'address))))

+(defun html-viewer-demo-print (self)
+  (let ((temp nil)
+        (temp2 nil))
+    (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
+                                "ExecWB"
+                                27 ; IDM_PRINT
+                                1 ; OLECMDEXECOPT_PROMPTUSER
+                                temp
+                                temp2)))
+
 (defun test-html-viewer-demo ()
   (capi:display (make-instance 'html-viewer-demo)))


Re: Problem with com:invoke-dispatch-method

OK, following up to myself here.  Turns out I had the wrong value for IDM_PRINT - it should be 6 instead of 27.  The html-viewer-demo-print function should now looks like:

(defun html-viewer-demo-print (self)
  (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
                              "ExecWB"
                              6 ; IDM_PRINT
                              1 ; OLECMDEXECOPT_PROMPTUSER
                              nil
                              nil))

This causes the WebBrowser control to print, but still gives the error (backtrace included):

Error: #<Pointer to type COM:VARIANT = #x008C9960> is not of type CONS.
  1 (abort) Return to event loop.

Type :b for backtrace, :c <option number> to proceed,  or :? for other options

CL-USER 1 : 1 > :b
Call to SEQ::CADDR-1ARG
Call to COM:INVOKE
Call to COM:INVOKE-DISPATCH-METHOD
Call to CAPI::EXECUTE-CALLBACK
Call to CAPI:EXECUTE-WITH-INTERFACE
Call to (SUBFUNCTION 1 (WIN32:DEFINE-TYPE-NOTIFICATION-FUNCTION CAPI-WIN32-LIB::R-BUTTON WIN32:BN_CLICKED))
Call to WIN32::WND-PROC
Call to FLI::FOREIGN-CALLABLE-ENTRY-POINT-AUX-NESTED
Call to WIN32::CALL-WINDOW-PROC$RAW
Call to WIN32::WND-PROC
Call to FLI::FOREIGN-CALLABLE-ENTRY-POINT-AUX-NESTED
Call to WIN32:DISPATCH-MESSAGE
Call to WIN32::PROCESS-MESSAGES
Call to MP::WIN32-PROCESS-WAIT-FOR-EVENT
Call to MP:PROCESS-READ-EVENT
Call to CAPI-INTERNALS:LOOP-PROCESS-EVENTS
Call to CAPI::INTERFACE-EVENT-LOOP
Call to CAPI::INITIALIZE-AND-PROCESS-EVENTS
Call to (SUBFUNCTION MP::PROCESS-SG-FUNCTION MP::INITIALIZE-PROCESS-STACK)



On 1/1/06, Tom Pierce <t.pierce@computer.org> wrote:
Hello All,

I'm having a problem and I hope someone can help me.  I'm trying to
interact with the WebBrowser ActiveX control in a similar fashion to
the html-viewer.lisp sample that ships with LWW.  I am able to call
almost all the methods I need with com:invoke-dispatch-method.
However, I have a requirement to be able to print from the control.
In order to do this, I need to call the ExecWB method and pass in some
parameters (see
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/Objects/WebBrowser.asp) .
  It takes 4 parameters - an OLECMDID, an OLECMDEXECOPT, a Variant,
and a Variant.  In the case of printing, you use OLECMDID with a value
of IDM_PRINT ( http://msdn.microsoft.com/workshop/browser/mshtml/reference/constants/idm_print.asp)
and away you go (the last 2 parameters are optional).

I have tried adding a Print button to the html-viewer.lisp sample and
a corresponding callback function that looks like this:

(defun html-viewer-demo-print (self)
  (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
                              "ExecWB"
                              27 ; IDM_PRINT
                              1 ; OLECMDEXECOPT_PROMPTUSER))

But I get an error:

Missing value for in/out arg 3.

I try supplying all 4 parameters with a function that looks like this:

(defun html-viewer-demo-print (self)
  (let ((temp nil)
        (temp2 nil))
    (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
                                "ExecWB"
                                27 ; IDM_PRINT
                                1 ; OLECMDEXECOPT_PROMPTUSER
                                temp
                                temp2)))

But I get an error:

#<Pointer to type COM:VARIANT = #x008C0108> is not of type CONS.

I've tried various versions of this with temp and temp2 having values
made by make-lisp-variant, fli:allocate-foreign-object, arrays, lists
and I haven't been able to get past the "Pointer to type..." error.  I
feel like I'm just missing it somehow.

Can someone please help?  I've included a patch below with my changes
to html-viewer.lisp.

Thanks!
Tom

------

--- orig/html-viewer.lisp       2006-01-01 15:34: 16.111235200 -0600
+++ print-test/html-viewer.lisp 2006-01-01 15:20:16.564025600 -0600
@@ -32,10 +32,14 @@
    (go-button capi:push-button
               :text "Go"
               :callback 'html-viewer-demo-go
-              :callback-type :interface))
+              :callback-type :interface)
+   (print-button capi:push-button
+                 :text "Print"
+                 :callback 'html-viewer-demo-print
+                 :callback-type :interface))
   (:layouts
    (controls-layout capi:row-layout
-                    '(address go-button))
+                    '(address go-button print-button))
    (main-layout capi:column-layout
                 '(controls-layout html-pane)))
   (:default-initargs
@@ -54,6 +58,16 @@
                               (capi:text-input-pane-text
                                (slot-value self 'address))))

+(defun html-viewer-demo-print (self)
+  (let ((temp nil)
+        (temp2 nil))
+    (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
+                                "ExecWB"
+                                27 ; IDM_PRINT
+                                1 ; OLECMDEXECOPT_PROMPTUSER
+                                temp
+                                temp2)))
+
(defun test-html-viewer-demo ()
   (capi:display (make-instance 'html-viewer-demo)))

Re: Problem with com:invoke-dispatch-method

Thanks, Martin.  I'm going to put an ignore-errors around it for now.

On 1/5/06, Martin Simmons <martin@lispworks.com > wrote:

>>>>> On Mon, 2 Jan 2006 21:24:24 -0600, Tom Pierce < t.pierce@computer.org> said:

  Tom> OK, following up to myself here.  Turns out I had the wrong value for
  Tom> IDM_PRINT - it should be 6 instead of 27.  The html-viewer-demo-print
  Tom> function should now looks like:

  Tom> (defun html-viewer-demo-print (self)
  Tom>   (com:invoke-dispatch-method (html-viewer-demo-dispatch self)
  Tom>                               "ExecWB"
  Tom>                               6 ; IDM_PRINT
  Tom>                               1 ; OLECMDEXECOPT_PROMPTUSER
  Tom>                               nil
  Tom>                               nil))

  Tom> This causes the WebBrowser control to print, but still gives the error
  Tom> (backtrace included):

  Tom> Error: #<Pointer to type COM:VARIANT =3D #x008C9960> is not of type CONS.

It looks like there is some problem with variant args at the moment.  We will
look at fixing this.

--
Martin Simmons                              Email: martin@lispworks.com
LispWorks Ltd, St John's Innovation Centre    TEL:   +44 1223 421860
Cowley Road, Cambridge CB4 0WS, England.      FAX:   +44 870 2206189


Updated at: 2020-12-10 08:49 UTC