SetPrinterで、プリンタの設定をする。
SetPrinter function (WinSpool.h) - Win32 apps | Microsoft Docs
https://support.microsoft.com/ja-jp/help/140285/how-to-modify-printer-settings-by-using-setprinter
これで、プリンタ設定の変更が完了する。
pd.DesiredAccess = PRINTER_ACCESS_USE;
bOpen = OpenPrinter(ptszBuf, &hPrinter, &pd);
if (bOpen){
if (hPrinter != NULL){
_tprintf(_T("hPrinter = 0x%08x\n"), (unsigned long)hPrinter);
GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
_tprintf(_T("dwNeeded = %lu\n"), dwNeeded);
if (dwNeeded > 0){
hPrinterInfo2 = GlobalAlloc(GHND, dwNeeded);
if (hPrinterInfo2 != NULL){
pi2 = (PRINTER_INFO_2 *)GlobalLock(hPrinterInfo2);
if (pi2 != NULL){
bRet = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (bRet){
if (pi2->pDevMode != NULL){
_tprintf(_T("GetPrinter Get OK!\n"));
_tprintf(_T("pi2->pDevMode->dmDeviceName = %s\n"), pi2->pDevMode->dmDeviceName);
_tprintf(_T("pi2->pPrinterName = %s\n"), pi2->pPrinterName);
_tprintf(_T("pi2->pPortName = %s\n"), pi2->pPortName);
_tprintf(_T("pi2->pDriverName = %s\n"), pi2->pDriverName);
_tprintf(_T("pi2->pPrintProcessor = %s\n"), pi2->pPrintProcessor);
_tprintf(_T("pi2->pDatatype = %s\n"), pi2->pDatatype);
pi2->pDevMode->dmFields = DM_ORIENTATION;
pi2->pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
lFlag = DocumentProperties(NULL, hPrinter, ptszBuf, pi2->pDevMode, pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag == IDOK){
_tprintf(_T("DocumentProperties Update OK!\n"));
lFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (lFlag > 0){
_tprintf(_T("SetPrinter OK!\n"));
}
else{
DWORD e = GetLastError();
_tprintf(_T("SetPrinter NG! e = %lu\n"), e);
}
}
}
SetPrinterしてみると、
C:\Users\bg1\Documents\test>SetPrinter.exe
Default Printer: EPSON PX-S06 Series
hPrinter = 0x00453b2c
dwNeeded = 8944
GetPrinter Get OK!
pi2->pDevMode->dmDeviceName = EPSON PX-S06 Series
pi2->pPrinterName = EPSON PX-S06 Series
pi2->pPortName = USB001
pi2->pDriverName = EPSON PX-S06 Series
pi2->pPrintProcessor = winprint
pi2->pDatatype = RAW
DocumentProperties Update OK!
SetPrinter NG! e = 5
C:\Users\bg1\Documents\test>
Win32エラーコード一覧
5は『アクセスが拒否されました。』となっている。
でも設定は変わっている。
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bOpen = OpenPrinter(ptszBuf, &hPrinter, &pd);
if (bOpen){
if (hPrinter != NULL){
_tprintf(_T("hPrinter = 0x%08x\n"), (unsigned long)hPrinter);
GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
_tprintf(_T("dwNeeded = %lu\n"), dwNeeded);
if (dwNeeded > 0){
hPrinterInfo2 = GlobalAlloc(GHND, dwNeeded);
if (hPrinterInfo2 != NULL){
pi2 = (PRINTER_INFO_2 *)GlobalLock(hPrinterInfo2);
if (pi2 != NULL){
bRet = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (bRet){
if (pi2->pDevMode != NULL){
_tprintf(_T("GetPrinter Get OK!\n"));
_tprintf(_T("pi2->pDevMode->dmDeviceName = %s\n"), pi2->pDevMode->dmDeviceName);
_tprintf(_T("pi2->pPrinterName = %s\n"), pi2->pPrinterName);
_tprintf(_T("pi2->pPortName = %s\n"), pi2->pPortName);
_tprintf(_T("pi2->pDriverName = %s\n"), pi2->pDriverName);
_tprintf(_T("pi2->pPrintProcessor = %s\n"), pi2->pPrintProcessor);
_tprintf(_T("pi2->pDatatype = %s\n"), pi2->pDatatype);
pi2->pDevMode->dmFields = DM_ORIENTATION;
pi2->pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
lFlag = DocumentProperties(NULL, hPrinter, ptszBuf, pi2->pDevMode, pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag == IDOK){
_tprintf(_T("DocumentProperties Update OK!\n"));
lFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (lFlag > 0){
_tprintf(_T("SetPrinter OK!\n"));
}
else{
DWORD e = GetLastError();
_tprintf(_T("SetPrinter NG! e = %lu\n"), e);
}
}
}
pd.DesiredAccessを、PRINTER_ACCESS_USEから、PRINTER_ALL_ACCESSに変更。
変更はこちらにするべきだったかな。
C:\Users\bg1\Documents\test>SetPrinter.exe
Default Printer: EPSON PX-S06 Series
hPrinter = 0x0061c134
dwNeeded = 17144
GetPrinter Get OK!
pi2->pDevMode->dmDeviceName = EPSON PX-S06 Series
pi2->pPrinterName = EPSON PX-S06 Series
pi2->pPortName = USB001
pi2->pDriverName = EPSON PX-S06 Series
pi2->pPrintProcessor = winprint
pi2->pDatatype = RAW
DocumentProperties Update OK!
SetPrinter NG! e = 87
C:\Users\bg1\Documents\test>
87は、『パラメータが間違っています。』である。
なんでだろう・・・。
実はここまでオフラインだったので接続してオンラインにした。
C:\Users\bg1\Documents\test>SetPrinter.exe
Default Printer: EPSON PX-S06 Series
hPrinter = 0x0057cc24
dwNeeded = 17144
GetPrinter Get OK!
pi2->pDevMode->dmDeviceName = EPSON PX-S06 Series
pi2->pPrinterName = EPSON PX-S06 Series
pi2->pPortName = USB001
pi2->pDriverName = EPSON PX-S06 Series
pi2->pPrintProcessor = winprint
pi2->pDatatype = RAW
DocumentProperties Update OK!
SetPrinter OK!
C:\Users\bg1\Documents\test>
あれ、成功・・・。
オフラインの状態じゃダメなのか・・・。
というわけで、設定変更と印刷を同時に。
#include <windows.h>
#include <tchar.h>
#include <shlwapi.h>
int _tmain(int argc, TCHAR *argv[]){
TCHAR tszModulePath[MAX_PATH] = {0};
HANDLE hFile = NULL;
DWORD dwFileSize = 0;
BYTE *pBytes = NULL;
DWORD dwSize = 0;
TCHAR *ptszBuf = NULL;
BOOL bOpen = FALSE;
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS pd = {0};
DWORD dwNeeded = 0;
HGLOBAL hPrinterInfo2 = NULL;
PRINTER_INFO_2 *pi2 = NULL;
BOOL bRet = FALSE;
TCHAR tszDMDeviceName[CCHDEVICENAME + 64] = {0};
LONG lFlag = 0;
HGLOBAL hDevMode = NULL;
DOC_INFO_1 di1 = {0};
DWORD dwJob = 0;
BOOL bPage = FALSE;
BOOL bWrite = FALSE;
DWORD dwWritten = 0;
GetModuleFileName(NULL, tszModulePath, MAX_PATH);
PathRemoveFileSpec(tszModulePath);
_tcscat(tszModulePath, _T("\\test_text.txt"));
_tprintf(_T("tszModulePath = %s\n"), tszModulePath);
hFile = CreateFile(tszModulePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE){
_tprintf(_T("test_text.txt not found.\n"));
return -1;
}
dwFileSize = GetFileSize(hFile, NULL);
_tprintf(_T("dwFileSize = %lu\n"), dwFileSize);
pBytes = new BYTE[dwFileSize];
ReadFile(hFile, pBytes, dwFileSize, &dwFileSize, NULL);
CloseHandle(hFile);
GetDefaultPrinter(NULL, &dwSize);
ptszBuf = new TCHAR[dwSize];
GetDefaultPrinter(ptszBuf, &dwSize);
_tprintf(_T("Default Printer: %s\n"), ptszBuf);
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bOpen = OpenPrinter(ptszBuf, &hPrinter, &pd);
if (bOpen){
if (hPrinter != NULL){
_tprintf(_T("hPrinter = 0x%08x\n"), (unsigned long)hPrinter);
GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
_tprintf(_T("dwNeeded = %lu\n"), dwNeeded);
if (dwNeeded > 0){
hPrinterInfo2 = GlobalAlloc(GHND, dwNeeded);
if (hPrinterInfo2 != NULL){
pi2 = (PRINTER_INFO_2 *)GlobalLock(hPrinterInfo2);
if (pi2 != NULL){
bRet = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (bRet){
if (pi2->pDevMode != NULL){
_tprintf(_T("GetPrinter Get OK!\n"));
_tprintf(_T("pi2->pDevMode->dmDeviceName = %s\n"), pi2->pDevMode->dmDeviceName);
_tprintf(_T("pi2->pPrinterName = %s\n"), pi2->pPrinterName);
_tprintf(_T("pi2->pPortName = %s\n"), pi2->pPortName);
_tprintf(_T("pi2->pDriverName = %s\n"), pi2->pDriverName);
_tprintf(_T("pi2->pPrintProcessor = %s\n"), pi2->pPrintProcessor);
_tprintf(_T("pi2->pDatatype = %s\n"), pi2->pDatatype);
pi2->pDevMode->dmFields = DM_ORIENTATION;
pi2->pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
lFlag = DocumentProperties(NULL, hPrinter, ptszBuf, pi2->pDevMode, pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag == IDOK){
_tprintf(_T("DocumentProperties Update OK!\n"));
lFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (lFlag > 0){
_tprintf(_T("SetPrinter OK!\n"));
di1.pDocName = _T("StartPagePrinter");
di1.pOutputFile = NULL;
di1.pDatatype = _T("TEXT");
dwJob = StartDocPrinter(hPrinter, 1, (LPBYTE)&di1);
if (dwJob > 0){
_tprintf(_T("dwJob = %lu\n"), dwJob);
bPage = StartPagePrinter(hPrinter);
if (bPage){
bWrite = WritePrinter(hPrinter, pBytes, dwFileSize, &dwWritten);
if (bWrite){
_tprintf(_T("dwFileSize = %lu\n"), dwFileSize);
_tprintf(_T("dwWritten = %lu\n"), dwWritten);
}
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
}
else{
DWORD e = GetLastError();
_tprintf(_T("SetPrinter NG! e = %lu\n"), e);
}
}
}
else{
_tprintf(_T("pi2->pDevMode == NULL!\n"));
dwNeeded = DocumentProperties(NULL, hPrinter, ptszBuf, NULL, NULL, 0);
if (dwNeeded > 0){
hDevMode = GlobalAlloc(GHND, dwNeeded);
if (hDevMode != NULL){
pi2->pDevMode = (DEVMODE *)GlobalLock(hDevMode);
if (pi2->pDevMode != NULL){
lFlag = DocumentProperties(NULL, hPrinter, ptszBuf, pi2->pDevMode, NULL, DM_OUT_BUFFER);
if (lFlag == IDOK){
_tprintf(_T("DocumentProperties Get OK!\n"));
pi2->pDevMode->dmFields = DM_ORIENTATION;
pi2->pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
lFlag = DocumentProperties(NULL, hPrinter, ptszBuf, pi2->pDevMode, pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag == IDOK){
_tprintf(_T("DocumentProperties Update OK!\n"));
lFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (lFlag > 0){
_tprintf(_T("SetPrinter OK!\n"));
di1.pDocName = _T("StartPagePrinter");
di1.pOutputFile = NULL;
di1.pDatatype = _T("TEXT");
dwJob = StartDocPrinter(hPrinter, 1, (LPBYTE)&di1);
if (dwJob > 0){
_tprintf(_T("dwJob = %lu\n"), dwJob);
bPage = StartPagePrinter(hPrinter);
if (bPage){
bWrite = WritePrinter(hPrinter, pBytes, dwFileSize, &dwWritten);
if (bWrite){
_tprintf(_T("dwFileSize = %lu\n"), dwFileSize);
_tprintf(_T("dwWritten = %lu\n"), dwWritten);
}
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
}
else{
DWORD e = GetLastError();
_tprintf(_T("SetPrinter NG! e = %lu\n"), e);
}
}
}
GlobalUnlock(hDevMode);
}
GlobalFree(hDevMode);
}
}
}
}
GlobalUnlock(hPrinterInfo2);
}
GlobalFree(hPrinterInfo2);
}
}
ClosePrinter(hPrinter);
}
}
delete[] ptszBuf;
delete[] ptszBuf;
return 0;
}
これだと、
縦のまま・・・。
ハンドル閉じてないから、設定変更が、印刷に反映されない。
こうすると、
C:\Users\bg1\Documents\test>SetPrinter.exe
tszModulePath = C:\Users\bg1\Documents\test\test_text.txt
dwFileSize = 8562
Default Printer: EPSON PX-S06 Series
hPrinter = 0x005cb76c
dwNeeded = 17144
GetPrinter Get OK!
pi2->pDevMode->dmDeviceName = EPSON PX-S06 Series
pi2->pPrinterName = EPSON PX-S06 Series
pi2->pPortName = USB001
pi2->pDriverName = EPSON PX-S06 Series
pi2->pPrintProcessor = winprint
pi2->pDatatype = RAW
DocumentProperties Update OK!
SetPrinter OK!
hPrinter = 0x005cb76c
dwJob = 4
dwFileSize = 8562
dwWritten = 8562
C:\Users\bg1\Documents\test>
で、
横に設定変更されて印刷もできた。
Sample/winapi/SetPrinter/SetPrinter/src/SetPrinter at master · bg1bgst333/Sample · GitHub