⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispatch.java

📁 java 与COM组件的连接桥
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright (c) 1999-2004 Sourceforge JACOB Project.
 * All rights reserved. Originator: Dan Adler (http://danadler.com).
 * Get more information about JACOB at http://sourceforge.net/projects/jacob-project
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package com.jacob.com;

import java.lang.reflect.Array;
import java.util.Date;

/**
 * Object represents MS level dispatch object. 
 * Each instance of this points at some data structure on the
 * MS windows side.   
 * 
 * 
 * <p>You're going to live here a lot
 */
public class Dispatch extends JacobObject
{
    public static final int LOCALE_SYSTEM_DEFAULT = 2048;
    public static final int Method = 1;
    public static final int Get = 2;
    public static final int Put = 4;
    public static final int PutRef = 8;
    public static final int fdexNameCaseSensitive = 1;
    public static final int DISPID_UNKNOWN = -1;
    public static final int DISPID_VALUE = 0;
    public static final int DISPID_PROPERTYPUT = -3;
    public static final int DISPID_NEWENUM = -4;
    public static final int DISPID_EVALUATE = -5;
    public static final int DISPID_CONSTRUCTOR = -6;
    public static final int DISPID_DESTRUCTOR = -7;
    public static final int DISPID_COLLECT = -8;
    public static final int DISPID_AUTOSIZE = -500;
    public static final int DISPID_BACKCOLOR = -501;
    public static final int DISPID_BACKSTYLE = -502;
    public static final int DISPID_BORDERCOLOR = -503;
    public static final int DISPID_BORDERSTYLE = -504;
    public static final int DISPID_BORDERWIDTH = -505;
    public static final int DISPID_DRAWMODE = -507;
    public static final int DISPID_DRAWSTYLE = -508;
    public static final int DISPID_DRAWWIDTH = -509;
    public static final int DISPID_FILLCOLOR = -510;
    public static final int DISPID_FILLSTYLE = -511;
    public static final int DISPID_FONT = -512;
    public static final int DISPID_FORECOLOR = -513;
    public static final int DISPID_ENABLED = -514;
    public static final int DISPID_HWND = -515;
    public static final int DISPID_TABSTOP = -516;
    public static final int DISPID_TEXT = -517;
    public static final int DISPID_CAPTION = -518;
    public static final int DISPID_BORDERVISIBLE = -519;
    public static final int DISPID_APPEARANCE = -520;
    public static final int DISPID_MOUSEPOINTER = -521;
    public static final int DISPID_MOUSEICON = -522;
    public static final int DISPID_PICTURE = -523;
    public static final int DISPID_VALID = -524;
    public static final int DISPID_READYSTATE = -525;
    public static final int DISPID_REFRESH = -550;
    public static final int DISPID_DOCLICK = -551;
    public static final int DISPID_ABOUTBOX = -552;
    public static final int DISPID_CLICK = -600;
    public static final int DISPID_DBLCLICK = -601;
    public static final int DISPID_KEYDOWN = -602;
    public static final int DISPID_KEYPRESS = -603;
    public static final int DISPID_KEYUP = -604;
    public static final int DISPID_MOUSEDOWN = -605;
    public static final int DISPID_MOUSEMOVE = -606;
    public static final int DISPID_MOUSEUP = -607;
    public static final int DISPID_ERROREVENT = -608;
    public static final int DISPID_READYSTATECHANGE = -609;
    public static final int DISPID_AMBIENT_BACKCOLOR = -701;
    public static final int DISPID_AMBIENT_DISPLAYNAME = -702;
    public static final int DISPID_AMBIENT_FONT = -703;
    public static final int DISPID_AMBIENT_FORECOLOR = -704;
    public static final int DISPID_AMBIENT_LOCALEID = -705;
    public static final int DISPID_AMBIENT_MESSAGEREFLECT = -706;
    public static final int DISPID_AMBIENT_SCALEUNITS = -707;
    public static final int DISPID_AMBIENT_TEXTALIGN = -708;
    public static final int DISPID_AMBIENT_USERMODE = -709;
    public static final int DISPID_AMBIENT_UIDEAD = -710;
    public static final int DISPID_AMBIENT_SHOWGRABHANDLES = -711;
    public static final int DISPID_AMBIENT_SHOWHATCHING = -712;
    public static final int DISPID_AMBIENT_DISPLAYASDEFAULT = -713;
    public static final int DISPID_AMBIENT_SUPPORTSMNEMONICS = -714;
    public static final int DISPID_AMBIENT_AUTOCLIP = -715;
    public static final int DISPID_AMBIENT_APPEARANCE = -716;
    public static final int DISPID_AMBIENT_CODEPAGE = -725;
    public static final int DISPID_AMBIENT_PALETTE = -726;
    public static final int DISPID_AMBIENT_CHARSET = -727;
    public static final int DISPID_AMBIENT_TRANSFERPRIORITY = -728;
    /**
     * This is public because Dispatch.cpp knows its name and accesses
     * it directly to get the disptach id.  You really can't rename
     * it or make it private
     */
    public int m_pDispatch;
    
	/** program Id passed in by ActiveX components in their constructor */
    private String programId = null;
  
    private static int NOT_ATTACHED = 0;

    /**
     * Dummy empty array used one doesn't have to be created on every 
     * invocation
     */
    private final static Object[] NO_OBJECT_ARGS = new Object[0];
    /**
     * Dummy empty array used one doesn't have to be created on every 
     * invocation
     */
    private final static Variant[] NO_VARIANT_ARGS = new Variant[0];
    /**
     * Dummy empty array used one doesn't have to be created on every 
     * invocation
     */
    private final static int[] NO_INT_ARGS = new int[0];


    /**
     * zero argument constructor that sets the dispatch pointer to 0
     * This is the only way to create a Dispatch without a value in the pointer field.
     */
    public Dispatch() {
        m_pDispatch = NOT_ATTACHED;
    }

    /**
     * This constructor calls createInstance with progid. This is the
     * constructor used by the ActiveXComponent or by programs that 
     * don't like the activeX interface but wish to create new connections
     * to windows programs.
     * <p>
     * This constructor always creates a new windows/program object
     * because it is based on the CoCreate() windows function.  
     * <p>
     * @throws IllegalArgumentException if null is passed in as the program id
     * <p>
     * @param requestedProgramId
     */
    public Dispatch(String requestedProgramId) {
        programId = requestedProgramId;
        if (programId != null && !"".equals(programId)){
        	createInstanceNative(requestedProgramId);
        } else {
        	throw new IllegalArgumentException(
        			"Dispatch(String) does not accept null or an empty string as a parameter");
        }
    }
    
    /**
     * native call createInstance only used by the constructor with the same parm
     * type. This probably should be private.  It is the wrapper for the
     * Windows CoCreate() call
     * <P>
     * This ends up calling CoCreate down in the JNI layer
     * <p>
     * The behavior is different if a ":" character exists in the progId.  In that
     * case CoGetObject and CreateInstance (someone needs to describe this better)
     * 
     * @param progid
     */
    private native void createInstanceNative(String progid);

    /**
     * native call getActiveInstance only used by the constructor with the same parm
     * type. This probably should be private.  It is the wrapper for the
     * Windows GetActiveObject() call
     * <P>
     * This ends up calling GetActiveObject down in the JNI layer
     * <p>
     * This does not have the special behavior for program ids with ":" in them
     * that createInstance has. 
     * 
     * @param progid
     */
    private native void getActiveInstanceNative(String progid);
    
    /**
     * Wrapper around the native method
     * @param pProgramIdentifier name of the program you wish to connect to
     */
    protected void getActiveInstance(String pProgramIdentifier){
    	if (pProgramIdentifier == null || "".equals(pProgramIdentifier)){
    		throw new IllegalArgumentException("program id is required");
    	}
    	this.programId = pProgramIdentifier;
    	getActiveInstanceNative(pProgramIdentifier);
    }

    /**
     * native call coCreateInstance only used by the constructor with the same parm
     * type. This probably should be private.  It is the wrapper for the
     * Windows CoCreate() call
     * <P>
     * This ends up calling CoCreate down in the JNI layer
     * <p>
     * This does not have the special behavior for program ids with ":" in them
     * that createInstance has. 
     * 
     * @param progid
     */
    private native void coCreateInstanceNative(String progid);

    /**
     * Wrapper around the native method
     * @param pProgramIdentifier
     */
    protected void coCreateInstance(String pProgramIdentifier){
    	if (pProgramIdentifier == null || "".equals(pProgramIdentifier)){
    		throw new IllegalArgumentException("program id is required");
    	}
    	this.programId = pProgramIdentifier;
    	coCreateInstanceNative(pProgramIdentifier);
    }

    /**
     * Return a different interface by IID string.
     * <p>
     * Once you have a Dispatch object, you can navigate to the other 
     * interfaces of a COM object by calling QueryInterafce. 
     * The argument is an IID string in the format: 
     * "{9BF24410-B2E0-11D4-A695-00104BFF3241}". You typically get 
     * this string from the idl file (it's called uuid in there). 
     * Any interface you try to use must be derived from IDispatch. T
     * The atl example uses this.
     * <p>
     * The Dispatch instance resulting from this query is instanciated in the
     * JNI code.
     * 
     * @param iid
     * @return Dispatch a disptach that matches ??
     */
    public native Dispatch QueryInterface(String iid);

    /**
     * Constructor that only gets called from JNI
     * QueryInterface calls JNI code that looks up the object 
     * for the key passed in.  The JNI CODE then creates a new dispatch object
     * using this constructor
     * @param pDisp
     */
    protected Dispatch(int pDisp) {
        m_pDispatch = pDisp;
    }

    /**
     * Constructor to be used by subclass that want to swap themselves
     * in for the default Dispatch class.  Usually you will have a
     * class like WordDocument that is a subclass of Dispatch and it
     * will have a constructor public WordDocument(Dispatch).  That
     * constructor should just call this constructor as super(Dispatch)
     * 
     * @param dispatchToBeDisplaced 
     */
    public Dispatch(Dispatch dispatchToBeDisplaced) {
        //TAKE OVER THE IDispatch POINTER
        this.m_pDispatch = dispatchToBeDisplaced.m_pDispatch;
        //NULL OUT THE INPUT POINTER
        dispatchToBeDisplaced.m_pDispatch = NOT_ATTACHED;
    }
    
    /**
     * returns the program id if an activeX component created this
     * otherwise it returns null. This was added to aid in debugging
     * @return the program id an activeX component was created against
     */
    public String getProgramId(){
        return programId;
    }
    
    /*
     *  (non-Javadoc)
     * @see java.lang.Object#finalize()
     */
    protected void finalize() {
        safeRelease();
    }
    
    /*
     *  (non-Javadoc)
     * @see com.jacob.com.JacobObject#safeRelease()
     */
    public void safeRelease()
    {
        super.safeRelease();
        if (isAttached()){
            release();
            m_pDispatch = NOT_ATTACHED;
        } else {
            // looks like a double release
            if (isDebugEnabled()){debug(this.getClass().getName()+":"+this.hashCode()+" double release");}
        }
    }
    
    /**
     * 
     * @return true if there is an underlying windows dispatch object
     */
    protected boolean isAttached(){
    	if (m_pDispatch == NOT_ATTACHED){
    		return false;
    	} else {
    		return true;
    	}
    }

    /**
     * @throws IllegalStateException if this dispatch isn't hooked up
     * @throws IllegalArgumentException if null the dispatch under test is null
     * @param theOneInQuestion dispatch being tested
     */
    private static void throwIfUnattachedDispatch(Dispatch theOneInQuestion){
      	if (theOneInQuestion == null) {
      		throw new IllegalArgumentException("Can't pass in null Dispatch object");
    	} else if (theOneInQuestion.isAttached()){
    		return;
    	} else {
    		throw new IllegalStateException("Dispatch not hooked to windows memory");
    	}
    }
    
    /**
     * Map args based on msdn doc
     * This method relies on the variant constructor except for arrays 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -