5 votos

¿Cómo cambiar el cursor del ratón de una herramienta complementaria de ArcMap utilizando Arcobjects?

¿Es posible cambiar el cursor del ratón de una herramienta complementaria de ArcMap mediante Arcobjects? Tengo el cursor establecido en el archivo Config.esriaddinx, sin embargo, me gustaría cambiar el cursor para reflejar la funcionalidad subyacente de la herramienta. La herramienta tiene la funcionalidad de seleccionar y medir. He añadido un segundo archivo de cursor (.cur) a los recursos de mi proyecto en VS 2013. He encontrado varias soluciones, de las cuales ninguna me ha funcionado, incluyendo:

¿Cómo puedo acceder a los cursores estándar de ArcMap?

Cursor de ratón personalizado del complemento de ArcGIS

Establecer la propiedad del cursor para la herramienta complementaria de ArcGIS 10

AYUDA Problemas para configurar el cursor del ratón para la herramienta AddIn

He intentado cambiar la acción de construcción a AddInContent, Embedded Resource y Resource. Al utilizar Recurso incrustado, se devuelve lo siguiente: "El formato de la imagen no es válido. El archivo de imagen puede estar dañado. Nombre del parámetro: stream"

m_customCursor = New System.Windows.Forms.Cursor(Me.GetType.Assembly.GetManifestResourceStream("MyAddin.customCursorFile.cur"))
MyBase.Cursor = m_customCursor

Utilizando IMouseCursor.SetCursor para cambiar a un cursor incorporado parece funcionar, pero el cursor sólo cambia por un momento, y luego vuelve al cursor establecido en el archivo Config.

Dim newCursor As IMouseCursor = New MouseCursorClass
newCursor.SetCursor(2)

He probado varios de los ejemplos de esri enlazados para cursores personalizados sin ningún éxito.

¿Existe un método definitivo que se pueda utilizar para cambiar dinámicamente el cursor del ratón de una herramienta addin de Arcobjects?

2voto

jeff porter Puntos 1808

Lo siguiente me funciona en 10.4. Puse el código en el sub de la herramienta OnActivate. No estoy seguro, pero puede que tengas que eliminar la referencia al cursor del archivo Config.esriaddinx.

Para utilizar un cursor incorporado en Windows:

MyBase.Cursor = Windows.Forms.Cursors.Cross (or whatever cursor you want to use)

Para utilizar un cursor personalizado añada un archivo .cur existente a su solución VS, o cree uno nuevo. (Detalles aquí: http://www.dotnetheaven.com/article/cursors-in-vb.net ) Y a continuación, establezca la "Acción de construcción" en Embedded Resource y ajuste la opción "Copiar en el directorio de salida" a Copy always .

Esto copiará el archivo .cur a la carpeta de caché de ensamblaje en las máquinas de los clientes, donde los complementos están desempaquetados.

Luego, en el código, para establecer el cursor personalizado, utilice:

MyBase.Cursor = New System.Windows.Forms.Cursor(My.MyProject.Application.Info.DirectoryPath & "\Cursor1.cur")

La ubicación del addin en la carpeta de la caché de ensamblajes es devuelta por My.MyProject.Application.Info.DirectoryPath para que el código encuentre el archivo .cur allí.

0 votos

¿Puede explicarlo? ¿Qué tipo de "ruta de acceso al cursor personalizado" utiliza? ¿Guarda el archivo como un recurso o algo más que se incluye en la construcción?

0 votos

He editado la respuesta con algo más de información sobre el archivo .cur. Hágame saber si necesita más aclaraciones.

0 votos

Gracias por la aclaración. He estado atascado en cómo utilizar los recursos incrustados, pero me has puesto en la dirección correcta. También ayuda si los archivos del cursor son de color de 24 bits.

1voto

Flinkman Puntos 4821

Barbarosa, aquí hay un sub de una de mis herramientas que establece el cursor utilizando un mapa de bits dibujado "en la memoria", aunque usted podría fácilmente cargar un mapa de bits o un archivo de cursor de los recursos o la ubicación conocida ( System.Reflection.Assembly.GetExecutingAssembly().Location quizás). Probablemente sea un poco demasiado prolijo, pero seguro que hay una o dos joyas que pueden ayudarte con tu(s) punto(s) conflictivo(s).

Tenga en cuenta que el cursor de la herramienta es sólo válido mientras el cursor del ratón está sobre el lienzo de ArcMap y luego vuelve al cursor de la ventana actual tan pronto como el cursor del ratón abandona la ventana. this.Cursor es una propiedad de ESRI.ArcGIS.Desktop.AddIns.Tool no así para ESRI.ArcGIS.Desktop.AddIns.Button .

System.Windows.Forms.Cursor gFirstSelectionCursor;
System.Windows.Forms.Cursor gSecondSelectionCursor;
System.Windows.Forms.Cursor gSnappingCursor;

public void SetCursor()
        {
            gDispTran = gDoc.ActiveView.ScreenDisplay.DisplayTransformation;
            int pHalfCursorSize = (int)cCursorSize / 2;
            int pQuarterCursorSize = (int)pHalfCursorSize / 2;

            System.Drawing.Point UL = new System.Drawing.Point(pQuarterCursorSize, pQuarterCursorSize);
            System.Drawing.Point UR = new System.Drawing.Point(cCursorSize - pQuarterCursorSize, pQuarterCursorSize);
            System.Drawing.Point LL = new System.Drawing.Point(pQuarterCursorSize, cCursorSize - pQuarterCursorSize);
            System.Drawing.Point LR = new System.Drawing.Point(cCursorSize - pQuarterCursorSize, cCursorSize - pQuarterCursorSize);

            Bitmap pBitmap = new Bitmap(cCursorSize, cCursorSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Graphics pGraphics = Graphics.FromImage(pBitmap);
            pGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
            Rectangle pRect = new Rectangle(0, 0, cCursorSize, cCursorSize);
            int pHalfSelection = (int)gSelectionTolerance / 2;
            pRect = new Rectangle(pHalfCursorSize - pHalfSelection, pHalfCursorSize - pHalfSelection, gSelectionTolerance, gSelectionTolerance);
            Color pCol = Color.Transparent;

            Color pCircleColour;

            if (gCursorColour == gCursorEnum.Black)
                pCircleColour = Color.Black;
            else if (gCursorColour == gCursorEnum.Red)
                pCircleColour = Color.Red;
            else if (gCursorColour == gCursorEnum.White)
                pCircleColour = Color.White;
            else if (gCursorColour == gCursorEnum.Yellow)
                pCircleColour = Color.Yellow;
            else
                pCircleColour = Color.Black;

            // set the draw lines to the same colour as the
            // selection circle
            ILineSymbol pLineSym = new SimpleLineSymbol();
            pLineSym.Color.RGB = ((pCircleColour.R | pCircleColour.G << 8) | pCircleColour.B << 0x10);

            //pLineSym.Color = (IColor)ESRI.ArcGIS.ADF.Converter.ToRGBColor(pCircleColour);
            pLineSym.Width = 1;
            gSym = (ISymbol)pLineSym;

            Brush pBrush = new SolidBrush(pCol);
            float[] pDashValues = { 3, 1 };
            Pen pPen = new Pen(pCircleColour, 1);
            pPen.DashPattern = pDashValues;
            pGraphics.FillRectangle(pBrush, pRect);
            pGraphics.DrawEllipse(pPen, pRect);
            gFirstSelectionCursor = new System.Windows.Forms.Cursor(pBitmap.GetHicon());
            // second cursor
            pBitmap = new Bitmap(cCursorSize, cCursorSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            pGraphics = Graphics.FromImage(pBitmap);
            pGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
            pGraphics.DrawLine(pPen, UL, LR);
            pGraphics.DrawLine(pPen, LL, UR);
            gSecondSelectionCursor = new System.Windows.Forms.Cursor(pBitmap.GetHicon());
            // third cursor
            pBitmap = new Bitmap(cCursorSize, cCursorSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            pGraphics = Graphics.FromImage(pBitmap);
            pGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
            pGraphics.DrawLine(pPen, UL, LR);
            pGraphics.DrawLine(pPen, LL, UR);
            pRect = new Rectangle((int)pHalfCursorSize / 2, (int)pHalfCursorSize / 2, pHalfCursorSize, pHalfCursorSize);
            pGraphics.DrawEllipse(pPen, pRect);
            gSnappingCursor = new System.Windows.Forms.Cursor(pBitmap.GetHicon());

            if (gSelectionStarted)
                this.Cursor = gSecondSelectionCursor;
            else
                this.Cursor = gFirstSelectionCursor;
        }

Esto define el cursor como un círculo de cCursorSize cuando se selecciona y cambia a una X grande cuando se selecciona algo. Tenga en cuenta que los cursores reales son globales, lo que permite un cambio rápido durante el evento OnMouseDown; este sub se llama sólo al iniciar la herramienta y cuando el cCursorSize se modifica a través de un formulario.

0 votos

+1 por el gran ejemplo. Definitivamente unas cuantas joyas. Estoy atascado en cómo utilizar un recurso incrustado, y estaría interesado en saber si es posible utilizar un archivo marcado como AddinContent en su lugar.

0 votos

No estoy seguro de si los recursos mencionados como stackoverflow.com/questions/90697/ se compilan en un addin. No uso muchas imágenes, etc., excepto los iconos, así que no necesito recursos. Este post stackoverflow.com/questions/8515106/ y codeproject.com/Questions/631425/ arroja algo de luz sobre la carga de un cursor desde un archivo .cur.

1voto

Nehal J. Wani Puntos 290

Bueno, finalmente encontré una solución que funciona después de un par de días de intentos, gracias a Michael Miles-Stimson, la siguiente es una respuesta súper simple a lo que estaba luchando.

Yo estaba recibiendo ese mismo problema de cambio de icono y encontré esto como la solución más directa. this.Cursor parece marcar la diferencia combinada con los cursores en System.Windows.Forms . He puesto la siguiente línea OnUpdate() y mi herramienta está haciendo todo lo que quería.

this.Cursor = Cursors.Cross;

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X