36 mensajes Página 1 de 2
Buenas, os dejo una pequeña introducción muy rapida al tema, c# es un lenguaje muy amigable y sencillo, con una curva de aprendizaje mucho mas corta de lo normal.

http://www.youtube.com/watch?v=oOf40sJyzq4 [Ver en HQ]


Y os dejo material del curso:
-Enlace al template proyecto para crear dlls: http://sites.google.com/site/robertgies ... gedexports
-Codigo a ingresar en un control windows forms (activex):
namespace ..............
    [ProgId("Webcam.PablokoControl")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public partial class ************ : UserControl
...

Para meter en la clase principal

///     <summary>
        ///     Register the class as a control and     set     it's CodeBase entry
        ///     </summary>
        ///     <param name="key">The registry key of the control</param>
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open the CLSID\{guid} key for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // And create       the     'Control' key - this allows     it to show up in
            // the ActiveX control container
            RegistryKey ctrl = k.CreateSubKey("Control");
            ctrl.Close();

            // Next create the CodeBase entry   - needed if     not     string named and GACced.
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();

            // Finally close the main   key
            k.Close();
        }

        ///     <summary>
        ///     Called to unregister the control
        ///     </summary>
        ///     <param name="key">Tke registry key</param>
        [ComUnregisterFunction()]
        public static void UnregisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open     HKCR\CLSID\{guid} for write     access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // Delete the 'Control'     key, but don't throw an exception if it does not exist
            k.DeleteSubKey("Control", false);

            // Next     open up InprocServer32
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);

            // And delete the CodeBase key,     again not throwing if missing
            k.DeleteSubKey("CodeBase", false);

            // Finally close the main key
            k.Close();
        }



Propiets/assamblyinfo.cs:
[assembly: ComVisible(true)]
 
Parsed in 0.008 seconds, using GeSHi 1.0.8.9


Este codigo siempre hay que ponerlo como directiva, una vez hecho ya esta, todo funcionara correcto como en el ejemplo

Otra cosilla digna de mencionar, las dll generadas NO SE REGISTRAN CON REGSERV32 y desconozco si se puede hacer con system.registeractivex pero supongo que NO, en su lugar esas dll se registran con un exe llamado REGASM.EXE (si lo compilas con vs re registra solo) si vemos que la cosa se complica en el momento de redistribuir monto una dll para registrar estos controles

Register the DLL again using 'Regasm' as follows.

Open the DOS prompt via
"Start > Programs > Accessories > Command Prompt".
Enter the following command according to the programming language used:
C#:
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm.exe" "<Path to the DLL>.dll" /codebase


Aqui os dejo un pequeño ejemplo de la aplicacion para la webcam de demostración recordad registrar la dll antes de debugear el proyecto

Descargar:
Contenido Oculto: ON
	<br />Usted necesita responder en este tema para ver el contenido oculto.


Codigo fuente (a insertar un picturebox llamado PbxImagen)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;                // Para trabajar con imágenes
using System.Drawing.Drawing2D;           // Para trabajar con Imágenes
using System.Runtime.InteropServices;
using Microsoft.Win32;   // Para usar API
using System.Reflection;
using System.IO;

namespace WindowsFormsControlLibrary1
{
    [ProgId("Webcam.PablokoControl")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public partial class UserControl1 : UserControl
    {




        public UserControl1()
        {
            InitializeComponent();
            WebCam MiWebcam = new WebCam(10, PbxImagen);
        }

        private void UserControl1_Load(object sender, EventArgs e)
        {
            WebCam MiWebcam = new WebCam(10, PbxImagen);
            PbxImagen.Width = this.Width;
            PbxImagen.Height = this.Height;
        }

        public void Question()
        {
            MessageBox.Show("Who is number one?");
        }

        public string sakatambliki = "sakatambliki!";

        public void Capturar(int cp)
        {
            WebCam MiWebcam = new WebCam(10, PbxImagen);
            MiWebcam.Capturar(cp);
        }

        public void Parar()
        {
            WebCam MiWebcam = new WebCam(10, PbxImagen);
            MiWebcam.StopCaptura();
        }

        public void Foto()
        {
            WebCam MiWebcam = new WebCam(10, PbxImagen);
            MiWebcam.GuardarImagen();
        }

        public String GetWebcams()
        {
            WebCam MiWebcam = new WebCam(10, PbxImagen);
            return MiWebcam.Listar2();
        }

        ///     <summary>
        ///     Register the class as a control and     set     it's CodeBase entry
        ///     </summary>
        ///     <param name="key">The registry key of the control</param>
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open the CLSID\{guid} key for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // And create       the     'Control' key - this allows     it to show up in
            // the ActiveX control container
            RegistryKey ctrl = k.CreateSubKey("Control");
            ctrl.Close();

            // Next create the CodeBase entry   - needed if     not     string named and GACced.
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();

            // Finally close the main   key
            k.Close();
        }

        ///     <summary>
        ///     Called to unregister the control
        ///     </summary>
        ///     <param name="key">Tke registry key</param>
        [ComUnregisterFunction()]
        public static void UnregisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open     HKCR\CLSID\{guid} for write     access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // Delete the 'Control'     key, but don't throw an exception if it does not exist
            k.DeleteSubKey("Control", false);

            // Next     open up InprocServer32
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);

            // And delete the CodeBase key,     again not throwing if missing
            k.DeleteSubKey("CodeBase", false);

            // Finally close the main key
            k.Close();
        }
       
       
       
       
       
       
       
       
       
        public class WebCam
        {

            // Conserva esta cabecera
            // Empeorxdevil 2007

            class SaveImage
            {

                // Conserva esta cabecera
                // Emperorxdevil 2007

                /// <summary>
                /// Imagen que contiene la clase
                /// </summary>
                public Image Tmp; //  referencia a la imagen del Picturebox Asociado
                Form Ref; // referencia que necesitare a este formulario

                Form Opciones;
                GroupBox Gr;
                RadioButton R1;
                RadioButton R2;
                RadioButton R3;
                TextBox Porciento;
                TextBox Larg;        // Objetos necesarios para formar el diálogo
                TextBox Anch;
                Label L1;
                Label L2;
                Button Acepta;
                Button Cancelar;

                SaveFileDialog Sv;
                DialogResult rs;


                /// <summary>
                /// Constructor de clase SaveImage
                /// </summary>
                /// <param name="imagen">Imagen que se va a guardar</param>
                /// <param name="Interfaz"> Si se mostrará Interfaz</param>
                public SaveImage(Image imagen, bool Interfaz)
                {

                    Tmp = imagen; // Asigno la imagen...              
                    Opciones = new Form();
                    Ref = Opciones;
                    Opciones.Width = 333;     // Configuracion
                    Opciones.Height = 198;
                    Opciones.Text = "Parámetros de Imagen";
                    Opciones.ControlBox = false;
                    Opciones.ShowInTaskbar = false;
                    Opciones.FormBorderStyle = FormBorderStyle.FixedDialog;

                    Gr = new GroupBox();
                    Gr.Width = 288;
                    Gr.Height = 105;
                    Gr.Text = "Configuración";
                    Gr.Location = new Point(18, 15);
                    Porciento = new TextBox();
                    Porciento.Enabled = false;                   // Configuracion
                    Porciento.Text = "";
                    Porciento.Width = 37;
                    Porciento.Height = 20;
                    Porciento.MaxLength = 3;
                    Porciento.TextAlign = HorizontalAlignment.Center;
                    Porciento.Location = new Point(147, 47);
                    R1 = new RadioButton();
                    R1.Text = "Guardar con Dimensiones Actuales";
                    R1.Width = 191;
                    R1.Height = 17;
                    Gr.Controls.Add(R1);
                    R1.Location = new Point(18, 25);
                    R2 = new RadioButton();
                    R2.CheckedChanged += new EventHandler(R2_CheckedChanged);
                    R2.Text = "Reducir tamaño al";
                    R2.Width = 115;             // Configuracion
                    R2.Height = 17;
                    R2.Location = new Point(18, 48);
                    Gr.Controls.Add(R2);
                    Gr.Controls.Add(Porciento);
                    L1 = new Label();
                    L1.Text = "%";
                    L1.AutoSize = true;
                    L1.Location = new Point(195, 50);
                    Gr.Controls.Add(L1);
                    R3 = new RadioButton();
                    R3.CheckedChanged += new EventHandler(R3_CheckedChanged);
                    R3.Text = "Cambiar tamaño a"; // Configuracion
                    R3.Width = 113;
                    R3.Height = 17;
                    R3.Location = new Point(18, 71);
                    Gr.Controls.Add(R3);
                    L2 = new Label();
                    L2.Text = "X";
                    L2.AutoSize = true;
                    L2.Location = new Point(195, 75);
                    Gr.Controls.Add(L2);
                    Larg = new TextBox();
                    Larg.Enabled = false;
                    Larg.Width = 37;
                    Larg.Height = 20;
                    Larg.MaxLength = 4;
                    Larg.TextAlign = HorizontalAlignment.Center;
                    Larg.Location = new Point(147, 71);
                    Gr.Controls.Add(Larg);

                    Anch = new TextBox();
                    Anch.Enabled = false;
                    Anch.Width = 37;
                    Anch.Height = 20;
                    Anch.MaxLength = 4;
                    Anch.TextAlign = HorizontalAlignment.Center; // Configuracion
                    Anch.Location = new Point(218, 70);
                    Gr.Controls.Add(Anch);

                    Acepta = new Button();
                    Acepta.Text = "Aceptar";
                    Acepta.Width = 59;
                    Acepta.Height = 26;
                    Acepta.Location = new Point(247, 133);
                    Acepta.Click += new EventHandler(Acepta_Click);

                    Cancelar = new Button();
                    Cancelar.Text = "Cancelar";
                    Cancelar.Width = 59;
                    Cancelar.Height = 26;
                    Cancelar.Location = new Point(18, 133);
                    Cancelar.Click += new EventHandler(Cancelar_Click);
                    Opciones.Controls.Add(Gr);
                    Opciones.Controls.Add(Acepta);
                    Opciones.Controls.Add(Cancelar);
                    Opciones.StartPosition = FormStartPosition.CenterScreen;
                    Opciones.ShowDialog();

                }


                /// <summary>
                /// Constructor de la clase SaveImage sin Interfaz
                /// </summary>
                /// <param name="imagen">Imagen a Guardar</param>
                public SaveImage(Image imagen)
                {
                    Tmp = imagen; // Asigno la imagen...  
                }

                void R3_CheckedChanged(object sender, EventArgs e)
                {
                    if (this.R3.Checked) { this.Anch.Enabled = true; this.Larg.Enabled = true; }
                    else { this.Anch.Enabled = false; this.Larg.Enabled = false; }
                }
                void R2_CheckedChanged(object sender, EventArgs e)
                {
                    if (this.R2.Checked) { this.Porciento.Enabled = true; }
                    else { this.Porciento.Enabled = false; }
                }
                void Acepta_Click(object sender, EventArgs e)
                {
                    try
                    {
                        if (R1.Checked || R2.Checked || R3.Checked)
                        {

                            if (R2.Checked) { Tmp = Resize(Tmp, Convert.ToInt32(Porciento.Text)); }

                            if (R3.Checked) { Tmp = Resize(Tmp, Convert.ToInt32(Larg.Text), Convert.ToInt32(Anch.Text)); }

                            Sv = new SaveFileDialog(); // Creo un diálogo para salvar la imagen
                            Sv.Title = "Guardar imagen como..."; // Lo configuro
                            Sv.Filter = "Archivo JPG|*.jpg|Archivo PNG|*.png|Archivo GIF|*.gif|Mapa de Bits|*.bmp";
                            rs = Sv.ShowDialog(); // Lo muestro modal


                            if (rs == DialogResult.OK)
                            {

                                int x = Sv.FilterIndex; // Ontengo la extensión seleccionada  

                                switch (x)
                                {
                                    // Salvo la imagen en el formato deseado
                                    case 1:
                                        Tmp.Save(Sv.FileName, ImageFormat.Jpeg);
                                        break;
                                    case 2:
                                        Tmp.Save(Sv.FileName, ImageFormat.Png);
                                        break;
                                    case 3:
                                        Tmp.Save(Sv.FileName, ImageFormat.Gif);
                                        break;
                                    case 4:
                                        Tmp.Save(Sv.FileName, ImageFormat.Bmp);
                                        break;
                                }
                                Ref.Dispose(); // Cierro el formulario        
                            }
                        }
                        else { MessageBox.Show("Al menos debe selecionar una opción", "xdevilWebCapture", MessageBoxButtons.OK, MessageBoxIcon.Warning); }

                    }

                    catch
                    {
                        MessageBox.Show("Introduzca valores válidos", "xdevilWebCapture", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }

                }
                void Cancelar_Click(object sender, EventArgs e)
                {
                    Ref.Dispose(); // Cierro el formulario
                }



                /// <summary>
                /// Escala la imagen capturada al % especificado
                /// </summary>
                /// <param name="foto"> Imagen que se quiere escalar </param>
                /// <param name="TantoPorCiento"> Porcentaje de reducción</param>
                /// <returns>Imagen escalada</returns>
                public Image Resize(Image foto, int TantoPorCiento)
                {

                    float Tporciento = ((float)TantoPorCiento / 100); // Obtengo el coeficiente de dimension                    
                    int ImgOrAncho = foto.Width;
                    int ImgOrAlto = foto.Height; // Obtengo las dimensiones originales de la foto

                    int OrigX = 0;
                    int OrigY = 0;
                    int ResX = 0;  // Variables referencia para saber donde empiezo a contar px
                    int ResY = 0;

                    int ResAncho = (int)(ImgOrAncho * Tporciento);
                    int ResAlto = (int)(ImgOrAlto * Tporciento); // Obtengo las dimensiones al % especificado    

                    Bitmap RszIm = new Bitmap(ResAncho, ResAlto, PixelFormat.Format24bppRgb); // Creo una imagen con esas dimensiones y bpp
                    RszIm.SetResolution(foto.HorizontalResolution, foto.VerticalResolution); // Le doy la misma res. que la original

                    Graphics Gfoto = Graphics.FromImage(RszIm); // Creo una intancia de Graphics para manejar la imagen nueva
                    Gfoto.InterpolationMode = InterpolationMode.HighQualityBicubic; // Especifico la calidad del algoritmo de sampleo
                    // De la foto original, obtengo la redimensionada (mediante un rectángulo)
                    Gfoto.DrawImage(foto, new Rectangle(ResX, ResY, ResAncho, ResAlto), new Rectangle(OrigX, OrigY, ImgOrAncho, ImgOrAlto), GraphicsUnit.Pixel);
                    Gfoto.Dispose(); // Ya no me hace falta esto, asi que lo descargo

                    return (RszIm); // Devuelvo la imagen redimensionada
                }
                /// <summary>
                /// Redimensiona la imagen en pixeles
                /// </summary>
                /// <param name="foto"> Imagen a redimensionar</param>
                /// <param name="ancho">Ancho de la imagen</param>
                /// <param name="alto">Alto de la imagen</param>
                /// <returns>Imagen redimensionada</returns>
                public Image Resize(Image foto, int ancho, int alto)
                {

                    int ImgORAncho = foto.Width;
                    int ImgOrAlto = foto.Height; // Obtengo las dimensiones de la foto

                    int OrigX = 0;
                    int OrigY = 0;
                    int ResX = 0;  // Varables referencia para saber donde contar px
                    int ResY = 0;

                    float Porciento = 0;
                    float PorcientoAncho = 0; // Porcentajes de sampleo
                    float PorcientoAlto = 0;

                    PorcientoAncho = ((float)ancho / (float)ImgORAncho);
                    PorcientoAlto = ((float)alto / (float)ImgOrAlto); //Calculo el % que puedo resamplear

                    if (PorcientoAlto < PorcientoAncho)
                    {
                        Porciento = PorcientoAlto;
                    }
                    else
                    { // Para resamplear bien                
                        Porciento = PorcientoAncho;
                    }


                    int AnchuraFinal = (int)(ImgORAncho * Porciento);
                    int AlturaFinal;  // Calculo las nuevas dimensiones                

                    if (ancho > alto)
                    {
                        AlturaFinal = (int)(ImgOrAlto * Porciento);
                    }
                    else
                    {
                        AlturaFinal = AnchuraFinal;
                    } // Para proporcionar la imagen

                    Bitmap RszIm = new Bitmap(ancho, alto, PixelFormat.Format24bppRgb);
                    RszIm.SetResolution(foto.HorizontalResolution, foto.VerticalResolution);

                    Graphics Gfoto = Graphics.FromImage(RszIm);
                    Gfoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    Gfoto.DrawImage(foto, new Rectangle(ResX, ResY, AnchuraFinal, AlturaFinal), new Rectangle(OrigX, OrigY, ImgORAncho, ImgOrAlto), GraphicsUnit.Pixel);
                    Gfoto.Dispose();
                    return (RszIm);

                }

            } /// Clase que guarda las imágenes

            #region Funciones API

            [DllImport("user32.dll", EntryPoint = "SendMessage")]
            public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

            [DllImport("avicap32.dll", EntryPoint = "capCreateCaptureWindowA")]
            public static extern int capCreateCaptureWindowA(string lpszWindowName, int dwStyle, int X, int Y, int nWidth, int nHeight, int hwndParent, int nID);

            [DllImport("user32.dll", EntryPoint = "EmptyClipboard")]
            public static extern int EmptyClipboard();

            [DllImport("avicap32.dll", EntryPoint = "capGetDriverDescriptionA")]
            public static extern bool capGetDriverDescriptionA(int wDriverIndex, [MarshalAs(UnmanagedType.VBByRefStr)]ref String lpszName, int cbName, [MarshalAs(UnmanagedType.VBByRefStr)] ref String lpszVer, int cbVer);
            //public static extern bool capGetDriverDescriptionA(int wdriver, string lpszName, int cbName, string lpszVer, int cbVer);


            #endregion

            #region Constantes API

            const int WM_USER = 1024;
            const int WM_CAP_CONNECT = 1034;
            const int WM_CAP_DISCONNECT = 1035;
            const int WM_CAP_GET_FRAME = 1084;  // Constantes necesarias
            const int WM_CAP_COPY = 1054;
            const int WM_CAP_START = WM_USER;
            const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
            const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;

            #endregion

            private int Frecuencia = 0; // Frecuencia de captura de imagen  
            private int CamHandle = 0; // Handle del dispositivo


            Timer reloj; // Timer
            //ComboBox Cbx; // Para referencia al Combobox
            PictureBox Pbx; // Para referencia al Picturebox


            /// <summary>
            /// Crea una instancia de la clase WebCam de Emperorxdevil
            /// </summary>
            /// <param name="frecuencia">Intervalo de tiempo en el que se capturarán las imágenes</param>
            /// <param name="pct">PictureBox en el cual se mostrará lo capturado por la webcam</param>
            /// <param name="cb"> Listbox en el que se mostrarán las Cams detectadas</param>
            public WebCam(int frecuencia, PictureBox pct)
            {

                Frecuencia = frecuencia;
                Pbx = pct;              // Inicio las variables necesarias
                reloj = new Timer(); // Creo el timer
                reloj.Tick += new EventHandler(reloj_Tick); // Le asigno el controlador  
                reloj.Interval = Frecuencia; // Asigno la velocidad de captura
                //Cbx = cb; //Configuro la referencia

            }

            private void reloj_Tick(object sender, EventArgs e)
            {

                SendMessage(CamHandle, WM_CAP_GET_FRAME, 0, 0); // Capturo la imagen
                SendMessage(CamHandle, WM_CAP_COPY, 0, 0); // La copio al portapeles
                SaveImage k = new SaveImage(Clipboard.GetImage());
               
                Pbx.Image = k.Resize(Clipboard.GetImage(),Pbx.Width,Pbx.Height); // La mando al Picturebox
               
                EmptyClipboard(); // Vacío el portapapeles

            }
            /// <summary>
            /// Listará las cámaras web encontradas en el Combobox asociado
            /// </summary>
            /*public void Listar()
            {

                bool valor;
                string nombre;
                string version;
                int x = 0;

                do
                {
                    nombre = "Dispositivo" + x.ToString();
                    valor = capGetDriverDescriptionA(x, nombre, 100, "v1", 100);
                    if (valor) Cbx.Items.Add(nombre);
                    x = x + 1;
                } while (!valor == false);

            }*/

            /*public void Listar()
            {
                bool valor;
                String nombre = "".PadRight(100); ;
                String version = "".PadRight(100); ;
                int x = 0;
                do
                {
                    valor = capGetDriverDescriptionA(x, ref nombre, 100, ref version, 100);
                    if (valor)
                    {
                        Cbx.Items.Add(nombre + " " + version);
                    }

                    x = x + 1;

                } while (!valor == false);
            }*/


            public String Listar2()
            {
                bool valor;
                string gg = "";
                String nombre = "".PadRight(100); ;
                String version = "".PadRight(100); ;
                int x = 0;
                do
                {
                    valor = capGetDriverDescriptionA(x, ref nombre, 100, ref version, 100);
                    if (valor)
                    {

                        gg = gg + nombre + " " + version + "|";
                        //Cbx.Items.Add(nombre + " " + version);
                    }

                    x = x + 1;

                } while (!valor == false);
                return gg;
            }
            /// <summary>
            /// La WebCam se Encenderá y mostrará lo capturado en el PictureBox referenciado
            /// </summary>
            /// <param name="Dispositivo">Nº de dispositivo del Combobox</param>        
            public void Capturar(int Dispositivo)
            {

                try
                {

                    StopCaptura(); // Antes de nada "reseteo" el dispositivo  
                    CamHandle = capCreateCaptureWindowA("XdevilCapture" + Dispositivo.ToString(), 0, 0, 0, 0, 0, Pbx.Handle.ToInt32(), Dispositivo); // Obtengo el Handle de la cam
                    SendMessage(CamHandle, WM_CAP_CONNECT, 0, 0); // Enciendo la cam
                    SendMessage(CamHandle, WM_CAP_SET_PREVIEWRATE, 30, 0); // Establezco los frames de captura /seg
                    SendMessage(CamHandle, WM_CAP_SET_PREVIEW, 0, 0); // Empiezo a capturar
                    reloj.Start(); // Inicio la captura      
                }

                catch (Exception e)
                {
                    MessageBox.Show("No se puede Iniciar la WebCam", "Error");
                }

            }
            /// <summary>
            /// Detiene la captura de imágenes y apaga la WebCam
            /// </summary>
            public void StopCaptura()
            {


                try
                {
                    reloj.Stop(); // Paro el reloj que captura
                    SendMessage(CamHandle, WM_CAP_DISCONNECT, 0, 0); // Apago la cam
                    EmptyClipboard(); // Vacío el portapapeles
                }

                catch (Exception e) { } // No hago nada.. pa k ?

            }
            /// <summary>
            /// Muestra diferentes parametros configurables de la imagen que se va a guardar
            /// </summary>
            public void GuardarImagen()
            {

                SaveImage s = new SaveImage(Pbx.Image, true); // Creo la clase que guarda las fotos
            }


        }
       
       
    }
}
 
Parsed in 0.057 seconds, using GeSHi 1.0.8.9
ImagenImagenImagenImagen
ese tioooooooooooooooooooooooooooooooooo!!!!!!!!!!

chicas risas... lo primero de todo tener listo un buen chusto!!!
whoooooooo amigo sin duda eres el mejor este video es de puta madre, lastima que no se pudo ver bien, pero es un gran trabajo, felicidades y espero continúes con algunos videos.
Imagen
Buenas, acabo de terminar el interfaz de eventos para controles activex creados en c#

Justo ademas de añadir la directiva comvisible(true) en propiets/assamblyinfo.cs y de añadir las dos funciones de com dispatch:

///     <summary>
        ///     Register the class as a control and     set     it's CodeBase entry
        ///     </summary>
        ///     <param name="key">The registry key of the control</param>
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open the CLSID\{guid} key for write access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // And create       the     'Control' key - this allows     it to show up in
            // the ActiveX control container
            RegistryKey ctrl = k.CreateSubKey("Control");
            ctrl.Close();

            // Next create the CodeBase entry   - needed if     not     string named and GACced.
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();

            // Finally close the main   key
            k.Close();
        }

        ///     <summary>
        ///     Called to unregister the control
        ///     </summary>
        ///     <param name="key">Tke registry key</param>
        [ComUnregisterFunction()]
        public static void UnregisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT\", "");

            // Open     HKCR\CLSID\{guid} for write     access
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

            // Delete the 'Control'     key, but don't throw an exception if it does not exist
            k.DeleteSubKey("Control", false);

            // Next     open up InprocServer32
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);

            // And delete the CodeBase key,     again not throwing if missing
            k.DeleteSubKey("CodeBase", false);

            // Finally close the main key
            k.Close();
        }
Parsed in 0.006 seconds, using GeSHi 1.0.8.9


Ademas de añadir sobre la clase principal la descripcion com (con una pequeña modificación):

    [ProgId("Webcam.PablokoControl")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComSourceInterfaces(typeof(IControlEvents))] //cosa nueva para el interfaz de eventos
    public partial class UserControl1 : UserControl..................
Parsed in 0.002 seconds, using GeSHi 1.0.8.9


ya podemos exportar propiedades

//dentro de la clase principal
//ams: qinterface.sakatambliki="..." o x=qinterface.sakatambliki
public string sakatambliki = "sakatambliki!";
Parsed in 0.002 seconds, using GeSHi 1.0.8.9


o metodos

//dentro de la clase principal
//ams: qinterface:Question() / x=qinterface:Question(args...)
        public void Question()
        {
            MessageBox.Show("Who is number one?");
        }
Parsed in 0.002 seconds, using GeSHi 1.0.8.9


Una vez que tenemos todo esto claro, hay que añadir una serie de funcionalidades al proyecto para usar las clases.

Lo primero de todo es crear una clase contenedora de eventos, podreis utilizar esto como plantilla:

//en el namespace

    [ComVisible(true)]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IControlEvents
   {

        [DispId(1)]
        void Bark(string callData);

        [DispId(2)]
        void Howl(string callData, string dos);

        [DispId(3)]
        void Eat();
       
    }
Parsed in 0.003 seconds, using GeSHi 1.0.8.9


Aqui definimos la clase exportada de eventos, pero estos eventos usan argumentos que deben pasar por otro objeto, asi que por cada evento se debe crear un "handler" que pueda hacer su interfaz, esto es, pegar justamente despues del codigo anterior esto:

    [ComVisible(false)]
    public delegate void ControlEventHandler(string callData);

    [ComVisible(false)]
    public delegate void ControlEventHandler2(string callData, string dos);

    [ComVisible(false)]
    public delegate void ControlEventHandler3();
Parsed in 0.002 seconds, using GeSHi 1.0.8.9


Esto nos proporcionará la capacidad de mandar argumentos en nuestro evento, hecho esto, ya solo nos queda dejar disponible este interfaz en la clase principal, asi que hay que insertar un poco de codigo en la clase principal:

        public event ControlEventHandler Bark;

        public event ControlEventHandler2 Howl;

        public event ControlEventHandler3 Eat;
Parsed in 0.002 seconds, using GeSHi 1.0.8.9


Como veis este codigo conecta el handler con la funcion definida en la clase, una vez hecho esto ya esta disponible en nnuestra clase principal las funciones, en este caso bark, howl y eat

ejemplo de uso:

        public void Question()
        {
            //Hacer alguna tarea
            Bark("proceso finalizado");
        }
 
Parsed in 0.002 seconds, using GeSHi 1.0.8.9

result = ActiveX.CreateControl("Plugin1", "Webcam.PablokoControl");
result1 = ActiveX.QueryInterface("Plugin1");
ActiveX.SetEnabled("Plugin1", true);

Events = {}
  function Events:Bark(a)
        Dialog.Message('',a)
  end
  function Events:Howl(a,b)
        Dialog.Message(b,a)
  end
  function Events:Eat()
        Dialog.Message('','')
  end


ActiveX.JoinEvents("Plugin1", result1, Events);
Parsed in 0.003 seconds, using GeSHi 1.0.8.9


Este plugin activex no soporta la interfaz de tablas, o por lo menos aun no he podido descubrir el tipo de valor asociado a la tabla, asi que de momento con usar strings, ints y longs deberia ser suficiente

Con esto tenemos un acercamiento mucho mas que decente al sistema de objetos de ams
ImagenImagenImagenImagen
RegisterActiveXCS.dll

Esta libreria consta de una funcion para registrar los activex dll, ya que con el metodo regserv32 o system.registeractivex no funciona me he decidido a idear algun sistema facil de redistribuir para realizar el registro de librerias.

function RegisterActivexCS(val)
        DLL.CallFunction("AutoPlay\\Docs\\RegisterActivexCS.dll", "Register", "\""..val.."\"", DLL_RETURN_TYPE_STRING, DLL_CALL_STDCALL);
end

RegisterActivexCS(_SourceFolder.."\\AutoPlay\\Docs\\MyLibrary.dll")
Parsed in 0.002 seconds, using GeSHi 1.0.8.9


De este modo se pueden guardar todas las librerias y sus assamblys dependientes en una sola carpeta y registrarlas para su uso con el objecto activex

http://www.multiupload.com/1BV28RS9KU

UPDATE: Codigo fuente, que no se me olvide!
using System;
using System.Collections.Generic;
using System.Text;
using RGiesecke.DllExport;
using System.Diagnostics;
using System.Windows.Forms;

namespace RegisterActivexCS
{
   internal static class UnmanagedExports
   {
      [DllExport("Register", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
      static void reg(string file)
      {
         string cor=System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
         cor += "regasm.exe";
         
         ProcessStartInfo startInfo = new ProcessStartInfo(cor);
         startInfo.WindowStyle = ProcessWindowStyle.Hidden;

         Process.Start(startInfo);
         startInfo.Arguments = "\"" + file + "\" /codebase";

         Process.Start(startInfo);
      }


      [DllExport("Unregister", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
      static void unreg(string file)
      {
          string cor = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
          cor += "regasm.exe";

          ProcessStartInfo startInfo = new ProcessStartInfo(cor);
          startInfo.WindowStyle = ProcessWindowStyle.Hidden;

          Process.Start(startInfo);
          startInfo.Arguments = "\"" + file + "\" /unregister";

          Process.Start(startInfo);
      }
   }
}
 
Parsed in 0.005 seconds, using GeSHi 1.0.8.9
ImagenImagenImagenImagen
brutal tengo que mirarmelo con calmaaaaaaa! eres el puto!
ya me he mirado el video y me a gustado mucho ahora cuendo tenga algo de tiempo voy a ponerlo en practica y crear mi primera DLL. muchas gracias como siempre pabloko te superas!!!!
excelente!! mil gracias !man aportazo!!!!!! sigue asi T_T!! :DDDD
he fijado este tema por que considero que es de lo mejor por no decir directamente lo mejor de esta sección.
amigo crees mejor calidad de video porque definitivamente no puedo leerlo una influye mucho mi ceguera y otra la calidad espero tu respuesta y gracias-
Imagen
el vídeo en youtube se puede ver a 720... creo que eso es una buena calidad.
si vas a youtube se ve en HD, ceone ya podrias mejorar el player del bbcode, ahora youtube ya no inserta los video con flash y object sino que lo hace con otro metodo y un iframe, sobre todo para navegadores con html5 y toda la pesca http://apiblog.youtube.com/2010/07/new- ... ideos.html

Tengo noticias nuevas acerca de esto, ya he podido interfacear tablas en controles activex, solo me falta limar un poco y lo subo para todos.

Ademas en otro pequeño tutorial os voy a enseñar a debuguear con visual studio dlls y controles activex
ImagenImagenImagenImagen
genial alfi puedo leerlo jajaja gracias y si podrias redimencionar al menos las medidas del bbcode para una mejor calidad.
Imagen
estamos en ello...
thank you

:cerrado: :cerrado: :cerrado:
Imagen
gra
Buenisimo tutorial , despues de intentar realizar un proyecto siguiendo los pasos de san pabloko de asis XD , me encontre con que no habia manera de registrar el active a pesar de seguir los pasos al pie de la letra , asi que le di la vara a pabloko y resulta que obvio un paso en visual studio para que se produzca el registro del activex , debeis activar la casilla en proyecto/propiedades/generar/Registrar para interporalidad com si no haceis esto os volbereis locos como yo :hypno: , una imagen de muestra.

Imagen
start learn.................
???
thanks
Gracias por el curso.
36 mensajes Página 1 de 2

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron