2009-06-30 4 views
4

MS Office 인쇄 대화 상자의 프린터 선택 콤보 상자를 에뮬레이트하려고합니다. 드롭 다운 목록에는 왼쪽에 대형 프린터 아이콘이있는 프린터 이름이 포함되어 있습니다. Vista 팩스 프린터에는 좋은 팩스 아이콘이 있고 공유 프린터는 기본 프린터로 표시되어 있습니다. 가장 좋은 방법은 탐색기에서 제어판 -> 프린터를 보는 것처럼 프린터 정보를 더 볼 수있게하는 것입니다.현재 사용자 프린터의 아이콘 검색 중

어떤 아이디어로 시작해야할까요?

SHGetFileInfo으로 중간 성공했지만 의견을 환영합니다.

[운영 체제 : 윈도우, 코드 언어 : 어떤] C/Win32에서의

답변

4

은 무엇입니까 나는 마침내 떠올랐다. 다양한 OLE 인터페이스에는 IShellFolder Extended Type Library v1.2이 필요합니다. 나는이 형식 라이브러리가 VB6에 더 좋은 방법으로 이식 될 수 있다고 확신하지만 결과는 다음과 같습니다.

Option Explicit 

Private Const CSIDL_PRINTERS As Long = &H4 
Private Const SHGFI_PIDL  As Long = &H8 
Private Const SHGFI_ICON  As Long = &H100 
Private Const SHGFI_DISPLAYNAME As Long = &H200 
Private Const MAX_PATH   As Long = 260 

Private Declare Function SHGetDesktopFolder Lib "shell32" (ppshf As IShellFolder) As Long 
Private Declare Function SHGetSpecialFolderLocation Lib "shell32.dll" (ByVal hwndOwner As Long, ByVal nFolder As Long, pidl As Long) As Long 
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long) 
Private Declare Function SHGetFileInfo Lib "shell32" Alias "SHGetFileInfoA" (pszPath As Any, ByVal dwFileAttributes As Long, psfi As SHFILEINFO, ByVal cbFileInfo As Long, ByVal uFlags As Long) As Long 
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long) 
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (lpPictDesc As PICTDESC, riid As Any, ByVal fPictureOwnsHandle As Long, ppRet As IPicture) As Long 

Private Type SHFILEINFO 
    hIcon    As Long 
    iIcon    As Long 
    dwAttributes  As Long 
    szDisplayName  As String * MAX_PATH 
    szTypeName   As String * 80 
End Type 

Private Type PICTDESC 
    Size    As Long 
    Type    As Long 
    hBmpOrIcon   As Long 
    hPal    As Long 
End Type 

Private Sub Command1_Click() 
    Dim IID_IShellFolder As IShellFolderEx_TLB.GUID 
    Dim IID_IPicture(0 To 3) As Long 
    Dim pidlPrinters() As Byte 
    Dim pidlCurrent() As Byte 
    Dim pidlAbsolute() As Byte 
    Dim pDesktopFolder As IShellFolder 
    Dim pPrintersFolder As IShellFolder 
    Dim pEnumIds  As IEnumIDList 
    Dim lPtr   As Long 
    Dim uInfo   As SHFILEINFO 
    Dim uPict   As PICTDESC 
    Dim sPrinterName As String 
    Dim oPrinterIcon As StdPicture 

    '--- init consts 
    IID_IShellFolder.Data1 = &H214E6 '--- {000214E6-0000-0000-C000-000000000046} 
    IID_IShellFolder.Data4(0) = &HC0 
    IID_IShellFolder.Data4(7) = &H46 
    IID_IPicture(0) = &H7BF80980 '--- {7BF80980-BF32-101A-8BBB-00AA00300CAB} 
    IID_IPicture(1) = &H101ABF32 
    IID_IPicture(2) = &HAA00BB8B 
    IID_IPicture(3) = &HAB0C3000 
    '--- init local vars 
    uPict.Size = Len(uPict) 
    uPict.Type = vbPicTypeIcon 
    Call SHGetDesktopFolder(pDesktopFolder) 
    '--- retrieve enumerator of Printers virtual folder 
    Call SHGetSpecialFolderLocation(0, CSIDL_PRINTERS, lPtr) 
    pidlPrinters = pvToPidl(lPtr) 
    Call pDesktopFolder.BindToObject(VarPtr(pidlPrinters(0)), 0, IID_IShellFolder, pPrintersFolder) 
    Call pPrintersFolder.EnumObjects(0, SHCONTF_NONFOLDERS, pEnumIds) 
    '--- loop printers 
    Do While pEnumIds.Next(1, lPtr, 0) = 0 '--- S_OK 
     pidlCurrent = pvToPidl(lPtr) 
     '--- combine pidls: Printers + Current 
     ReDim pidlAbsolute(0 To UBound(pidlPrinters) + UBound(pidlCurrent)) 
     Call CopyMemory(pidlAbsolute(0), pidlPrinters(0), UBound(pidlPrinters) - 1) 
     Call CopyMemory(pidlAbsolute(UBound(pidlPrinters) - 1), pidlCurrent(0), UBound(pidlCurrent) - 1) 
     '--- retrieve info 
     Call SHGetFileInfo(pidlAbsolute(0), 0, uInfo, Len(uInfo), SHGFI_PIDL Or SHGFI_DISPLAYNAME Or SHGFI_ICON) 
     sPrinterName = Left(uInfo.szDisplayName, InStr(uInfo.szDisplayName, Chr$(0)) - 1) 
     '--- extract icon 
     uPict.hBmpOrIcon = uInfo.hIcon 
     Call OleCreatePictureIndirect(uPict, IID_IPicture(0), True, oPrinterIcon) 
     '--- show 
     Set Picture = oPrinterIcon 
     MsgBox sPrinterName 
    Loop 
End Sub 

Private Function pvToPidl(ByVal lPtr As Long) As Byte() 
    Dim lTotal  As Long 
    Dim nSize  As Integer 
    Dim baPidl() As Byte 

    Do 
     Call CopyMemory(nSize, ByVal (lPtr + lTotal), 2) 
     lTotal = lTotal + nSize 
    Loop While nSize <> 0 
    ReDim baPidl(0 To lTotal + 1) 
    Call CopyMemory(baPidl(0), ByVal lPtr, lTotal + 2) 
    Call CoTaskMemFree(lPtr) 
    pvToPidl = baPidl 
End Function 
0

그것은 \ '의 쉬운 클래식 (Win32 grp 참조는 MS 내부에서 탐색기 소스 코드)

+0

무슨 뜻입니까? 게시물에 대한 직접 링크를 제공 할 수 있습니까? – wqw

0

당신은 어떻게 말을하지 않습니다 당신이 SHGetFileInfo를 요구하고있다,하지만 난 당신이 SHGFI_PIDL 플래그를 설정하고

이/기본 오버레이 아이콘을 공유하려면 정규화 된 PIDL (그리고 어쩌면 SHGFI_USEFILEATTRIBUTES)를 사용할 필요 거라 생각의 SHGFI_ADDOVERLAYS 플래그를 설정 여기

+0

예, PIDL을 얻는 것이 고통이었습니다. 특히 VB6에서 – wqw

관련 문제