UPDATE: updated code for 3.20.
This is just for testing purposes, not a complete app, and you'll notice there are lots of features missing; but it loads and shows jpeg and gif files. Enjoy it;
Code: Select all
;
; Picture View for PB Windows
;
; Written in PureBasic by El_Choni
;
; Thanks: Rings for helping me to deal with bitmaps in memory
;
version.s = "0.1"
Structure ImageData
width.l
height.l
colors.l
chars.l
bits.b
EndStructure
Global IData.ImageData, BmpSize, BmpImage, FileSize, loaded.b, WindowWidth, WindowHeight, ImgWidth, ImgHeight, MenuHeight, xImg, yImg, ParentHandle, ptMinTrackSizex, aspect.f, hDC
*BmpFile.BITMAPFILEHEADER
*BmpInfo.BITMAPINFOHEADER
bmp.BITMAP
#BI_RGB = 0
Global File.s, gpPicture
gpPicture = 0
pstm = 0
#E_POINTER = $80000005
#E_NOINTERFACE = $80000004
#E_OUTOFMEMORY = $80000002
#IPicture_Release = 8
#IPicture_Get_Width = 24
#IPicture_Get_Height = 28
#IPicture_Render = 32
Global lphmwidth, lphmheight
ptMinTrackSizex = 320
Global nwidth, nheight, hmheight, hmwidth, rc.RECT
Procedure UpdateImage()
If loaded
ImgHeight = WindowHeight
ImgWidth = ImgHeight*aspect
If ImgWidth>WindowWidth
ImgWidth = WindowWidth
ImgHeight = ImgWidth/aspect
EndIf
If WindowWidth=ptMinTrackSizex And ImgWidth> 16
UpdateImage()
If loaded
SetWindowText_(ParentHandle, "Picture View - "+File+" "+StrF(((ImgWidth/IData\width)*100), 2)+"%")
EndIf
EndIf
Case #WM_PAINT
result = UpdateImage()
EndSelect
ProcedureReturn result
EndProcedure
Main:
tab.s = Chr(9)
open.s = tab+"Ctrl+O"
save.s = tab+"Ctrl+S"
tabquit.s = tab+"Ctrl+Q"
cien.s = tab+"Ctrl+Alt+0"
zoomin.s = tab+"+"
zoomout.s = tab+"-"
copy.s = tab+"Ctrl+C"
paste.s = tab+"Ctrl+V"
#Open = 0
#Save = 1
#Quit = 2
#Actual = 3
#Zoom_In = 4
#Zoom_Out = 5
#Copy = 6
#Paste = 7
OleInitialize_(0)
If OpenWindow(0, 100, 100, 480, 320, #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget, "Little Image Tool")
ParentHandle = WindowID()
If CreateMenu(0, ParentHandle)
MenuTitle("&File")
MenuItem(#Open, "&Open"+open)
MenuBar()
MenuItem(#Save, "&Save as..."+save)
MenuBar()
MenuItem(#Quit, "&Quit"+tabquit)
MenuTitle("&Tools")
MenuItem(#Actual, "100%"+cien)
MenuItem(#Zoom_In, "Zoom in"+zoomin)
MenuItem(#Zoom_Out, "Zoom out"+zoomout)
MenuBar()
MenuItem(#Copy, "&Copy"+copy)
MenuItem(#Paste, "Paste"+paste)
EndIf
DragAcceptFiles_(ParentHandle, #TRUE)
MenuHeight = GetSystemMetrics_(#SM_CYCAPTION)+GetSystemMetrics_(#SM_CYMENU)+8
Brush.LOGBRUSH\lbColor = 0
SetClassLong_(ParentHandle, #GCL_HBRBACKGROUND, CreateBrushIndirect_(Brush))
If CreateGadgetList(ParentHandle)
CreateImage(0, WindowWidth(), WindowHeight())
ImageGadget = ImageGadget(0, 0, MenuHeight, WindowWidth(), WindowHeight()+MenuHeight, UseImage(0))
hDC = GetDC_(ImageGadget)
WindowWidth = WindowWidth()
WindowHeight = WindowHeight()
SetWindowCallback(@ResizeCallback())
File = ProgramParameter()
Gosub OpenFile
SetForegroundWindow_(ParentHandle)
AddKeyboardShortcut(0, #PB_Shortcut_O|#PB_Shortcut_Control, #Open)
AddKeyboardShortcut(0, #PB_Shortcut_S|#PB_Shortcut_Control, #Save)
AddKeyboardShortcut(0, #PB_Shortcut_Q|#PB_Shortcut_Control, #Quit)
AddKeyboardShortcut(0, #PB_Shortcut_Pad0|#PB_Shortcut_Alt|#PB_Shortcut_Control, #Actual)
AddKeyboardShortcut(0, #PB_Shortcut_Add, #Zoom_In)
AddKeyboardShortcut(0, #PB_Shortcut_Subtract, #Zoom_Out)
AddKeyboardShortcut(0, #PB_Shortcut_C|#PB_Shortcut_Control, #Copy)
AddKeyboardShortcut(0, #PB_Shortcut_V|#PB_Shortcut_Control, #Paste)
Repeat
Select WaitWindowEvent()
Case #PB_EventMenu
Select EventMenuID()
Case #Open
Gosub Open
Case #Save
Gosub Save
Case #Quit
Quit = 1
Case #Actual
Gosub ActualPixels
Case #Zoom_In
Gosub ZoomIn
Case #Zoom_Out
Gosub ZoomOut
Case #Copy
Gosub Copy
Case #Paste
Gosub Paste
EndSelect
Case #WM_DROPFILES
AllocateMemory(3, 256, 0)
hDrop = EventwParam()
DragQueryFile_(hDrop, 0, MemoryID(), 256)
File = PeekS(MemoryID())
FreeMemory(3)
DragFinish_(hDrop)
Gosub OpenFile
Case #PB_EventCloseWindow
Quit = 1
EndSelect
Until Quit
EndIf
EndIf
OleUninitialize_()
End
;
; Actual pixels (100%)
;
ActualPixels:
If loaded
ResizeWindow(nwidth, nheight+MenuHeight)
SetWindowText_(ParentHandle, "Picture View - "+File+" 100%")
EndIf
Return
;
; Zoom out
;
ZoomOut:
If loaded
ResizeWindow(ImgWidth/2, (ImgHeight/2)+MenuHeight)
delayed = 0
EndIf
Return
;
; Zoom in
;
ZoomIn:
If loaded
ResizeWindow(ImgWidth*2, (ImgHeight*2)+MenuHeight)
delayed = 0
EndIf
Return
;
; Open image directly
;
OpenFile:
extension.s = LCase(Right(File, 4))
If extension=".gif" Or extension=".jpe" Or extension=".jpg" Or extension=".bmp"
Gosub OpenPicture
Gosub ShowImage
Gosub ActualPixels
EndIf
Return
;
; Open image request
;
Open:
File = OpenFileRequester("Open image file","","Windows BMP Image (*.bmp)|*.bmp|GIF Image (*.gif)|*.gif|Jpeg Image (*.jpg)|*.jpe;*.jpg", 0)
extension.s = LCase(Right(File, 4))
If extension=".gif" Or extension=".jpe" Or extension=".jpg" Or extension=".bmp"
Gosub OpenPicture
Gosub ShowImage
Gosub ActualPixels
EndIf
Return
;
; Save
;
Save:
If loaded
File = SaveFileRequester("Save image file","","Windows BMP Image (*.bmp)|*.bmp", 0)
If Len(File)>0
SaveImage(0, File)
EndIf
EndIf
Return
;
; Copy image to clipboard
;
Copy:
If loaded
SetClipboardData(#PB_ClipboardImage, ImageID())
EndIf
Return
;
; Paste image
;
Paste:
OpenClipboard_(ParentHandle)
If IsClipboardFormatAvailable_(#CF_BITMAP)
If loaded
DeleteObject_(iHwnd)
FreeMemory(0)
Else
FreeImage(0)
EndIf
ciHwnd = GetClipboardData_(#CF_BITMAP)
GetObject_(ciHwnd, SizeOf(BITMAP), @bmp)
SelectObject_(hDC, ciHwnd)
IData\width = bmp\bmWidth
IData\height = bmp\bmHeight
IData\bits = bmp\bmBitsPixel*bmp\bmPlanes
pad = (bmp\bmWidthBytes-IData\width)*IData\height
iHwnd = CreateCompatibleBitmap_(hDC, IData\width, IData\height)
loaded = 1
aspect = IData\width/IData\height
RGBQuad = 0
If IData\bits>3))+pad
BmpImage = AllocateMemory(0, BmpSize, 0)
*BmpInfo = BmpImage+SizeOf(BITMAPFILEHEADER)
*BmpInfo\biSize = SizeOf(BITMAPINFOHEADER)
*BmpInfo\biWidth = IData\width
*BmpInfo\biHeight = IData\height
*BmpInfo\biPlanes = 1
*BmpInfo\biBitCount = IData\bits
*BmpInfo\biCompression = #BI_RGB; Currently supports only uncompressed images
GetDIBits_(hDC, ciHwnd, 0, IData\height, BMPImage+SizeOf(BITMAPFILEHEADER)+SizeOf(BITMAPINFOHEADER)+2+RGBQuad, BMPImage+SizeOf(BITMAPFILEHEADER), #DIB_RGB_COLORS)
CopyMemory(*BmpInfo, BmpImage+SizeOf(BITMAPFILEHEADER), SizeOf(BITMAPINFOHEADER)+RGBQuad+2)
FreeMemory(1)
*BmpFile = BmpImage
*BmpFile\bfType = 19778
*BmpFile\bfOffBits = SizeOf(BITMAPFILEHEADER)+SizeOf(BITMAPINFOHEADER)+RGBQuad+2
*BmpFile\bfSize = BmpSize
*BmpFile\bfReserved1 = 0
*BmpFile\bfReserved2 = 0
SetDIBits_(hDC, iHwnd, 0, IData\height, BmpImage+*BmpFile\bfOffBits, BmpImage+SizeOf(BITMAPFILEHEADER), 0)
ResizeWindow(IData\width, IData\height+MenuHeight)
EndIf
CloseClipboard_()
Return
;
; Open image file
;
OpenPicture:
If ReadFile(0, File)
LoadLibrary_("OLEPRO32.DLL")
LoadLibrary_("ADVAPI32.DLL")
LoadLibrary_("OLEAUT32.DLL")
FileSize = FileSize(File)
If loaded
FreeMemory(0)
EndIf
hGlobal = GlobalAlloc_(#GMEM_MOVEABLE, FileSize);
pvData = GlobalLock_(hGlobal)
ReadData(pvData, FileSize)
CloseFile(0)
GlobalUnlock_(hGlobal)
CreateStreamOnHGlobal_(hGlobal, #TRUE, @pstm)
If gpPicture
CallCOM(#IPicture_Release, gpPicture)
EndIf
Select OleLoadPicture_(pstm, FileSize, #FALSE, ?IID_IPicture, @gpPicture)
Case #E_POINTER
Error = 222
Case #E_NOINTERFACE
Error = 223
Case #E_OUTOFMEMORY
Error = 224
Default
Error = 0
EndSelect
CallCOM(#IPicture_Release, pstm)
GlobalFree_(hGlobal)
xscreenpixels = GetDeviceCaps_(hDC, #LOGPIXELSX)
yscreenpixels = GetDeviceCaps_(hDC, #LOGPIXELSY)
CallCOM(#IPicture_Get_Width, gpPicture, @hmwidth)
CallCOM(#IPicture_Get_Height, gpPicture, @hmheight)
nwidth = (hmwidth*xscreenpixels)/2540
nheight = (hmheight*yscreenpixels)/2540
ResizeGadget(0, 0, 0, nwidth, nheight)
ResizeWindow(nwidth, nheight+MenuHeight)
rc.RECT
GetClientRect_(ImageGadget, @rc)
ps.PAINTSTRUCT
ps\hdc = hDC
ps\fErase = 1
ps\rcPaint = @rc
aspect = nwidth/nheight
loaded = 1
UpdateImage()
EndIf
Return
;
; Save Bmp file
;
SaveBmp:
If CreateFile(0, File)
WriteData(BmpImage, *BmpFile\bfSize)
CloseFile(0)
EndIf
Return
;
; Show image
;
ShowImage:
Return
If BmpImage
If loaded
DeleteObject_(iHwnd)
Else
FreeImage(0)
EndIf
ResizeWindow(IData\width, IData\height+MenuHeight)
iHwnd = CreateCompatibleBitmap_(GetDC_(ParentHandle), IData\width, IData\height)
DestroyWindow_(ImageGadget)
ImageGadget = ImageGadget(0, 0, MenuHeight, IData\width, IData\height, iHwnd)
hDC = GetDC_(ImageGadget)
SetDIBits_(hDC, iHwnd, 0, IData\height, BmpImage+*BmpFile\bfOffBits, BmpImage+SizeOf(BITMAPFILEHEADER), 0)
loaded = 1
aspect = IData\width/IData\height
SetForegroundWindow_(ParentHandle)
UpdateImage()
EndIf
Return
![section .data]
IID_IPicture:
!dd $07bf80980
!dw $0bf32, $0101a
!db $08b, $0bb, 0, $0aa, 0, $030, $0c, $0ab