VB에서 EXE, DLL 등의 문자열, 이미지 리소스를 편집을 위한 예제 프로그램
Private Type BITMAP
bmType As Long ' this must be zero
bmWidth As Long ' bitmap width
bmHeight As Long ' bitmap height
bmWidthBytes As Long ' bytes in horiz raster line
bmPlanes As Integer ' number of color planes
bmBitsPixel As Integer ' number of bits per pixel
bmBits As Long ' address of pixel data in memory
End Type
Private Type StringTable
id As Long
Text As String
End Type
Private Const IMAGE_ARCHIVE_START_SIZE = 8
Private Const IMAGE_BITMAP = 0
Private Const LR_CREATEDIBSECTION = &H2000
' Predefined Resource Types
Private Const DIFFERENCE = 11
Private Const RT_ACCELERATOR = 9&
Private Const RT_ANICURSOR = (21)
Private Const RT_ANIICON = (22)
Private Const RT_BITMAP = 2&
Private Const RT_CURSOR = 1&
Private Const RT_DIALOG = 5&
Private Const RT_DLGINCLUDE = 17
Private Const RT_ICON = 3&
Private Const RT_FONT = 8&
Private Const RT_FONTDIR = 7&
Private Const RT_GROUP_CURSOR = (RT_CURSOR + DIFFERENCE)
Private Const RT_GROUP_ICON = (RT_ICON + DIFFERENCE)
Private Const RT_HTML = 23
Private Const RT_MENU = 4&
Private Const RT_MESSAGETABLE = 11
Private Const RT_PLUGPLAY = 19
Private Const RT_RCDATA = 10&
Private Const RT_STRING = 6&
Private Const RT_VERSION = 16
Private Const RT_MYOWN_TYPE1 = 10001
Private Const RT_MYOWN_TYPE2 = 10002
Private Const ENGLISH_US = 1033
Private Declare Function BeginUpdateResource Lib "kernel32" Alias "BeginUpdateResourceA" ( _
ByVal pstrFileName As String, ByVal bDeleteExistingResources As Long) As Long
Private Declare Function UpdateResource Lib "kernel32" Alias "UpdateResourceA" ( _
ByVal hUpdate As Long, ByVal lpType As Long, ByVal lpName As Long, _
ByVal wLanguage As Integer, lpData As Any, ByVal cbData As Long) As Long
Private Declare Function EndUpdateResource Lib "kernel32" Alias "EndUpdateResourceA" ( _
ByVal hUpdate As Long, ByVal fDiscard As Long) As Long
Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
ByVal lpLibstrFileName As String) As Long
Private Declare Function FindResourceEx Lib "kernel32" Alias "FindResourceExA" ( _
ByVal hModule As Long, ByVal lpType As Long, ByVal lpName As Long, _
ByVal wLanguage As Long) As Long
Private Declare Function LoadResource Lib "kernel32" ( _
ByVal hInstance As Long, ByVal hResourceInfo As Long) As Long
Private Declare Function LockResource Lib "kernel32" ( _
ByVal hResourceData As Long) As Long
Private Declare Function SizeofResource Lib "kernel32" ( _
ByVal hInstance As Long, ByVal hResourceInfo As Long) As Long
Private Declare Function FreeLibrary Lib "kernel32" ( _
ByVal hLibModule As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
Destination As Any, Source As Any, ByVal Length As Long)
'//APIs to display Bitmap from Resource
Private Declare Function BitBlt Lib "gdi32.dll" ( _
ByVal hDestDC As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hSrcDC As Long, _
ByVal xSrc As Long, _
ByVal ySrc As Long, _
ByVal dwRop As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32.dll" ( _
ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" ( _
ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" ( _
ByVal hObject As Long) As Long
Private Declare Function LoadImage Lib "user32.dll" Alias "LoadImageA" ( _
ByVal hInst As Long, _
ByVal lpsz As String, _
ByVal un1 As Long, _
ByVal n1 As Long, _
ByVal n2 As Long, _
ByVal un2 As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" ( _
ByVal hdc As Long, _
ByVal hObject As Long) As Long
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal _
hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
'//API To display string item from resource
Private Declare Function LoadString Lib "user32.dll" Alias "LoadStringA" ( _
ByVal hInstance As Long, _
ByVal wID As Long, _
ByVal lpBuffer As String, _
ByVal nBufferMax As Long) As Long
'//1033=ENGLISH (US)
Public Function StringResourceModify(strResExePath As String, id As Integer, _
ByVal strText As String, Optional LangID As Long = ENGLISH_US) As Boolean
Dim ret As Long
Dim hResource As Long
Dim x As Long
Dim iGroup As Integer
Dim hObject As Long
Dim hResourceData As Long
Dim lpResourceData As Long
Dim cbResource As Long
Dim hModule As Long
Dim lpData() As Byte
Dim lpReadData() As Byte
Dim cbText As Integer
If id < 1 Then Exit Function
'Calculate # of groups of strings
iGroup = Int(id / 16&) + 1
'Open the file
hModule = LoadLibrary(strResExePath)
hObject = FindResourceEx(hModule, RT_STRING, iGroup, LangID) '//6=StringType
hResourceData = LoadResource(hModule, hObject)
lpResourceData = LockResource(hResourceData)
cbResource = SizeofResource(hModule, hObject)
If cbResource <= 32 Or hObject = 0 Then
cbResource = 32& + Len(strText) * 2&
ReDim lpData(cbResource - 1)
cbText = Len(strText)
CopyMemory lpData(2& * (id - (iGroup - 1) * 16&)), cbText, 2&
If Len(strText) Then
CopyMemory lpData(2& + 2& * (id - (iGroup - 1) * 16&)), ByVal StrPtr(strText), Len(strText) * 2
End If
Else
ReDim lpReadData(cbResource - 1)
CopyMemory lpReadData(0), ByVal lpResourceData, cbResource
Dim countX As Long
Dim CHECKLNG As Integer
For x = 0 To (id - (iGroup - 1) * 16&) - 1
CopyMemory CHECKLNG, lpReadData(countX), 2&
countX = countX + 2 + CHECKLNG * 2
Next
CopyMemory CHECKLNG, lpReadData(countX), 2&
ReDim lpData(countX + 2 + Len(strText) * 2 + (cbResource - (countX + 2 + CHECKLNG * 2)) - 1)
CopyMemory lpData(0), lpReadData(0), countX
cbText = Len(strText)
CopyMemory lpData(countX), cbText, 2&
If Len(strText) Then
CopyMemory lpData(countX + 2), ByVal StrPtr(strText), Len(strText) * 2
End If
If (cbResource - (countX + 2 + CHECKLNG * 2)) > 0 Then
CopyMemory lpData(countX + 2 + Len(strText) * 2), lpReadData(countX + 2 + CHECKLNG * 2), (cbResource - (countX + 2 + CHECKLNG * 2))
End If
End If
'Free the loaded exe/dll file
FreeLibrary hModule
'Start resource update to the exe/dll
hResource = BeginUpdateResource(strResExePath, ByVal 0&)
'Update the ressource iGroup
ret = UpdateResource(hResource, 6&, CLng(iGroup), CInt(LangID), lpData(0), UBound(lpData) + 1)
'This will actually write the update to the disk and end the resource update process
ret = EndUpdateResource(hResource, ByVal 0&)
StringResourceModify = ret
End Function
Private Function StringResourceList(strFileName As String, Optional LangID As Long = ENGLISH_US) As StringTable()
Dim ret As Long
Dim hResource As Long
Dim x As Long
Dim iGroup As Integer
Dim hObject As Long
Dim hResourceData As Long
Dim lpResourceData As Long
Dim cbResource As Long
Dim hModule As Long
Dim lpData() As Byte
Dim lpReadData() As Byte
Dim Out() As StringTable
Dim countX As Long
Dim CHECKLNG As Integer
Dim temp As String
ReDim Out(0)
hModule = LoadLibrary(strFileName)
For iGroup = 1 To 4096
hObject = FindResourceEx(hModule, 6&, iGroup, LangID)
hResourceData = LoadResource(hModule, hObject)
lpResourceData = LockResource(hResourceData)
cbResource = SizeofResource(hModule, hObject)
If cbResource >= 31 And hObject <> 0 Then
ReDim lpReadData(cbResource - 1)
CopyMemory lpReadData(0), ByVal lpResourceData, cbResource
countX = 0
x = 0
Do While countX < UBound(lpReadData)
CopyMemory CHECKLNG, lpReadData(countX), 2&
countX = countX + 2
If CHECKLNG Then
ReDim Preserve Out(UBound(Out) + 1)
Out(UBound(Out)).id = (iGroup - 1) * 16& + x
temp = Space(CHECKLNG * 2)
CopyMemory ByVal StrPtr(temp), lpReadData(countX), CHECKLNG * 2
Out(UBound(Out)).Text = temp
countX = countX + CHECKLNG * 2
End If
x = x + 1
Loop
End If
Next
FreeLibrary hModule
StringResourceList = Out
End Function
Private Function BitmapResourceModify(strResExePath As String, strFileToLoad As String, _
Optional nResType As Long = RT_BITMAP, Optional nID As Long = 101, Optional bDelete As Boolean = False) As Boolean
Dim nFile As Long
Dim Data() As Byte
Dim arrSize As Long
Dim ret As Long
Dim Handle As Long
nFile = FreeFile
'//We need to pass byte buffer so create a ByteArry from file
Open strFileToLoad For Binary As nFile
arrSize = LOF(nFile) - 14
ReDim Data(0 To arrSize - 1)
Get nFile, 15, Data
Close nFile
Handle = BeginUpdateResource(strResExePath, 0) '//0=Dont delete existing resource items
If Handle = 0 Then Exit Function
If bDelete = False Then
'//Add/Modify
ret = UpdateResource(Handle, ByVal nResType, ByVal nID, 1033, Data(0), arrSize)
Else
'//To Delete Resource item pass lpData=ByVal 0& (NULL) and cbData=0
ret = UpdateResource(Handle, ByVal nResType, ByVal nID, 1033, ByVal 0&, 0)
End If
ret = EndUpdateResource(Handle, 0)
BitmapResourceModify = ret
End Function
Sub DisplayBitmapRes(hDcDisplay As Long, sResFile As String, ResId As Long)
Const IMAGE_BITMAP = 0&
Const LR_CREATEDIBSECTION = &H2000
Dim hDLL As Long
Dim sID As String
Dim sIdent102 As String
Dim hMemDC As Long
Dim lret As Long
Dim hBmp As Long
Dim oldhBmp As Long
Dim picwid As Long, pichgt As Long
Dim BMP As BITMAP
sID = "#" & ResId '//Name is in #xxxx format
hDLL = LoadLibrary(sResFile)
' Could use LoadBitmap but it has been superceded by
' LoadImage which is more flexible.
' Hbmp = LoadBitmap(hDLL, sID)
' First bitmap in DLL
hBmp = LoadImage(hDLL, sID, IMAGE_BITMAP, _
0, 0, LR_CREATEDIBSECTION)
GetObjectAPI hBmp, Len(BMP), BMP
picwid = BMP.bmWidth
pichgt = BMP.bmHeight
' Blit it to a pictureBox
hMemDC = CreateCompatibleDC(hDcDisplay)
oldhBmp = SelectObject(hMemDC, hBmp)
lret = BitBlt(hDcDisplay, 0, 0, picwid, pichgt, _
hMemDC, 0, 0, vbSrcCopy)
DeleteObject hBmp
' Clean Up
SelectObject hMemDC, oldhBmp
DeleteDC hMemDC
DeleteObject hBmp
FreeLibrary hDLL
End Sub
Sub DisplayStringRes(sResFile As String, ResId As Long)
Dim c As Integer, s As String, id As Long, hDLL As Long
c = 1024
s = String(c, 0)
hDLL = LoadLibrary(sResFile)
c = LoadString(hDLL, ResId, s, c)
MsgBox s
FreeLibrary hDLL
End Sub
Private Sub Command1_Click()
Dim sResExeFilePath As String
Dim sBMPFileToLoadPath As String
sResExeFilePath = App.Path & "\test.exe"
sBMPFileToLoadPath = App.Path & "\bmp_to_load.bmp"
'//Note: ID Must be unique with in the same group of resource
'//otherwise resource item will be overwritten by update
'//Save Bitmap Resource Demo
MsgBox BitmapResourceModify(sResExeFilePath, sBMPFileToLoadPath, RT_BITMAP, 101), , "BitmapResourceModify"
'//Delete Bitmap Resource Demo
'//MsgBox BitmapResourceModify(sResExeFilePath, sBMPFileToLoadPath, RT_BITMAP, 101,True)
'//Save String Resource Demo
MsgBox StringResourceModify(sResExeFilePath, 101, "This is test1"), , "StringResourceModify"
MsgBox StringResourceModify(sResExeFilePath, 102, "This is test2"), , "StringResourceModify"
MsgBox StringResourceModify(sResExeFilePath, 103, "This is test3"), , "StringResourceModify"
'//To remove string ID=102 just pass strText=vbNullString
'MsgBox StringResourceModify(sResExeFilePath, 102, vbNullString)
Dim st() As StringTable, sMsg As String, i As Long
st = StringResourceList(sResExeFilePath)
For i = 0 To UBound(st)
sMsg = sMsg & st(i).id & " : " & st(i).Text & vbCrLf
Next
MsgBox sMsg, , "List of string items"
DisplayBitmapRes Picture1.hdc, sResExeFilePath, 101
DisplayStringRes sResExeFilePath, 101
Me.Caption = "BMP Resource from : " & sResExeFilePath
End Sub
Private Sub Form_Load()
Command1.Caption = "Modify Resource Demo"
End Sub
원본출처 :
http://binaryworld.net/Main/CodeDetail.aspx?CodeId=3778
댓글을 달아 주세요