Jump to content
Sign in to follow this  
Akarillon

Adding a new printer, AutoIT bugs[Solved]

Recommended Posts

I am trying to add a printer via the network share \\winprint($OS)\$printername

But it seems like when the program gets to RegRead(to check if the printer is correctly added) it stops working and I have to exit the script by force.

The program running got to be exited via the task manager(Autoit3Wrapper.exe*32)

Really need this to work =)

$CurrentOS = 0
$Printer = 0
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
  Case $GUI_EVENT_CLOSE
   Exit
  Case $Start
   $Printer = GUICtrlRead($Input)
   If GUICtrlRead(7) = "Windows XP" Then
    $CurrentOS = 2
   ElseIf GUICtrlRead(7) = "Windows Vista" Then
    $CurrentOS = 2
   ElseIf GUICtrlRead(7) = "Windows 7" Then
    $CurrentOS = 64
   EndIf
   _RunDOS('start \\winprint' & $CurrentOS & '\' & $Printer & '')
   RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices', '\\winprint' & $CurrentOS & '\' & $Printer & '')
   If @error Then
    MsgBox(0, "Error", 'Error' & @error & ' appeared.' & @CRLF & 'Please contact edb@kjemi.uio.no.')
   Else
    MsgBox(0, "Done", "Printer should have been added successfully!")
   EndIf
  Case $Exit
   Exit
EndSwitch
WEnd

Kind Regards,

Akarillon

Edited by Akarillon

Challenge accepted!

Share this post


Link to post
Share on other sites

no.. the line should say exactly:

\\winprint64\kj_vu18

This is an example of the printer kj_vu18 on a server that does 64bit drivers


Challenge accepted!

Share this post


Link to post
Share on other sites

I found the error I think.

When I go into the task manager I can end 2 processes.

And 1 is the AutoIt3Wrapper.exe*32 and the other is cmd.exe

When I ended cmd.exe before AutoIt3Wrapper.exe*32 the script finished.

So is it safe(stable) to add a ProcessEnd in the middle of the script?


Challenge accepted!

Share this post


Link to post
Share on other sites

I have a old script that may give you some ideas.

#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Process.au3>
#include <Array.au3>
$g_szVersion = "PrintInst.exe"
If WinExists($g_szVersion) Then Exit
Opt("TrayIconDebug", 1) ;debug is on

Dim $hService, _
        $data, _
        $sPrinter, _
        $sPrinterList, _
        $font = "Comic Sans MS", _
        $Input[12], $Combo[7], $radio[7], _
        $check[11], $Button[6]

Global Enum Step + 25 _
        $CON_POS_1 = 25, _
        $CON_POS_2, _
        $CON_POS_3, _
        $CON_POS_4, _
        $CON_POS_5, _
        $CON_POS_6, _
        $CON_POS_7, _
        $CON_POS_8, _
        $CON_POS_9, _
        $CON_POS_10, _
        $CON_POS_11

GUICreate("", 600, 290, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS))
GUICtrlCreateLabel("\\", 20, 54, 10, 20)
$iniread_1 = IniRead(@ScriptDir & "/npu.ini", "SERVER", "SERVER", "")
$iniread_2 = IniRead(@ScriptDir & "/npu.ini", "Printers", "PLIST", "")
iniwrite(@ScriptDir & "/npu.ini", "Printers", "LOCAL", "")
$iniread_3 = IniRead(@ScriptDir & "/npu.ini", "Printers", "LOCAL", "")
$LocalPrinters = StringSplit($iniread_3, "|")
If $LocalPrinters[0] > 10 Then
    ReDim $LocalPrinters[11]
EndIf

$Input[1] = GUICtrlCreateInput($iniread_1, 35, 50, 100, 20)

For $i = 2 To 11
    $Input[$i] = GUICtrlCreateInput("", 270, Eval("CON_POS_" & $i - 1), 270, 21)
    If ($i - 1) <= $LocalPrinters[0]Then
        GUICtrlSetData(-1, $LocalPrinters[$i - 1])
    EndIf
Next

For $i = 1 To 6
    $Combo[$i] = GUICtrlCreateCombo("", 20, Eval("CON_POS_" & $i + 2), 170, 21)
    GUICtrlSetData(-1, $iniread_2)
    $radio[$i] = GUICtrlCreateRadio("", 210, Eval("CON_POS_" & $i + 2), 15, 21)
Next

For $i = 1 To 10
    $check[$i] = GUICtrlCreateCheckbox("", 550, Eval("CON_POS_" & $i), 20, 20)
Next

GUICtrlCreateLabel("Currently install printers", 270, 3, 200, 21)
GUICtrlCreateLabel("Delete", 550, 7, 100, 21)
GUICtrlCreateGroup("Default", 200, 62, 50, 160)

$Button[1] = GUICtrlCreateButton("Run", 20, 225, 35, 30)
$Button[2] = GUICtrlCreateButton("Exit", 65, 225, 35, 30)
$Button[3] = GUICtrlCreateButton("Find", 146, 50, 43, 20)
$Button[4] = GUICtrlCreateButton("Find", 498, 3, 43, 20)
$Button[5] = GUICtrlCreateButton("Restart Spooler", 110, 225, 80, 30)

$Label_1 = GUICtrlCreateLabel("   Network Printer Utility" & @CRLF & "for Windows Print Servers", 20, 0, 240, 50)
GUICtrlSetFont(-1, 10, 400, "", $font)
$Label_2 = GUICtrlCreateLabel("2006 CTS Scripting Team", 40, 270, 130, 25)
$_dummy = GUICtrlCreateDummy()

GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $Button[1]
            _Rprinter()
            _instprint()
            MsgBox(0, "", "Done!", 3)
        Case $Button[2]
            ExitLoop
        Case $Button[3]
            $data = GUICtrlRead($Input[1], 0)
            _netprint1()
        Case $Button[4]
            _getinstalledPrinters()
        Case $Button[5]
            _restart()
        Case Else
            ;;;
    EndSwitch
WEnd

Exit

Func _netprint1()
    $hService = ObjGet("winmgmts:{impersonationLevel=impersonate}!" & "\\" & $data & "\root\cimv2")
    If @error Then
        MsgBox(48, "ERROR", "No Printers Found. Possible issues: " & @CRLF _
                 & "" & @CRLF _
                 & "  1. The Windows Print Server name has been entered in incorrectly." & @CRLF _
                 & "  2. You are trying to access a Novell Server. This utility does not support Novell Print Servers." & @CRLF _
                 & "  3. There are no printers shared on the Windows Print Server you selected.")
    Else
        _np2()
    EndIf
EndFunc   ;==>_netprint1

Func _np2()
    Local $i = 0
    Local $sPrinters = ""
    Local $aArray[1]

    SplashTextOn("", "Gathering printers, please wait...", 150, 75)

    For $y = 1 To 6
        GUICtrlSetData($Combo[$y], "")
    Next
    IniWrite(@ScriptDir & "/npu.ini", "Printers", "PLIST", "")

    $oPrinterList = $hService.ExecQuery ("Select * From Win32_Printer")

    For $oPrinter In $oPrinterList
        ReDim $aArray[$i + 1]
        $aArray[$i] = StringUpper($oPrinter.name)
        $i += 1
    Next

    _ArraySort($aArray)

    For $i = 0 To UBound($aArray)-1
        For $y = 1 To 6
            GUICtrlSetData($Combo[$y], $aArray[$i])
        Next
    Next

    $iElements = UBound($aArray) - 1
    For $x = 0 To $iElements
        If $x = $iElements Then
            $sPrinters &= $aArray[$x]
        Else
            $sPrinters &= $aArray[$x] & "|"
        EndIf
    Next

    IniWrite(@ScriptDir & "/npu.ini", "Printers", "PLIST", $sPrinters)
    $dataget2 = GUICtrlRead($Input[1], 0)
    IniWrite(@ScriptDir & "/npu.ini", "SERVER", "SERVER", $dataget2)
    SplashTextOn("", "Select what printers you wish to install", 150, 75)
    Sleep(2000)
    SplashOff()
EndFunc   ;==>_np2

Func _instprint()
    Local $ComboGet[7], $RadioGet[7]

    SplashTextOn("", "Installing printer, please wait...", 150, 75)

    $InputGet = GUICtrlRead($Input[1], 0)

    For $i = 1 To 6
        $ComboGet[$i] = GUICtrlRead($Combo[$i], 0)
        $RadioGet[$i] = GUICtrlRead($radio[$i], 0)
    Next

    For $i = 1 To 6
        If $ComboGet[$i] <> "" Then
            RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /ga /c\\" & @ComputerName & " /n\\" & $InputGet & "\" & $ComboGet[$i])
        EndIf
    Next
    _RunDOS("NET STOP spooler")
    _RunDOS("NET START spooler")
    sleep(10000)
    For $i = 1 To 6
            If $RadioGet[$i] = 1 Then
                If $ComboGet[$i] <> "" Then
                RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /y /n\\"&$iniread_1&"\"& $ComboGet[$i])
                endif
            EndIf
            GUICtrlSetData($Combo[$i],"")
            GUICtrlSetState($radio[$i], $GUI_UNCHECKED)
            sleep(50)
            GUICtrlSetData($Combo[$i],$iniread_2)
    Next
    SplashOff()
EndFunc   ;==>_instprint

func _restart()
    SplashTextOn("", "Stopping Print Spooler, please wait...", 150, 75)
    _RunDOS("NET STOP spooler")
    SplashOff()
    SplashTextOn("", "Starting Print Spooler, please wait...", 150, 75)
    _RunDOS("NET START spooler")
    SplashOff()
EndFunc

Func _getinstalledPrinters()

    SplashTextOn("", "Gathering installed printers, please wait...", 200, 75)

    IniWrite(@ScriptDir & "/npu.ini", "Printers", "LOCAL", "")
    $hService = ObjGet("winmgmts:{impersonationLevel=impersonate}!" & "\\" & @ComputerName & "\root\cimv2")
    $sPrinterList = $hService.ExecQuery ("Select * From Win32_Printer")
    ConsoleWrite('$sPrinterList.count = ' & $sPrinterList.count & @LF)
    For $sPrinter In $sPrinterList
        ConsoleWrite('$sPrinter.name = ' & $sPrinter.name & @LF)
        $rd3 = IniRead(@ScriptDir & "/npu.ini", "Printers", "LOCAL", "")
        IniWrite(@ScriptDir & "/npu.ini", "Printers", "LOCAL", $rd3 & $sPrinter.name & "|")
    Next
    $local = StringSplit(IniRead(@ScriptDir & "/npu.ini", "Printers", "LOCAL", ""), "|")
    If UBound($local) < 11 Then ReDim $local[11]
    For $i = 1 To 10
        GUICtrlSetData($Input[$i + 1], $local[$i])
    Next

    SplashOff()
EndFunc   ;==>_getinstalledPrinters

Func _Rprinter()
    Local $InputGet[11]
    For $i = 2 To 11
        $InputGet[$i - 1] = GUICtrlRead($Input[$i])
    Next
    For $i = 1 To 10
        If GUICtrlRead($check[$i]) = 1 Then
            SplashTextOn("", "Removing printer, please wait...", 150, 50)
            GUICtrlSetState($check[$i], $GUI_UNCHECKED)
            sleep(1000)
            If $InputGet[$i] <> "" Then
                $str = StringLeft($InputGet[$i], 2)
                If $str = "\\" Then
                    RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /gd /dn /n /c\\" & @ComputerName & " /n" & $InputGet[$i])
                    ;RunWait(@SystemDir & "\RUNDLL32 PRINTUI.DLL,PrintUIEntry /gd /q /c\\" & @ComputerName & " /n" & $InputGet[$i]) ;mine original
                    ;RunWait(@ComSpec & ' /c RUNDLL32 PRINTUI.DLL,PrintUIEntry /gd /dn /q /n "' & $ret & '"', '', @SW_HIDE) ;danny35
                    GUICtrlSetData($InputGet[$i], "")
                Else
                    RunWait(@SystemDir & '\RUNDLL32 PRINTUI.DLL,PrintUIEntry /dl /q /n "' & $InputGet[$i] & '" /c\\' & @ComputerName)
                EndIf
            EndIf
        EndIf
    Next

EndFunc   ;==>_Rprinter

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By argumentum
      #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $edit, $GuiChild = 0 GuiExample() Func GuiExample() ; https://www.autoitscript.com/forum/topic/202986-parent-child-guis-and-input-control-fails/ Local $GuiMain = GUICreate("GuiExample w/child (parent)", 350, 300) GUISetOnEvent($GUI_EVENT_CLOSE, "GuiOnEvent_CLOSE", $GuiMain) GUISetState(@SW_SHOW, $GuiMain) $edit = GUICtrlCreateEdit("", 10, 70, 300, 200) ; It does not matter what GUI is on, GUICtrlSetData($edit, "play around with the inputs" & _ ; the parent's controls will @CRLF & "and press enter." & _ ; bleed through a $WS_CHILD gui. @CRLF & @CRLF & "It should trigger the" & _ @CRLF & " GUICtrlSetOnEvent()") GUICtrlCreateButton("reload alt.", 225, 40, 120, 25) ; run alternate versions, GUICtrlSetOnEvent(-1, "OnBttnRunAlt") ; with and without child GUI. GUICtrlSetTip(-1, "run alternate versions," & @LF & "with and without child GUI.") ;I need this child(s), but with it, it does not behave as expected. ;..for this test you can comment it out, to see that it should work. ;..but with the child, instead it executes after clicking another control. If Not StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then $GuiChild = GUICreate("GuiExample w/child (child)", 320, 280, 5, 5, $WS_CHILD, $WS_TABSTOP, $GuiMain) EndIf If $GuiChild Then GUISetBkColor(0x888888, $GuiChild) ; for the dramatic effect :) If $GuiChild Then GUISwitch($GuiChild) ; ..just in case.. tho should not matter. GUICtrlCreateInput("This text 1", 5, 10, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) GUICtrlSetOnEvent(-1, "OnInputEnterKeyOne") GUICtrlCreateInput("This text 2", 5, 35, 200, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_WANTRETURN)) GUICtrlSetOnEvent(-1, "OnInputEnterKeyTwo") If $GuiChild Then GUICtrlCreateButton("flash child", 220, 8, 120, 25) GUICtrlSetOnEvent(-1, "OnFlashBttn") GUISetState(@SW_SHOW, $GuiChild) OnFlashBttn() EndIf MainLoopExample() EndFunc Func MainLoopExample() While 1 Sleep(100) WEnd EndFunc Func OnInputEnterKeyOne() GUICtrlSetData($edit, @SEC &'.' & @MSEC& ' - Func OnInputEnterKey One ()' & @CRLF) EndFunc Func OnInputEnterKeyTwo() GUICtrlSetData($edit, @SEC &'.' & @MSEC& ' - Func OnInputEnterKey Two ()' & @CRLF) EndFunc Func OnFlashBttn() WinSetTrans($GuiChild, "", 50) Sleep(300) WinSetTrans($GuiChild, "", 255) EndFunc Func OnBttnRunAlt() If StringInStr($CmdLineRaw, "/ExampleOnlyParent") Then ShellExecute(@ScriptFullPath, "") Else ShellExecute(@ScriptFullPath, "/ExampleOnlyParent") EndIf GuiOnEvent_CLOSE() EndFunc Func GuiOnEvent_CLOSE() GUIDelete() Exit EndFunc I need this child(s), but with it, it does not behave as expected.
      ..for this test you can comment the child GUI out, to see that it should work.
      With the child, instead it executes after clicking another control.
      Thanks
      Edit: Modified the example for dramatic effect  
      Edit 2: Solved my problems at a post somewhere down this thread.
    • By EmilyLove
      What is Rollbar?
      Rollbar provides real-time error alerting & debugging tools for developers. Learn more about it at https://rollbar.com/product/
      Demo: https://rollbar.com/demo/demo/
      Screenshot:
      Instructions: (RollbarTest.au3)
      ; Include RollbarSDK #include "RollbarSDK.au3" ;Turns on ConsoleWrite debugging override. ;Global $Rollbar_Debug=False ; Initialize RollbarSDK with the project's API key. ; Parameters ....: $__Rollbar_sToken - [Required] Go to https://rollbar.com/<User>/<ProjectName>/settings/access_tokens/ for your project. Use the token for post_server_item. _Rollbar_Init("eaa8464a4082eeabd9454465b8f0c0af") ; Write code that causes an error you want to catch, then call ; _Rollbar_Send ; Parameters ....: $__Rollbar_sErrorLevel - [Required] Must be one of the following values: Debug, Info, Warning, Error, Critical. ; $__Rollbar_sMessage - [Required] The message to be sent. This should contain any useful debugging info that will help you debug. ; $__Rollbar_sMessageSummary - [Optional] A string that will be used as the title of the Item occurrences will be grouped into. Max length 255 characters. If omitted, Rollbar will determine this on the backend. _Rollbar_Send("Debug", "This is an debug message. If you received this, you were successful!", "Debug Message") _Rollbar_Send("Info", "This is a test message. If you received this, you were successful!", "Info Message") _Rollbar_Send("Warning", "This is an warning message. If you received this, you were successful!", "Warning Message") _Rollbar_Send("Error", "This is an error message. If you received this, you were successful!", "Error Message") _Rollbar_Send("Critical", "This is an critical message. If you received this, you were successful!", "Critical Message") _Rollbar_Send("Info", "This is a test message. If you received this, you were successful!") ;No Message ; Rollbar_Send's helper functions ; Parameters ....: $__Rollbar_sMessage - [Required] The message to be sent. This should contain any useful debugging info that will help you debug. ; $__Rollbar_sMessageSummary - [Optional] A string that will be used as the title of the Item occurrences will be grouped into. Max length 255 characters. If omitted, Rollbar will determine this on the backend. _Rollbar_SendDebug("This is an debug message. If you received this, you were successful!", "Debug Message") _Rollbar_SendInfo("This is a test message. If you received this, you were successful!", "Info Message") _Rollbar_SendWarning("This is an warning message. If you received this, you were successful!", "Warning Message") _Rollbar_SendError("This is an error message. If you received this, you were successful!", "Error Message") _Rollbar_SendCritical("This is an critical message. If you received this, you were successful!", "Critical Message") ; Usable Example Local $sImportantFile = "C:\NOTAREALFILE_1234554321.txt" Switch FileExists($sImportantFile) Case True MsgBox(0, "Example Script", "An important file was found. Continuing...") Case Else _Rollbar_SendCritical('An important file was missing. Halting... File: "' & $sImportantFile & '"', 'Important file "' & $sImportantFile & '" is missing.') EndSwitch Notes: Please comment your feedback, advice, & suggestions below. While this is only a proof of concept, I will expand its feature set for everyone to use. 
      Right now, it is fully functional but not tested in production.
       
       
      Changelog:
      RollbarSDK.au3
      RollbarTest.au3
      v0.2
       
      v0.1.1
       
    • By qsek
      Im not sure if this is intended but normally Autoit variables are always passed as copies (except objects i think).
      But below i observed an unconsistency when copying maps with nested maps inside.
      Issue:
      If you create a nested map1 and copy it to a new map2, changing a nested value in map2 will also change the nested value in map1
      Dim $player[] Dim $sub[] $player.test1 = 1 $player.test2 = $sub $player.test2.child1 = "org" $player.test2.childext = $sub $player.test2.childext.child1 = "org2" $playerold = $player ; make a copy of the whole map ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF); original nested value in $player $playerold.test2.child1 = "changed" ; edit a nested value in $playerold ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF) ; original nested value in $player changed ConsoleWrite("---------------------" & @CRLF) ConsoleWrite("player.test2.childext.child1 : "& $player.test2.childext.child1 & @CRLF); original level2 nested value in $player $playerold.test2.childext.child1 = "changed2" ; edit a level2 nested value in $playerold ConsoleWrite("player.test2.child1 : "& $player.test2.child1 & @CRLF); original level1 nested value in $player stayed the same ConsoleWrite("player.test2.childext.child1 : "& $player.test2.childext.child1 & @CRLF); original level2 nested value in $player changed  
    • By EmilyLove
      As the title says, when a script that is stored on a Google Drive File Stream drive is ran or compiled, it fails to work at all.
      Basically, Google Drive File Stream creates a G:\ drive where you can access all your files. The difference between this and Google Backup and Sync is your files are downloaded as needed rather than they always be downloaded and taking up storage. 
      How to Reproduce Bug
      1. Download and Install Google Drive File Stream
      2. Sign into Google Drive File Stream with a G Suite account. 
      3. Create a AutoIt Script and save it to Google Drive File Stream. (See attached file)
      4. Attempt to run or compile this AutoIt Script. 
       
      AutoIt appears to act like the script is (incorrectly) empty and ends immediately. (You can kind of tell based on file sizes from a successful and failed compile).
      I've also attached a Process Monitor log file. Hopefully someone can figure this out, because having to move the script out of the drive just to run or compile it is super annoying and I lose version revisioning Google Drive provides me.
      test.au3
      Logfile.PML
    • By AndyS19
      I am trying to print using a small font, but no mater how I try it, the printed font remains unchanged.
      I have created a sample script that sets the font to 8.
      Here are the functions I use to create, then set the font:
      Func _Printer_SetFont($hDC) Local $hFont If ($a__Printer_Font == 0) Then _Printer_MakeFont() EndIf $hFont = $a__Printer_Font _LogMsg("+++: $hDC & " & $hDC & ", $hFont = " & $hFont) _WinAPI_SetFont($hDC, $hFont) ; <===================== EndFunc ;==>_Printer_SetFont Func _Printer_MakeFont() Local $hFontDC, $err, $errm, $str, $flag, $iHeight $flag = $FW_BOLD $iHeight = 8 $hFontDC = _WinAPI_CreateFont( _ $iHeight, _ 0, _ ; average character width 0, _ ; angle of escape 0, _ ; base-line orientation $flag, _ ; font weight - $FW_NORMAL, $FW_BOLD, etc. False, _ ; italic False, _ ; underline False, _ ; strikeout $DEFAULT_CHARSET, _ ; the character set $OUT_DEFAULT_PRECIS, _ ; the output precision $CLIP_DEFAULT_PRECIS, _ ; the clipping precision $DEFAULT_QUALITY, _ ; the output quality 0, _ ; the pitch and family of the font "courier new") ; typeface name _LogMsg("+++: $hFontDC = 0x" & Hex($hFontDC)) If ($hFontDC <= 0) Then $str = "_WinAPI_CreateFont() failed." & @CRLF $err = _WinAPI_GetLastError() $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: " & $err & ", 0) - '" & $errm & "'" & @CRLF & $str) Exit (9) EndIf $a__Printer_Font = $hFontDC EndFunc ;==>_Printer_MakeFont Here is the complete script:
      #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 Opt('MustDeclareVars', 1) #include <APIDlgConstants.au3> #include <FontConstants.au3> #include <WinAPI.au3> ; #VARIABLES# ================================================================ Global $i__LastLineNum = -1, $i__NextLineNum = -1, $i__ThisLineNum = -1 Global $i__LeftMargin_X, $i__TopMargin_Y, $i__PageWidth, $i__PageHeight Global $i__CurrentPos_X, $i__CurrentPos_Y Global $i__Printer_Char_H = -1, $i__Printer_Char_W = -1 Global $a__Printer_Font = 0 Global $i__x_start, $i__x_end, $i__y_start, $i__y_end ; ============================================================================ ; #CONSTANTS# ================================================================ Global $PHYSICALWIDTH = 110, $PHYSICALHEIGHT = 111 Global $PHYSICALOFFSETX = 112, $PHYSICALOFFSETY = 113 Const $VLINESPACE = 20 ; Number of pixels between lines Global Const $tagPD = "align 1;DWORD lStructSize;" & "HWND hwndOwner;" & "handle hDevMode;" & "handle hDevNames;" & _ "handle hDC;" & "DWORD Flags;" & _ "WORD nFromPage;" & "WORD nToPage;" & "WORD nMinPage;" & "WORD nMaxPage;" & "WORD nCopies;" & _ "handle hInstance;" & "LPARAM lCustData;" & "ptr lpfnPrintHook;" & "ptr lpfnSetupHook;" & _ "ptr lpPrintTemplateName;" & "ptr lpSetupTemplateName;" & "handle hPrintTemplate;" & "handle hSetupTemplate" Global Const $tagDOCINFO = "int Size;" & "ptr DocName;" & "ptr Output;" & "ptr Datatype;" & "dword Type" ; ============================================================================ _Main() Func _Main() Local $hDC, $str, $str2 = "", $linenum $hDC = _Printer_Open(0, Default, "DOCNAME: ++++") _LogMsg("+++: $hPrintDc = 0x" & Hex($hDC)) If (Not $hDC) Then Exit (1) _Printer_SetFont($hDC) For $y = 1 To 10 $str2 &= "123456789." Next $linenum = 30 ; Start in the middle of the page For $x = 1 To 15 $str = "[" & $x & " " & $str2 _LogMsg("+++: $str ==>" & $str & "<==") _Printer_PrintTextLine($hDC, $str, $linenum) $linenum += 1 Next _Printer_Close($hDC) EndFunc ;==>_Main Func _Printer_SetFont($hDC) Local $hFont If ($a__Printer_Font == 0) Then _Printer_MakeFont() EndIf $hFont = $a__Printer_Font _LogMsg("+++: $hDC & " & $hDC & ", $hFont = " & $hFont) _WinAPI_SetFont($hDC, $hFont) ; <===================== EndFunc ;==>_Printer_SetFont Func _Printer_MakeFont() Local $hFontDC, $err, $errm, $str, $flag, $iHeight $flag = $FW_BOLD $iHeight = 8 $hFontDC = _WinAPI_CreateFont( _ $iHeight, _ 0, _ ; average character width 0, _ ; angle of escape 0, _ ; base-line orientation $flag, _ ; font weight - $FW_NORMAL, $FW_BOLD, etc. False, _ ; italic False, _ ; underline False, _ ; strikeout $DEFAULT_CHARSET, _ ; the character set $OUT_DEFAULT_PRECIS, _ ; the output precision $CLIP_DEFAULT_PRECIS, _ ; the clipping precision $DEFAULT_QUALITY, _ ; the output quality 0, _ ; the pitch and family of the font "courier new") ; typeface name _LogMsg("+++: $hFontDC = 0x" & Hex($hFontDC)) If ($hFontDC <= 0) Then $str = "_WinAPI_CreateFont() failed." & @CRLF $err = _WinAPI_GetLastError() $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: " & $err & ", 0) - '" & $errm & "'" & @CRLF & $str) Exit (9) EndIf $a__Printer_Font = $hFontDC EndFunc ;==>_Printer_MakeFont Func _Printer_Open($hGUI = 0, $iFlags = Default, $sDocName = "") Local $hDC, $tPD, $err If $iFlags = Default Then $iFlags = 0 $iFlags = BitOR($iFlags, $PD_RETURNDC) $iFlags = BitOR($iFlags, $PD_USEDEVMODECOPIESANDCOLLATE) EndIf $tPD = DllStructCreate($tagPD) DllStructSetData($tPD, "lStructSize", DllStructGetSize($tPD)) DllStructSetData($tPD, "hwndOwner", $hGUI) ; If $hGUI <> 0 Then DllStructGetData($tPD, "hInstance", _WinAPI_GetModuleHandle("")) EndIf DllStructSetData($tPD, "Flags", $iFlags) DllStructSetData($tPD, "nCopies", 2) Local $bRet = DllCall("Comdlg32.dll", "int", "PrintDlgW", "ptr", DllStructGetPtr($tPD)) $err = @error If $err Then $err = _WinAPI_GetLastError() Local $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: _Printer_Open() returns: (1, " & $err & ", 0) - '" & $errm & "'") $tPD = 0 Return SetError(1, $err, 0) EndIf If $bRet[0] = True Then $hDC = DllStructGetData($tPD, "hDC") Else Return SetError(2, $err, 0) EndIf $tPD = 0 __Printer_SetupCharWH($hDC) _Printer_GetMetrics($hDC) _Printer_Startup($hDC, $sDocName) Return (SetError(0, 0, $hDC)) EndFunc ;==>_Printer_Open Func _Printer_Startup($hDC, $sDocName) Local $oDocNameStruct, $DOCINFO, $printJobID, $errstr __Printer_SetupCharWH($hDC) ; Get the height and width of a printer character $oDocNameStruct = DllStructCreate("char DocName[" & StringLen($sDocName & Chr(0)) & "]") DllStructSetData($oDocNameStruct, "DocName", $sDocName & Chr(0)) ; Size of DOCINFO structure $DOCINFO = DllStructCreate($tagDOCINFO) ; Structure for Print Document info DllStructSetData($DOCINFO, "Size", 20) ; Size of DOCINFO structure DllStructSetData($DOCINFO, "DocName", DllStructGetPtr($oDocNameStruct)) ; Set name of print job (Optional) _Printer_GetMetrics($hDC) $printJobID = _Printer_StartDoc($hDC, $DOCINFO) ; start new print doc If ($printJobID <= 0) Then $errstr = "_Printer_StartDoc() failed" _LogMsg("+++: _Printer_Startup() returns: @error = 1 - " & $errstr) Return (SetError(1, 0, $errstr)) EndIf Return (SetError(0, 0, $printJobID)) ; print job ID EndFunc ;==>_Printer_Startup Func _Printer_Close($hDC) _Printer_EndPage($hDC) ; End the currend page _Printer_EndDoc($hDC) ; End the print job _WinAPI_DeleteDC($hDC) ; Delete the printer device context EndFunc ;==>_Printer_Close Func _Printer_EndPage($hDC) Local $aResult If ($i__ThisLineNum > 1) Then $aResult = DllCall("GDI32.dll", "long", "EndPage", "hwnd", $hDC) EndIf _Printer_SetInitial_XY() $i__ThisLineNum = -1 Return ($aResult[0]) EndFunc ;==>_Printer_EndPage Func _Printer_EndDoc($hDC) Local $aResult $aResult = DllCall("GDI32.dll", "long", "EndDoc", "hwnd", $hDC) Return ($aResult[0]) EndFunc ;==>_Printer_EndDoc Func _Printer_TextOut($hDC, $iXStart, $iYStart, $sString) Local $aResult $aResult = DllCall("GDI32.dll", _ "long", "TextOut", _ "hwnd", $hDC, _ "long", $iXStart, _ "long", $iYStart, _ "str", $sString, _ "long", StringLen($sString)) Return $aResult[0] ; 0 = fail, 1 = OK EndFunc ;==>_Printer_TextOut Func _Printer_PrintTextLine($hDC, $sText, $iLineNumber = -1) Local $ret, $lines, $ndx If ($iLineNumber <= 0) Then $iLineNumber = $i__ThisLineNum EndIf $sText = StringStripWS($sText, 2) ; Clear trailing whitespace ; Break text into an array of lines, based on any of the ; usual line endings (@CR, @LF, etc.) found in the string. $sText = StringRegExpReplace($sText, "[\\][n]", @CR) $sText = StringReplace($sText, @CRLF, @LF) $sText = StringReplace($sText, @CR, @LF) While (StringRight($sText, 1) == @LF) StringTrimRight($sText, 1) ; remove trailing LF's WEnd $lines = StringSplit($sText, @LF, 2) ; Now print each line in the array of lines, advancing the ; printer line position each time For $ndx = 0 To UBound($lines) - 1 $i__CurrentPos_X = $i__x_start ; $i__LeftMargin_X $i__CurrentPos_Y = (($i__Printer_Char_H + $VLINESPACE) * $iLineNumber) + $i__y_start $ret = _Printer_TextOut($hDC, $i__CurrentPos_X, $i__CurrentPos_Y, $lines[$ndx]) $iLineNumber += 1 $i__ThisLineNum += 1 If ($ret == 0) Then ExitLoop If ($iLineNumber > $i__LastLineNum) Then _Printer_EndPage($hDC) $iLineNumber = 1 $i__ThisLineNum = 1 EndIf Next ; Calculate next x/y position $i__CurrentPos_Y = (($i__Printer_Char_H + $VLINESPACE) * $iLineNumber) Return (SetError(0, 0, $iLineNumber)) EndFunc ;==>_Printer_PrintTextLine Func _Printer_StartDoc($hDC, $tDocInfo) Local $aResult $aResult = DllCall("GDI32.dll", "long", "StartDoc", "hwnd", $hDC, "ptr", DllStructGetPtr($tDocInfo)) _Printer_SetInitial_XY() Return ($aResult[0]) ; >0 = OK, <=0 = Fail EndFunc ;==>_Printer_StartDoc Func _Printer_GetMetrics($hDC) $i__LeftMargin_X = _WinAPI_GetDeviceCaps($hDC, $PHYSICALOFFSETX) $i__TopMargin_Y = _WinAPI_GetDeviceCaps($hDC, $PHYSICALOFFSETY) $i__PageWidth = _WinAPI_GetDeviceCaps($hDC, $PHYSICALWIDTH) $i__PageHeight = _WinAPI_GetDeviceCaps($hDC, $PHYSICALHEIGHT) #Tidy_Off _LogMsg("+++:" & @CRLF _ & "$PHYSICALOFFSETX [" & $PHYSICALOFFSETX & "] $i__LeftMargin_X = " & $i__LeftMargin_X & @CRLF _ & "$PHYSICALOFFSETY [" & $PHYSICALOFFSETY & "] $i__TopMargin_Y = " & $i__TopMargin_Y & @CRLF _ & "$PHYSICALWIDTH [" & $PHYSICALWIDTH & "] $i__PageWidth = " & $i__PageWidth & @CRLF _ & "$PHYSICALHEIGHT [" & $PHYSICALHEIGHT & "] $i__PageHeight = " & $i__PageHeight & @CRLF _ ) #Tidy_On $i__x_start = $i__LeftMargin_X - 75 $i__y_start = $i__TopMargin_Y - 75 $i__x_end = $i__PageWidth - 250 $i__y_end = $i__PageHeight - 200 _Printer_SetInitial_XY() $i__LastLineNum = _Printer_GetLastLineNum() EndFunc ;==>_Printer_GetMetrics Func _Printer_SetInitial_XY() $i__CurrentPos_X = $i__LeftMargin_X $i__CurrentPos_Y = $i__TopMargin_Y * 22 EndFunc ;==>_Printer_SetInitial_XY Func _Printer_GetLastLineNum() Local $x1, $y, $linenumber $linenumber = -1 If ($i__Printer_Char_H > 0) Then For $x1 = 1 To 999 $y = (($i__Printer_Char_H + $VLINESPACE) * ($x1 + 1)) If ($y >= $i__y_end) Then $linenumber = $x1 ExitLoop EndIf Next EndIf If ($linenumber == -1) Then MsgBox(0, "Internal Error", "ERROR: Could not calculate the last line number") Exit (1) EndIf $linenumber -= 1 Return ($linenumber) EndFunc ;==>_Printer_GetLastLineNum Func __Printer_SetupCharWH($hDC) Local $vExtents $vExtents = _WinAPI_GetTextExtentPoint32($hDC, "x") $i__Printer_Char_W = DllStructGetData($vExtents, "X") ; Get the width of a character $i__Printer_Char_H = DllStructGetData($vExtents, "Y") ; Get the height of a character EndFunc ;==>__Printer_SetupCharWH Func _LogMsg($msg, $lnum = @ScriptLineNumber) If (StringLeft($msg, 4) = "+++:") Then $msg = StringTrimLeft($msg, 5) $msg = StringStripWS($msg, 3) ConsoleWrite("+++:" & $lnum & "] " & $msg & @CRLF) EndFunc ;==>_LogMsg Func _Printer_SetFont($hDC) Local $hFont If ($a__Printer_Font == 0) Then _Printer_MakeFont() EndIf $hFont = $a__Printer_Font _LogMsg("+++: $hDC & " & $hDC & ", $hFont = " & $hFont) _WinAPI_SetFont($hDC, $hFont) ; <===================== EndFunc ;==>_Printer_SetFont Func _Printer_MakeFont() Local $hFontDC, $err, $errm, $str, $flag, $iHeight $flag = $FW_BOLD $iHeight = 8 $hFontDC = _WinAPI_CreateFont( _ $iHeight, _ 0, _ ; average character width 0, _ ; angle of escape 0, _ ; base-line orientation $flag, _ ; font weight - $FW_NORMAL, $FW_BOLD, etc. False, _ ; italic False, _ ; underline False, _ ; strikeout $DEFAULT_CHARSET, _ ; the character set $OUT_DEFAULT_PRECIS, _ ; the output precision $CLIP_DEFAULT_PRECIS, _ ; the clipping precision $DEFAULT_QUALITY, _ ; the output quality 0, _ ; the pitch and family of the font "courier new") ; typeface name _LogMsg("+++: $hFontDC = 0x" & Hex($hFontDC)) If ($hFontDC <= 0) Then $str = "_WinAPI_CreateFont() failed." & @CRLF $err = _WinAPI_GetLastError() $errm = _WinAPI_GetLastErrorMessage() _LogMsg("+++: " & $err & ", 0) - '" & $errm & "'" & @CRLF & $str) Exit (9) EndIf $a__Printer_Font = $hFontDC EndFunc ;==>_Printer_MakeFont Here is the full script.  Run it to see the problem:
×
×
  • Create New...