http://blog.csdn.net/giselite/article/details/8451877
来看一下ArcMap的符号选择器:
ArcMap的符号选择器都提供了符号的预览图,另一个预览图的位置是在按钮上,比如设置MapGrid的格网交点符号和格网线符号。
本文给出生成这里的符号预览图的代码。
方法1:通过ISymbologyStyleClass的Preview方法生成预览图
- private string routin_ReadRegistry(string sKey)
- {
- Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey, true);
- if (rk == null) return "";
- return (string)rk.GetValue("InstallDir");
- }
- public void LoadStyleGalleryItems()
- {
- string sInstall = routin_ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
- if (sInstall == "")
- {
- return;
- }
- ISymbologyControl pSymbologyControl = new SymbologyControlClass();
- pSymbologyControl.LoadStyleFile(sInstall + "\\Styles\\ESRI.ServerStyle");
- m_pSymbologyStyleClass = pSymbologyControl.GetStyleClass(esriSymbologyStyleClass.esriStyleClassScaleBars);
- //Clean items in ImageComboBox and images in ImageCollection.
- this.imageComboBoxEdit1.Properties.Items.Clear();
- this.imageCollection1.Images.Clear();
- int nWidth, nHeight;
- nWidth = this.imageCollection1.ImageSize.Width;
- nHeight = this.imageCollection1.ImageSize.Height;
- Image pImage = null;
- //Load StyleGalleryItems into he ImageComboBox's drop down list.
- IStyleGalleryItem pStyleGalleryItem = null;
- IPictureDisp pPicture = null;
- for (int i = 0; i < m_pSymbologyStyleClass.get_ItemCount(m_pSymbologyStyleClass.StyleCategory); i++)
- {
- pStyleGalleryItem = m_pSymbologyStyleClass.GetItem(i);
- pPicture = m_pSymbologyStyleClass.PreviewItem(pStyleGalleryItem, nWidth, nHeight);
- pImage = System.Drawing.Image.FromHbitmap(new IntPtr(pPicture.Handle));
- AddItem(pStyleGalleryItem.Name, pImage, pStyleGalleryItem, i);
- }
- this.imageComboBoxEdit1.SelectedIndex = 0;
- }
- private void AddItem(string sDescription, Image pImage, IStyleGalleryItem pStyleGalleryItem, int nImageIndex)
- {
- this.imageComboBoxEdit1.Properties.Items.Add(new ImageComboBoxItem(sDescription, pStyleGalleryItem, nImageIndex));
- this.imageCollection1.Images.Add(pImage);
- }
- //其中m_pSymbologyStyleClass是ISymbologyStyleClass的实例。
- //上面的代码演示如何使用ISymbologyControl接口在下拉列表控件中加载符号集,其中包含生成预览图的代码,对于符号选择器,使用SymbologyControl,可以直接参考AE范例里的符号选择器的例子,下面是符号选择器里更为精简的代码:
- protected void PreviewImage()
- {
- ISymbologyStyleClass pSymbologyStyleClass = wndSymbologyControl.GetStyleClass(wndSymbologyControl.StyleClass);
- IPictureDisp pPicture = pSymbologyStyleClass.PreviewItem(m_StyleGalleryItem, wndPictureEdit.Width - 10, wndPictureEdit.Height - 10);
- Image pImage = Image.FromHbitmap(new IntPtr(pPicture.Handle));
- wndPictureEdit.Image = pImage;
- }
- protected void LoadStyleCalss(esriSymbologyStyleClass styleClass)
- {
- string sInstall = routin_ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
- wndSymbologyControl.LoadStyleFile(sInstall + "\\Styles\\ESRI.ServerStyle");
- wndSymbologyControl.StyleClass = styleClass;
- m_SymbologyStyleClass = wndSymbologyControl.GetStyleClass(wndSymbologyControl.StyleClass);
- m_SymbologyStyleClass.SelectItem(0);
- }
方法2:通过IStyleGalleryClass的Preview方法获取符号的预览图
- private Image PreViewMarkerSymbol(ISymbol pSymbol, int width, int height)
- {
- IStyleGalleryClass pStyleGalleryClass = new MarkerSymbolStyleGalleryClass();
- Image img = new Bitmap(width, height);
- Graphics gc = Graphics.FromImage(img);
- IntPtr hdc = gc.GetHdc();
- tagRECT rect = new tagRECT();
- rect.left = 0;
- rect.top = 0;
- rect.right = width;
- rect.bottom = height;
- pStyleGalleryClass.Preview(pSymbol, hdc.ToInt32(), ref rect);
- gc.ReleaseHdc(hdc);
- gc.Dispose();
- return img;
- }
- private void checkEdit2_CheckedChanged(object sender, EventArgs e)
- {
- if (m_bLoading) return;
- if (mMapGrid != null)
- {
- if (checkEdit2.Checked)
- {
- mMapGrid.LineSymbol = null;
- ISimpleMarkerSymbol pSimpleMarkerSymbol = new SimpleMarkerSymbol();
- pSimpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCross;
- IMarkerSymbol pMarkerSymbol = pSimpleMarkerSymbol as IMarkerSymbol;
- mMapGrid.TickMarkSymbol = pMarkerSymbol;
- mMapGrid.SetLabelVisibility(true, true, true, true);
- simpleButton1.Image = PreViewMarkerSymbol(pMarkerSymbol as ISymbol, simpleButton1.Height, simpleButton1.Width);
- if (ValueChanged != null) ValueChanged();
- }
- }
- }
使用第二种方法时,要注意ISymbol对象的类型。因为所有符号集类都实现了IStyleGalleryClass接口,如MarkerSymbolStyleGalleryClass、LineSymbolStyleGalleryClass、ScaleBarStyleGalleryClass等。生成预览图时,各符号的预览图只能由与其对应的StyleGalleryClass来生成,也就是说NorthArrow类型的符号只能用NorthArrowStyleGalleryClass来预览,而不能用其它类型,像下面这样是会发生异常的:
- private void checkEdit3_CheckedChanged(object sender, EventArgs e)
- {
- if (m_bLoading) return;
- if (mMapGrid != null)
- {
- if (checkEdit3.Checked)
- {
- ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbol();
- pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
- ILineSymbol pLineSymbol = pSimpleLineSymbol as ILineSymbol;
- mMapGrid.LineSymbol = pLineSymbol;
- mMapGrid.TickMarkSymbol = null;
- mMapGrid.SetLabelVisibility(true, true, true, true);
- simpleButton1.Image = PreViewMarkerSymbol(pLineSymbol as ISymbol, simpleButton1.Height, simpleButton1.Width);
- if (ValueChanged != null) ValueChanged();
- }
- }
- }
这里,传入的是LineSymbol对象,在PreViewMarkerSymbol中,用MarkerSymbolStyleGalleryClass的事例来预览一个LineSymbol,程序在调用Preview时,会直接崩溃,正确的用法是:
- private Image PreViewLineSymbol(ISymbol pSymbol, int width, int height)
- {
- IStyleGalleryClass pStyleGalleryClass = new LineSymbolStyleGalleryClass();
- Image img = new Bitmap(width, height);
- Graphics gc = Graphics.FromImage(img);
- IntPtr hdc = gc.GetHdc();
- tagRECT rect = new tagRECT();
- rect.left = 0;
- rect.top = 0;
- rect.right = width;
- rect.bottom = height;
- pStyleGalleryClass.Preview(pSymbol, hdc.ToInt32(), ref rect);
- gc.ReleaseHdc(hdc);
- gc.Dispose();
- return img;
- }
- private void checkEdit3_CheckedChanged(object sender, EventArgs e)
- {
- if (m_bLoading) return;
- if (mMapGrid != null)
- {
- if (checkEdit3.Checked)
- {
- ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbol();
- pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
- ILineSymbol pLineSymbol = pSimpleLineSymbol as ILineSymbol;
- mMapGrid.LineSymbol = pLineSymbol;
- mMapGrid.TickMarkSymbol = null;
- mMapGrid.SetLabelVisibility(true, true, true, true);
- simpleButton1.Image = PreViewLineSymbol(pLineSymbol as ISymbol, simpleButton1.Height, simpleButton1.Width);
- if (ValueChanged != null) ValueChanged();
- }
- }
- }
实际上IStyleGalleryItem的Item成员,都是ISymbol成员,因此一个ISymbol对象,除了可以直接用IStyleGalleryClass的Previe预览以外,还可以转换成IStyleGalleryItem然后使用ISymbologyStyleClass的Preview方法来预览,比如:
IStyleGalleryItem pStyleGalleryItem = new ServerStyleGalleryItemClass(); IClone pClone = pScaleBar as IClone; pStyleGalleryItem.Item = pClone.Clone();
之后就可以使用第一种方法来生成预览图了。
下面是自制的符号选择器: