DocumentProperties() İşlevi ile yazıcı ayarlarını değiştirme

Bu makalede, işleviyle yazıcı ayarlarının nasıl değiştirileceği gösterilmektedir DocumentProperties() .

Orijinal ürün sürümü: Yazıcı
Özgün KB numarası: 167345

Özet

Yazıcı ayarlarını değiştirmek için DEVMODE yapısı kullanmak, yalnızca yapı alanlarını değiştirmekten daha zordur. Özellikle, bir cihaz için geçerli bir DEVMODE yapısı yalnızca işlev tarafından DocumentProperties() değiştirilebilen özel veriler içerir.

Bu makalede, işlevle DEVMODE yapısının içeriğinin nasıl değiştirileceği DocumentProperties() açıklanmaktadır.

Daha fazla bilgi

Win32 SDK'sı tarafından belgelendiği gibi bir DEVMODE yapısı, genel veya 'cihazdan bağımsız veriler' ile özel veya 'cihaza bağımlı veriler' içerir. BIR DEVMODE'un özel bölümü, DEVMODE yapısı tarafından tanımlanan ortak bölümün hemen ardından, belleğin bitişik bir arabelleğinde bulunur.

Bir program, yazıcıdan yazıcıya ve yazıcı sürücüsünün sürümünden sürümüne farklı olduğundan bu arabelleğin boyutunu tahmin edemez. Ayrıca, bir program tarafından bildirilen bir DEVMODE yapısı özel cihaz verileri için yeterli alan içermez. Özel verileri olmayan bir DEVMODE arabelleği , ResetDC()ve DocumentProperties()gibi CreateDC()işlevlere geçirilirse işlev başarısız olabilir.

Cihaz sürücüsüyle bir DEVMODE'u güvenilir bir şekilde kullanmak için aşağıdaki adımları izleyerek bunu oluşturun ve değiştirin:

  1. Cihazdan gerekli arabellek boyutunu belirleyin ve ardından bu arabellek için yeterli bellek ayırın.

    DocumentProperties() , son parametre 0 olarak ayarlandığında DEVMODE arabelleği için gereken bayt sayısını döndürür. Bu makaledeki örnek kod, arabelleğin doğru boyutunu belirlemek için bu tekniği kullanır. Örnek kod daha sonra yeterince büyük bir arabellek ayırmak için C çalışma zamanı bellek ayırma işlevini malloc() kullanır. DocumentProperties() gibi ve işlevleri ResetDC()CreateDC() ve bir DEVMODE işaretçilerini parametre olarak kullandığından, çoğu uygulama bir işaretçi tarafından ele alınan belleği ayırabilir.

    Ancak, genel belleğe işlenmesi gereken ortak PrintDlg() alma parametreleri gibi işlevler. Bir program bu işlevlerden birine parametre olarak son DEVMODE arabelleği kullanıyorsa kullanarak bellek ayırmalı ve kullanarak GlobalAlloc()GlobalLock()arabelleğe bir işaretçi almalıdır.

  2. Cihaz sürücüsünden DEVMODE arabelleğinin varsayılan ayarlarla başlatılmasını isteyin.

    Örnek kod, ayrılmış arabelleği geçerli varsayılan ayarlarla başlatmak için ikinci kez çağırır DocumentProperties() . DocumentProperties() komutu fMode parametresinde geçirildiğinde pDevModeOutput parametresi olarak adlandırılan arabelleği yazıcının DM_OUT_BUFFER geçerli ayarlarıyla doldurur.

  3. DEVMODE'un ortak bölümünde değişiklik yapın ve cihaz sürücüsünden çağrısı DocumentProperties()yaparak değişiklikleri DEVMODE'un özel bölümüyle birleştirmesini isteyin.

    2. adımda geçerli ayarlarla arabelleği başlatan örnek kod, DEVMODE'un genel bölümünde değişiklikler yapar. DEVMODE üyelerinin açıklamaları için Win32 SDK belgelerine bakın. Bu örnek kod, yazıcının yönlendirme ve çift yönlü (çift taraflı) ayarları kullanıp kullanamayacağını belirler ve bunları uygun şekilde değiştirir.

    Not

    DEVMODE'un dmFields üyesindeki bir bayrak, yalnızca yazıcının ilişkili yapı üyesini kullandığının göstergesidir. Yazıcılar çeşitli fiziksel özelliklere sahiptir ve bu nedenle DEVMODE'un belgelenen özelliklerinin yalnızca bir alt kümesini destekleyemeyebilir. Bir DEVMODE alanının desteklenen ayarlarını belirlemek için uygulamalar kullanmalıdır DeviceCapabilities().

    Örnek kod daha sonra üçüncü bir çağrısı DocumentProperties() yapar ve hem pDevModeInput hem de pDevModeOutput parametrelerinde DEVMODE arabelleği geçirir. Ayrıca or("|") işlecini kullanarak fMode parametresinde DM_IN_BUFFER ve DM_OUT_BUFFER birleşik komutlarını geçirir. Bu komutlar işleve giriş arabelleğinde bulunan ayarları almasını ve bunları cihazın geçerli ayarlarıyla birleştirmesini söyler. Ardından sonucu out parametresinde belirtilen arabelleğe yazar.

Not

DocumentProperties() , belirli bir yazıcıyı bir yazıcı tutamacını kullanarak ifade eder: hPrinter. Bu tanıtıcı, örnek kodun da gösterildiği adresinden OpenPrinter()elde edilir. OpenPrinter() , genellikle İşletim Sistemi kabuğunda göründüğü gibi yazıcının kolay adı olan bir yazıcının adını gerektirir. Bu ad, tarafından döndürülen PrintDlg()DEVNAMES yapısından veya Varsayılan Yazıcı'dan alınabilirEnumPrinters().

Bu makalede, doğru arabellek boyutunu ayırmanın ve bu arabelleği başlatmanın ilk iki adımı ile DocumentProperties()gerçekleştirilir. Bu adımları kullanarak GetPrinter()da izleyebilirsiniz.

Daha fazla bilgi ve bunun bir örneği için bkz. SetPrinter işlevini kullanarak yazıcı ayarlarını değiştirme.

Örnek Kod

Örnek kod, DEVMODE arabelleği almak ve değiştirmek için bu üç adımı izler. İşlev adlandırılmış bir yazıcı alır ve bu özellikleri destekliyorsa devMODE'yi çift taraflı ve yatay yönde yazdıracak şekilde yapılandırır. Çağırana döndürülen sonuçta elde edilen DEVMODE, , SetPrinter(), PrintDlg()veya ResetDC()gibi CreateDC()DEVMODE arabelleklerini kullanan diğer API çağrıları için uygundur. Çağıran DEVMODE arabelleği kullanarak tamamlandığında, çağıran belleği boşaltmaktan sorumludur.

 LPDEVMODE GetLandscapeDevMode(HWND hWnd, char *pDevice)
 {
    HANDLE hPrinter;
    LPDEVMODE pDevMode;
    DWORD dwNeeded, dwRet;
    
    /* Start by opening the printer */ 
    if (!OpenPrinter(pDevice, &hPrinter, NULL))
        return NULL;
    
    /*
    * Step 1:
    * Allocate a buffer of the correct size.
    */ 
    dwNeeded = DocumentProperties(hWnd,
    hPrinter, /* Handle to our printer. */ 
    pDevice, /* Name of the printer. */ 
    NULL, /* Asking for size, so */ 
    NULL, /* these are not used. */ 
    0); /* Zero returns buffer size. */ 
    pDevMode = (LPDEVMODE)malloc(dwNeeded);
    
    /*
    * Step 2:
    * Get the default DevMode for the printer and
    * modify it for your needs.
    */ 
    dwRet = DocumentProperties(hWnd,
    hPrinter,
    pDevice,
    pDevMode, /* The address of the buffer to fill. */ 
    NULL, /* Not using the input buffer. */ 
    DM_OUT_BUFFER); /* Have the output buffer filled. */ 
    if (dwRet != IDOK)
    {
        /* If failure, cleanup and return failure. */ 
        free(pDevMode);
        ClosePrinter(hPrinter);
        return NULL;
    }
    
    /*
    * Make changes to the DevMode which are supported.
    */ 
    if (pDevMode->dmFields & DM_ORIENTATION)
    {
        /* If the printer supports paper orientation, set it.*/ 
        pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
    }
    
    if (pDevMode->dmFields & DM_DUPLEX)
    {
        /* If it supports duplex printing, use it. */ 
        pDevMode->dmDuplex = DMDUP_HORIZONTAL;
    }
    
    /*
    * Step 3:
    * Merge the new settings with the old.
    * This gives the driver an opportunity to update any private
    * portions of the DevMode structure.
    */ 
    dwRet = DocumentProperties(hWnd,
    hPrinter,
    pDevice,
    pDevMode, /* Reuse our buffer for output. */ 
    pDevMode, /* Pass the driver our changes. */ 
    DM_IN_BUFFER | /* Commands to Merge our changes and */ 
    DM_OUT_BUFFER); /* write the result. */ 
    
    /* Finished with the printer */ 
    ClosePrinter(hPrinter);
    
    if (dwRet != IDOK)
    {
        /* If failure, cleanup and return failure. */ 
        free(pDevMode);
        return NULL;
    }
    
    /* Return the modified DevMode structure. */ 
    return pDevMode;
}