MySetPrinter(), Hilfe für Port C nach PB

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

MySetPrinter(), Hilfe für Port C nach PB

Beitrag von Lord »

Hallo!

Auf der deutschen MS-Seite ist eine Beispiel für die Anwendung von SetPrinter() aufgeführt:
http://support.microsoft.com/kb/140285/de

Diesen versuche ich nach PureBasic zu portieren, was aber nicht so recht gelingen will.

Hier zuerst der Code von der MSDN-Seite:

Code: Alles auswählen

// MySetPrinter
// 
// Demonstrates how to use the SetPrinter API.  This particular function changes the orienation
// 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;
}
Und hier mein Versuch in PureBasic:

Code: Alles auswählen

EnableExplicit
Procedure MySetPrinter(pPrinterName, dmOrientation)
  Protected hPrinter
  Protected dwNeeded
  Global *pi2.PRINTER_INFO_2
  Global *pDevMode.DEVMODE
  Protected pd.PRINTER_DEFAULTS
  Protected bFlag.i
  Protected lFlag.i
  
  pd\DesiredAccess = #PRINTER_ALL_ACCESS
  bFlag = OpenPrinter_(pPrinterName, @hPrinter, pd)
  
  If ( ~bFlag| (hPrinter=0))
    Debug "Fehler: OpenPrinter_()"
    ProcedureReturn #False
  EndIf
  
  SetLastError_(0)
  
  bFlag=GetPrinter_(hPrinter, 2, 0, 0, @dwNeeded)
  
  If (~bflag & (GetLastError_() <> #ERROR_INSUFFICIENT_BUFFER) | (dwNeeded=0))
    ClosePrinter_(hPrinter)
    Debug "Fehler GetPrinter_()"
    ProcedureReturn -1;#False
  EndIf
  
  *pi2=AllocateMemory(dwNeeded)
  If *pi2=0
    ClosePrinter_(hPrinter)
    Debug "Fehler AllocMemomry())"
    ProcedureReturn -2;#False
  EndIf
  
  bFlag=GetPrinter_(hPrinter, 2, *pi2, dwNeeded, @dwNeeded)
  Debug bflag
  If bFlag=0
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    Debug "Fehler GetPrinter_()"
    ProcedureReturn -3;#False
  EndIf
  
  If *pi2\pDevMode = 0
    dwNeeded=DocumentProperties_(0, hPrinter, pPrinterName, 0, 0, 0)
    If dwNeeded<=0
      FreeMemory(*pi2)
      ClosePrinter_(hPrinter)
      Debug "Fehler DocumentProperties_()"
      ProcedureReturn -4;#False
    EndIf
    
    *pDevMode=AllocateMemory(dwNeeded)
    If *pDevMode=0
      FreeMemory(*pi2)
      ClosePrinter_(hPrinter)
      Debug "Fehler AllocMemory()"
      ProcedureReturn -5;#False
    EndIf
    
    
    lFlag=DocumentProperties_(0, hPrinter, pPrinterName, *pDevMode, 0, #DM_OUT_BUFFER)
    If (lFlag<>#IDOK) | (*pDevMode=0)
      FreeMemory(*pDevMode)
      FreeMemory(*pi2)
      ClosePrinter_(hPrinter)
      Debug "Fehler DocumentProperties_()"
      ProcedureReturn -6;#False
    EndIf
    
    *pi2\pDevMode=*pDevMode
    
  EndIf
  
  If (~(*pi2\pDevMode\dmFields & #DM_ORIENTATION))
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler: Änderung nicht unterstützt."
    ProcedureReturn -7,#False
  EndIf
  
  *pi2\pDevMode\dmFields = #DM_ORIENTATION
  *pi2\pDevMode\dmOrientation = dmOrientation
  
  *pi2\pSecurityDescriptor = 0
  
  lFlag=DocumentProperties_(0, hPrinter, pPrinterName, *pi2\pDevMode, *pi2\pDevMode, #DM_IN_BUFFER|#DM_OUT_BUFFER)
  If lFlag<>#IDOK
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler DocumentProperties() 2"
    ProcedureReturn -8;#False
  EndIf
  
  bflag=SetPrinter_(hPrinter, 2, *pi2, 0)
  If ~bFlag
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler SetPrinter_()"
    ProcedureReturn -9;#False
  EndIf
  
  SendMessageTimeout_(#HWND_BROADCAST, #WM_DEVMODECHANGE, 0, pPrinterName, #SMTO_NORMAL, 1000, 0)
  
  
  
  If *pi2
    FreeMemory(*pi2)
  EndIf
  If hPrinter
    ClosePrinter_(hPrinter)
  EndIf
  If *pDevMode
    FreeMemory(*pDevMode)
  EndIf
  
  ProcedureReturn #True
EndProcedure

lpAppName$="WINDOWS"
lpKeyName$="DEVICE"
lpDefault$=""
lpFileName$="Win.Ini"

STDPrinterName$ = Space(#MAX_PATH)
GetPrivateProfileString_(@lpAppName$,@lpKeyName$,@lpDefault$, @STDPrintername$, #MAX_PATH, @lpFileName$)
STDPrintername$ = StringField(STDPrintername$, 1,",")

Debug MySetPrinter(@STDPrinterName$,1)

OpenWindow(0, 10,10,200,200,"")
Repeat
  Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow
Der übersetzte Teil befindet sich in der Prozedur MySetPrinter().

Aktuell bereiten mir diese Zeilen Probleme:

Code: Alles auswählen

	// 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;
Ich habe sie so übersetzt:

Code: Alles auswählen

  If (~(*pi2\pDevMode\dmFields & #DM_ORIENTATION))
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler: Änderung nicht unterstützt."
    ProcedureReturn -7,#False
  EndIf
  
  *pi2\pDevMode\dmFields = #DM_ORIENTATION
  *pi2\pDevMode\dmOrientation = dmOrientation
Die Fehlermeldung beim Kompilieren lautet:
Zeile 233: Verwendung einer undefinierten Struktur:.
Kann mir da einer der C- und API-Gurus helfen, die Prozedur zum Laufen zu bekommen?
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von NicTheQuick »

Statt der Zeile

Code: Alles auswählen

If (~(*pi2\pDevMode\dmFields & #DM_ORIENTATION))
sollte auch eher das hier stehen

Code: Alles auswählen

If (Not (*pi2\pDevMode\dmFields & #DM_ORIENTATION))
Ein Ausrufezeichen (!) in C(++) ist nämlich ein logisches Nicht und deshalb musst du da auch das logische Nicht in PB nehmen.

Und wegen der Struktur: Wenn eine Struktur nicht in PB bekannt ist, musst du sie eben selbst hinzufügen. Ich denke per Google oder MSDN wirst du die originale Speidzifikation schon finden.
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von Lord »

Hallo NicTheQuick!

Danke für Deine Antwort.
NicTheQuick hat geschrieben:Statt der Zeile

Code: Alles auswählen

If (~(*pi2\pDevMode\dmFields & #DM_ORIENTATION))
sollte auch eher das hier stehen

Code: Alles auswählen

If (Not (*pi2\pDevMode\dmFields & #DM_ORIENTATION))
Ein Ausrufezeichen (!) in C(++) ist nämlich ein logisches Nicht und deshalb musst du da auch das logische Nicht in PB nehmen.

Und wegen der Struktur: Wenn eine Struktur nicht in PB bekannt ist, musst du sie eben selbst hinzufügen. Ich denke per Google oder MSDN wirst du die originale Speidzifikation schon finden.
Hätte ich jetzt nicht gedacht, daß das so nicht geht, denn weiter oben
im Code hatte ich das binäre NOT bereits erfolgreich benutzt:

Code: Alles auswählen

  If (~bflag & (GetLastError_() <> #ERROR_INSUFFICIENT_BUFFER) | (dwNeeded=0))
Muß dort auch das logische NOT eingesetzt werden?

Was die fehlende Struktur betrifft, dachte (denke) ich, daß sie bereits
definiert sein muß.
ABBKlaus hatte einen Code gepostet (http://www.purebasic.fr/english/viewtop ... t=pdevmode),
der diese Struktur ebenfalls nutzt, ohne sie im Code definiert zu haben.
Ich muß dort zwar die Zeile

Code: Alles auswählen

          Debug "Size            : "+Str(*pJobInfo\iSize)
korrigieren, da *pJobInfo\iSize wohl *pJobInfo\Size heißen muß, aber
das war wohl nur ein Tippfehler.

Wo finde ich jetzt die fehlende Struktur für PB?

Ich weiß nicht, wie ich die Originalstruktur nach PureBasic
portieren muß:

Code: Alles auswählen

typedef struct _devicemode {
  TCHAR dmDeviceName[CCHDEVICENAME];
  WORD  dmSpecVersion;
  WORD  dmDriverVersion;
  WORD  dmSize;
  WORD  dmDriverExtra;
  DWORD dmFields;
  union {
    struct {
      short dmOrientation;
      short dmPaperSize;
      short dmPaperLength;
      short dmPaperWidth;
      short dmScale;
      short dmCopies;
      short dmDefaultSource;
      short dmPrintQuality;
    };
    struct {
      POINTL dmPosition;
      DWORD  dmDisplayOrientation;
      DWORD  dmDisplayFixedOutput;
    };
  };
  short dmColor;
  short dmDuplex;
  short dmYResolution;
  short dmTTOption;
  short dmCollate;
  TCHAR dmFormName[CCHFORMNAME];
  WORD  dmLogPixels;
  DWORD dmBitsPerPel;
  DWORD dmPelsWidth;
  DWORD dmPelsHeight;
  union {
    DWORD dmDisplayFlags;
    DWORD dmNup;
  };
  DWORD dmDisplayFrequency;
#if (WINVER >= 0x0400)
  DWORD dmICMMethod;
  DWORD dmICMIntent;
  DWORD dmMediaType;
  DWORD dmDitherType;
  DWORD dmReserved1;
  DWORD dmReserved2;
#if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)
  DWORD dmPanningWidth;
  DWORD dmPanningHeight;
#endif 
#endif 
} DEVMODE, *PDEVMODE, *LPDEVMODE;
Ich bin für jede Hilfe dankbar.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von NicTheQuick »

Das mit dem ~bflag ist in dem Fall ja richtig, weil dort in C auch ein ~ (bitweises Nicht) steht. Das (~(*pi2\pDevMode\dmFields & #DM_ORIENTATION)) geht in diesem Fall genau so gut wie mit dem Not, aber in andere Fällen kann das evtl. zu Fehlern führen. Deswegen hab ich dich da korrigiert.

Wegen der Struktur kann ich dir nicht sonderlich gut weiter helfen, weil ich kein Windows nutze, aber alle in PB deklarierten Strukturen findest du im Strukturverzeichnis im Menü "Werkzeuge" der IDE.
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von Lord »

Hallo NicTheQuick!

Nochmals Danke für Deine Hilfestellung.
NicTheQuick hat geschrieben:Das mit dem ~bflag ist in dem Fall ja richtig, weil dort in C auch ein ~ (bitweises Nicht) steht. Das (~(*pi2\pDevMode\dmFields & #DM_ORIENTATION)) geht in diesem Fall genau so gut wie mit dem Not, aber in andere Fällen kann das evtl. zu Fehlern führen. Deswegen hab ich dich da korrigiert.
...
OK.
NicTheQuick hat geschrieben:...
Wegen der Struktur kann ich dir nicht sonderlich gut weiter helfen, weil ich kein Windows nutze, aber alle in PB deklarierten Strukturen findest du im Strukturverzeichnis im Menü "Werkzeuge" der IDE.
Ja, ich habe sie jetzt im Strukturverzeichnis auch gefunden.
Sie ist PB also bekannt.
Warum kann ich dann das Feld *pi2\pDevMode\dmFields nicht ansprechen,
bzw. warum erhalte ich beim Kompilieren die Fehlermeldung, daß die Struktur
undefiniert sei?
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von ts-soft »

Du deklarierst die strukturevariable als Pointer, deshalb wird auch kein Speicher dafür angelegt!
Ich hab mir den Code nicht weiter angesehen, aber Globale Deklaration besser nicht in einer
Procedure deklarieren, sondern im Hauptcode, da diese auch überall gültig ist.

Code: Alles auswählen

Global *pi2.PRINTER_INFO_2 = AllocateMemory(SizeOf(PRINTER_INFO_2))
Global *pDevMode.DEVMODE = AllocateMemory(SizeOf(DEVMODE))
Und Deine ganzen Memorys solltest Du auch, sobald diese nicht mehr gebraucht werden,
freigeben.

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von Lord »

Hallo Thomas!

Wird nicht durch

Code: Alles auswählen

  *pi2=AllocateMemory(dwNeeded)
und

Code: Alles auswählen

    *pDevMode=AllocateMemory(dwNeeded)
jeweils der Speicher angefordert?
Diese werden auch im Fehlerfall und bei Beendigung der
Prozedur freigegeben.
Es ist doch eine 1:1-Übersetzung des C-Codes.

Und die Global-Definition habe ich auch nur deshalb drin,
damit ich mir im Variablen-Viewer diese ansehen kann.
Original sind sie mit Protected deklariert.

Ihr müßt schon entschuldigen, aber mit Pointern, Strukturen
und erst Recht mit "Übersetzungen" von C nach PB habe ich
es bis jetzt eigentlich nicht zu tun gehabt.

Vielleicht kann mir ja doch noch einer helfen. :oops:
Bild
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von Danilo »

Hallo Lord, habe mal einige Stellen korrigiert. '&&' ist in PB 'And', '||' ist in PB 'Or' usw.

Bei der Struktur PRINTER_INFO_2 ist in PB *pDevMode als Zeiger ohne Typ drin, deshalb habe
ich eine Kopie der Struktur genommen und es in *pDevMode.DEVMODE geändert.

Code: Alles auswählen

;
; by Lord
;
; http://support.microsoft.com/kb/140285/de
;
; http://forums.purebasic.com/german/viewtopic.php?f=6&t=26423
;
EnableExplicit

Structure PRINTER_INFO_2_NEW
    *pServerName
    *pPrinterName
    *pShareName
    *pPortName
    *pDriverName
    *pComment
    *pLocation
    *pDevMode.DEVMODE
    *pSepFile
    *pPrintProcessor
    *pDatatype
    *pParameters
    *pSecurityDescriptor.SECURITY_DESCRIPTOR
    Attributes.l
    Priority.l
    DefaultPriority.l
    StartTime.l
    UntilTime.l
    Status.l
    cJobs.l
    AveragePPM.l
EndStructure


; MySetPrinter
; 
; Demonstrates how to use the SetPrinter API.  This particular function changes the orienation
; for the printer specified in pPrinterName to the orientation specified in dmOrientation.
; 
;
; Valid values for dmOrientation are:
; #DMORIENT_PORTRAIT (1)
; or
; #DMORIENT_LANDSCAPE (2)
;
Procedure MySetPrinter(pPrinterName, dmOrientation)
  Protected hPrinter
  Protected dwNeeded
  Protected *pi2.PRINTER_INFO_2_NEW
  Protected *pDevMode.DEVMODE
  Protected pd.PRINTER_DEFAULTS
  Protected bFlag.i
  Protected lFlag.i
  
  pd\DesiredAccess = #PRINTER_ALL_ACCESS
  bFlag = OpenPrinter_(pPrinterName, @hPrinter, pd)
  
  If Not bFlag Or hPrinter=0
    Debug "Fehler: OpenPrinter_()"
    ProcedureReturn #False
  EndIf
  
  SetLastError_(0)
  
  bFlag=GetPrinter_(hPrinter, 2, 0, 0, @dwNeeded)
  
  If Not bflag And (GetLastError_() <> #ERROR_INSUFFICIENT_BUFFER) Or (dwNeeded=0)
    ClosePrinter_(hPrinter)
    Debug "Fehler GetPrinter_()"
    ProcedureReturn -1;#False
  EndIf
  
  *pi2=AllocateMemory(dwNeeded)
  If *pi2=0
    ClosePrinter_(hPrinter)
    Debug "Fehler AllocMemomry())"
    ProcedureReturn -2;#False
  EndIf
  
  bFlag=GetPrinter_(hPrinter, 2, *pi2, dwNeeded, @dwNeeded)
  ;Debug bflag
  If bFlag=0
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    Debug "Fehler GetPrinter_()"
    ProcedureReturn -3;#False
  EndIf
  
  If *pi2\pDevMode = 0
    dwNeeded=DocumentProperties_(0, hPrinter, pPrinterName, 0, 0, 0)
    If dwNeeded<=0
      FreeMemory(*pi2)
      ClosePrinter_(hPrinter)
      Debug "Fehler DocumentProperties_()"
      ProcedureReturn -4;#False
    EndIf
    
    *pDevMode=AllocateMemory(dwNeeded)
    If *pDevMode=0
      FreeMemory(*pi2)
      ClosePrinter_(hPrinter)
      Debug "Fehler AllocMemory()"
      ProcedureReturn -5;#False
    EndIf
    
    
    lFlag=DocumentProperties_(0, hPrinter, pPrinterName, *pDevMode, 0, #DM_OUT_BUFFER)
    If (lFlag<>#IDOK) ;Or (*pDevMode=0)
      FreeMemory(*pDevMode)
      FreeMemory(*pi2)
      ClosePrinter_(hPrinter)
      Debug "Fehler DocumentProperties_()"
      ProcedureReturn -6;#False
    EndIf
    
    *pi2\pDevMode=*pDevMode
    
  EndIf
  
  If Not (*pi2\pDevMode\dmFields & #DM_ORIENTATION)
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler: Änderung nicht unterstützt."
    ProcedureReturn -7;#False
  EndIf
  
  *pi2\pDevMode\dmFields = #DM_ORIENTATION
  *pi2\pDevMode\dmOrientation = dmOrientation
  
  *pi2\pSecurityDescriptor = 0
  
  lFlag=DocumentProperties_(0, hPrinter, pPrinterName, *pi2\pDevMode, *pi2\pDevMode, #DM_IN_BUFFER|#DM_OUT_BUFFER)
  If lFlag<>#IDOK
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler DocumentProperties() 2"
    ProcedureReturn -8;#False
  EndIf
  
  bflag=SetPrinter_(hPrinter, 2, *pi2, 0)
  If Not bFlag
    FreeMemory(*pi2)
    ClosePrinter_(hPrinter)
    If *pDevMode
      FreeMemory(*pDevMode)
    EndIf
    Debug "Fehler SetPrinter_()"
    ProcedureReturn -9;#False
  EndIf
  
  SendMessageTimeout_(#HWND_BROADCAST, #WM_DEVMODECHANGE, 0, pPrinterName, #SMTO_NORMAL, 1000, 0)
  
  
  
  If *pi2
    FreeMemory(*pi2)
  EndIf
  If hPrinter
    ClosePrinter_(hPrinter)
  EndIf
  If *pDevMode
    FreeMemory(*pDevMode)
  EndIf
  
  ProcedureReturn #True
EndProcedure



Define lpAppName$="WINDOWS"
Define lpKeyName$="DEVICE"
Define lpDefault$=""
Define lpFileName$="Win.Ini"
Define STDPrinterName$ = Space(#MAX_PATH)
Define Event

GetPrivateProfileString_(@lpAppName$,@lpKeyName$,@lpDefault$, @STDPrintername$, #MAX_PATH, @lpFileName$)
STDPrintername$ = StringField(STDPrintername$, 1,",")

Debug STDPrintername$
Debug MySetPrinter(@STDPrinterName$,#DMORIENT_PORTRAIT)

OpenWindow(0, 10,10,200,200,"")
Repeat
  Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Lord
Beiträge: 324
Registriert: 21.01.2008 19:11

Re: MySetPrinter(), Hilfe für Port C nach PB

Beitrag von Lord »

Hallo Danilo!

Danke für die ausführliche Hilfe.

Da habe ich ja doch nicht soviel falsch gemacht
bei meinem ersten Versuch. Es funktioniert jetzt
jedenfalls prima.
Bild
Antworten