Pergunta

Eu gostaria de ser capaz de mudar as propriedades da impressora sem abrir a janela de propriedades da impressora ...

Usando os DocumentProperties (importado da Winspool.drv) função até agora não conseguiu, porque enquanto ele é fácil de suprimir o diálogo de aparecer, parece que o valor retornado pelo PrinterSettings.GetHdevmode () não está refletindo os PrinterSettings que é chamá-lo, mas em vez disso o valor das propriedades da impressora anteriores retornam OK. Por exemplo, isso me dá os valores anteriores (erradas) da última chamada para as propriedades, em vez dos valores que deveriam ter das PrinterSettings objeto:

IntPtr hdevmode = PrinterSettings.GetHdevmode(PrinterSettings.DefaultPageSettings);
PrinterSettings.SetHdevmode(hdevmode);
PrinterSettings.DefaultPageSettings.SetHdevmode(hdevmode);

Assim que GetHdevmode têm um bug ou isso é o que seu suposto fazer? Existe um C # solução para este ou alguém ainda tem alguma informação sobre isso? Eu tenho dificuldade até mesmo para encontrar informações sobre o tema.

Agradecemos antecipadamente por qualquer insight.

EDIT: Eu não quero fazer isso muito pessoal de um problema, mas espero ter toda a informação, neste caso, pode fornecer uma resposta que é uma solução útil para outros também.

Aqui é um ++ DLL C que tenho escrito, a fim de ter uma solução para este problema. A sua não é atualmente trabalhando - ela muda outra memória, tais como cópias, e não ter sucesso em mudar o papersize "subjacente". Eu pensei que tudo que eu precisava fazer era especificar o tampão da bandeira para fora, a fim de fazer as mudanças?

extern "C" __declspec(dllexport) DEVMODE* __stdcall GetRealHDevMode(int width, int height, char *printerName, DEVMODE* inDevMode)
    {
//declare handles and variables
HANDLE printerHandle;
LPHANDLE printerHandlePointer(&printerHandle);

//get printer handle pointer
OpenPrinter((LPWSTR)printerName, printerHandlePointer, NULL);

//Get size needed for public and private devmode data and declare devmode structure
size_t devmodeSize = DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, NULL, NULL, 0);
DEVMODE* devmode = reinterpret_cast<DEVMODE*>(new char[devmodeSize + sizeof(DEVMODE) + sizeof(inDevMode->dmDriverExtra)]);

//lock memory
GlobalLock(devmode);

//fill the out buffer
DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, devmode, NULL, DM_OUT_BUFFER);

//change the values as required
devmode->dmPaperWidth = width;
devmode->dmPaperLength = height;
devmode->dmPaperSize = DMPAPER_USER;

devmode->dmFields &= ~DM_PAPERSIZE;
devmode->dmFields &= ~DM_PAPERLENGTH;
devmode->dmFields &= ~DM_PAPERWIDTH;
devmode->dmFields |= (DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH);

//input flag on now to put the changes back in
DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);

//unlock memory
GlobalUnlock(devmode);

//return the devmode that was used to alter the settings
return devmode;
    }

Eu percebi o código C ++ foi suficiente para alterar as configurações, então tudo que eu faço em C # é o seguinte:

public PrinterSettings ChangePrinterProperties(PrinterSettings inPrinterSettings)
    {
        IntPtr TemphDevMode = inPrinterSettings.GetHdevmode(inPrinterSettings.DefaultPageSettings);
        IntPtr hDevMode = GetRealHDevMode((int)(inPrinterSettings.DefaultPageSettings.PaperSize.Width * 2.54F),
            (int)(inPrinterSettings.DefaultPageSettings.PaperSize.Height * 2.54F),
            inPrinterSettings.PrinterName, TemphDevMode);
        GlobalFree(hDevMode);
        return inPrinterSettings;
    }

UPDATE: Mudou-se a ordem um pouco com dmPaperSize e dmFields. melhores resultados; não chegou lá ainda.

UPDATE 2: Ok, eu encontrei uma página microsoft que diz a documentação está errado. MSDN diz para definir dmPaperSize para 0 quando você quiser especificar a largura e altura enquanto a correção de suporte da Microsoft diz configurá-lo para DMPAPER_USER. http://support.microsoft.com/kb/108924

Foi útil?

Solução

Existem 2 problemas com a forma como você está especificando o tamanho do papel na DEVMODE:

(1) Se você especificar DM_PAPERWIDTH ou DM_PAPERLENGTH ou ambos, você não deve também definir o bit DM_PAPERSIZE. Ele depende do driver de impressora, mas muitos motoristas ignoram DM_PAPERLENGTH / largura no código acima.

(2) Muitos motoristas não suportam DM_PAPERLENGTH / WIDTH em tudo. Com esses drivers, você simplesmente não pode definir o tamanho do papel que você está tentando fazer acima. Você só pode selecionar uma das dmPaperSizes predefinidos.

Você pode usar DeviceCapabilities (DC_FIELDS) para determinar se o driver suporta DM_PAPERLENGTH / largura.

Você pode usar DeviceCapabilities (DC_PAPERS) para enumerar os dmPaperSizes permitidos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top