最近在做一个电子档案管理的项目。现在还处于初期,只是做一个简单demo拿去跟客户演示。至于最后谈不谈得下来,到底做不做,反正我是不看好,但没因为这样就马马虎虎、草草了事。这个项目算是b/s加c/s混合体,现在已经做的应该占六七成吧,算个半成品。
开侃了。
一直以来都是做web开发,winform完全小白一个,可能连入门都算不上。可该做的还是得做呀。先描述下这项目吧。在对方现有web系统中嵌入activex,做身份证扫描、电子签名及拍照,然后上传服务器(对方可能要提供基本数据接口合成一条记录)保存,最后就是随时查看这些电子档了,出了纠纷可以做了依据。
设备、身份证扫描、拍片这都有第三方提供了,听起来似乎没什么要做的了。这里不得不报怨下,一些公司项目、技术文档管理很稀乱。给的库在我这死都运行不起来,跟他们技术谈,结果是给的库是老版本,害我折腾那么久。
如何写activex就不说了,网上大把的资料,我不想重复添加像垃圾。说说遇到的些问题,可能对你来说是小意思,那请绕行去看更有价值的东西。要学的东西太多,学也学不完,我是很有压力。
一、Dictionary作为数据源绑定到ComboBox(其它类似)
1 Dictionary<string,int> resolutionList=new Dictionary<string,int>();
2
3 BindingSource bs=new BindingSource();
4 bs.DataSource=resolutionList;
5 ComboBox.DataSource=bs;
6 ComboBox.DisplayMember="key";
7 ComboBox.ValueMember="value";
二、调用c++库中返回为BYTE*的函数
方法原型如下:
1 BYTE* WINAPI captureBitmapData(INT pCamera)
2 {
3 return CAST_PTR(pCamera)->captureBitmapData();
4 }
看到这,首先就是找c#与c++类型对照表,可惜没找到。后来瞎试试出来了,至于为什么要这样,我也说不清。下面是c#中的声明方法:
1 [DllImport(@"xxx.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
2 [return: MarshalAs(UnmanagedType.SysUInt, SizeConst = 3)]
3 public static extern IntPtr captureBitmapData(int pCamera);
最后调用如下:
1 byte[] data = new byte[1024];
2
3 IntPtr wnd = captureBitmapData(objCamera);
4 Marshal.Copy(wnd, data, 0, data.Length);
三、listView项排序
参考:http://blog.csdn.net/lilongherolilong/article/details/6689109
在此之上针对项目做了点拓展,这叫微创新。哈哈我笑了,前辈太多,压力大。项目中通过listView维护着一个List<Image>,最后通知listView顺序合成一张图
1 Point p;//点击时坐标
2
3 private void listView1_MouseClick(object sender, MouseEventArgs e)//项右键菜单
4 {
5 if (e.Button == MouseButtons.Right)
6 {
7 p = new Point(e.X, e.Y);
8 contextMenuStrip1.Show(listView1, p);
9 }
10 }
11
12 private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
13 {
14 listView1.DoDragDrop(e.Item, DragDropEffects.Move);
15 }
16
17 private void listView1_DragDrop(object sender, DragEventArgs e)
18 {
19 // 返回插入标记的索引值
20 int index = listView1.InsertionMark.Index;
21 // 如果插入标记不可见,则退出.
22 if (index == -1)
23 {
24 return;
25 }
26 // 如果插入标记在项目的右面,使目标索引值加一
27 if (listView1.InsertionMark.AppearsAfterItem)
28 {
29 index++;
30 }
31
32 //拖动项
33 ListViewItem item = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
34
35 int currentIndex=item.Index;
36 images.Insert(index, (Image)images[currentIndex].Clone());
37
38 if (currentIndex > index)
39 currentIndex++;
40 images.RemoveAt(currentIndex);
41
42
43 listView1.Items.Insert(index, (ListViewItem)item.Clone());
44 listView1.Items.Remove(item);
45
46
47 }
48
49 private void listView1_DragEnter(object sender, DragEventArgs e)
50 {
51 e.Effect = e.AllowedEffect;
52
53 }
54
55
56 private void cms_delete_Click(object sender, EventArgs e)//ContextMenuStrip删除菜单项
57 {
58 ListViewItem item = listView1.GetItemAt(p.X, p.Y);
59 if (item != null)
60 {
61 images.RemoveAt(item.Index);
62
63 listView1.Items.Remove(item);
64
65 imageList1.Images.Clear();
66 imageList1.Images.AddRange(images.ToArray());
67
68 for (int i = 0; i < images.Count; i++)
69 {
70 listView1.Items[i].ImageIndex = i;
71 }
72
73 }
74 }
75
76 private void listView1_DragOver(object sender, DragEventArgs e)
77 {
78 Point point = listView1.PointToClient(new Point(e.X, e.Y));
79 // 返回离鼠标最近的项目的索引
80 int index = listView1.InsertionMark.NearestIndex(point);
81 // 确定光标不在拖拽项目上
82 if (index > -1)
83 {
84 Rectangle itemBounds = listView1.GetItemRect(index);
85 if (point.X > itemBounds.Left + (itemBounds.Width / 2))
86 {
87 listView1.InsertionMark.AppearsAfterItem = true;
88 }
89 else
90 {
91 listView1.InsertionMark.AppearsAfterItem = false;
92 }
93 }
94 listView1.InsertionMark.Index = index;
95 }
96
97 private void listView1_DragLeave(object sender, EventArgs e)
98 {
99 listView1.InsertionMark.Index = -1;
100 }
101
102 private class ListViewIndexComparer : System.Collections.IComparer
103 {
104 public int Compare(object x, object y)
105 {
106 return ((ListViewItem)x).Index - ((ListViewItem)y).Index;
107 }
108 }
四、panel内容太大后,做拖动浏览(电子阅读软件、ps都有)
pictureBox1.Cursor=new Cursor(this.GetType(), "");
panel1.Cursor = new Cursor(this.GetType(), "Resources.openhand.cur");
加载时调用,Resources.openhand.cur、Resources.openhand.cur是内嵌的光标文件
1 bool move=false;
2 private new void MouseDown(object sender, MouseEventArgs e)//鼠标按下
3 {
4 move = true;
5 Cursor.Current = new Cursor(this.GetType(), "Resources.closedhand.cur");
6 pt = panel1.PointToClient(pictureBox1.PointToScreen(e.Location)); // 鼠标是按在picturebox上,需要转化成相对于panel的坐标
7 def.X = panel1.HorizontalScroll.Value;
8 def.Y = panel1.VerticalScroll.Value;
9 }
10
11
12 private new void MouseMove(object sender, MouseEventArgs e)//鼠标移动
13 {
14 if (!move) return;
15 Point cur = panel1.PointToClient(pictureBox1.PointToScreen(e.Location)); // 当前鼠标坐标,同样需要转化成相对于panel的坐标
16 cur = new Point(pt.X - cur.X, pt.Y - cur.Y);
17 cur.X = def.X + cur.X;
18 cur.Y = def.Y + cur.Y;
19 if (0 > cur.X) cur.X = 0; // 如果超出范围重设
20 if (0 > cur.Y) cur.Y = 0;
21 if (panel1.HorizontalScroll.Visible)
22 panel1.HorizontalScroll.Value = cur.X; // 如果存在对应的滚动条,则赋值
23 if (panel1.VerticalScroll.Visible)
24 panel1.VerticalScroll.Value = cur.Y;
25 }
26
27 private new void MouseUp(object sender, MouseEventArgs e)//鼠标弹起
28 {
29 move = false;
30 }
ps:可能细心的朋友看到了身份证扫描、拍照(要调用摄像头)等字眼,希望我给出dll及相关代码。dll调用是针对特定硬件,给你也没用。有用我就传上来了,俺可不在乎这东西,再说了传上来哪天要用自己也好找。如果你非得要,下面留下联系方式吧。