Este ejemplo muestra como poner en cero la coordenada Z de unos elementos dentro de un dibujo de AutoCAD, es decir "baja" las entidades que estén dibujadas a una altura en el eje Z y le asigna el valor "0", o en el caso de polilíneas 3d las aplana poniendole a todos sus vertices una altura 0 en Z y respentando sus coordenadas X e Y. Solo tiene en cuenta los puntos, los textos (TEXT y MTEXT), las líneas y las polilíneas. Básicamente lo que hace es hacer un conjunto por cada tipo de entidad (línea, polilínea, texto, y punto) analizar los puntos por cada uno de los elementos dentro del conjunto y redefinir cada punto poniendo en 0 su coordenada Z, en el caso de las polilíneas recorre uno por uno todos los vértices que la componen.
El ejemplo puede mejorarse, quizás no sea la forma más óptima de hacerlo, por ejemplo podriamos hacer solo un conjunto y trabajar con todos lo elementos, pero bueno de esta manera quizás es un poco más claro, además hay que tener en cuenta que no contempla todos los elementos, como bloques, circulos, igualmente una vez que se comprende se puede agregar el tipo de elemento necesario.
Otra cosa a tener en cuenta es que trabaja con polilíneas 3d (POLYLINE) y no con polilíneas 2d (LWPOLYLINE) ya que las polilíneas 2d están dibujadas en un plano, para bajarla podemos moverla directamente, no hace falta cambiar la coordenada Z de cada uno de sus vértices.
(defun c:2d()
(setq conj (ssget "x" '((0 . "POLYLINE")))) ;;;;;1
(if (/= conj nil)
(progn
(setq lar (sslength conj))
(setq no 0)
(while (< no lar) ;;;;;;2
(setq ent (ssname conj no)) ;;;;;;3
(setq vert (entnext ent)) ;;;;;;4
(setq pto (entget vert))
(while (/= (cdr (assoc 0 pto)) "SEQEND") ;;;;;;5
(setq coords (cdr (assoc 10 pto)))
(setq x (car coords))
(setq y (car (cdr coords)))
(entmod (subst (cons 10 (list x y 0.0)) (assoc 10 pto) pto)) ;;;;;;6
(setq vert (entnext vert) pto (entget vert)) ;;;;;;7
)
(entupd ent) ;;;;;;8
(princ (strcat "\rConvirtiendo polilíneas 3d a 2d: " (itoa no) " de " (itoa lar)))
(setq no (+ 1 no))
)
)
)
(setq conj (ssget "x" '((0 . "LINE")))) ;;;;;;9
(if (/= conj nil)
(progn
(setq lar (sslength conj))
(setq no 0)
(while (< no lar)
(setq ent (ssname conj no))
(setq enti (entget ent))
(setq pto (cdr (assoc 10 enti)))
(setq x (car pto))
(setq y (car (cdr pto)))
(entmod (subst (cons 10 (list x y 0.0)) (assoc 10 enti) enti))
(entupd ent)
(princ (strcat "\rConvirtiendo líneas 3d a 2d: " (itoa no) " de " (itoa lar)))
(setq no (+ 1 no))
)
(setq no 0)
(while (< no lar)
(setq ent (ssname conj no))
(setq enti (entget ent))
(setq pto (cdr (assoc 11 enti)))
(setq x (car pto))
(setq y (car (cdr pto)))
(entmod (subst (cons 11 (list x y 0.0)) (assoc 11 enti) enti))
(entupd ent)
(princ (strcat "\rConvirtiendo líneas 3d a 2d: " (itoa no) " de " (itoa lar)))
(setq no (+ 1 no))
)
)
)
(setq conj (ssget "x" '((0 . "POINT"))))
(if (/= conj nil)
(progn
(setq lar (sslength conj))
(setq no 0)
(while (< no lar)
(setq ent (ssname conj no))
(setq enti (entget ent))
(setq pto (cdr (assoc 10 enti)))
(setq x (car pto))
(setq y (car (cdr pto)))
(entmod (subst (cons 10 (list x y 0.0)) (assoc 10 enti) enti))
(entupd ent)
(princ (strcat "\rBajando coordenada Z de los puntos: " (itoa no) " de " (itoa lar)))
(setq no (+ 1 no))
)
)
)
(setq conj (ssget "x" '((-4 . " <> )(0 . "TEXT")(0 . "MTEXT")(-4 . "or>" ))))
(if (/= conj nil)
(progn
(setq lar (sslength conj))
(setq no 0)
(while (< no lar)
(setq ent (ssname conj no))
(setq enti (entget ent))
(setq pto (cdr (assoc 10 enti)))
(setq x (car pto))
(setq y (car (cdr pto)))
(entmod (subst (cons 10 (list x y 0.0)) (assoc 10 enti) enti))
(entupd ent)
(princ (strcat "\rBajando coordenada Z de los Textos: " (itoa no) " de " (itoa lar)))
(setq no (+ 1 no))
)
)
)
)
;Breve comentario de las líneas marcadas
; 1.- se crea el conjunto con todas las entidades POLYLINE del dibujo
; 2.- si el conjunto no está vacío calculamos el largo y vamos recorriendo uno por uno los elementos
; 3.- obtengo el nombre de la entidad
; 4.- se obtiene el primer vértice de la polilinea
; 5.- se recorre toda la polilinea analizando uno por uno sus vértices
; 6.- se modifica la altura del vértice mediante el comando entmod
; 7.- voy al siguiente vértice
; 8.- se hace visual el cambio mediante entupd
; 9.- se hace un nuevo conjunto, esta vez con las líneas
Como detectar el dispositivo móvil en asp
Algunas veces es necesario detectar si nuestra página esta siendo navegada a través de una pc o de un dispositivo móvil como una pda, ppc o smartphone y enviar al cliente a una versión apropiada para su plataforma. Este ejemplo muestra en asp como reconocer el dispositivo y redireccionar al cliente, si este está viendo nuestro sitio desde una pc lo manda a la página inicial del sitio, si está viendo desde una Pocket PC o PDA lo manda a una versión html más pequeña y si está navegando con un celular lo manda a una versión wap. Para esto podemos consultar los valores de las variables "HTTP_ACCEPT" y "HTTP_USER_AGENT".
Para obtener los valores de variables usamos Request.ServerVariables("HTTP_ACCEPT") y Request.ServerVariables("HTTP_USER_AGENT")
"HTTP_ACCEPT" sirve para avisarle al servidor el tipo de contenido que el navegador del cliente soporta y es útil para detectar los navegadores de los teléfonos celulares, que solo soportan wap. El valor devuelto por "HTTP_ACCEPT" para un celular con navegador wap es "text/vnd.wap.wml", y para los navegadores HTML es "*/*" (Internet Explorer 6 e Internet Explorer 4.01 para pocket PC ) y "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" (Firefox 2.0).
"HTTP_USER_AGENT" nos devuelve información acerca de el sistema operativo, la versión y el tipo de navegador del cliente y otras cosas, por lo tanto podemos saber si es una pda.
Unos valores de "HTTP_USER_AGENT" pueden ser:
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" Internet Explorer 6.0,
"Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3" firefox 2.0,
"Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)" Pocket pc con IE 4.0.
Entonces lo que tenemos que hacer es buscar la cadena que identifique nuestro dispositivo y redireccionar.
El código sería algo como esto:
<% var = Request.ServerVariables("HTTP_ACCEPT")
var2= Request.ServerVariables("HTTP_USER_AGENT")
if (instr(var2,"PPC") <> 0 or instr(var2,"Windows CE") <> 0 or instr(var2,"PDA") <> 0 instr or(var2,"Palm") <> 0 or instr(var2,"BlackBerry") <> 0) then
Response.Redirect("ppc/main.asp")
else
if (var = "text/vnd.wap.wml") then
Response.Redirect("ppc/main.wml")
else
Response.Redirect("home.htm")
end if
end if
%>
Primero obtenemos el valor de las variables luego buscamos dentro de user_agent el valor correspondiente a nuestro dispositivo movil, si lo encontramos se redirecciona a la página correspondiente, si no está comprobamos si es un navegador wap, si tampoco es, se manda al cliente a la web diseñada para pc.
Sería bueno que este código esté en la primer página que visita el cliente, así direccionamos directamente a su versión adecuada. Generalmente lo colocamos en default.asp, dentro del server.
Los valores de dispositivos móviles que estamos buscando dentro de user_agent son los más comunes pero hay otros.
Un ejemplo en PHP muy bueno que a mi me sirvió bastante lo pueden encontrar acá y para la parte de los navegadores wap acá.
Para obtener los valores de variables usamos Request.ServerVariables("HTTP_ACCEPT") y Request.ServerVariables("HTTP_USER_AGENT")
"HTTP_ACCEPT" sirve para avisarle al servidor el tipo de contenido que el navegador del cliente soporta y es útil para detectar los navegadores de los teléfonos celulares, que solo soportan wap. El valor devuelto por "HTTP_ACCEPT" para un celular con navegador wap es "text/vnd.wap.wml", y para los navegadores HTML es "*/*" (Internet Explorer 6 e Internet Explorer 4.01 para pocket PC ) y "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" (Firefox 2.0).
"HTTP_USER_AGENT" nos devuelve información acerca de el sistema operativo, la versión y el tipo de navegador del cliente y otras cosas, por lo tanto podemos saber si es una pda.
Unos valores de "HTTP_USER_AGENT" pueden ser:
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" Internet Explorer 6.0,
"Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3" firefox 2.0,
"Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)" Pocket pc con IE 4.0.
Entonces lo que tenemos que hacer es buscar la cadena que identifique nuestro dispositivo y redireccionar.
El código sería algo como esto:
<% var = Request.ServerVariables("HTTP_ACCEPT")
var2= Request.ServerVariables("HTTP_USER_AGENT")
if (instr(var2,"PPC") <> 0 or instr(var2,"Windows CE") <> 0 or instr(var2,"PDA") <> 0 instr or(var2,"Palm") <> 0 or instr(var2,"BlackBerry") <> 0) then
Response.Redirect("ppc/main.asp")
else
if (var = "text/vnd.wap.wml") then
Response.Redirect("ppc/main.wml")
else
Response.Redirect("home.htm")
end if
end if
%>
Primero obtenemos el valor de las variables luego buscamos dentro de user_agent el valor correspondiente a nuestro dispositivo movil, si lo encontramos se redirecciona a la página correspondiente, si no está comprobamos si es un navegador wap, si tampoco es, se manda al cliente a la web diseñada para pc.
Sería bueno que este código esté en la primer página que visita el cliente, así direccionamos directamente a su versión adecuada. Generalmente lo colocamos en default.asp, dentro del server.
Los valores de dispositivos móviles que estamos buscando dentro de user_agent son los más comunes pero hay otros.
Un ejemplo en PHP muy bueno que a mi me sirvió bastante lo pueden encontrar acá y para la parte de los navegadores wap acá.
Insertar un texto en un dibujo (AutoCAD, Visual Lisp)
Aquellos que conocen programas de dibujo como AutoCAD o MicroStation deben saber que podemos realizar pequeñas personalizaciones o comandos personalizados, que pueden llegar a ser muy útiles y acelerar bastante el trabajo, pudiendo incluso hasta automatizar algunas tareas manuales rutinarias. Para hacer estos programas y comandos podemos utilizar el Editor de Visual Basic, y programar en VBA, hay un montón de ejemplos en la web de VBA. En el caso particular de AutoCAD podemos programar también en AutoLISP, LISP es un lenguaje de programación de alrededor de los 60 (si mal no recuerdo) que se basa en paréntesis, y que es muy potente para algunas cosas, sobre todo para funciones recursivas. AutoCAD adoptó una versión del lenguaje llamada AutoLISP, podemos acceder al compilador a través del menu tools/AutoLISP/Visual LISP Editor, incluso AutoCAD tiene unos ejemplos y tutoriales muy buenos de este lenguaje.
Este ejemplo está hecho en Visual LISP, es bastante sencillo, lo único que hace es buscar todas las polilíneas del dibujo, e insertar un texto que dice el layer en el cuál está dibujada la polilínea en el su punto inicial.
(defun insertartexto (pto texto layer) ;función que inserta el texto
(if (= (tblsearch "LAYER" layer) nil)
(command "_LAYER" "_N" layer "_C" 3 layer "")
)
(setq x (car pto))
(setq y (car(cdr pto)))
(setq z 0.0)
;(setq z (car(cdr (cdr pto))))
(setq tx (cons '(73 . 0) tx ))
(setq tx (cons '(100 . "AcDbText") tx ))
(setq tx (cons '(210 0.0 0.0 1.0) tx ))
(setq tx (cons '(11 0.0 0.0 0.0) tx ))
(setq tx (cons '(72 . 0) tx ))
(setq tx (cons '(71 . 0) tx ))
(setq tx (cons '(7 . "STANDARD") tx ))
(setq tx (cons '(51 . 0.0) tx ))
(setq tx (cons '(41 . 1.0) tx ))
(setq tx (cons '(50 . 0.0) tx ))
(setq tx (cons (cons 1 texto) tx ))
(setq tx (cons '(40 . 1.5) tx ))
(setq tx (cons (list 10 x y z) tx ))
(setq tx (cons '(100 . "AcDbText") tx ))
(setq tx (cons '(6 . "Continuous") tx ))
(setq tx (cons (cons 8 layer) tx ))
(setq tx (cons '(410 . "Model") tx ))
(setq tx (cons '(67 . 0) tx ))
(setq tx (cons '(100 . "AcDbEntity") tx ))
(setq tx (cons '(5 . "F290") tx ))
(setq tx (cons '(0 . "TEXT") tx ))
(entmake tx)
(setq tx nil)
)
;==============================================================================
(defun c:test()
(setq conj (ssget "x" '((0 . "LWPOLYLINE")))) ;Selecciona todas las polilíneas del dibujo
(if (= conj nil)
(progn
(alert "\nNo se encuentra ninguna polilínea en el dibujo")
(exit)
)
)
(setq lar (sslength conj) no 0)
(while (< no lar)
(setq ent (ssname conj no)) ;Selecciona una polilínea
(setq pto (cdr (assoc 10 (entget ent)))) ;Obtiene el primer punto de la Polilínea
(setq txt (cdr (assoc 8 (entget ent)))) ;Obtiene el nombre del layer de la polilínea
(insertartexto pto txt "0" ) ;Llama a la función que inserta el texto
(setq no (+ 1 no))
)
)
El ejemplo tiene una función que se encarga de generar una entidad texto e insertarla, la función insertartexto recibe como parámetros el punto de inserción del texto, la cadena (el texto en si que vamos a ver) y el nombre del layer en el cual se va a insertar el texto. Si bien este ejemplo quizás es un poco avanzado para alguien que recién comienza la idea es mostrar una función un poco más profunda, ya que ejemplos simples hay en el tutorial de AutoCAD.
Breve descripción: primero hay que cargar el comando ya sea a través del comando load (si tenemos todo el código en un txt) o tipeandolo en el editor VisualLisp y usando el boton load active window .Una vez que tenemos el comando en memoria para ejecutarlo hay que tipear test.
Lo primero que hace es un conjunto con todas las polilíneas del dibujo mediante la función ssget, luego con sslength obtenemos el largo de este conjunto, establecemos un contador en cero y con un bucle while recorremos una por una las polilíneas del conjunto, asignando la actual a una variable llamada ent a través de la función ssname. De la polilínea actual obtenemos el nombre del layer y su primer punto, luego llamamos a la función insertartexto mandandole como parametros el punto de inserción, el texto en si y el layer en el que se va a insertar.
La función insertartexto utiliza entmake para generar el texto, previamente cargamos todos sus atributos en una lista. Cualquier duda o por algún otro ejemplo del tema pueden escribir acá.
Este ejemplo está hecho en Visual LISP, es bastante sencillo, lo único que hace es buscar todas las polilíneas del dibujo, e insertar un texto que dice el layer en el cuál está dibujada la polilínea en el su punto inicial.
(defun insertartexto (pto texto layer) ;función que inserta el texto
(if (= (tblsearch "LAYER" layer) nil)
(command "_LAYER" "_N" layer "_C" 3 layer "")
)
(setq x (car pto))
(setq y (car(cdr pto)))
(setq z 0.0)
;(setq z (car(cdr (cdr pto))))
(setq tx (cons '(73 . 0) tx ))
(setq tx (cons '(100 . "AcDbText") tx ))
(setq tx (cons '(210 0.0 0.0 1.0) tx ))
(setq tx (cons '(11 0.0 0.0 0.0) tx ))
(setq tx (cons '(72 . 0) tx ))
(setq tx (cons '(71 . 0) tx ))
(setq tx (cons '(7 . "STANDARD") tx ))
(setq tx (cons '(51 . 0.0) tx ))
(setq tx (cons '(41 . 1.0) tx ))
(setq tx (cons '(50 . 0.0) tx ))
(setq tx (cons (cons 1 texto) tx ))
(setq tx (cons '(40 . 1.5) tx ))
(setq tx (cons (list 10 x y z) tx ))
(setq tx (cons '(100 . "AcDbText") tx ))
(setq tx (cons '(6 . "Continuous") tx ))
(setq tx (cons (cons 8 layer) tx ))
(setq tx (cons '(410 . "Model") tx ))
(setq tx (cons '(67 . 0) tx ))
(setq tx (cons '(100 . "AcDbEntity") tx ))
(setq tx (cons '(5 . "F290") tx ))
(setq tx (cons '(0 . "TEXT") tx ))
(entmake tx)
(setq tx nil)
)
;==============================================================================
(defun c:test()
(setq conj (ssget "x" '((0 . "LWPOLYLINE")))) ;Selecciona todas las polilíneas del dibujo
(if (= conj nil)
(progn
(alert "\nNo se encuentra ninguna polilínea en el dibujo")
(exit)
)
)
(setq lar (sslength conj) no 0)
(while (< no lar)
(setq ent (ssname conj no)) ;Selecciona una polilínea
(setq pto (cdr (assoc 10 (entget ent)))) ;Obtiene el primer punto de la Polilínea
(setq txt (cdr (assoc 8 (entget ent)))) ;Obtiene el nombre del layer de la polilínea
(insertartexto pto txt "0" ) ;Llama a la función que inserta el texto
(setq no (+ 1 no))
)
)
El ejemplo tiene una función que se encarga de generar una entidad texto e insertarla, la función insertartexto recibe como parámetros el punto de inserción del texto, la cadena (el texto en si que vamos a ver) y el nombre del layer en el cual se va a insertar el texto. Si bien este ejemplo quizás es un poco avanzado para alguien que recién comienza la idea es mostrar una función un poco más profunda, ya que ejemplos simples hay en el tutorial de AutoCAD.
Breve descripción: primero hay que cargar el comando ya sea a través del comando load (si tenemos todo el código en un txt) o tipeandolo en el editor VisualLisp y usando el boton load active window .Una vez que tenemos el comando en memoria para ejecutarlo hay que tipear test.
Lo primero que hace es un conjunto con todas las polilíneas del dibujo mediante la función ssget, luego con sslength obtenemos el largo de este conjunto, establecemos un contador en cero y con un bucle while recorremos una por una las polilíneas del conjunto, asignando la actual a una variable llamada ent a través de la función ssname. De la polilínea actual obtenemos el nombre del layer y su primer punto, luego llamamos a la función insertartexto mandandole como parametros el punto de inserción, el texto en si y el layer en el que se va a insertar.
La función insertartexto utiliza entmake para generar el texto, previamente cargamos todos sus atributos en una lista. Cualquier duda o por algún otro ejemplo del tema pueden escribir acá.
Instalar SQL Server Mobile edition en la PDA
Esta es una breve explicación de como instalar SQL Server 2005 Mobile edition en el dispositivo móvil para poder desarrollar alguna aplicación con base de datos. Dependiendo de la versión de Visual Studio 2005 que tengamos puede que SQL Server Mobile venga o no incluido (creo que SQL Server solo viene en las versiones pro o superiores), si viene incluido los más probable es que esté en el directorio "C:\Archivos de programa\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\Sqlce30setupen.msi" (suponiendo que Visual Studio esté instalado en la ubicación por defecto), si no lo tenemos podemos descargarlo acá (el archivo es algo así como Sqlce30setupen.msi).
La instalación en la pc es sencilla tiene unos requerimientos de Software como Windows 2000 SP4, Windows XP SP2 o Windows 2003, obviamente una cuenta con privilegios de administrador, .NET framework 2.0 (si tenemos instalado Visual Studio 2005 ya está instalado), MDAC 2.7 para el acceso a datos, además los servicios de IIS, y Replication components de SQL Server 2000 SP3 o SQL Server 2005 (para poder replicar con la base de datos de la pda) .
Luego de instalado esto tendremos en nuestro grupo de programas una carpeta llamada "SQL Server 2005 Mobile edition" que contiene "SQL Mobile books online", está es toda la referencia de programación para VB, C# y C++.
La instalación en la PDA dependerá del lenguaje en el que vamos a desarrollar, si trabajamos con Visual Basic o C#, la instalación es automática, solo necesitamos incluir en nuestro proyecto las referencias a System.Data.SQLClient y System.Data.SQLServerCe para esto en el menú elegimos la opción "Project/add reference" y las seleccionamos de la solapa .NET, si no aparecen podemos ver como encontralas acá.
Luego al comienzo de nuestro formulario incluimos la directiva para usar el namespace
En VB
Imports System.Data.SqlClient
Imports System.Data.SqlServerCe
En C#
using System.Data.SqlClient;
using System.Sata.SqlServerCe;
Y listo, cuando ejecutemos la aplicación (aunque solo tenga un formulario vacío) instalará Compact Framework si es que no está instalado y luego SQL Server Mobile.
Si trabajamos con C++, SQL Server mobile no se instala en forma automática , para ello debemos copiar los archvivos sqlce30.dev.ENU.ppc.wce4.armv4.CAB, sqlce30.ppc.wce4.armv4.CAB y sqlce30.repl.ppc.wce4.armv4.CAB que están en la carpeta "C:\Archivos de programa\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\wce400\armv4" (la ubicación puede variar dependiendo de la plataforma de nuestra PDA y su procesador, genéricamente la ruta sería "C:\Archivos de programa\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\plataforma \procesador \" ) en la PDA y luego ejecutarlos en esta, los archivos deben estar en la memoria principal, no se puede instala SQL Server Mobile en una tarjeta de memoria, pero si almacenar ahí las bases de datos.
Luego de ejecutados los archivos ya está instalado SQL server, podemos ver además el Query Analyze que nos permite crear bases de datos y manipularlas.
La instalación en la pc es sencilla tiene unos requerimientos de Software como Windows 2000 SP4, Windows XP SP2 o Windows 2003, obviamente una cuenta con privilegios de administrador, .NET framework 2.0 (si tenemos instalado Visual Studio 2005 ya está instalado), MDAC 2.7 para el acceso a datos, además los servicios de IIS, y Replication components de SQL Server 2000 SP3 o SQL Server 2005 (para poder replicar con la base de datos de la pda) .
Luego de instalado esto tendremos en nuestro grupo de programas una carpeta llamada "SQL Server 2005 Mobile edition" que contiene "SQL Mobile books online", está es toda la referencia de programación para VB, C# y C++.
La instalación en la PDA dependerá del lenguaje en el que vamos a desarrollar, si trabajamos con Visual Basic o C#, la instalación es automática, solo necesitamos incluir en nuestro proyecto las referencias a System.Data.SQLClient y System.Data.SQLServerCe para esto en el menú elegimos la opción "Project/add reference" y las seleccionamos de la solapa .NET, si no aparecen podemos ver como encontralas acá.
Luego al comienzo de nuestro formulario incluimos la directiva para usar el namespace
En VB
Imports System.Data.SqlClient
Imports System.Data.SqlServerCe
En C#
using System.Data.SqlClient;
using System.Sata.SqlServerCe;
Y listo, cuando ejecutemos la aplicación (aunque solo tenga un formulario vacío) instalará Compact Framework si es que no está instalado y luego SQL Server Mobile.
Si trabajamos con C++, SQL Server mobile no se instala en forma automática , para ello debemos copiar los archvivos sqlce30.dev.ENU.ppc.wce4.armv4.CAB, sqlce30.ppc.wce4.armv4.CAB y sqlce30.repl.ppc.wce4.armv4.CAB que están en la carpeta "C:\Archivos de programa\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\wce400\armv4" (la ubicación puede variar dependiendo de la plataforma de nuestra PDA y su procesador, genéricamente la ruta sería "C:\Archivos de programa\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\plataforma
Luego de ejecutados los archivos ya está instalado SQL server, podemos ver además el Query Analyze que nos permite crear bases de datos y manipularlas.
Leer un archivo de texto en C++, en una PDA
Este ejemplo tiene una función que abre un archivo de texto, lo lee y carga las líneas leídas en un Listbox, está hecho en C++, con VS 2005, para una PDA con Windows Mobile 2003 SE, pero funciona bien para una aplicación Windows de escritorio. La función es muy básica, simplemente abre el archivo usando _wfopen, lee los primeros nueve registros con fread y va cargando el Listbox, usando la función SendMessage. Falta hacer un par de cosas, como verificar errores y leer el archivo hasta su fin o retornar valores para saber el resultado, pero bueno el objetivo es mostrar como abrir y leer el archivo y además las conversión entre cadenas de ancho fijo y multibyte.
//****************************************************
//llamada a la función en el bucle de mensajes
case ID_MEN32782:
CargarLista(List1); //List1 es el handle del list box
break;
//****************************************************
//función
void CargarLista(HWND Lista){
FILE *stream;
wchar_t buff[20]={};
char buf[20]={};
HWND hWnd;
if( (stream = _wfopen( L"Storage Card\\Mis Doc\\arch.txt", L"r" )) == NULL )
MessageBox(hWnd, L"No se puede abrir el arvhivo", L"ERROR:", MB_ICONERROR | MB_OK);
for (int i=0;i<8;i++)
{
fread( buf, sizeof(char), 17, stream ); //fread devuelve el resultado char (multibyte)
mbstowcs( buff, buf, 16); //mbstowcs lo convierte a wchar_t (unicode), se desprecia el último byte porque es el salto de línea
SendMessage(Lista, LB_ADDSTRING, 0, (LPARAM)buff);
}
fclose(stream);
delete []buff;
delete []buf;
}
//****************************************************
//llamada a la función en el bucle de mensajes
case ID_MEN32782:
CargarLista(List1); //List1 es el handle del list box
break;
//****************************************************
//función
void CargarLista(HWND Lista){
FILE *stream;
wchar_t buff[20]={};
char buf[20]={};
HWND hWnd;
if( (stream = _wfopen( L"Storage Card\\Mis Doc\\arch.txt", L"r" )) == NULL )
MessageBox(hWnd, L"No se puede abrir el arvhivo", L"ERROR:", MB_ICONERROR | MB_OK);
for (int i=0;i<8;i++)
{
fread( buf, sizeof(char), 17, stream ); //fread devuelve el resultado char (multibyte)
mbstowcs( buff, buf, 16); //mbstowcs lo convierte a wchar_t (unicode), se desprecia el último byte porque es el salto de línea
SendMessage(Lista, LB_ADDSTRING, 0, (LPARAM)buff);
}
fclose(stream);
delete []buff;
delete []buf;
}
Conectarse a una BD en SQL server mobile con VB .net
Este ejemplo está programado en Visual Studio 2005, en Visual Basic para una PDA, lo que hace es conectarse a una base de datos SQL server mobile, hacer una consulta y llenar un datagrid con los resultados. Es necesario que esté instalado en la PDA SQL Server. En este caso la consulta se hace en el momento en que se instancia el formulario, por lo tanto cuando aparece ya está el datagrid cargado con los resultados.
Private sqlConn As System.Data.SqlServerCe.SqlCeConnection
Private sqlDA As System.Data.SqlServerCe.SqlCeDataAdapter
Private sqlDS As System.Data.DataSet
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
DataGrid1.BackgroundColor = Color.White
Try
sqlDS = New DataSet
sqlConn = New SqlCeConnection("Data Source='Storage Card\SQL\BD.sdf'")
sqlDA = New SqlCeDataAdapter("SELECT nro, cliente, fcom AS Fecha FROM tabla1", sqlConn)
sqlDA.Fill(sqlDS, "Sini")
DataGrid1.DataSource = sqlDS.Tables("Sini")
Catch err As SqlCeException
MsgBox("No se puede abrir la base de datos, verifique la tarjeta de memoria", MsgBoxStyle.Critical)
Exit Sub
End Try
End Sub
Private sqlConn As System.Data.SqlServerCe.SqlCeConnection
Private sqlDA As System.Data.SqlServerCe.SqlCeDataAdapter
Private sqlDS As System.Data.DataSet
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
DataGrid1.BackgroundColor = Color.White
Try
sqlDS = New DataSet
sqlConn = New SqlCeConnection("Data Source='Storage Card\SQL\BD.sdf'")
sqlDA = New SqlCeDataAdapter("SELECT nro, cliente, fcom AS Fecha FROM tabla1", sqlConn)
sqlDA.Fill(sqlDS, "Sini")
DataGrid1.DataSource = sqlDS.Tables("Sini")
Catch err As SqlCeException
MsgBox("No se puede abrir la base de datos, verifique la tarjeta de memoria", MsgBoxStyle.Critical)
Exit Sub
End Try
End Sub
Leer datos del GPS bluetooth en una PDA en C++
Este código tiene una función que lee los datos enviados por un GPS Bluetooth en una PDA con Windows Mobile 2003 SE, está desarrollado en C++ con VS 2005.
En este caso particular el GPS no está integrado en la PDA envía los datos en formato NMEA a través de una conexión Bluetooth. Al puerto Bluetooth lo podemos leer como un puerto COM más, solo tenemos que saber de antemano cual es el número de los puertos COM de entrada y de salidada del Bluetooth. Esto podemos hacerlo leyendo el registro de la PDA, en mi caso particular es el "COM5:". Una vez que conocemos el puerto que tiene la función de Bluetoot in, leemos los datos con la función ReadFile como con cualquier puerto COM en la PDA o en Windows. La función lee los datos almacenados en el puerto, estableciendo previamente algunos parámetros como velocidad, timeouts y buffers, luego falta procesar los datos obtenidos (en este caso los datos vienen en formato NMEA, hay que procesarlos para obtener los valores de Latitud, Longitud, cantidad de satélites, etc). De la misma manera podemos utilizar esta función o alguna similar para obtener los datos de cualquier dispositivo que envíe a un puerto COM, ya sea en el dispositivo móvil o en nuestra aplicación Windows.
Este es solo un ejemplo, estableciendo algunos valores solo para mostrar como se hace, y guardando los resultados obtenidos en un array local, sin procesarlos luego, es probable que haya que hacerle algunos retoques a la hora de ponerlo en práctica en un programa real.
/*en la parte de definiciones*/
bool PuertoCom(wchar_t *Port);
/*Para llamar la función, por ejemplo al hacer clic en algún botón*/
bool result;
result = PuertoCom(L"COM5:");
if (result == true){
MessageBox(hWnd, L"Se leyeron los datos del puerto", L"OK:", MB_ICONINFORMATION | MB_OK);
}else{
MessageBox(hWnd, L"No se puede abrir, leer el puerto", L"ERROR:", MB_ICONERROR | MB_OK);
}
/*Implementación de la función*/
bool PuertoCom(wchar_t *Port){
HANDLE PCom;
OVERLAPPED ov;
DCB dcb;
COMMTIMEOUTS to;
DWORD x;
COMSTAT cs;
char tmp[1024];
wchar_t buf[1024];
//abrir el puerto
PCom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(PCom ==INVALID_HANDLE_VALUE) return false;
//Obtener los timeouts actuales del puerto
if (GetCommTimeouts(PCom, &to) == 0) return false;
//Setear timeouts en el puerto
to.ReadIntervalTimeout = MAXDWORD;
to.ReadTotalTimeoutMultiplier = 0;
to.ReadTotalTimeoutConstant = 0;
to.WriteTotalTimeoutMultiplier = 0;
to.WriteTotalTimeoutConstant = 0;
if (SetCommTimeouts(PCom, &to) == 0) return false;
//setear buffers del puerto
if (SetupComm(PCom, 1024, 1024) == 0) return false;
//Obtener estado del puerto
if (GetCommState(PCom, &dcb) == 0) return false;
//Setear estado del puerto
dcb.BaudRate = (DWORD)38400; //Velocidad;
dcb.ByteSize = (BYTE)8; //NBits;
dcb.Parity = (BYTE)0; //Paridad;
dcb.StopBits = (BYTE)1; //StopBits;
if (SetCommState(PCom, &dcb) == 0) return false;
//Leer datos del puerto
if (ReadFile(PCom, tmp, 1024, &x, &ov) != 0){ //almacenamos en tmp los datos leídos del puerto
int a = strlen(tmp);
BSTR unicodestr = SysAllocStringLen(NULL, a);
::MultiByteToWideChar(CP_ACP, 0, tmp, a, unicodestr, a);
wcscpy(buf ,unicodestr); //convertir la cadena char devuelta por ReadFile en wschar_t
::SysFreeString(unicodestr);
}
//Cerrar puerto com
SetCommMask(PCom, 0);
CloseHandle(PCom);
return true;
}
En este caso particular el GPS no está integrado en la PDA envía los datos en formato NMEA a través de una conexión Bluetooth. Al puerto Bluetooth lo podemos leer como un puerto COM más, solo tenemos que saber de antemano cual es el número de los puertos COM de entrada y de salidada del Bluetooth. Esto podemos hacerlo leyendo el registro de la PDA, en mi caso particular es el "COM5:". Una vez que conocemos el puerto que tiene la función de Bluetoot in, leemos los datos con la función ReadFile como con cualquier puerto COM en la PDA o en Windows. La función lee los datos almacenados en el puerto, estableciendo previamente algunos parámetros como velocidad, timeouts y buffers, luego falta procesar los datos obtenidos (en este caso los datos vienen en formato NMEA, hay que procesarlos para obtener los valores de Latitud, Longitud, cantidad de satélites, etc). De la misma manera podemos utilizar esta función o alguna similar para obtener los datos de cualquier dispositivo que envíe a un puerto COM, ya sea en el dispositivo móvil o en nuestra aplicación Windows.
Este es solo un ejemplo, estableciendo algunos valores solo para mostrar como se hace, y guardando los resultados obtenidos en un array local, sin procesarlos luego, es probable que haya que hacerle algunos retoques a la hora de ponerlo en práctica en un programa real.
/*en la parte de definiciones*/
bool PuertoCom(wchar_t *Port);
/*Para llamar la función, por ejemplo al hacer clic en algún botón*/
bool result;
result = PuertoCom(L"COM5:");
if (result == true){
MessageBox(hWnd, L"Se leyeron los datos del puerto", L"OK:", MB_ICONINFORMATION | MB_OK);
}else{
MessageBox(hWnd, L"No se puede abrir, leer el puerto", L"ERROR:", MB_ICONERROR | MB_OK);
}
/*Implementación de la función*/
bool PuertoCom(wchar_t *Port){
HANDLE PCom;
OVERLAPPED ov;
DCB dcb;
COMMTIMEOUTS to;
DWORD x;
COMSTAT cs;
char tmp[1024];
wchar_t buf[1024];
//abrir el puerto
PCom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(PCom ==INVALID_HANDLE_VALUE) return false;
//Obtener los timeouts actuales del puerto
if (GetCommTimeouts(PCom, &to) == 0) return false;
//Setear timeouts en el puerto
to.ReadIntervalTimeout = MAXDWORD;
to.ReadTotalTimeoutMultiplier = 0;
to.ReadTotalTimeoutConstant = 0;
to.WriteTotalTimeoutMultiplier = 0;
to.WriteTotalTimeoutConstant = 0;
if (SetCommTimeouts(PCom, &to) == 0) return false;
//setear buffers del puerto
if (SetupComm(PCom, 1024, 1024) == 0) return false;
//Obtener estado del puerto
if (GetCommState(PCom, &dcb) == 0) return false;
//Setear estado del puerto
dcb.BaudRate = (DWORD)38400; //Velocidad;
dcb.ByteSize = (BYTE)8; //NBits;
dcb.Parity = (BYTE)0; //Paridad;
dcb.StopBits = (BYTE)1; //StopBits;
if (SetCommState(PCom, &dcb) == 0) return false;
//Leer datos del puerto
if (ReadFile(PCom, tmp, 1024, &x, &ov) != 0){ //almacenamos en tmp los datos leídos del puerto
int a = strlen(tmp);
BSTR unicodestr = SysAllocStringLen(NULL, a);
::MultiByteToWideChar(CP_ACP, 0, tmp, a, unicodestr, a);
wcscpy(buf ,unicodestr); //convertir la cadena char devuelta por ReadFile en wschar_t
::SysFreeString(unicodestr);
}
//Cerrar puerto com
SetCommMask(PCom, 0);
CloseHandle(PCom);
return true;
}
Ejecutar un programa externo desde aplicación C++ para PPC
En este ejemplo vemos como iniciar un programa externo, en C++ desde nuestra aplicación, el ejemplo está programado en VS 2005 para una Pocket PC con "Windows Mobile 2003 SE", en este caso se ejecuta el programa de la cámara de fotos, pero funciona con otros programas por ejemplo el solitario (solitare.exe, por si están trabajando en una que no tenga cámara). Lo hacemos a través de la función ShellExecuteEx. Es necesario incluir la librería shellapi.h para que funcione, en este caso particular el programa de la cámara se ejecuta cuando se presiona un botón en un formulario por lo tanto está dentro del bucle de mensajes del formulario.
/*en las declaraciones*/
#include < shellapi.h >
/*en el bucle de mensajes del formulario o la ventana*/
case IDC_BUTTON3:
SHELLEXECUTEINFO lpExecInfo;
memset(&lpExecInfo, 0, sizeof(SHELLEXECUTEINFO));
lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
lpExecInfo.lpFile = L"\\Windows\\camera.exe";
lpExecInfo.nShow = SW_SHOWNORMAL;
lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShellExecuteEx(&lpExecInfo);
break;
/*en las declaraciones*/
#include < shellapi.h >
/*en el bucle de mensajes del formulario o la ventana*/
case IDC_BUTTON3:
SHELLEXECUTEINFO lpExecInfo;
memset(&lpExecInfo, 0, sizeof(SHELLEXECUTEINFO));
lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
lpExecInfo.lpFile = L"\\Windows\\camera.exe";
lpExecInfo.nShow = SW_SHOWNORMAL;
lpExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShellExecuteEx(&lpExecInfo);
break;
Suscribirse a:
Entradas (Atom)


