只要指一下路径,就可以打印任何文件了!Public Const SW_SHOWMINNOACTIVE = 7 Declare Function ShellExecuteAny Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As Any, ByVal lpDirectory As Any, ByVal nShowCmd As Long) As LongPrivate Sub Form_Load() Ret = ShellExecuteAny(me.hWnd , "print", path, ByVal 0&, ByVal 0&, SW_SHOWMINNOACTIVE) End Sub
to zhjian6(网中剑):非常感谢你的回复,我想起来以前曾经用过ShellExecuteA来打开任意文件的,忘了,因为我不怎么用VB的,也很少用API之类。只是恐怕用这个还是不行,比如打印Word文档的时候,会把Word文档跳出来(当然打印完毕后自动关闭了),如果一次打印的Word文档多的话,一次次跳出来岂不很烦。to ecstar(我的飞刀呢?):同样感谢你的回复,你说的这个方法对于我前面说的第3点问题是一种解决方案。或许我的这样一个命题本来就不太合适吧?我的原意是这样的:在办公工作流中,员工打印需要由领导审批,领导审批同意则由打印管理员打印所有提交的文件。现在想把打印管理员节省出来,在领导同意的时候就直接打印文件。所以希望打印在后台无声无息,并且最好能智能一点,如可以指定打印机,全部打印完后能给提示。想来想去,可能是难以做到了。感谢所有回复的人,不管对我有无帮助,都会给分的,暂时再观察一周,一周后我再结帖。
编程来识别某一文件是否有打印这一项,可以找出它的扩展名,通过下面的程序来实现,它有Print和Printto两项Option Explicit Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long ' Note that if you declare the lpData parameter as String, you must pass it By Value. Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As LongPrivate Const HKEY_CLASSES_ROOT = &H80000000 Private Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" (ByVal hKey As Long, ByVal lpClass As String, lpcbClass As Long, ByVal lpReserved As Long, lpcSubKeys As Long, lpcbMaxSubKeyLen As Long, lpcbMaxClassLen As Long, lpcValues As Long, lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, lpcbSecurityDescriptor As Long, lpftLastWriteTime As FILETIME) As Long Private Declare Function RegEnumKey Lib "advapi32.dll" Alias "RegEnumKeyA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, ByVal cbName As Long) As Long Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Private Sub SetExtOperation(ByVal ext As String) 'ext传入扩展名如".txt" Dim hKey As Long, typeData As Long, lenData As Long Dim S As String, ret As Long, Name As String, Idx As Long Dim nSubKey As Long, maxSubKeyLen As Long, maxClassLen As Long Dim nValue As Long, maxValueNameLen As Long, maxValueLen As Long Dim sd As Long, WriteTime As FILETIME List1.Clear ret = RegOpenKey(HKEY_CLASSES_ROOT, ext, hKey) If ret <> 0 Then Exit Sub ret = RegQueryValueEx(hKey, "", 0, typeData, ByVal vbNullString, lenData) If ret = 0 Then S = String(lenData, Chr(0)) RegQueryValueEx hKey, "", ByVal 0, typeData, ByVal S, lenData S = Left(S, InStr(S, Chr(0)) - 1) ret = RegOpenKey(HKEY_CLASSES_ROOT, S & "\shell", hKey) If ret <> 0 Then Exit Sub ret = RegQueryInfoKey(hKey, vbNullString, 0, ByVal 0, nSubKey, maxSubKeyLen, maxClassLen, nValue, maxValueNameLen, maxValueLen, sd, WriteTime) Name = String(maxSubKeyLen + 1, Chr(0)) For Idx = 0 To nSubKey - 1 ret = RegEnumKey(hKey, Idx, Name, Len(Name)) If ret = 0 Then List1.AddItem Left(Name, InStr(Name, Chr(0)) - 1) End If Next End If RegCloseKey hKey End SubPrivate Sub Command2_Click() SetExtOperation ".PDF" End Sub
另外你说的“如果更严格一点需要判断文件格式。”,怎么判断?
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\WINWORD.EXE\shell\Print\command
名称:(默认) 类型:REG_SZ 数据:"C:\Program Files\Microsoft Office\Office10\WINWORD.EXE" /x /n /ddeHKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\EXCEL.EXE\shell\Print\command
名称:(默认) 类型:REG_SZ 数据:"C:\Program Files\Microsoft Office\Office10\EXCEL.EXE" /eHKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\notepad.exe\shell\print\command
名称:(默认) 类型:REG_EXPAND_SZ 数据:%SystemRoot%\system32\NOTEPAD.EXE /p %1因此可以按照文件的扩展名,从注册表找出相应的打印指令,调用对应的程序来打印。可是,在知道扩展名之后,怎么样找出对应的打印指令呢。扩展名是随机的啊。另外
1、上面的数据怎么doc和xls的有双引号,txt的却没有;
2、对于%SystemRoot%又怎么处理呢?从哪里读取出%SystemRoot%的具体值。
3、假如扩展名是cpp,从注册表中找不出对应的打印指令,但实际上可以用NOTEPAD来打印的,对于这种情况又如何处理。怎么知道文件是纯文本文件呢?
请大侠继续指教。
Declare Function ShellExecuteAny Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hWnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As Any, ByVal lpDirectory As Any, ByVal nShowCmd As Long) As LongPrivate Sub Form_Load()
Ret = ShellExecuteAny(me.hWnd , "print", path, ByVal 0&, ByVal 0&, SW_SHOWMINNOACTIVE)
End Sub
[Printer]
notepad=txt,cpp,log
或者txt=notepad
cpp=notepad
log=notepad另外设置一个默认的
这个变量可以直接用在批处理文件中
%SystemRoot%
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long ' Note that if you declare the lpData parameter as String, you must pass it By Value.
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As LongPrivate Const HKEY_CLASSES_ROOT = &H80000000
Private Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" (ByVal hKey As Long, ByVal lpClass As String, lpcbClass As Long, ByVal lpReserved As Long, lpcSubKeys As Long, lpcbMaxSubKeyLen As Long, lpcbMaxClassLen As Long, lpcValues As Long, lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, lpcbSecurityDescriptor As Long, lpftLastWriteTime As FILETIME) As Long
Private Declare Function RegEnumKey Lib "advapi32.dll" Alias "RegEnumKeyA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, ByVal cbName As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Sub SetExtOperation(ByVal ext As String) 'ext传入扩展名如".txt"
Dim hKey As Long, typeData As Long, lenData As Long
Dim S As String, ret As Long, Name As String, Idx As Long
Dim nSubKey As Long, maxSubKeyLen As Long, maxClassLen As Long
Dim nValue As Long, maxValueNameLen As Long, maxValueLen As Long
Dim sd As Long, WriteTime As FILETIME
List1.Clear
ret = RegOpenKey(HKEY_CLASSES_ROOT, ext, hKey)
If ret <> 0 Then Exit Sub
ret = RegQueryValueEx(hKey, "", 0, typeData, ByVal vbNullString, lenData)
If ret = 0 Then
S = String(lenData, Chr(0))
RegQueryValueEx hKey, "", ByVal 0, typeData, ByVal S, lenData
S = Left(S, InStr(S, Chr(0)) - 1)
ret = RegOpenKey(HKEY_CLASSES_ROOT, S & "\shell", hKey)
If ret <> 0 Then Exit Sub
ret = RegQueryInfoKey(hKey, vbNullString, 0, ByVal 0, nSubKey, maxSubKeyLen, maxClassLen, nValue, maxValueNameLen, maxValueLen, sd, WriteTime)
Name = String(maxSubKeyLen + 1, Chr(0))
For Idx = 0 To nSubKey - 1
ret = RegEnumKey(hKey, Idx, Name, Len(Name))
If ret = 0 Then
List1.AddItem Left(Name, InStr(Name, Chr(0)) - 1)
End If
Next
End If
RegCloseKey hKey
End SubPrivate Sub Command2_Click()
SetExtOperation ".PDF"
End Sub