Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-03-2005
Avatar de orfeo
orfeo orfeo is offline
Miembro
 
Registrado: may 2003
Posts: 99
Poder: 21
orfeo Va por buen camino
como saber si una vandera (flag) esta activa o no en una variable DWord

Hola estoy usando FindFirstPrinterChangeNotification para informarme sobre cambios de la impresora... Uso Win2k.SP4 + Delphi 6

Mi duda es sobre como saber que vanderas (opciones de monitoreo) del campo bandera 'fdwFlags' estan activas.
Se supone que soporta varias condiciones de monitorio, por ejemplo PRINTER_CHANGE_ADD_JOB PRINTER_CHANGE_SET_JOB PRINTER_CHANGE_DELETE_JOB PRINTER_CHANGE_WRITE_JOB.


Código:
    HANDLE FindFirstPrinterChangeNotification(

    HANDLE hPrinter,	// handle to printer or print server to monitor for changes
    DWORD fdwFlags,	// flags that specify the conditions to monitor
    DWORD fdwOptions,	// reserved, must be zero
    LPVOID pPrinterNotifyOptions	// pointer to structure specifying printer information
                                       to monitor
   );
Les detallo los pasos

defino Optio como DWord; y luego seteo

Options:=PRINTER_CHANGE_ADD_JOB+PRINTER_CHANGE_SET_JOB;
(esto al parecer anda, por como se comporta el monitoreo)
y luego uso Options como parametro de la funcion FindFirstPrinterChangeNotification.

el problema viene cuando llamo a FindNextPrinterChangeNotification
Código:
   BOOL FindNextPrinterChangeNotification(

    HANDLE hChange,	// handle to change notification object of interest
    PDWORD pdwChange,	// pointer to a value that indicates the condition that changed
    LPVOID pPrinterNotifyOptions,	// pointer to a structure that specifies a refresh flag
    LPVOID *ppPrinterNotifyInfo	// pointer to a pointer that receives printer information buffer
   );
en pdwChange devuelve lo que sucedio con la impresora, supuestamente son valores de las constantes PRINTER_CHANGE_ADD_JOB PRINTER_CHANGE_SET_JOB, pero no se como saber cual de las dos fue la activa.

con un if pdwChange=PRINTER_CHANGE_ADD_JOB , en algunas combinaciones pasa de largo.


No se si me explique bien, pero en si quiero saber como preguntar por una vandera activa en una variable del api32 del tipo DWORD.
__________________
Aprendamos a ser civilizados

Última edición por orfeo fecha: 03-03-2005 a las 03:16:58.
Responder Con Cita
  #2  
Antiguo 03-03-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Algo como

Código Delphi [-]
if pdwChange and PRINTER_CHANGE_ADD_JOB <> 0 then
 { la bandera PRINTER_CHANGE_ADD_JOB está activa }

// Saludos
Responder Con Cita
  #3  
Antiguo 03-03-2005
Avatar de orfeo
orfeo orfeo is offline
Miembro
 
Registrado: may 2003
Posts: 99
Poder: 21
orfeo Va por buen camino
Cita:
Empezado por roman
Algo como

Código Delphi [-]
if pdwChange and PRINTER_CHANGE_ADD_JOB <> 0 then
 { la bandera PRINTER_CHANGE_ADD_JOB está activa }

// Saludos
Roman lo voy aprobar, pero solo tengo una duda....
Como se lee esta sentencia? porque estas preguntando si una variable Dword es true. Si esta es mayor a 0 supongo que lo tomara como true (al estilo C) pero RINTER_CHANGE_ADD_JOB es una constante en Exadecimal o octal (no recuerdo bien) definita en wnspool (creo), esta simpre es distinta de 0.
__________________
Aprendamos a ser civilizados
Responder Con Cita
  #4  
Antiguo 03-03-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por orfeo
porque estas preguntando si una variable Dword es true
No, no estoy preguntando eso. El operador and en esa expresión no es el operador lógico entre variables booleanas sino un operador de bits.

La cuestión es más o menos así (ejemplifico con un byte pero es similar para un dword). En la representación interna de la máquina, un byte consta de ocho bits, cada bit puede tomar el valor 0 ó 1. Cuando aplicas el operador and a dos bytes el efecto es el de aplicar un and lógico bit por bit según la tabla

Código:
+-----+-----+-----+
| and |  0  |  1  |
+-----+-----+-----+
|  0  |  0  |  0  |
+-----+-----+-----+
|  1  |  0  |  1  |
+-----+-----+-----+
Así, si tienes los bytes


Código:
b1 = 00110100 (52 decimal)
b2 = 10101110 (174 decimal)
la operación and te da:


Código:
b1        = 00110100
b2        = 10101110
b1 and b2 = 00100100 (36 decimal)
Análogamente, el operador or aplicado a números enteros significa la aplicación de un or lógico bit por bit según la tabla:


Código:
+-----+-----+-----+
| or  |  0  |  1  |
+-----+-----+-----+
|  0  |  0  |  1  |
+-----+-----+-----+
|  1  |  1  |  1  |
+-----+-----+-----+
Con b1 y b2 como arriba tendrías:


Código:
b1       = 00110100
b2       = 10101110
b1 or b2 = 10111110 (190 decimal)
Ahora bien, lo que comunmente se conoce como una bandera (flag) es una potencia de 2. La representación en bits de una potencia de 2 consta exclusivamente de ceros con un único 1 en el lugar n-ésimo contando desde cero de derecha a izquierda, donde n es la potencia. Así, por ejemplo,


Código:
2^0 = 00000001 (1 decimal)
2^1 = 00000010 (2 decimal)
2^2 = 00000100 (4 decimal)
2^3 = 00001000 (8 decimal
2^4 = 00010000 (16 decimal)
2^5 = 00100000 (32 decimal)
2^6 = 01000000 (64 decimal)
2^7 = 10000000 (128 decimal)
Si combinas dos banderas mediante el operador or (que en este caso es lo mismo que sumar), aplicando el or lógico bit por bit, lo que obtienes es un byte con dos 1 en las posiciones de cada bandera. Por ejemplo:

2^2 or 2^6 = 01000100

es decir, un arreglo de ocho bits con dos de ellos prendidos (= a 1). Esta es la forma en que las banderas las puedes combinar en un sólo número.

La pregunta entoces es, ¿cómo saber en general qué banderas (bits) en un byte dado están prendidas?

Si volvemos al operador and nota que la única manera en que dos bits den igual a 1 es cuando ambos son 1. Como una bandera (potencia de 2) sólo tiene un bit 1 y todos los demás 0, al hacer el and con otro byte se apagan todos los bits excepto, posiblemente, el que está en la misma posición que el 1 en la potencia de 2. Luego entonces todo depende exclusivamente del valor del bit en esa posición (has aislado el bit). Si es 1 entonces el resultado será un byte con un único 1 (en la misma posición que el de la potencia de 2) y si es cero será un byte con sólo 0s, es decir, igual al número 0.

Por ejemplo, si b=00101011 y la bandera es f=2^3=00001000, entonces

b and f = 00001000 <> 0 (decimal)

Pero si la bandera es f=2^5=00100000 entonces

b and f = 00000000 = 0 (decimal)

En resumen, al hacer el and de un byte cualquiera y una bandera (potencia de 2) el resultado sólo puede ser
  • 0 si el byte tiene prendido el bit en la posición de la potencia de 2
  • 1 si el byte tiene apagado el bit en la posición de la potencia de 2

y de aquí la comparación con 0 para saber si está prendida o apagada.

// Saludos

Última edición por roman fecha: 03-03-2005 a las 07:18:39.
Responder Con Cita
  #5  
Antiguo 03-03-2005
Avatar de orfeo
orfeo orfeo is offline
Miembro
 
Registrado: may 2003
Posts: 99
Poder: 21
orfeo Va por buen camino
que puedo decir...
A sido una explicacion grandiosa

muchas gracias...
__________________
Aprendamos a ser civilizados
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 10:12:59.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi