随笔 - 1, 文章 - 0, 评论 - 0, 引用 - 0
数据加载中……

Java call native methods in a DLL without JNI (Call PageSetupDlg function in comdlg32.dll)

最近由于项目的要求, 需要在SWT程序中打印自定义的表格, 并能设置页面和页面空白的大小。

再查看了SWT的文档后发现, SWT只封装了PrintDLG打印对话框,可以设置页面的大小,但不能设置页面空白的大小。
由于本人以前是VB程序员,本能的就想到了comdlg32.dll 中的PageSetupDlg对话框。 如果可以直接调用这个对话框, 省掉了多少麻烦事啊。

但是用JNI调用dll中的函数也很麻烦, 还不如自己做一个页面设置对话框来的方便。 于是查了一下sourceforge, 发现了JNative这个类库。 在稍稍看了JNative的源码之后觉得这个库写的真是不错。 封装了许多Win32 api中的类型(HWND,DWORD, LPARAM 等等) 方便使用, 并且直接wrapper了不少dll (比如 Gdi32, Kernel32, Shell32, User32等dll), 其中居然也包括ComDlg32 (可惜只封装了ChooseColor 颜色选择对话框)。


不过不要紧, 既然有了ChooseColor的例子,那我们就自己动手调用PageSetupDlg吧。

先查一下msdn, 看一看PageSetupDlg函数的用法

BOOL PageSetupDlg(      

    LPPAGESETUPDLG lppsd

);


PAGESETUPDLG Structure:
typedef struct tagPSD {
    DWORD lStructSize;
    HWND hwndOwner;
    HGLOBAL hDevMode;
    HGLOBAL hDevNames;
    DWORD Flags;
    POINT ptPaperSize;
    RECT rtMinMargin;
    RECT rtMargin;
    HINSTANCE hInstance;
    LPARAM lCustData;
    LPPAGESETUPHOOK lpfnPageSetupHook;
    LPPAGEPAINTHOOK lpfnPagePaintHook;
    LPCTSTR lpPageSetupTemplateName;
    HGLOBAL hPageSetupTemplate;
} PAGESETUPDLG, 
*LPPAGESETUPDLG;


其中有两个结构RECT, 和 POINT是Jnative 没有封装的, 我们先封装这两个结构:

POINT.java
 1 package de.ikoffice.ktableextension.printer;
 2 
 3 import org.xvolks.jnative.exceptions.NativeException;
 4 import org.xvolks.jnative.misc.basicStructures.AbstractBasicData;
 5 import org.xvolks.jnative.misc.basicStructures.LONG;
 6 import org.xvolks.jnative.pointers.Pointer;
 7 import org.xvolks.jnative.pointers.memory.GlobalMemoryBlock;
 8 
 9 /**
10  * @author Jun Huang
11  *
12  * The Gosurf Development Team
13  * 
14  */
15 public class POINT extends AbstractBasicData<POINT> {
16     LONG x;
17     LONG y;
18 
19     public POINT() throws NativeException {
20         super(null);
21         mValue = this;
22         createPointer();
23     }
24 
25     /*
26      * (non-Javadoc)
27      * 
28      * @see org.xvolks.jnative.misc.basicStructures.BasicData#createPointer()
29      */
30     public Pointer createPointer() throws NativeException {
31         pointer = new Pointer(new GlobalMemoryBlock(getSizeOf()));
32         return pointer;
33     }
34 
35     /*
36      * (non-Javadoc)
37      * 
38      * @see org.xvolks.jnative.misc.basicStructures.BasicData#getSizeOf()
39      */
40     public int getSizeOf() {
41         return 8;
42     }
43 
44     /*
45      * (non-Javadoc)
46      * 
47      * @see org.xvolks.jnative.misc.basicStructures.BasicData#getValueFromPointer()
48      */
49     public POINT getValueFromPointer() throws NativeException {
50         offset = 0;
51         x = new LONG(getNextInt());
52         y = new LONG(getNextInt());
53 
54         return getValue();
55     }
56 
57     public void setX(LONG x) throws NativeException {
58         this.x = x;
59         pointer.setIntAt(0, x.getValue());
60     }
61 
62     public void setY(LONG y) throws NativeException {
63         this.y = y;
64         pointer.setIntAt(4, y.getValue());
65     }
66 
67 }

RECT.java
 1 /**
 2  * 
 3  */
 4 package de.ikoffice.ktableextension.printer;
 5 
 6 import org.xvolks.jnative.exceptions.NativeException;
 7 import org.xvolks.jnative.misc.basicStructures.AbstractBasicData;
 8 import org.xvolks.jnative.misc.basicStructures.LONG;
 9 import org.xvolks.jnative.pointers.Pointer;
10 import org.xvolks.jnative.pointers.memory.GlobalMemoryBlock;
11 
12 /**
13  * @author Jun Huang
14  *
15  * The Gosurf Development Team
16  */
17 public class RECT extends AbstractBasicData<RECT> {
18     LONG left;
19     LONG top;
20     LONG right;
21     LONG bottom;
22     
23 
24     protected RECT() throws NativeException {
25         super(null);
26         mValue = this;
27         createPointer();
28     }
29 
30     /* (non-Javadoc)
31      * @see org.xvolks.jnative.misc.basicStructures.BasicData#createPointer()
32      */
33     public Pointer createPointer() throws NativeException {
34         pointer = new Pointer(new GlobalMemoryBlock(getSizeOf()));
35         return pointer;
36     }
37 
38     /* (non-Javadoc)
39      * @see org.xvolks.jnative.misc.basicStructures.BasicData#getSizeOf()
40      */
41     public int getSizeOf() {
42         return 16;
43     }
44 
45     /* (non-Javadoc)
46      * @see org.xvolks.jnative.misc.basicStructures.BasicData#getValueFromPointer()
47      */
48     public RECT getValueFromPointer() throws NativeException {
49         offset = 0;
50         left = new LONG(getNextInt());
51         top = new LONG(getNextInt());
52         right = new LONG(getNextInt());
53         bottom = new LONG(getNextInt());
54         
55         return getValue();
56     }
57 
58     public void setLeft(LONG left) throws NativeException {
59         this.left = left;
60         pointer.setIntAt(0, left.getValue());
61     }
62 
63     public void setTop(LONG top) throws NativeException {
64         this.top = top;
65         pointer.setIntAt(4, top.getValue());
66     }
67 
68     public void setRight(LONG right) throws NativeException {
69         this.right = right;
70         pointer.setIntAt(8, right.getValue());
71     }
72 
73     public void setBottom(LONG bottom) throws NativeException {
74         pointer.setIntAt(12, bottom.getValue());
75     }
76     
77     
78 
79 }
80 

然后封装PAGESETDLG结构
PAGESETUPDLG.java
  1 package de.ikoffice.ktableextension.printer;
  2 
  3 import org.xvolks.jnative.exceptions.NativeException;
  4 import org.xvolks.jnative.misc.basicStructures.AbstractBasicData;
  5 import org.xvolks.jnative.misc.basicStructures.HWND;
  6 import org.xvolks.jnative.misc.basicStructures.LONG;
  7 import org.xvolks.jnative.misc.basicStructures.LPARAM;
  8 import org.xvolks.jnative.pointers.NullPointer;
  9 import org.xvolks.jnative.pointers.Pointer;
 10 import org.xvolks.jnative.pointers.memory.GlobalMemoryBlock;
 11 import org.xvolks.jnative.util.Callback;
 12 
 13 /**
 14  * @author Jun Huang
 15  *
 16  * The Gosurf Development Team
 17  *
 18  */
 19 public class PAGESETUPDLG extends AbstractBasicData<PAGESETUPDLG> {
 20     
 21     LONG lStrurtSize;
 22     HWND hwndOwner;
 23     static Pointer hDevMode = new NullPointer();
 24     static Pointer hDevNames = new NullPointer();
 25     LONG flags;
 26     POINT ptPaperSize;
 27     RECT rtMinMargin;
 28     RECT rtMargin;
 29     HWND hInstance;
 30     LPARAM lCustData;
 31     Callback lpfnPageSetupHook;
 32     Callback lpfnPagePaintHook;
 33     Pointer lpPageSetupTemplateName;
 34     static Pointer hPageSetupTemplate = new NullPointer();
 35     
 36     
 37     public PAGESETUPDLG() throws NativeException {
 38         super(null);
 39         mValue = this;
 40         createPointer();
 41     }
 42     
 43     public void removeCallback() throws NativeException {
 44         //TODO
 45     }
 46     
 47     public void addCallback(Callback lCallback) throws NativeException {
 48         removeCallback();
 49         
 50         //TODO
 51     }
 52     
 53     public void setHwndOwner(HWND hwndOwner) throws NativeException {
 54         this.hwndOwner = hwndOwner;
 55         pointer.setIntAt(4, hwndOwner.getValue());
 56     }
 57 
 58     public void setFlags(LONG flags) throws NativeException {
 59         this.flags = flags;
 60         pointer.setIntAt(16, flags.getValue());
 61     }
 62 
 63     public void setHInstance(HWND instance) throws NativeException {
 64         hInstance = instance;
 65         pointer.setIntAt(60, instance.getValue());
 66     }
 67 
 68     public void setLCustData(LPARAM custData) throws NativeException {
 69         lCustData = custData;
 70         pointer.setIntAt(64, lCustData.getValue());
 71     }
 72 
 73     public void setLpPageSetupTemplateName(String lpPageSetupTemplateName) {
 74         
 75         this.lpPageSetupTemplateName = new NullPointer();
 76         
 77     }
 78 
 79     /* (non-Javadoc)
 80      * @see org.xvolks.jnative.misc.basicStructures.BasicData#createPointer()
 81      */
 82     public Pointer createPointer() throws NativeException {
 83         pointer = new Pointer(new GlobalMemoryBlock(getSizeOf()));
 84         pointer.setIntAt(0, getSizeOf());
 85         pointer.setIntAt(8, hDevMode.getPointer());
 86         pointer.setIntAt(12, hDevNames.getPointer());
 87         return pointer;
 88     }
 89 
 90     /* (non-Javadoc)
 91      * @see org.xvolks.jnative.misc.basicStructures.BasicData#getSizeOf()
 92      */
 93     public int getSizeOf() {
 94         
 95         return 84;
 96     }
 97 
 98     /* (non-Javadoc)
 99      * @see org.xvolks.jnative.misc.basicStructures.BasicData#getValueFromPointer()
100      */
101     public PAGESETUPDLG getValueFromPointer() throws NativeException {
102         offset = 0;
103         lStrurtSize = new LONG(getNextInt());    // 0
104         hwndOwner = new HWND(getNextInt());     // 4
105         
106         //Skip hDevMode
107         offset += 4;                             // 8
108         
109         //Skip hDevNames
110         offset += 4;                            // 12
111         
112         flags = new LONG(getNextInt());          // 16
113         
114         //ptPaperSize
115         ptPaperSize = new POINT();                // 20
116         ptPaperSize.setX(new LONG(getNextInt()));
117         ptPaperSize.setY(new LONG(getNextInt()));
118         
119         //rtMinMargin                        // 28    
120         rtMinMargin = new RECT();
121         rtMinMargin.setLeft(new LONG(getNextInt()));
122         rtMinMargin.setTop(new LONG(getNextInt()));
123         rtMinMargin.setRight(new LONG(getNextInt()));
124         rtMinMargin.setBottom(new LONG(getNextInt()));
125         
126         //rtMargin                            // 44
127         rtMargin = new RECT();
128         rtMargin.setLeft(new LONG(getNextInt()));
129         rtMargin.setTop(new LONG(getNextInt()));
130         rtMargin.setRight(new LONG(getNextInt()));
131         rtMargin.setBottom(new LONG(getNextInt()));
132         
133         hInstance = new HWND(getNextInt());        // 60
134         
135         lCustData = new LPARAM(getNextInt());     // 64
136         
137         //Skip lpfnPageSetupHook;                // 68
138         offset += 4;
139         
140         //Skip lpfnPagePaintHook;                // 72;
141         offset += 4;
142         
143         //Skip lpPageSetupTemplateName;            // 76;
144         offset += 4;
145         
146         //Skip hPageSetupTemplate;                // 80;
147         offset += 4;
148         
149         // 84
150         
151         return getValue();
152   
153     }
154 
155 }

我们所希望的返回值是页面大小和页面空白大小:
PageSetupResult.java
 1 /**
 2  * 
 3  */
 4 package de.ikoffice.ktableextension.printer;
 5 
 6 /**
 7  * @author Jun Huang
 8  *
 9  * The Gosurf Development Team
10  *
11  */
12 public class PageSetupResult {
13     
14     public final static int LEFT = 0;
15     public final static int TOP = 1;
16     public final static int RIGHT = 2;
17     public final static int BOTTOM = 3;
18     
19     private boolean ret = false;
20     private int[] margins = new int[4];
21     private int pageWidth = 0;
22     private int pageHeight = 0;
23     
24     public PageSetupResult() {
25         ret = false;
26         for (int i=0; i<=BOTTOM; i++) {
27             margins[i] = 2500;
28         }
29     }
30 
31     public boolean isRet() {
32         return ret;
33     }
34 
35     public int[] getMargins() {
36         return margins;
37     }
38 
39     public void setRet(boolean ret) {
40         this.ret = ret;
41     }
42 
43     public void setMargins(int[] margins) {
44         this.margins = margins;
45     }
46     
47     public void setMargin(int position, int mm) {
48         this.margins[position] = mm;
49     }
50     
51     public int getMargin(int position) {
52         return margins[position];
53     }
54 
55     public int getPageWidth() {
56         return pageWidth;
57     }
58 
59     public int getPageHeight() {
60         return pageHeight;
61     }
62 
63     public void setPageWidth(int pageWidth) {
64         this.pageWidth = pageWidth;
65     }
66 
67     public void setPageHeight(int pageHeight) {
68         this.pageHeight = pageHeight;
69     }
70   
71 }
72 

万事俱备,现在就可以点用PageSetupDlg函数了
ComDlg32Ex.java
 1 package de.ikoffice.ktableextension.printer;
 2 
 3 import org.xvolks.jnative.JNative;
 4 import org.xvolks.jnative.Type;
 5 import org.xvolks.jnative.exceptions.NativeException;
 6 import org.xvolks.jnative.misc.basicStructures.HWND;
 7 import org.xvolks.jnative.misc.basicStructures.LONG;
 8 import org.xvolks.jnative.misc.basicStructures.LPARAM;
 9 import org.xvolks.jnative.util.ComDlg32;
10 
11 /**
12  * @author Jun Huang
13  *
14  * The Gosurf Development Team
15  */
16 public class ComDlg32Ex extends ComDlg32 {
17     //Cache the JNative object between calls.
18     private static JNative nPageSetupDlg;
19     public final static int PSD_MINMARGINS = 0x1;
20     public final static int PSD_MARGINS = 0x2;
21     public final static int PSD_INTHOUSANDTHSOFINCHES = 0x4;
22     public final static int PSD_INHUNDREDTHSOFMILLIMETERS = 0x8;
23     
24     
25     public static PageSetupResult PageSetupDlg(HWND lOwner, HWND hInstance, LONG Flags, LPARAM lCustData) throws NativeException, IllegalAccessException {
26         PageSetupResult ret = new PageSetupResult();
27         
28         if(nPageSetupDlg == null) {
29             //JNative uses ANSI version ChooseColorA vs ChooseColorW
30             nPageSetupDlg = new JNative(DLL_NAME, "PageSetupDlgA");
31             //BOOL is in fact an INT
32             nPageSetupDlg.setRetVal(Type.INT);
33         }
34         PAGESETUPDLG nPageSetupDlgStruct = new PAGESETUPDLG();
35         nPageSetupDlgStruct.setHwndOwner(lOwner);
36         nPageSetupDlgStruct.setHInstance(hInstance);
37         nPageSetupDlgStruct.setFlags(Flags);
38         nPageSetupDlgStruct.setLCustData(lCustData);
39         
40         nPageSetupDlg.setParameter(0, nPageSetupDlgStruct.getPointer());
41         nPageSetupDlg.invoke();
42         
43         if("0".equals(nPageSetupDlg.getRetVal())) {
44             ret.setRet(false);
45             return ret;
46         } 
47         
48         ret.setRet(true);
49         ret.setMargin(PageSetupResult.LEFT, nPageSetupDlgStruct.getValueFromPointer().rtMargin.getValueFromPointer().left.getValue());
50         ret.setMargin(PageSetupResult.TOP, nPageSetupDlgStruct.getValueFromPointer().rtMargin.getValueFromPointer().top.getValue());
51         ret.setMargin(PageSetupResult.RIGHT, nPageSetupDlgStruct.getValueFromPointer().rtMargin.getValueFromPointer().right.getValue());
52         ret.setMargin(PageSetupResult.BOTTOM, nPageSetupDlgStruct.getValueFromPointer().rtMargin.getValueFromPointer().bottom.getValue());
53         ret.setPageWidth(nPageSetupDlgStruct.getValueFromPointer().ptPaperSize.getValueFromPointer().x.getValue());
54         ret.setPageHeight(nPageSetupDlgStruct.getValueFromPointer().ptPaperSize.getValueFromPointer().y.getValue());
55         
56         return ret;
57     }
58     
59     public static void main(String[] args) throws NativeException, IllegalAccessException {
60         PageSetupResult result = ComDlg32Ex.PageSetupDlg(new HWND(0), new HWND(0), new LONG(ComDlg32Ex.PSD_INHUNDREDTHSOFMILLIMETERS), new LPARAM(0));
61         System.out.println("The width of page: " + result.getPageWidth()+" mm");
62         System.out.println("The height of page: " + result.getPageHeight()+" mm");
63         System.out.println("The left margin of page: " + result.getMargin(PageSetupResult.LEFT) +" mm");
64         System.out.println("The top margin of page: " + result.getMargin(PageSetupResult.TOP) + " mm");
65         System.out.println("The right margin of page: " + result.getMargin(PageSetupResult.RIGHT) + " mm");
66         System.out.println("The bottom margin of page: " + result.getMargin(PageSetupResult.BOTTOM) + " mm");
67     }
68 
69 
70 }
71 

有空的话我尽量把ComDlg32中的对话框补全, 有什么问题大家可以一起探讨一下。
源码下载

posted on 2008-08-22 14:52 onkyo 阅读(744) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: