/* Demonstration program showing use of DevIL/OpenIL to load and modify variety of image types Written by Rich Schafermeyer 2005 Uses includes and DevIL library for Ibasic made by Todd Riggins [www.exodev.com] Link to Todd's includes and library is at http://www.pyxia.com/community/viewtopic.php?t=9041 Information on DevIL can be found at http://openil.sourceforge.net/ ' -------Version 1.02 Modifications in 1.02: added copy/paste to/from Clipboard, added convert to edges effect, added crop action Modifications in 1.01: added 1 level of undo, added restore, set rotate to 90 degrees instead of 45 degrees, allow overwriting of existing file on save, resize window if image greater than 400 by 350, change window caption to show file name ' Instructions: 1. Open Image 2. Select modification(s) 3. Modifications can be applied multiple times to add more of same effect, eg, pixelate 4. Can save image in original file format or convert to new format 5. To crop, choose from menu, then select region of image using the mouse 6. Press "L" or "l" to load an image (removed from code) 7. Press "S" or "s" to save an image ' 'Modified July 2019 by Brian Pugh 8. Press "U" or "u" to undo a modification 9. Press "R" or "r" to restore an image 10. Removed loadfile menuitem and relevant code 11. Added custom BrowseForFolder and FileListBox - from ebknoppert, now Freeware 12. Added Vertical and Horizontal Splitter Bars 13. Added Statusbar, showing filename and file's path 14. Adjusted picture dimensions to display correctly given width of Splitter and depth of Statusbar 15. Window adjusts to width and depth of loaded image; unless... 16. If image width or depth is less than 1024 x 768, windows size stays at 1024 x 768 17. Changed Save Image filter to reflect all file types that can be saved with DevIL 18. Pressing Cursor Up (enlarge) or Cursor Down (reduce) resizes a loaded image. Needs work! 19. Added filter when loading files to show most file types - only .tiff, .rgba, .bw, .jpeg missing from filter code I can live with that! 20. Now using DevIL 1.8.0 DLLs 21. Added an 'About' box, showing DevIL DLL versions 22. Added background colour to the BrowseForFolder and FileListBox controls 23. Added code to load and save last-used directory in ini file (DevIL.ini) 24. Added DevIl icon to statusbar and window caption 25. Removed the Cursor Up and Down keystrokes to enlarge/reduce an image, as it stopped the user from selecting a file in the filelistbox, and then using the cursor keys to move up and down the list 26. Added code in the Filter() SUB to speed up file listings 27. Added accelerator shortcut keys for Reduce (F5), Enlarge (F8), and Undo (Spacebar) 28. Removed all keyboard shortcuts, except for the new accelerators just added 29. Added dialog box showing keyboard shortcuts */ autodefine "off" $include "windowssdk.inc" $include "Commctrl.inc" $include "il.inc" $include "ilu.inc" $include "ilut.inc" $include "ctl.inc" $INCLUDE "Uxtheme.inc" $USE "Uxtheme.lib" 'Declare to initialise pbsctrl.dll $use "pbsctrl.lib" DECLARE IMPORT,InitPBSoftCtrls(),INT InitPBSoftCtrls() WINDOW win,winV,winH DIALOG d1,d2 FILE ini INT bitmap,bitmap2,bitmap3,x,y,w,h,pixelsize,i,drawrectangle,pos INT selection,buttondn,xstart,ystart,xend,yend,w1,l,t,h1,w2,h2 INT xmax,ymax,temp,bf,fl,min,max,currentsplitter,loop INT left,top,width,height,panes[2],splitWidth,sbarHeight,ww,hh,fError,ret UINT hDC,hInst,BFFhWnd ISTRING filename$[260],filenamesave$[260],directory$[260],showfilename$[260] ISTRING tempfilename$[260],a$[260],StartPath[260],Paths[260],filter[528] POINTER image[5] TYPE OPENFILENAME INT lStructSize INT hWndOwner INT hInstance POINTER lpstrFilter POINTER lpstrCustomFilter INT nMaxCustFilter INT nFilterIndex POINTER lpstrFile INT nMaxFile POINTER lpstrFileTitle INT nMaxFileTitle POINTER lpstrInitialDir POINTER lpstrTitle INT flags WORD nFileOffset WORD nFileExtensioN POINTER lpstrDefExt INT lCustData INT lpfnHook POINTER lpTemplateName ENDTYPE TYPE OPENFILENAMEEX OPENFILENAME ofn POINTER pvReserved UINT dwReserved UINT FlagsEx ENDTYPE OPENFILENAMEEX ofn SETID "OFN_ALLOWMULTISELECT",0x200 SETID "OFN_ENABLEHOOK",0x20 SETID "OFN_EXPLORER",0x80000 SETID "OFN_HIDEREADONLY",0x4 SETID "OFN_NONETWORKBUTTON",0x20000 SETID "OFN_OVERWRITEPROMPT",0x2 DECLARE zFileRequest(title:STRING,parent:POINTER,nOpen:INT,OPT filter:STRING,OPT ext:STRING,OPT flags:INT,OPT initdir:STRING),HEAP DECLARE ofnIBHookProc2(hDlg:UINT,uiMsg:UINT,wParam:UINT,lParam:UINT),INT DECLARE IMPORT,PathFindExtensionA(pszPath:POINTER),STRING DECLARE IMPORT,PathIsDirectoryA(pszPath:POINTER),INT 'Constants 'CONST WM_COMMAND=0x111 'CONST WS_HSCROLL=0x100000 'CONST LB_GETCURSEL=0x188 'CONST LB_SETCURSEL=0x186 'CONST LB_GETTEXT=0x189 'CONST LB_DELETESTRING=0x182 'CONST LB_GETCOUNT=0x18B CONST WM_USER=0x400 CONST BFF=300 CONST BFF_CLEAR =WM_USER+10000 'Remove all items from Treeview. CONST BFF_REFRESH =WM_USER+10001 'Forces a repaint. CONST BFF_PATH =WM_USER+10002 'New path, lParam is pszString CONST BFF_PATHBYPIDL =WM_USER+10003 'New path, wParam = %CSIDL_.. CONST BFF_JUMPTOPATH =WM_USER+10004 'Set to path. Selects the item with corresponding path, lParam is pszString CONST BFF_GETPATH =WM_USER+10005 'Returns path placed in provided buffer. wparam = size of empty buffer, lparam = pointer to buffer CONST BFF_GETPATHLEN =WM_USER+10006 'Use this to prepare a buffer. CONST BFF_EXPANDFIRSTITEM=WM_USER+10007 'Opens/closes the first treeview item, wParam is switch CONST BFF_READY=1 CONST BFF_SELCHANGE=2 CONST FLB=301 CONST FLB_BACKCOLOR =WM_USER+1000 'wParam is new RGB() CONST FLB_GETBACKCOLOR=WM_USER+1001 'Get backcolor CONST FLB_FORECOLOR =WM_USER+1002 'wParam is new RGB() CONST FLB_GETFORECOLOR=WM_USER+1003 'Get forecolor set CONST FLB_PATH =WM_USER+1004 'wParam is size of buffer set in lParam, 0 for szstring, lParam is buffer containing new path CONST FLB_GETPATH =WM_USER+1005 'wParam is size of buffer to fill, 0 for returning len required, lParam is buffer to fill CONST FLB_GETITEM =WM_USER+1006 'wParam is size of buffer to fill, 0 for returning len required, lParam is buffer to fill CONST FLB_SHOWICONS =WM_USER+1007 'wParam is Boolean CONST FLB_CLEAR =WM_USER+1008 'Empties control CONST FLB_REFRESH =WM_USER+1009 'Refills the control 'Treeview constants CONST TV_FIRST=0x1100 CONST TVM_SETBKCOLOR=(TV_FIRST+29) 'CONST TVM_SELECTITEM=(TV_FIRST+11) 'CONST TVGN_FIRSTVISIBLE=0x5 'CONST TVGN_CARET=0x9 'CONST TVGN_DROPHILITE=0x8 'About box constants CONST STATIC_1=501 CONST STATIC_2=502 CONST STATIC_3=503 CONST BUTTON_3=504 'Statusbar constants CONST CCM_FIRST=0x2000 CONST SB_SETBKCOLOR=(CCM_FIRST+1) CONST SB_SETICON=(WM_USER+15) INITCOMMONCONTROLSEX icc icc.dwSize=LEN(icc) icc.dwICC= ICC_BAR_CLASSES | ICC_LINK_CLASS | ICC_LISTVIEW_CLASSES | ICC_PROGRESS_CLASS | ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS InitCommonControlsEx (&icc) 'Check for ini file - if missing, write an ini file with default startup path and use that path for initial viewing fError=OPENFILE(ini,GETSTARTPATH+"DevIL.ini","R") IF fError<>0 CLOSEFILE ini OPENFILE(ini,GETSTARTPATH+"DevIL.ini","W") WRITE ini,GETSTARTPATH CLOSEFILE ini StartPath=GETSTARTPATH ELSE OPENFILE(ini,GETSTARTPATH+"DevIL.ini","R") READ ini,StartPath CLOSEFILE ini ENDIF SetCurrentDirectoryA(StartPath) ret=PathIsDirectoryA(StartPath) IF ret=0 MESSAGEBOX win,"Your last accessed directory is not available:\nUsing "+UCASE$(GETSTARTPATH),"Path error",48 SetCurrentDirectoryA(GETSTARTPATH) ENDIF OPENWINDOW win,0,0,1024,768,@MINBOX|@MAXBOX|@SIZE|@NOAUTODRAW|@MAXIMIZED,0,"DevIL Image Viewer",&mainwindow SETWINDOWCOLOR win,RGB(190,190,190) CONTROL win,@STATUS,"Status",0,0,0,0,0,200 GETCLIENTSIZE win,left,top,width,height panes=width/2,-1 CONTROLCMD win,200,@SWSETPANES,2,panes CONTROLCMD win,200,@SWSETPANETEXT,0,"DevIL 1.8.0" CONTROLCMD win,200,@SWSETPANETEXT,1,StartPath SENDMESSAGE win,SB_SETBKCOLOR,0,RGB(240,240,240),200 'Set Statusbar Colour UINT hIcon=LoadIconFromFile(GETSTARTPATH+"DevIL.ico") 'Load icon StatusBarPaneSetIcon(win,200,0,hIcon) 'Set Statusbar icon SETICON(win,hIcon) 'Set Window icon BEGINMENU win MENUTITLE "&File" MENUITEM "&Save Image",0,2 SEPARATOR MENUITEM "&Quit",0,3 ENDMENU BEGININSERTMENU win,1 MENUTITLE "&Edit" MENUITEM "&Undo\tSpace",0,100 MENUITEM "&Restore original",0,101 SEPARATOR MENUITEM "C&ut",0,102 MENUITEM "&Copy",0,103 MENUITEM "&Paste",0,104 SEPARATOR MENUITEM "Crop",0,105 ENDMENU BEGININSERTMENU win,2 MENUTITLE "&Modify" BEGINPOPUP "Flip" MENUITEM "&Vertically",0,14 MENUITEM "&Horizontally",0,15 ENDPOPUP BEGINPOPUP "Rotate 90 Degrees" MENUITEM "&Clockwise",0,19 MENUITEM "&Counterclockwise",0,25 ENDPOPUP BEGINPOPUP "Zoom" MENUITEM "&Enlarge\tF8",0,20 MENUITEM "&Reduce\tF5",0,21 ENDPOPUP SEPARATOR BEGINPOPUP "Blur" MENUITEM "&Average",0,11 MENUITEM "&Gaussian",0,12 ENDPOPUP MENUITEM "&Pixelate",0,18 MENUITEM "&Sharpen",0,22 MENUITEM "&Emboss",0,13 MENUITEM "&Convert to Edges",0,26 MENUITEM "&Add Noise",0,17 SEPARATOR MENUITEM "&Invert Colors",0,16 MENUITEM "&Alien Colors",0,10 MENUITEM "&More Contrast",0,23 MENUITEM "&Less Contrast",0,24 MENUTITLE "&Help" MENUITEM "&Shortcuts...",0,109 SEPARATOR MENUITEM "&About...",0,110 ENDMENU FOR i=100 TO 105 ENABLEMENUITEM win,i,0 NEXT i 'Accelerators ADDACCELERATOR win,@FVIRTKEY,0x77,20 'F5 key reduces image ADDACCELERATOR win,@FVIRTKEY,0x74,21 'F8 key enlarges image ADDACCELERATOR win,@FVIRTKEY,ASC(" "),100 'Spacebar undoes last action CreateSplitter(win,winV,0,400,-1,6,-1,50) SetSplitterColors(winV,RGB(128,128,128),RGB(128,0,128)) SetSplitterMin(winV,200) CreateSplitter(win,winH,1,0,320,200,6,51) SetSplitterColors(winH,RGB(128,128,128),RGB(128,0,128)) SetSplitterMin(winH,200) hInst=GetModuleHandleA(win.hWnd) CreateWindowExA(0x200,"BrowseForFolder","",0x56830027,0,0,0,0,win.hWnd,BFF,hInst,0) CreateWindowExA(0x200,"FileListBox","",0x56A10103|@HSCROLL,0,0,0,0,win.hWnd,FLB,hInst,0) Paths=StartPath BFFhWnd=GetDlgItem(win.hWnd,BFF) SENDMESSAGE BFFhWnd,TVM_SETBKCOLOR,0,RGB(240,240,240) SENDMESSAGE BFFhWnd,BFF_EXPANDFIRSTITEM,1,0 SENDMESSAGE win,BFF_JUMPTOPATH,LEN(Paths),Paths,BFF bf=SENDMESSAGE win,BFF_GETPATHLEN,0,0,BFF SENDMESSAGE win,FLB_SHOWICONS,1,0,FLB SENDMESSAGE win,FLB_BACKCOLOR,RGB(240,240,240),0,FLB IF bf>0 Paths=STRING$(bf,0) bf=SENDMESSAGE win,BFF_GETPATH,bf,Paths,BFF Paths=LEFT$(Paths,bf) SENDMESSAGE win,FLB_PATH,bf,Paths,FLB SENDMESSAGE win,FLB_REFRESH,bf,Paths,FLB ENDIF FilterFiles() SETCURSOR winV,@CSCUSTOM,LoadCursorA(0,IDC_SIZEWE) SETCURSOR winH,@CSCUSTOM,LoadCursorA(0,IDC_SIZENS) SizeControls() pixelsize=1 x=0 y=0 filter="Windows Bitmap (*.bmp)|*.bmp|C-style Header (*.h)|*.h|DirectDraw Surface (*.dds)|*.dds|JPEG (*.jpg)|*.jpg|" filter+="JPEG (*.jpe)|*.jpe|JPEG (*.jpeg)|*.jpeg|Palette (*.pal)|*.pal|ZSoft PCX (*.pcx)|*.pcx|" filter+="Portable Network Graphics (*.png)|*.png|PNM (*.pbm)|*.pbm|PNM (*.pgm)|*.pgm|PNM (*.ppm)|*.ppm|Adobe Photoshop (*.psd)|*.psd|Raw Data (*.raw)|*.raw|" filter+="Silicon Graphics (*.sgi)|*.sgi|Silicon Graphics (*.bw)|*.bw|Silicon Graphics (*.rgb)|*.rgb|Silicon Graphics (*.rgba)|*.rgba|" filter+="Targa (*.tga)|*.tga|TIF (*.tif)|*.tif|TIF (*.tiff)|*.tiff||" 'Initiate DevIL/OpenIL xInitIL() ilEnable(il_file_overwrite) 'On save, allows overwriting of existing file CREATEDIALOG d1,0,0,300,110,0x80C00080,win,"About DevIL Image Viewer",&d1_handler CONTROL d1,@STATIC,"DevIL DLL 1.8.0",14,18,200,20,0x5000010B,STATIC_1 CONTROL d1,@STATIC,"Ilu, Ilut DLLs 1.8.0",14,46,200,20,0x5000010B,STATIC_2 CONTROL d1,@BUTTON,"OK",100,78,100,20,0x50000000,BUTTON_3 CREATEDIALOG d2,0,0,300,140,0x80C00080,win,"Keyboard shortcuts",&d2_handler CONTROL d2,@STATIC,"F5 - reduce image size",14,18,200,20,0x5000010B,STATIC_1 CONTROL d2,@STATIC,"F8 - enlarge image size",14,46,200,20,0x5000010B,STATIC_2 CONTROL d2,@STATIC,"Spacebar - Undo last action",14,74,200,20,0x5000010B,STATIC_3 CONTROL d2,@BUTTON,"OK",100,106,100,20,0x50000000,BUTTON_3 ' GET THE TREEVIEW HANDLE INT tv_hwnd = GetDlgItem(win.hWnd, BFF) ' MODIFY THE TREEVIEW IF tv_hwnd THEN ' SHOW ALWAYS THE SELECTION ON THE TREEVIEW LONG lStyle = GetWindowLong(tv_hwnd, GWL_STYLE) lStyle = lStyle | TVS_SHOWSELALWAYS ' lStyle = lStyle & NOT(TVS_HASLINES) ' <-- if you want to remove the treeview lines uncomment this SetWindowLong(tv_hwnd, GWL_STYLE, lStyle) ' SET WINDOWS EXPLORER STYLE / YOU MUST USE A .MANIFEST FILE SetWindowTheme(tv_hwnd, L"explorer", NULL) ' the treeview is unicode!! ' SET INITIAL FOCUS ON THE TREEVIEW _SetFocus(tv_hwnd) ENDIF INT subclassID = 12345 HBRUSH hbrBkgnd = NULL ' SUBCLASS win DIALOG TO PAINT LISTBOX BACKGROUND & ITEMS USING WM_CTLCOLORLISTBOX MESSAGE SetWindowSubclass(win.hwnd, &subclassProc, subclassID, 0) ' IMAGE PADDING INT paddingX = 0 INT paddingY = 0 ' --------------------------- WAITUNTIL IsWindowClosed(win) ' --------------------------- RemoveWindowSubclass(win.hwnd, &subclassProc, subclassID) IF(bitmap) THEN DELETEIMAGE bitmap,@IMGBITMAP IF(bitmap2) THEN DELETEIMAGE bitmap2,@IMGBITMAP IF(bitmap3) THEN DELETEIMAGE bitmap3,@IMGBITMAP xShutdownIL() DeleteObject(hIcon) IF StartPath="" THEN StartPath=GETSTARTPATH OPENFILE(ini,GETSTARTPATH+"DevIL.ini","W") WRITE ini,StartPath CLOSEFILE ini END SUB subclassProc(hWnd:INT,uMsg:INT,wParam:INT,lParam:INT,uIdSubclass:UINT_PTR,dwRefData:DWORD_PTR),INT HDC hDC PAINTSTRUCT Ps WINRECT rc SELECT uMsg CASE WM_CTLCOLORLISTBOX ' PAINT FILELISTBOX IF lParam = GetDlgItem(win.hWnd, FLB) THEN HDC hdcStatic = wParam SetTextColor(hdcStatic, RGB(0,0,0)) SetBkColor(hdcStatic, RGB(240,240,240)) IF hbrBkgnd = NULL THEN hbrBkgnd = CreateSolidBrush(RGB(240,240,240)) RETURN hbrBkgnd ENDIF CASE WM_PAINT ' PAINT THE IMAGE hDC = BeginPaint(hWnd, &Ps) GetClientRect(hWnd, rc) OnPaint(hDC, rc) EndPaint(hWnd, &Ps) RETURN 0 ENDSELECT RETURN DefSubclassProc(hWnd, uMsg, wParam, lParam) ENDSUB SUB OnPaint(INT hDC, WINRECT rc) ' start double buffer INT hdcMem = CreateCompatibleDC(hDC) HBITMAP memBM = CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top) HBITMAP OldmemBM = SelectObject(hdcMem, memBM) ' paint background color HBRUSH hbrBkgnd = CreateSolidBrush(RGB(190,190,190)) FillRect(hdcMem, rc, hbrBkgnd) DeleteObject(hbrBkgnd) ' paint image PaintImage(hdcMem, rc) ' finish double buffer BitBlt(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hdcMem, 0, 0, SRCCOPY) SelectObject(hdcMem, OldmemBM) DeleteObject(memBM) DeleteDC(hdcMem) ENDSUB SUB PaintImage(INT hDC, WINRECT rc) BITMAP bit INT hdcMem = CreateCompatibleDC(hDC) INT oldBitmap = SelectObject(hdcMem, bitmap) GetObject(bitmap, LEN(bit), &bit) SetStretchBltMode(hDC, HALFTONE) StretchBlt(hDC, splitWidth + paddingX, paddingY, w, h, hdcMem, 0, 0, bit.bmWidth, bit.bmHeight, SRCCOPY) SelectObject(hdcMem, oldBitmap) DeleteDC(hdcMem) ENDSUB SUB mainwindow(),INT SELECT @MESSAGE CASE @IDCREATE CENTERWINDOW win CASE @IDCLOSEWINDOW CLOSEWINDOW win CASE WM_SPLITTERRBUTTONDN CASE& WM_SPLITTERLBUTTONDN CASE& WM_SPLITTERSIZED CASE& WM_SPLITTERSIZING currentsplitter=@WPARAM CASE& @IDSIZE RedrawWindow(win.hwnd, NULL, NULL, RDW_INVALIDATE) SizeControls() IF CONTROLEXISTS(win,200) CONTROLCMD win,200,@SWRESIZE GETCLIENTSIZE win,left,top,width,height panes=width/2,-1 CONTROLCMD win,200,@SWSETPANES,2,panes ENDIF CASE @IDCONTROL SELECT @CONTROLID 'Browse For Folder CASE BFF SELECT @NOTIFYCODE CASE BFF_SELCHANGE bf=SENDMESSAGE win,BFF_GETPATHLEN,0,0,BFF IF bf>0 Paths=STRING$(bf,"0") bf=SENDMESSAGE win,BFF_GETPATH,bf,Paths,BFF Paths=LEFT$(Paths,bf) SENDMESSAGE win,FLB_PATH,bf,Paths,FLB SENDMESSAGE win,FLB_REFRESH,bf,Paths,FLB FilterFiles() ENDIF StartPath=Paths CONTROLCMD win,200,@SWSETPANETEXT,1,StartPath ENDSELECT 'File List Box CASE FLB SELECT @NOTIFYCODE CASE @LBNSELCHANGE fl=SENDMESSAGE win,FLB_GETITEM,0,0,FLB IF fl>0 filename$=STRING$(fl,"0") fl=SENDMESSAGE win,FLB_GETITEM,fl,filename$,FLB loadfile() SETWINDOWCOLOR win,RGB(190,190,190) SETFOCUS win,FLB ENDIF ENDSELECT ENDSELECT CASE @IDMENUPICK SELECT @MENUNUM CASE 109 'keyboard help DOMODAL d2,win CASE 110 'About DOMODAL d1,win CASE 2 savefile() CASE 3 CLOSEWINDOW win CASE 10 'Alienify captureforundo() iluAlienify() updateimage() CASE 11 'Blur (average) captureforundo() iluBlurAvg(2) 'number of iterations, higher number is more blurred but slower updateimage() CASE 12 'Blur (gaussian) captureforundo() iluBlurGaussian(2) 'number of iterations, higher number is more blurred but slower updateimage() CASE 13 'Emboss captureforundo() iluEmboss() updateimage() CASE 14 'Flip captureforundo() iluFlipImage() updateimage() CASE 15 'Mirror captureforundo() iluMirror() updateimage() CASE 16 'Negative captureforundo() iluNegative() updateimage() CASE 17 'Noisify captureforundo() iluNoisify(0.2) '0.0=no noise, 1.0=extreme noise updateimage() CASE 18 'Pixelize captureforundo() pixelsize=pixelsize*4 'increase number to pixelate faster iluPixelize(pixelsize) updateimage() CASE 19 'Rotate Clockwise captureforundo() iluRotate(90) 'rotation degrees updateimage() CASE 20 'Enlarge captureforundo() iluEnlargeImage(1.5,1.5,1) 'multiplier of x,y,z dimension updateimage() CASE 21 'Reduce captureforundo() iluEnlargeImage(0.5,0.5,1) 'multiplier of x,y,z dimension updateimage() CASE 22 'Sharpen captureforundo() iluSharpen(1.5,2) '0.0-1.0 blurs while 1.0-2.5 increases sharpness/number of iterations increases effect updateimage() CASE 23 'More Contrast captureforundo() iluContrast(1.2) '1.0-1.7 increases contrast updateimage() CASE 24 'Less Contrast captureforundo() iluContrast(0.8) '0.0-1.0 decreases contrast updateimage() CASE 25 'Rotate CounterClockwise captureforundo() iluRotate(-90) 'rotation degrees updateimage() CASE 26 'Detect Edges captureforundo() iluEdgeDetectP() updateimage() CASE 100 'Undo ilutSetHBitMap(bitmap3) ENABLEMENUITEM win,100,0 updateimage() CASE 101 'Restore ilutSetHBitMap(bitmap2) ENABLEMENUITEM win,100,0 ENABLEMENUITEM win,101,0 FOR i=102 to 105 ENABLEMENUITEM win,i,1 NEXT i updateimage() CASE 102 'Cut ilutSetWinClipboard() deleteILimage() ENABLEMENUITEM win,104,1 CASE 103 'Copy ilutSetWinClipboard() CASE 104 'Paste ilutGetWinClipboard() FOR i=100 to 105 ENABLEMENUITEM win,i,1 NEXT i updateimage() CASE 105 'Crop captureforundo() cropdrawingmode() selection=1 ENDSELECT CASE @IDMOUSEMOVE IF ((selection=1)&(buttondn=1)) THEN RECT win,xstart,ystart,xend-xstart,yend-ystart,0 xend=@MOUSEX yend=@MOUSEY IF ((selection=1)&(buttondn=1)) THEN RECT win,xstart,ystart,xend-xstart,yend-ystart,0 CASE @IDLBUTTONDN xstart=@MOUSEX ystart=@MOUSEY buttondn=1 drawrectangle=1 CASE @IDLBUTTONUP buttondn=0 IF (selection=1) RECT win,xstart,ystart,xend-xstart,yend-ystart,0 cropimage() selection=0 ENDIF ENDSELECT RETURN 0 ENDSUB SUB loadfile() IF(bitmap) DELETEIMAGE bitmap,@IMGBITMAP ENDIF ilGenImages(1,image[1]) ilBindImage(image[1]) ilLoadImage(filename$) tempfilename$=filename$ hDC=gethdc(win) bitmap=ilutConvertToHBitmap(hDC) releasehdc(win,hDC) hDC=gethdc(win) bitmap2=ilutConvertToHBitmap(hDC) releasehdc(win,hDC) if(bitmap) SETWINDOWCOLOR win,RGB(190,190,190) getbitmapsize bitmap,ww,hh getclientsize win,l,t,w1,h1 INT _dx = w1 - splitWidth INT _dy = h1 - sbarHeight IF ww >= _dx THEN w = _dx paddingX = 0 ELSE w = ww paddingX = (_dx - w) / 2.0 ENDIF IF hh >= _dy THEN h = _dy paddingY = 0 ELSE h = hh paddingY = (_dy - h) / 2.0 ENDIF InvalidateRect(win.hwnd, NULL, NULL) for i=102 to 105 ENABLEMENUITEM win,i,1 next i parsefilename() SENDMESSAGE win,SB_SETBKCOLOR,0,RGB(89,198,133),200 'Set Statusbar Colour CONTROLCMD win,200,@SWSETPANETEXT,0,"Now viewing: "+UCASE$(a$)+" - "+STR$(ww)+" x"+STR$(hh) ENDIF ENDSUB SUB updateimage() getclientsize win,x,y,w,h rect win,0,0,w,h,rgb(255,255,255),rgb(255,255,255) hDC=gethdc(win) bitmap=ilutConvertToHBitmap(hDC) releasehdc(win,hDC) if(bitmap) getbitmapsize bitmap,w,h RedrawWindow(win.hwnd, NULL, NULL, RDW_INVALIDATE) ENDIF ENDSUB SUB deleteILimage() iluDeleteImage(image[1]) if(bitmap) THEN DELETEIMAGE bitmap,@IMGBITMAP getclientsize win,x,y,w,h rect win,0,0,w,h,rgb(255,255,255),rgb(255,255,255) deleteimage bitmap,@IMGBITMAP getclientsize win,x,y,w,h rect win,0,0,w,h,rgb(255,255,255),rgb(255,255,255) for i=101 to 105 ENABLEMENUITEM win,i,0 next i ENDSUB SUB captureforundo() for i=100 to 101 ENABLEMENUITEM win,i,1 next i hDC = gethdc(win) bitmap3=ilutConvertToHBitmap(hDC) releasehdc(win,hDC) ENDSUB SUB savefile() zFileRequest("Save Image",win,0,filter,"bmp",0,GETSTARTPATH) '0 for save - 1 for open IF (LEN(filenamesave$)=0) THEN RETURN tempfilename$=filenamesave$ parsefilename() CONTROLCMD win,200,@SWSETPANETEXT,0,"Saved as: "+a$ ilSaveImage(filenamesave$) SENDMESSAGE win,FLB_REFRESH,bf,Paths,FLB ENDSUB SUB parsefilename() a$=tempfilename$ i=0 DO pos=INSTR(a$,"\\") a$=RIGHT$(a$,LEN(a$)-pos) i=i+pos UNTIL pos=0 i=i directory$=LEFT$(tempfilename$,i) showfilename$=RIGHT$(tempfilename$,LEN(tempfilename$)-i) ENDSUB SUB cropdrawingmode() drawmode win,@transparent setlinestyle win,@lsdash,1 rastermode win,@rmnot ENDSUB SUB cropimage() 'OpenIL has the origin in LOWER left corner 'This is the reverse of normal window coordinates, where the origin is in the UPPER left corner normaldrawingmode() xmax=ilGetInteger(il_image_width) ymax=ilGetInteger(il_image_height) IF (xendxmax) then xend=xmax if (yend>ymax) then yend=ymax iluCrop(xstart,ymax-yend,0,xend-xstart,yend-ystart,0) updateimage() ENDSUB SUB normaldrawingmode() drawmode win,@transparent setlinestyle win,@lssolid,1 rastermode win,@rmcopypen ENDSUB SUB xInitIL() ilInit() iluInit() ilutInit() ENDSUB SUB xShutdownIL() ilShutDown() ENDSUB SUB FilterFiles() SendDlgItemMessage(win.hWnd,FLB,WM_SETREDRAW,0,0) 'Speeds up redraw INT count,x,y,flag,num ISTRING filename[260] ISTRING ext[8] ISTRING allowedextensions[128]=".BMP.CUT.DDS.GIF.ICO.CUR.JPG.JPE.LBM.LIF.LMP.MDL.MNG.PCD.PCX.PIC.PIX.PNG.PBM.PGM.PPM.PNM.PSD.PXR.SGI.RGB.TGA.TIF.WAL.XPM" count=SENDMESSAGE(win,LB_GETCOUNT,0,0,FLB)-1 num=(LEN(allowedextensions)/4)-1 FOR x=count TO 0 STEP - 1 flag=0 SENDMESSAGE win,LB_GETTEXT,x,filename,FLB ext=PathFindExtensionA(filename) FOR y=0 TO num IF UCASE$(ext)=MID$(allowedextensions,(4*y+1),4) flag=1 BREAKFOR ENDIF NEXT y IF flag=0 THEN SENDMESSAGE win,LB_DELETESTRING,x,0,FLB NEXT x SendDlgItemMessage(win.hWnd,FLB,WM_SETREDRAW,1,0) 'Reset redraw InvalidateRect(GETCONTROLHANDLE(win,FLB),0,1) ENDSUB SUB SizeControls() INT x1,y1,w1,h1,x2,y2,w2,h2 INT sbsx,sbsy,sbsw,sbsh GETSIZE win,sbsx,sbsy,sbsw,sbsh,200 sbarHeight=sbsh+2 GETCLIENTSIZE win,l,t,w,h GetSplitterPos(winV,x1,y1,w1,h1) GetSplitterPos(winH,x2,y2,w2,h2) IF x1>w-200 THEN x1=w-200 IF x1<200 THEN x1=200 SetSplitterPos(winV,x1,y1,w1,h) 'set the height of winV to client height h, also any adjustment to x1 IF y2>h-200 THEN y2=h-200 IF y2<200 THEN y2=200 SetSplitterPos(winH,x2,y2,x1,h2) 'set the width of winH to x1 of winV, also any adjustment to y2 GetSplitterPos(winV,x1,y1,w1,h1) GetSplitterPos(winH,x2,y2,w2,h2) SETSIZE win,0,0,x1,y2,BFF SETSIZE win,0,y2+h2-2,x1,h-y2-h2-20,FLB SetSplitterMax(winV,w-200) SetSplitterMax(winH,h-200) min=GetSplitterMin(winV) max=GetSplitterMax(winV) IF CONTROLEXISTS(win,200) CONTROLCMD win,200,@SWRESIZE GETCLIENTSIZE win,left,top,width,height panes=width/2,-1 CONTROLCMD win,200,@SWSETPANES,2,panes ENDIF splitWidth=w1+x1 'Set splitter true width ENDSUB SUB zFileRequest(title:STRING,parent:POINTER,nOpen:INT,OPT filter:STRING,OPT ext:STRING,OPT flags:INT,OPT initdir:STRING) POINTER pTest,p1,p2,mem,copymem INT bMulti,nReturn,x CHAR filtercopy[528] ISTRING strPath[260] ZeroMemory(ofn,LEN(OPENFILENAMEEX)) filtercopy[0]=0 mem=0 copymem=0 IF (GetVersion() & 0x000000FF) >= 5 ofn.ofn.lStructSize=LEN(OPENFILENAMEEX) ELSE ofn.ofn.lStructSize=LEN(OPENFILENAME) ENDIF ofn.ofn.lpstrTitle=title IF parent <> 0 THEN ofn.ofn.hWndOwner=#parent.hWnd pTest=filter IF pTest <> 0 x=0 DO IF filter[x]=ASC("|") THEN filtercopy[x]=0 ELSE filtercopy[x]=filter[x] x++ IF x > 527 THEN filter[x]=0 UNTIL filter[x]=0 filtercopy[x]=0 filtercopy[x+1]=0 ENDIF ofn.ofn.lpstrFilter=filtercopy ofn.ofn.lpstrDefExt=ext ofn.ofn.lpstrInitialDir=initdir ofn.ofn.lpfnHook=&ofnIBHookProc2 ofn.ofn.flags=@OFN_HIDEREADONLY | @OFN_EXPLORER | @OFN_ENABLEHOOK | @OFN_NONETWORKBUTTON ofn.ofn.flags=ofn.ofn.flags | flags IF (flags & @OFN_ALLOWMULTISELECT)=@OFN_ALLOWMULTISELECT bMulti=1 mem=ALLOCHEAP(30000) copymem=ALLOCHEAP(30000) ofn.ofn.lpstrFile=mem ofn.ofn.nMaxFile=32767 ELSE bMulti=0 copymem=ALLOCHEAP(528) ofn.ofn.lpstrFile=copymem ofn.ofn.nMaxFile=528 ENDIF IF nOpen=0 THEN ofn.ofn.flags=ofn.ofn.flags | @OFN_OVERWRITEPROMPT IF nOpen nReturn=GetOpenFileNameA(ofn) ELSE nReturn=GetSaveFileNameA(ofn) ENDIF IF(bMulti <> 0) IF nReturn <> 0 p1=mem p2=mem WHILE #p1 <> 0:p1=p1 + 1:ENDWHILE p1++ IF (p1 - p2) > ofn.ofn.nFileOffset lstrcpynA(copymem,mem,528) lstrcatA(copymem,"|") ELSE strPath=#p2 IF LEN(strPath) AND ( strPath[len(strPath)-1] <> ASC("\\") ) strPath=strPath+"\\" ENDIF #copymem=strPath p2=copymem p2=p2+lstrlenA(strPath) #p2=#p1 p2=p2+lstrlenA(p1) #p2="|" p2++ #p2=0 p1=p1+lstrlenA(p1)+1 DO #p2=strPath p2=p2+lstrlenA(strPath) #p2=#p1 p2=p2+lstrlenA(p1) #p2="|" p2++ #p2=0 p1=p1+lstrlenA(p1)+1 UNTIL #p1=0 ENDIF ENDIF FREEHEAP(mem) ENDIF IF nReturn=0 THEN #copymem="" filenamesave$=#copymem RETURN #copymem ENDSUB SUB ofnIBHookProc2(hDlg:UINT,uiMsg:UINT,wParam:UINT,lParam:UINT) WINDOW wTemp INT thWnd IF uiMsg=0x110 wTemp.hWnd=GetParent(hDlg) CENTERWINDOW wTemp thWnd=FindWindowExA(wTemp.hWnd,0,"SHELLDLL_DefView","") IF thWnd SENDMESSAGE thWnd,WM_COMMAND,0x702E,0 ENDIF ENDIF RETURN 0 ENDSUB 'Load an Icon from a file SUB LoadIconFromFile(STRING path),UINT RETURN _LoadImage(GetModuleHandle(0),path,IMAGE_ICON,16,16,LR_LOADFROMFILE) ENDSUB 'Set an icon to a pane SUB StatusBarPaneSetIcon(w:WINDOW,statusid:UINT,panenumber:INT,hIcon:UINT),INT RETURN SENDMESSAGE(w,SB_SETICON,panenumber,hIcon,statusid) ENDSUB SUB d1_handler(),INT 'About SELECT @MESSAGE CASE @IDINITDIALOG CENTERWINDOW d1 FOR loop=STATIC_1 TO STATIC_2 SETFONT d1,"Segoe UI",10,700,0x00FF0000,loop SETCONTROLCOLOR d1,loop,RGB(0,0,0),RGB(121,150,222) NEXT loop 'Colour the dialog window CASE WM_CTLCOLORDLG RETURN CreateSolidBrush(RGB(121,150,222)) CASE @IDCONTROL SELECT @CONTROLID CASE BUTTON_3 IF @NOTIFYCODE=0 CLOSEDIALOG d1,@IDOK ENDIF ENDSELECT ENDSELECT RETURN 0 ENDSUB SUB d2_handler(),INT 'Keyboard help SELECT @MESSAGE CASE @IDINITDIALOG CENTERWINDOW d2 FOR loop=STATIC_1 TO STATIC_3 SETFONT d2,"Segoe UI",10,700,0x00FF0000,loop SETCONTROLCOLOR d2,loop,RGB(0,0,0),RGB(121,150,222) NEXT loop 'Colour the dialog window CASE WM_CTLCOLORDLG RETURN CreateSolidBrush(RGB(121,150,222)) CASE @IDCONTROL SELECT @CONTROLID CASE BUTTON_3 IF @NOTIFYCODE=0 CLOSEDIALOG d2,@IDOK ENDIF ENDSELECT ENDSELECT RETURN 0 ENDSUB