ExtractIcon API dll이나 exe 파일에서 아이콘을 추출해 내는 API이다. 그러면 이 API를 활용해서 확장에 부여된 아이콘을 추출해 보자.

확장자에 설정된 아이콘의 정보는 레지스트리에 저장되 있다.
만약 텍스트 파일 확장자인 .TXT의 확장자에 대한 아이콘 정보를 얻기 위해 레지스트리에서 다음과 같이 값을 얻어야 한다.

실행에서 RegEdit를 입력하면 레지스트리 에디터 프로그램을 실행할수 있다.
레지스트리에서 루트 키중에 HKEY_CLASSES_ROOT키 아래에 확장자에 대한 정보가 저장되어 있다.


HKEY_CLASSES_ROOT 아래에 .확장자 이름으로 된 키를 찾느다. 여기 에서는 .txt가 되겠다


해당 키에 기본값에는 확장자에 대한 이름이 지정되어 있다. .txt에는 txtfile로 되어 있다.

다시 HKEY_CLASSES_ROOT키 아래에서 이전에 확장자에 할당될 이름과 같은 키를 찾는다. 여기서 txtfile


찾은 키의 DefaultIcon의 기본값을 읽으면 해당 이름의 확장자에 할당된 아이콘이 어떤 파일에 들어있고, 그 파일에서 몇번째의 아이콘인지를 알수 있다.


이 정보를 가지고 API를 사용하여 아이콘 핸들을 추출하여, DC에 그리면 된다.

다음 예제 소스의 초기 화면이다.


텍스트 박스에 .을 포함한 파일명이나 확장자를 입력하면 그 확장자에 대한 아이콘 정보를 얻어 픽처박스에 아이콘을 그린다.
다음 이미지는 텍스트 박스에 엔터를 입력한 후의 결과 이미지이다.



아래는 위 이미지에 대한 소스입니다.
' 확장자에 할당된 아이콘을 추출한다.
Option Explicit

Private Const ERROR_SUCCESS = 0
Private Const BufferSize = 500
Private Const HKEY_CLASSES_ROOT = &H80000000

Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByVal lpData As Any, lpcbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
Private Declare Function DrawIcon Lib "user32.dll" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal hIcon As Long) As Long
Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long
Private Declare Function GetSystemDirectory Lib "kernel32.dll" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long

Private Sub SetStringButter(Buffer As String, BufferLength As Long) ' 버퍼 할당
    BufferLength = BufferSize ' 버퍼 길이
    Buffer = Space$(BufferLength) ' 버퍼 할당
End Sub

Private Function GetStringInButter(ByVal Buffer As String, ByVal BufferLength As Long) As String ' 버퍼에 포함된 문자열을 반환, 어디까지 문자열 종료 까지만
    GetStringInButter = Left(Buffer, BufferLength - 1)
End Function

Public Sub GetDefaultIcon(ByVal FileName As String, ByVal Picture_hDC As Long)
    Dim GetInfoIconStatus As Boolean ' 아이콘 정보를 얻었는지에 대한 상태 플래그
    Dim ReturnValue As Long ' 반환값
    Dim RegKeyHandle As Long ' 레지스트리 키 핸들
    Dim Buffer As String ' 버퍼,확장자에 할당한 이름,아이콘 정보,아이콘 파일
    Dim BufferLength As Long ' 버퍼 길이,버퍼에 저장된 데이타 길이
    Dim IconNumber As Long ' 아이콘 번호
    Dim CommaPositon As Long ' 콤마 위치
    Dim IconHandle As Long ' 아이콘 핸들
   
    GetInfoIconStatus = False ' 아이콘 상태 플래그 초기화
    FileName = Mid$(FileName, InStrRev(FileName, ".")) ' 학장자만 얻는다 . 포함
    ReturnValue = RegOpenKey(HKEY_CLASSES_ROOT, FileName, RegKeyHandle) ' 확장자에 대한 레지스트리 키를 오픈한다.
    If ReturnValue = ERROR_SUCCESS Then ' 확장자 키를 오픈 성공이라면
        SetStringButter Buffer, BufferLength ' 버퍼 할당
        ReturnValue = RegQueryValueEx(RegKeyHandle, vbNullString, 0, 0, Buffer, BufferLength)
        Call RegCloseKey(RegKeyHandle)
        If ReturnValue = ERROR_SUCCESS Then ' 확장자에 할당한 이름을 읽어 왔다면
            Buffer = GetStringInButter(Buffer, BufferLength)
            ReturnValue = RegOpenKey(HKEY_CLASSES_ROOT, Buffer & "\DefaultIcon", RegKeyHandle)
            If ReturnValue = ERROR_SUCCESS Then ' 확장자에 할당된 이름에 대한 아이콘 정보가 있는 키 오픈에 성공 했다며
                SetStringButter Buffer, BufferLength ' 버퍼 할당
                ReturnValue = RegQueryValueEx(RegKeyHandle, vbNullString, 0, 0, Buffer, BufferLength)
                Call RegCloseKey(RegKeyHandle)
                If ReturnValue = ERROR_SUCCESS Then ' 아이콘 정보를 얻었다면
                    Buffer = GetStringInButter(Buffer, BufferLength)
                    CommaPositon = InStrRev(Buffer, ",")
                    If Not CommaPositon < 1 Then ' 제대로된 아이콘 정보가 있다면
                        IconNumber = Trim$(Mid$(Buffer, CommaPositon + 1))
                        Buffer = Trim$(Left(Buffer, CommaPositon - 1))
                        GetInfoIconStatus = True ' 아이콘 정보 얻음
                    End If
                End If
            End If
        End If
    End If
   
    If Not GetInfoIconStatus Then ' 아이콘 정보를 얻지 못했다면
        SetStringButter Buffer, BufferLength ' 버퍼 할당
        BufferLength = GetSystemDirectory(Buffer, BufferLength) + 1
        Buffer = GetStringInButter(Buffer, BufferLength) & "\SHELL32.DLL"
        IconNumber = IIf(StrComp(FileName, ".exe", vbTextCompare), 0, 2)
    End If

    ' 아이콘을 추출하고 DC에 그린다
    IconHandle = ExtractIcon(App.hInstance, Buffer, IconNumber) ' 아이콘 파일에서 추출
    If Not IconHandle = 1 And Not IconHandle = 0 Then ' 아이콘을 추출했다면
        ReturnValue = DrawIcon(Picture_hDC, 0, 0, IconHandle) ' 아이콘을 DC에 그리고
        ReturnValue = DestroyIcon(IconHandle) ' 추출한 아이콘을 제거(파일에서 제거가 아니다)
    End If
End Sub

Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
    If Not KeyCode = vbKeyReturn Then Exit Sub
    If Not CBool(InStr(Text1.Text, ".")) Then Exit Sub
    Picture1.Cls
    GetDefaultIcon Text1.Text, Picture1.hDC
    Text1.SetFocus
End Sub

Private Sub Form_Activate()
    Call Text1.SetFocus
End Sub

Private Sub Form_Load()
    Text1.Text = ".txt"
End Sub

 

+ Recent posts