SetPrinter işlevini kullanarak yazıcı ayarlarını değiştirme

işlevi, SetPrinter uygulamaların çeşitli yazıcı özniteliklerini değiştirmesine olanak tanır. Ancak, bu makaledeki kodun gösterdiği gibi, doğru çağırmak SetPrinteriçin belirli bir hazırlık miktarı gereklidir.

Orijinal ürün sürümü: Windows
Özgün KB numarası: 140285

SetPrinter için hPrinter parametresi

İlk parametre, ayarları değiştirilecek yazıcının tanıtıcısıdır. Bu parametre' den OpenPrinter()alınmalıdır.

SetPrinter için dwLevel parametresi

İkinci parametre, geçirilen SetPrinter()verilerin yapısını belirtir. Parametre değeri 0, 2, 3, 4,5, 6, 7, 8 veya 9 olabilir.

SetPrinter için lpbPrinter parametresi

Üçüncü parametre, ikinci parametredeki sayıya karşılık gelen bir PRINTER_INFO_n yapıdır n . Bu yapı, yalnızca yapının boyutunda bir arabellek olmadığından karışıklığa neden olabilir. Bu yapılar cihazdan bağımsız bilgiler içerir, ancak bellekte cihaz sürücüsü tarafından verilen bazı değişken miktarda cihaza bağımlı bilgi tarafından hemen takip edilir. Bu nedenle, bu arabelleğin ne kadar önemli olması gerektiğini belirlemek için küçük bir çalışma söz konusudur. Bu, gereken toplam boyuta ayarlanacak pcbNeeded çağrılarak GetPrinter()elde edilir.

Ayrıca, arabellekte genellikle cihazdan bağımsız ve cihaza bağımlı büyük miktarda bilgi bulunur. Uygulamanız bu yapı üyelerinin çoğunda değerleri bilmeyecek veya önemsemeyecektir. Bu nedenle, ilgilendiğiniz değişiklikleri yaptığınızda, diğer tüm veri parçaları için doğru değerleri takmanız gerekir. Bu diğer veri parçaları, ikinci kez çağırdığınızda GetPrinter() ayarlanır.

SetPrinter için DwCommand parametresi

Dördüncü parametre yazdırmayı duraklatmak, yazdırmayı sürdürmek veya tüm yazdırma işlerini temizlemek için kullanılır. Bu parametre genellikle kullanılanla aynı anda lpbPrinter kullanılmaz. Bu makale, yazıcı durumunu ayarlamayla ilgili olmadığından örnek kod bu parametreyi sıfır olarak ayarlar.

DEVMODE hakkında

Genellikle, tarafından işaret edilen yapı öğesi DEVMODE değiştirilir (öğesi yerinePRINTER_INFO_n).pDevMode Bu durumda, pDevMode->dmFields bayraklar uygulamaya hangi alanların değiştirilebileceğini söyler. Bu size tarafından GetPrinter()verildiğinden, değişikliği denemeden önce bayrağı deleyebilirsiniz dmFields .

Ayrıca, cihazdan bağımsız bölümündeki alanların değiştirilmesi, cihaza bağımlı bölümdeki DEVMODE değişiklikleri de etkileyebileceğinden, için tutarlı DEVMODE bir yapı oluşturmak için SetPrinter()aramadan önce aramanız DocumentProperties()SetPrinter() gerekir.

Örnek Kod

// MySetPrinter
// Demonstrates how to use the SetPrinter API.  This particular function changes the orientation
// for the printer specified in pPrinterName to the orientation specified in dmOrientation.
// Valid values for dmOrientation are:
// DMORIENT_PORTRAIT (1) or DMORIENT_LANDSCAPE (2)
BOOL MySetPrinter(LPTSTR pPrinterName, short dmOrientation)
{
    HANDLE hPrinter = NULL;
    DWORD dwNeeded = 0;
    PRINTER_INFO_2 *pi2 = NULL;
    DEVMODE *pDevMode = NULL;
    PRINTER_DEFAULTS pd;
    BOOL bFlag;
    LONG lFlag;

    // Open printer handle (on Windows NT, you need full-access because you
    // will eventually use SetPrinter)...
    ZeroMemory(&pd, sizeof(pd));
    pd.DesiredAccess = PRINTER_ALL_ACCESS;
    bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
    if (!bFlag || (hPrinter == NULL))
        return FALSE;

    // The first GetPrinter tells you how big the buffer should be in
    // order to hold all of PRINTER_INFO_2. Note that this should fail with
    // ERROR_INSUFFICIENT_BUFFER.  If GetPrinter fails for any other reason
    // or dwNeeded isn't set for some reason, then there is a problem...
    SetLastError(0);
    bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
    if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
    {
        ClosePrinter(hPrinter);
        return FALSE;
    }

    // Allocate enough space for PRINTER_INFO_2...
    pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
    if (pi2 == NULL)
    {
        ClosePrinter(hPrinter);
        return FALSE;
    }

    // The second GetPrinter fills in all the current settings, so all you
    // need to do is modify what you're interested in...
    bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
    if (!bFlag)
    {
        GlobalFree(pi2);
        ClosePrinter(hPrinter);
        return FALSE;
    }

    // If GetPrinter didn't fill in the DEVMODE, try to get it by calling
    // DocumentProperties...
    if (pi2->pDevMode == NULL)
    {
        dwNeeded = DocumentProperties(NULL, hPrinter,
        pPrinterName,
        NULL, NULL, 0);
        if (dwNeeded <= 0)
        {
            GlobalFree(pi2);
            ClosePrinter(hPrinter);
            return FALSE;
        }

        pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
        if (pDevMode == NULL)
        {
            GlobalFree(pi2);
            ClosePrinter(hPrinter);
            return FALSE;
        }

        lFlag = DocumentProperties(NULL, hPrinter,
        pPrinterName,
        pDevMode, NULL,
        DM_OUT_BUFFER);
        if (lFlag != IDOK || pDevMode == NULL)
        {
            GlobalFree(pDevMode);
            GlobalFree(pi2);
            ClosePrinter(hPrinter);
            return FALSE;
        }
        pi2->pDevMode = pDevMode;
    }

    // Driver is reporting that it doesn't support this change...
    if (!(pi2->pDevMode->dmFields & DM_ORIENTATION))
    {
        GlobalFree(pi2);
        ClosePrinter(hPrinter);
        if (pDevMode)
        GlobalFree(pDevMode);
        return FALSE;
    }

    // Specify exactly what we are attempting to change...
    pi2->pDevMode->dmFields = DM_ORIENTATION;
    pi2->pDevMode->dmOrientation = dmOrientation;

    // Do not attempt to set security descriptor...
    pi2->pSecurityDescriptor = NULL;

    // Make sure the driver-dependent part of devmode is updated...
    lFlag = DocumentProperties(NULL, hPrinter,
      pPrinterName,
      pi2->pDevMode, pi2->pDevMode,
      DM_IN_BUFFER | DM_OUT_BUFFER);
    if (lFlag != IDOK)
    {
        GlobalFree(pi2);
        ClosePrinter(hPrinter);
        if (pDevMode)
            GlobalFree(pDevMode);
        return FALSE;
    }

    // Update printer information...
    bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
    if (!bFlag)
    // The driver doesn't support, or it is unable to make the change...
    {
        GlobalFree(pi2);
        ClosePrinter(hPrinter);
        if (pDevMode)
            GlobalFree(pDevMode);
        return FALSE;
    }

    // Tell other apps that there was a change...
    SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
      (LPARAM)(LPCSTR)pPrinterName,
      SMTO_NORMAL, 1000, NULL);

    // Clean up...
    if (pi2)
        GlobalFree(pi2);
    if (hPrinter)
        ClosePrinter(hPrinter);
    if (pDevMode)
        GlobalFree(pDevMode);
    return TRUE;
}