Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

OpenPrinter y encriptar en Rad Studio 11

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: OpenPrinter y encriptar en Rad Studio 11 Responder citando

Hola a todos,

Tengo esta funciona de hace mil años para XE3 y ahora acabo de montarme el Rad Studio 11 para ir poniéndome al día, pero tengo problemas con dos cosas.

Cuando uso OpenPrinter, creo que de una funciona que sacamos de aqui:

void __fastcall TFMain::ImprimirESC(AnsiString PrinterName, LPVOID Data,DWORD Count)
{
// Estructura con la informacion sobre el documento
struct {
char *DocName, *OutputFile, *DataType;
} DocInfo = {"Abrir", 0, "RAW"};

// Obtener un handle de Impresora
HANDLE Handle;

OpenPrinter

if (!OpenPrinter(PrinterName.c_str(), &Handle, NULL))
throw Exception("Operación invalida con la Impresora");

try {
// Informar al spooler del comienzo de impresion
if (StartDocPrinter(Handle, 1, LPBYTE(&DocInfo)) == 0)
throw Exception("Operación invalida con la Impresora");

// Enviar los Datos Directamente
DWORD Bytes;
if (!WritePrinter(Handle, Data, Count, &Bytes) || Bytes != Count)
throw Exception("Operación invalida con la Impresora");
}
__finally {
ClosePrinter(Handle); // Devolver el handle de impresora
}
}
// ---------------------------------------------------------------------------

En XE3 funciona perfectamente y en BC 11 da este error:

[bcc32c Error] Main.cpp(289): no matching function for call to 'OpenPrinterW'
winspool.h(1334): candidate function not viable: no known conversion from 'char *' to 'LPWSTR' (aka 'wchar_t *') for 1st argument

En el caso de la función "Encriptar" que también salió del FORO:

En esta linea:

unsigned char *cVariable=Cadena.c_str();

Me da este error:

[bcc32c Error] Main.cpp(91): cannot initialize a variable of type 'unsigned char *' with an rvalue of type 'char *'


Se os ocurre como solucionarlo?

Un saludo

Carlos
_________________
Carlos J. Fernandez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Hola Carlos,

Prueba así:
Código:
void __fastcall TFMain::ImprimirESC(String PrinterName, LPVOID Data, DWORD Count)
{
    // Estructura con la informacion sobre el documento
    DOC_INFO_1 DocInfo = { L"Abrir", 0, L"RAW" };

    // Obtener un handle de Impresora
    HANDLE Handle;

    if (!OpenPrinter(PrinterName.c_str(), &Handle, NULL))
        throw Exception("Operación invalida con la Impresora");

    try
    {
        // Informar al spooler del comienzo de impresion
        if (StartDocPrinter(Handle, 1, LPBYTE(&DocInfo)) == 0)
            throw Exception("Operación invalida con la Impresora");

        // Enviar los Datos Directamente
        DWORD Bytes;
        if (!WritePrinter(Handle, Data, Count, &Bytes) || Bytes != Count)
            throw Exception("Operación invalida con la Impresora");
    } __finally
    {
        ClosePrinter(Handle); // Devolver el handle de impresora
    }
}


Lo otro si me pones la función entera o el enlace del foro donde la encontraste puedo mirarlo, pero las dos cosas están relacionados con los cambios a Unicode, por lo que es interesante echarle un vistazo a este video por ejemplo:
[Migración de proyectos C++ Builder a Unicode]
https://www.youtube.com/watch?v=W518DbJa5R4
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Muchas gracias Leo,

Voy a mirarlo y te cuento.

Un saludo

Carlos
_________________
Carlos J. Fernandez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

_Leo escribió:
Hola Carlos,

Prueba así:
Código:
void __fastcall TFMain::ImprimirESC(String PrinterName, LPVOID Data, DWORD Count)
{
    // Estructura con la informacion sobre el documento
    DOC_INFO_1 DocInfo = { L"Abrir", 0, L"RAW" };

    // Obtener un handle de Impresora
    HANDLE Handle;

    if (!OpenPrinter(PrinterName.c_str(), &Handle, NULL))
        throw Exception("Operación invalida con la Impresora");

    try
    {
        // Informar al spooler del comienzo de impresion
        if (StartDocPrinter(Handle, 1, LPBYTE(&DocInfo)) == 0)
            throw Exception("Operación invalida con la Impresora");

        // Enviar los Datos Directamente
        DWORD Bytes;
        if (!WritePrinter(Handle, Data, Count, &Bytes) || Bytes != Count)
            throw Exception("Operación invalida con la Impresora");
    } __finally
    {
        ClosePrinter(Handle); // Devolver el handle de impresora
    }
}


Lo otro si me pones la función entera o el enlace del foro donde la encontraste puedo mirarlo, pero las dos cosas están relacionados con los cambios a Unicode, por lo que es interesante echarle un vistazo a este video por ejemplo:
[Migración de proyectos C++ Builder a Unicode]
https://www.youtube.com/watch?v=W518DbJa5R4


Leo,

En la primer linea:

DOC_INFO_1 DocInfo = { L"Abrir", 0, L"RAW" };

Me da este error:

[bcc32c Error] Main.cpp(306): cannot initialize a member subobject of type 'LPSTR' (aka 'char *') with an lvalue of type 'const wchar_t [6]'

En el caso de lo de encriptar, el código es este, lo saque de aqui:

AnsiString __fastcall TFMain::Encriptar(AnsiString Cadena)
{
unsigned char *cVariable=Cadena.c_str();
double cuantos=sizeof(cVariable);
char aClave[12][6]={"10101\0", "10001\0", "10110\0", "11001\0", "11001\0", "10011\0","11101\0", "10101\0", "11100\0", "10101\0", "10011\0", "11011\0"};
AnsiString cCambio, cBin1, cBin2, cClave;
int nChar, nDato, nValor;
cCambio = "";
nDato = 0;
nChar = 0;
while (cVariable[nChar] != NULL)
{
if (nDato > 5)
nDato = 0;

nValor = cVariable[nChar];
cBin1 = "";
cBin2 = "";
cClave = aClave[nDato];

while (nValor > 1)
{
cBin1 = IntToStr(nValor % 2) + cBin1;
nValor = INT(nValor / 2);
}
cBin1 = IntToStr(nValor) + cBin1;

if (cBin1.Length() > cClave.Length())
while (cClave.Length() < cBin1.Length())
cClave = "0" + cClave;
else
while (cBin1.Length() < cClave.Length())
cBin1 = "0" + cBin1;

for (int j = cClave.Length(); j > 0; j--)
cBin2 += cClave.SubString(j,1) ^ cBin1.SubString(j,1);

nValor = 0;
for (int j = cBin2.Length(); j > 0; j--)
nValor += StrToInt(cBin2.SubString(j,1)) * pow(2, (j - 1));

cCambio += CHAR(nValor);
nDato ++;
nChar ++;
}
return (cCambio);
}
//---------------------------------------------------------------------------
_________________
Carlos J. Fernandez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Carlos J. Fernandez escribió:
En la primer linea:

DOC_INFO_1 DocInfo = { L"Abrir", 0, L"RAW" };

Me da este error:

[bcc32c Error] Main.cpp(306): cannot initialize a member subobject of type 'LPSTR' (aka 'char *') with an lvalue of type 'const wchar_t [6]'


Esto es porque probablemente el proyecto donde lo estas usando no es un proyecto nuevo sino uno heredado de alguna versión vieja, y seguramente en las opciones del proyecto lo tienes como ANSI (char):

MENU: Project -> Options... -> C++ Shared Options -> "_TCHAR maps to" = "char"

en vez de Unicode (wchar_t) que es como viene por defecto desde hace muchas versiones.

Aquí una versión para que funcione de las dos maneras y tanto en versiones viejas como en la última:
Código:
void __fastcall TFMain::ImprimirESC(AnsiString PrinterName, LPVOID Data, DWORD Count)
{
    // Estructura con la informacion sobre el documento
    DOC_INFO_1 DocInfo = { TEXT("Abrir"), 0, TEXT("RAW") };

    // Obtener un handle de Impresora
    HANDLE Handle;

    if (!OpenPrinterA(PrinterName.c_str(), &Handle, NULL))
        throw Exception("Operación invalida con la Impresora");

    try
    {
        // Informar al spooler del comienzo de impresion
        if (StartDocPrinter(Handle, 1, LPBYTE(&DocInfo)) == 0)
            throw Exception("Operación invalida con la Impresora");

        // Enviar los Datos Directamente
        DWORD Bytes;
        if (!WritePrinter(Handle, Data, Count, &Bytes) || Bytes != Count)
            throw Exception("Operación invalida con la Impresora");
    }
    __finally
    {
        ClosePrinter(Handle); // Devolver el handle de impresora
    }
}


Y la de Cifrado, solo era un cast en la función "pow", al menos de lo que has pegado es lo único que me falla en todas las versiones que lo he probado. Quedaría así, también la he probado en versiones viejas por si acaso para que funcione en todas (he quitado la variable "cuantos" que no se estaba usando:
Código:
AnsiString __fastcall TFMain::Encriptar(AnsiString Cadena)
{
    unsigned char* cVariable = Cadena.c_str();
    char aClave[12][6] = { "10101\0", "10001\0", "10110\0", "11001\0",
        "11001\0", "10011\0", "11101\0", "10101\0", "11100\0", "10101\0",
        "10011\0", "11011\0" };
    AnsiString cCambio, cBin1, cBin2, cClave;
    int nChar, nDato, nValor;
    cCambio = "";
    nDato = 0;
    nChar = 0;
    while (cVariable[nChar] != NULL) {
        if (nDato > 5)
            nDato = 0;

        nValor = cVariable[nChar];
        cBin1 = "";
        cBin2 = "";
        cClave = aClave[nDato];

        while (nValor > 1) {
            cBin1 = IntToStr(nValor % 2) + cBin1;
            nValor = INT(nValor / 2);
        }
        cBin1 = IntToStr(nValor) + cBin1;

        if (cBin1.Length() > cClave.Length())
            while (cClave.Length() < cBin1.Length())
                cClave = "0" + cClave;
        else
            while (cBin1.Length() < cClave.Length())
                cBin1 = "0" + cBin1;

        for (int j = cClave.Length(); j > 0; j--)
            cBin2 += cClave.SubString(j, 1) ^ cBin1.SubString(j, 1);

        nValor = 0;
        for (int j = cBin2.Length(); j > 0; j--)
            nValor += StrToInt(cBin2.SubString(j, 1)) * pow((double)2, (j-1));

        cCambio += CHAR(nValor);
        nDato++;
        nChar++;
    }
    return (cCambio);
}
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Muchas gracias Leo,

Voy a probarlo a ver si me funciona todo.

Un abrazo

Carlos
_________________
Carlos J. Fernandez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Leo,

No entiendo porque pero me da el mismo error:

En la primera linea:

unsigned char* cVariable = Cadena.c_str();

Da el error:

[bcc32c Error] Main.cpp(97): cannot initialize a variable of type 'unsigned char *' with an rvalue of type 'char *'

He probado poniendo en donde me decías:

MENU: Project -> Options... -> C++ Shared Options -> "_TCHAR maps to" = "char"

Y también poniendo:

MENU: Project -> Options... -> C++ Shared Options -> "_TCHAR maps to" = "wchar_t"

Pero en los dos casos da el mismo error, que raro porque a ti te compila bien, algo se me esta pasando por alto.

Un saludo.

Carlos
_________________
Carlos J. Fernandez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Ya veo porque me ha compilado.. como sabes las versiones actuales llevan dos compiladores, el antiguo de Borland y el más actual Clang, en las primeras versiones donde empezaron a incluir el nuevo seguían teniendo por defecto activo el de Borland y en las opciones del proyecto se podía activar el nuevo, pero a partir de una versión, no recuerdo si la 10, llevan activo por defecto Clang y en las opciones del proyecto permite elegir el antiguo de Borland, muchas veces cuando hago algo rápido o tengo que consultar cabeceras usando la tecla CTRL lo cambio, y me despiste.

Ahora está probado para que compile en los dos compiladores y tanto si se usa Unicode (wchar_t) como ANSI (char). Lo ideal sería usar siempre Unicode como viene activo por defecto desde hace muchas versiones y no habría que hacer tantos cast y cosas que no me gustan de ese código para que funcione en las distintas versiones, pero como es código que en el foro igual va a usar más gente, para evitar problemas suelo tener en cuenta que compile sin importar que combinación se tenga activa. Antes de la versión 10 era más fácil hacer funciones sin tanto malabarismo para ANSI y Unicode a la vez ya que String en ANSI es un typedef a AnsiString y en Unicode a UnicodeString, pero desde la versión 10, String ya es siempre UnicodeString.

Código:
void __fastcall TFMain::ImprimirESC(AnsiString PrinterName, LPVOID Data, DWORD Count)
{
    // Estructura con la informacion sobre el documento
    DOC_INFO_1 DocInfo = { (PTCHAR)TEXT("Abrir"), 0, (PTCHAR)TEXT("RAW") };

    // Obtener un handle de Impresora
    HANDLE Handle;

    if (!OpenPrinterA(PrinterName.c_str(), &Handle, NULL))
        throw Exception("Operación invalida con la Impresora");

    try
    {
        // Informar al spooler del comienzo de impresion
        if (StartDocPrinter(Handle, 1, LPBYTE(&DocInfo)) == 0)
            throw Exception("Operación invalida con la Impresora");

        // Enviar los Datos Directamente
        DWORD Bytes;
        if (!WritePrinter(Handle, Data, Count, &Bytes) || Bytes != Count)
            throw Exception("Operación invalida con la Impresora");
    }
    __finally
    {
        ClosePrinter(Handle); // Devolver el handle de impresora
    }
}

Código:
AnsiString __fastcall TFMain::Encriptar(AnsiString Cadena)
{
    unsigned char* cVariable = (PUCHAR)Cadena.c_str();
    char aClave[12][6] = { "10101", "10001", "10110", "11001", "11001",
        "10011", "11101", "10101", "11100", "10101", "10011", "11011" };
    AnsiString cCambio, cBin1, cBin2, cClave;
    int nChar, nDato, nValor;
    cCambio = "";
    nDato = 0;
    nChar = 0;
    while (cVariable[nChar] != NULL) {
        if (nDato > 5)
            nDato = 0;

        nValor = cVariable[nChar];
        cBin1 = "";
        cBin2 = "";
        cClave = aClave[nDato];

        while (nValor > 1) {
            cBin1 = IntToStr(nValor % 2) + cBin1;
            nValor = INT(nValor / 2);
        }
        cBin1 = IntToStr(nValor) + cBin1;

        if (cBin1.Length() > cClave.Length())
            while (cClave.Length() < cBin1.Length())
                cClave = "0" + cClave;
        else
            while (cBin1.Length() < cClave.Length())
                cBin1 = "0" + cBin1;

        for (int j = cClave.Length(); j > 0; j--)
            cBin2 += cClave.SubString(j, 1) ^ cBin1.SubString(j, 1);

        nValor = 0;
        for (int j = cBin2.Length(); j > 0; j--)
            nValor += StrToInt(cBin2.SubString(j, 1)) * pow((double)2, (j-1));

        cCambio += CHAR(nValor);
        nDato++;
        nChar++;
    }
    return (cCambio);
}


A ver si por fin va la vencida Wink
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Leo,

Ahora si jejeje muchas gracias eres un crack.

Un saludo

Carlos
_________________
Carlos J. Fernandez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.