用ShellExecute列印是否可以不用預設印表機 |
答題得分者是:danny
|
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
|
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
應該沒辦法 .......
不過可以用切換的, 先記錄原來的預設印表機, 再設定你的印表機為預設印表機, 用ShellExecute列印pdf 檔案完畢後, 再切回原來的預設印表機 但是現在問題來了... ShellExecute 並不會等你列印完就會繼續你Delphi中下一行程式, 所以你必須用 CreateProcess 取代 ShellExecute 至於 CreateProcess 的用法, 請善用搜尋功能可以找到好幾篇程式可以使用 ===================引 用 jook152 文 章=================== 我要用ShellExecute列印pdf 檔案 , 因為我的程式是preview主要檔案,當主要檔案被列印時利用ShellExecute列印出其附件, 但在印主要檔案時可能不是用預設印表機, 在印附件時是否可以依照主要檔案列印時選的印表機列印??? 若用ShellExecute無法做到,那有什麼方式可以用嗎?? 我只要主要檔案跟附件可以從同一台印表機印出但不一定是預設印表機 且要可以印pdf 檔,就可以了~~~不知道有什麼方法可以做到??
------
將問題盡快結案也是一種禮貌! |
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
|
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
使用 ShellExecute 基本上我想的到的是, 必需要配合 FinePrint 之類列印管理軟體, 然後再指定印表機
>但CreateProcess不是執行某個程式嗎??那這樣我要如何CreateProcess列印附件??它不是只能執行"執行檔"嗎? 是沒錯! 但你開啟 PDF 也需要某個 "執行檔" 吧! PDF 檔是當參數傳給他開啟而已 >還是其實你的意思是要我先用切換預設印表機 ShellExecute列印附件後再用CreateProcess繼續執行下面的程式??? 不是, CreateProcess 是用來取代 ShellExecute 的方法 ===================引 用 jook152 文 章=================== 不好意思,這麼久才回 先確定一下你的意思 你是指不要用ShellExecute直接用CreateProcess,但CreateProcess不是執行某個程式嗎??那這樣我要如何CreateProcess列印附件??它不是只能執行"執行檔"嗎??我的附件都是pdf..... 還是其實你的意思是要我先用切換預設印表機 ShellExecute列印附件後再用CreateProcess繼續執行下面的程式???
------
將問題盡快結案也是一種禮貌! |
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
我後來在討論區找到更改預設印表機的方式
我試了一下 [code delphi] sprint:=GetDefaultPrinter; //取得原始預設印表機 SetDefaultPrinter2(sPrnName); // 更改預設印表機 ShellExecute(Application.Mainform.Handle,'Print',Pchar(要列印的pdf 路徑),nil, nil, SW_SHOW); SetDefaultPrinter2(sprint); // 恢復原始預設印表機 function GetDefaultPrinter: string; var ResStr: array[0..255] of Char; begin GetProfileString('Windows', 'device', '', ResStr, 255); Result := StrPas(ResStr); end; procedure SetDefaultPrinter1(NewDefPrinter: string); var ResStr: array[0..255] of Char; begin StrPCopy(ResStr, NewdefPrinter); WriteProfileString('windows', 'device', ResStr); StrCopy(ResStr, 'windows'); SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@ResStr)); end; procedure SetDefaultPrinter2(PrinterName: string); var I: Integer; Device: PChar; Driver: PChar; Port: PChar; HdeviceMode: THandle; aPrinter: TPrinter; begin Printer.PrinterIndex := -1; GetMem(Device, 255); GetMem(Driver, 255); GetMem(Port, 255); aPrinter := TPrinter.Create; try for I := 0 to Printer.Printers.Count - 1 do begin if Printer.Printers[I] = PrinterName then begin aprinter.PrinterIndex := I; aPrinter.getprinter(device, driver, port, HdeviceMode); StrCat(Device, ','); StrCat(Device, Driver); StrCat(Device, Port); WriteProfileString('windows', 'device', Device); StrCopy(Device, 'windows'); SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@Device)); end; end; finally aPrinter.Free; end; FreeMem(Device, 255); FreeMem(Driver, 255); FreeMem(Port, 255); end; [/code] GetDefaultPrinter,SetDefaultPrinter2,SetDefaultPrinter1這三個函式都是引用討論區的資料 執行結果是都可以印,但那必須是要用debug的方式一步一步的run並進入函式才會依我選的印表機列印出來 若直接run執行檔(exe)它還是會跑到原始的預設印表機!! 為什麼會這樣??不管我用SetDefaultPrinter2還是SetDefaultPrinter1結果都一樣 debug時就ok,但一run執行檔就不行?? |
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
更改預設印表機有 OS 的分別, 以下是設定預設印表機的 procedure
有一點你必須注意, 在設定預設印表機時有可能會等一段時間, 但也可能不用等, 完全看你當時的 CPU 是否 busy [code delphi] // 設定 Default Printer Name procedure SetDefaultPrinterName(PrinterName: String); var dwVersion: DWORD; strPrinterInfo: string; const MAXPRINTERINFO = 50; begin SetLength(strPrinterInfo, MAXPRINTERINFO); if GetProfileString(PChar('PrinterPorts'), PChar(PrinterName), '', PChar(strPrinterInfo), MAXPRINTERINFO) > 0 then begin SetLength(strPrinterInfo, StrLen(PChar(strPrinterInfo))); strPrinterInfo := PrinterName ',' Copy(strPrinterInfo, 1, Pos(':,', strPrinterInfo)); if not WriteProfileString(PChar('Windows'), PChar('Device'), PChar(strPrinterInfo)) then raise Exception.Create('無法設定預設印表機資訊') else begin dwVersion := GetVersion(); if (dwVersion < $80000000) then SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0) // Windows NT 系列 else SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, 0); // 非 Windows NT 系列 end; end else raise Exception.Create('無法讀取預設印表機資訊'); end; [/code] ===================引 用 jook152 文 章=================== 我後來在討論區找到更改預設印表機的方式 我試了一下 [code delphi] sprint:=GetDefaultPrinter; //取得原始預設印表機 SetDefaultPrinter2(sPrnName); // 更改預設印表機 ShellExecute(Application.Mainform.Handle,'Print',Pchar(要列印的pdf 路徑),nil, nil, SW_SHOW); SetDefaultPrinter2(sprint); // 恢復原始預設印表機 function GetDefaultPrinter: string; var ResStr: array[0..255] of Char; begin GetProfileString('Windows', 'device', '', ResStr, 255); Result := StrPas(ResStr); end; procedure SetDefaultPrinter1(NewDefPrinter: string); var ResStr: array[0..255] of Char; begin StrPCopy(ResStr, NewdefPrinter); WriteProfileString('windows', 'device', ResStr); StrCopy(ResStr, 'windows'); SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@ResStr)); end; procedure SetDefaultPrinter2(PrinterName: string); var I: Integer; Device: PChar; Driver: PChar; Port: PChar; HdeviceMode: THandle; aPrinter: TPrinter; begin Printer.PrinterIndex := -1; GetMem(Device, 255); GetMem(Driver, 255); GetMem(Port, 255); aPrinter := TPrinter.Create; try for I := 0 to Printer.Printers.Count - 1 do begin if Printer.Printers[I] = PrinterName then begin aprinter.PrinterIndex := I; aPrinter.getprinter(device, driver, port, HdeviceMode); StrCat(Device, ','); StrCat(Device, Driver); StrCat(Device, Port); WriteProfileString('windows', 'device', Device); StrCopy(Device, 'windows'); SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@Device)); end; end; finally aPrinter.Free; end; FreeMem(Device, 255); FreeMem(Driver, 255); FreeMem(Port, 255); end; [/code] GetDefaultPrinter,SetDefaultPrinter2,SetDefaultPrinter1這三個函式都是引用討論區的資料 執行結果是都可以印,但那必須是要用debug的方式一步一步的run並進入函式才會依我選的印表機列印出來 若直接run執行檔(exe)它還是會跑到原始的預設印表機!! 為什麼會這樣??不管我用SetDefaultPrinter2還是SetDefaultPrinter1結果都一樣 debug時就ok,但一run執行檔就不行??
------
將問題盡快結案也是一種禮貌! |
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
|
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
|
u86210779
一般會員 發表:16 回覆:41 積分:16 註冊:2004-06-08 發送簡訊給我 |
|
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
[code delphi] a:=GetDefaultPrinter; //取得原始預設印表機 SetDefaultPrinter2(user選擇的印表機); // 更改預設印表機 //開啟pdf pdfAVDOC:=CreateOleObject('AcroExch.AVDoc'); // 建立Acrobat View 視覺化物件 pdfPDDOC:=CreateOleObject('AcroExch.PDDoc'); // 建立Acrobat View 非視覺化(控制)物件 pdfAPP:=CreateOleObject('AcroExch.APP'); // 建立Acrobat View application pdfAVDOC.open(sPrnName,StrExtract(sPrnName,'/',3)); pdfAVDOC:=pdfAPP.GetActiveDoc; pdfPDDOC:=pdfAVDOC.GetPDDoc; //pdfAPP.Show; // 是否顯示 Acrobat View vPage:=pdfPDDOC.GetNumPages; pdfAVDOC.PrintPagesSilent(0,vPage-1, 0, 0, 0); pdfPDDOC.close; pdfAPP.Exit; //列印完畢,恢復原始預設印表機 SetDefaultPrinter2(StrExtract(a,',')); [/code] GetDefaultPrinter,SetDefaultPrinter2和CreateOleObject('AcroExch.AVDoc');CreateOleObject(...) 這些在討論區裡面都有,我都是引用討論區的前輩們分享函式 去搜尋一下應該找得到 |
jook152
一般會員 發表:7 回覆:13 積分:4 註冊:2007-07-09 發送簡訊給我 |
[code delphi] a:=GetDefaultPrinter; //取得原始預設印表機 SetDefaultPrinter2(user選擇的印表機); // 更改預設印表機 //開啟pdf pdfAVDOC:=CreateOleObject('AcroExch.AVDoc'); // 建立Acrobat View 視覺化物件 pdfPDDOC:=CreateOleObject('AcroExch.PDDoc'); // 建立Acrobat View 非視覺化(控制)物件 pdfAPP:=CreateOleObject('AcroExch.APP'); // 建立Acrobat View application pdfAVDOC.open(欲開啟的檔案路徑,欲顯示的pdf標題名稱); pdfAVDOC:=pdfAPP.GetActiveDoc; pdfPDDOC:=pdfAVDOC.GetPDDoc; //pdfAPP.Show; // 是否顯示 Acrobat View vPage:=pdfPDDOC.GetNumPages; pdfAVDOC.PrintPagesSilent(0,vPage-1, 0, 0, 0); pdfPDDOC.close; pdfAPP.Exit; //列印完畢,恢復原始預設印表機 SetDefaultPrinter2(StrExtract(a,',')); [/code] GetDefaultPrinter,SetDefaultPrinter2和CreateOleObject('AcroExch.AVDoc');CreateOleObject(...) 這些在討論區裡面都有,我都是引用討論區的前輩們分享函式 去搜尋一下應該找得到 |
u86210779
一般會員 發表:16 回覆:41 積分:16 註冊:2004-06-08 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |