Liberty Basic is develeopped by Carl Gundel Original Newsletter compiled by Alyce Watson and Brosco Translation to HTML: Raymond Roumeas
© 2000, Cliff Bros and Alyce Watson All Rights Reserved
- Writing output 'code'
- Launching the default web browser and email client
- Fun with the caret
- Timing and benchmarking
- Making professional-looking applications
- Do it with math?
We try to present a variety of articles to satisfy as many
different areas of interest, and as many levels of programming skill
as possible. If a particular newsletter does not appeal to you,
please be patient. Ideas for newsletter topics are always welcome, as
are submissions of articles. Thanks.
Liberty BASIC allows you to distribute your programs to the public. When you register, you get a password that gives you the ability to use the runtime engine to run your tokenized code.
The runtime engine is named "run.exe". You may make standalone programs by tokenizing your code with password. In version 1.42 of Liberty BASIC, you need only enter your username and password once in the Liberty BASIC editor, and all tokenized code created after that will automatically contain your password. Look in the Setup menu for "Enter registration code."
To make a TKN, load the desired BASIC code into the LB editor, and choose MAKE TKN from the RUN menu.
Once you have made a tkn, you must make a copy of the runtime engine and rename it to match the name of your tokenized file. If your tokenized file is called "cruncher.tkn", then rename "run.exe" to "cruncher.exe".
In addition to the TKN, the runtime engine, and any bitmaps, text files, or other files required by your program, you must include a set of runtime DLLs in your distribution package, so that people who do not have the Liberty BASIC language installed on their systems can run your program.
These DLLs must either be in the program directory, the Windows directory, the Windows/system directory, or in the user's path statement.
VWVM11.DLL VWBAS11.DLL VWSIGNON.DLL VWFONT.DLL VWFLOAT.DLL VWABORT.DLL VWDLGS.DLL
You must also include VWSIGNON.BMP. Here are the instructions for using and altering this bitmap, directly from the Liberty BASIC Helpfile:
c) You will want to edit the startup bitmap VWSIGNON.BMP to your liking using Paintbrush. The bitmap should not be more than 16 colors, and it shouldn't be much larger than the supplied example. These color and size restrictions are to minimize the possibility of protection faults happening during program startup.
Because of licensing issues for some development resources we used to create Liberty BASIC, your vwsignon.bmp file must make mention of:
Portions copyright 1991 Digitalk, Inc.
Take a look at the included VWSIGNON.BMP. The Digitalk, Inc copyright notice is very small. Feel free to do the same with the above required notices.
It is possible to change the icon that displays with your program from the Liberty BASIC torch default icon, to any 16 color icon of your choice. Remember that the format MUST be 16 colors.
To do this from within the Liberty BASIC editor, you must have your system set to 16 color display mode. You can do this in your Control Panel settings, or by booting in Safe Mode. This is a small bug in Liberty BASIC.
After you have placed your display in 16 color resolution, go to the Setup menu of the Liberty BASIC editor and choose, "Change runtime icon." Just follow the directions. When you are done, you may set your display resolution back to normal.
The runtime engine, run.exe contains the data for the runtime icon. Changing the icon simply requires that we remove the data for the torch icon from the file and replace it with the data for the desired 16 color icon.
Anthony Liquori has provided the code to accomplish this substitution. Using this method, we may change the runtime icon without changing the display color resolution of our systems. Brian Pugh has added a very nice gui. We'll use their code in our open source editor to provide a runtime icon changer.
Anthony has chosen to open, read and write to the runtime engine by using API calls. For an excellent explanation of file manipulation, Dean Hodgson's tutorial is a MUST HAVE.
Get it here: http://alyce.50megs.com/sss/
What follows is a brief summary of the method used to change the runtime icon. It is not a complete explanation.
The entire program is included in this newsletter, and it has been integrated into the open source editor, whose code is attached. This method requires intermediate to advanced understanding of API's and file manipulation in Liberty BASIC. It is great to know that we don't need to understand it to be able to use this handy tool.
First, the icon file is opened, and the data is read into a string variable called icont$:
open icon$ for input as #1icon 'open up the icon icont$=input$(#1icon,lof(#1icon)) 'read the icon close #1icon 'close icon
Anthony has determined the part of the icon data that will be needed. The header of the icon file will not be placed into the runtime engine, so the first 21 bytes will not be used. The part of the icon file that will be copied into the runtime engine starts at byte 22.
ico=hexdec("16") '= 22 in decimal numbers 'skip the header and put all the actual data into icondata$ icondata$=mid$(icont$,ico,len(icont$)) 'Editor's note: the above appears to be incorrect, and 'should be: icondata$=mid$(icont$,ico) or ' icondata$=mid$(icont$,ico,len(icont$)-ico)
Next, the runtime engine file is opened with the API
function, _lopen: ' Opens up runtime for write & read access and returns the handle into hFile calldll #kernel,"_lopen",runtime$ as ptr,_ _OF_WRITE as short,hFile as word
Be sure to check Dean's explanations or these functions! The function _llseek is used to position the pointer within the file. It is first positioned at the beginning of the file.
' Moves the file pointer to the beginning of the file, ' this is why i used apis instead of lb calldll #kernel,"_llseek",hFile as word,_ 0 as long,0 as short,result as long
Next, the file pointer is moved to the spot where the new data will be inserted. This is at position 6655, which is equivalent to hexdec("19ff")
runpos=hexdec("19ff") ' Moves to the position of the icon resource calldll #kernel,"_llseek",hFile as word,_ runpos as long,1 as short,result as long
With the pointer at the proper position, the icon data that was extracted from the icon file is written into place with the function _lwrite:
calldll #kernel,"_lwrite",hFile as word,icondata$ as ptr,_ iconlength as short,result as short
A file opened via API must be closed via API, with _lclose:
calldll #kernel,"_lclose",hFile as word,result as short
Here is a small program that also changes the icon in the runtime engine, but this one does it with straight Liberty BASIC functions -- no API calls. The comments serve as the documentation.
filedialog "Choose icon",DefaultDir$+"\*.ico",icon$ 'Open the chosen icon file and read the 'data into a string called t$: open icon$ for input as #1 t$=input$(#1,lof(#1)) close #1 'For demo purposes, unrem these lines to read file header: ' for i = 1 to 21 ' print asc(mid$(t$,i,1)) ' next i 'The first bytes are the header, so 'skip header and take data starting at 21: start=21 'Skip the header and put all the actual data into icondata$ icondata$=mid$(t$,start) 'Check to see if the icon is 32 x 32 by 'checking to see if byte 7 and byte 8 are chr$(32): if mid$(t$,7,1)<>chr$(32) or mid$(t$,8,1)<>chr$(32) then [wrong.size] 'Check to see if the icon is 16 color 'by checking byte 9 to see if it is chr$(16): if mid$(t$,9,1)<>chr$(16) then [wrong.color] filedialog "Choose runtime engine",DefaultDir$+"\*.exe",runtime$ 'Open runtime engine file and read it into 'a string called r$: open runtime$ for input as #2 r$=input$(#2,lof(#2)) close #2 cursor hourglass print "Please wait..." 'The position for icon data in runtime engine: runpos=6655 'The length of the actual icon data: length=len(icondata$) 'The position after icon data in runtime: newpos=runpos+length 'Concatenate data strings. The 'beginning of runtime file comes first, 'then replace icon data with icondata$, 'then append the end of the runtime file: newrun$=left$(r$,runpos-1)+icondata$+mid$(r$,newpos) 'Open a file called test.exe to make a test of the 'runtime engine with the new icon. 'Write the string of data to the file: open DefaultDir$+"\test.exe" for output as #test print #test, newrun$ close #test cursor normal print DefaultDir$+"\Test.exe contains new icon." input a$ [wrong.size] print "Error. Icon is not 32x32." end [wrong.color] print "Error. Icon is not 16 colors." end
It isn't difficult to extract and view icon files. Note that these files can be extracted for viewing from ICO, EXE and DLL files, but the runtime icon changer requires that the file be in ICO format.
The steps for icon extraction and viewing:
1) GetDC of your program's window with USER.
calldll #iconuser,"GetDC",_ hico as word,_ 'window handle hicodc as word 'returns handle of device context
2) Obtain the instance handle, with GetWindowWord from USER:
calldll #iconuser,"GetWindowWord",_ hico as word,_ 'window handle _GWL_HINSTANCE as word,- 'flag requesting instance handle hCurrentInst as word 'returns instance handle
3) The icon's handle is obtained with a call to SHELL to ExtractIcon:
calldll #iconshell,"ExtractIcon",_ hCurrentInst as word,_ 'instance handle szFile$ as ptr,_ 'name of file containing icon 0 as ushort,_ 'icon index, 0=first icon in file hicon as word 'returns handle of icon
4) Once the handle of the icon is obtained, it can be used in a call to USER to DrawIcon, which displays the icon on the window whose DC is used in the call, at the location specified. Note that this icon display is not flushed, which means that the icon will not 'stick' if the window is covered and then refreshed.
calldll #iconuser,"DrawIcon",_ hicodc as short,_ 'device context handle of window x as short,_ 'x location to display icon y as short,_ 'y location to display icon hicon as word,_ 'handle of icon to display Ret as short
5) Any time you get a Device Context (DC) you must release it before the program ends:
calldll #iconuser,"ReleaseDC",_ hico as word,_ 'window handle hicodc as word,_ 'handle of device context Ret as ushort --------------------------------------------------------- ' Icon changer code begins here ' This cannot make Icons ' Ok first I have tried to document this well ' If you don't understand or something doesn't work, PLEASE ' email me at ajl13@b... ' Oh, real quick. I, Anthony Liguori, copyright this or ' whatever under the GNU copyright ' So you can play with or include this in your programs as ' long as you give me credit ' Heh-hee. It didn't take that long, but... ' Modified Feb, 1999, by Brian D. Pugh ' Cosmetic changes to GUI ' Retains path after selecting runtime exe, in anticipation ' that the icon required is in the same dir as the runtime ' Shows current icon in selected runtime exe ' Shows new icon in runtime exe AFTER pressing the Change! button ' Won't let you select an icon until you have selected the runtime exe ' Icon change coding remains the same (couldn't alter anything of Anthony's!) UpperLeftX=int((DisplayWidth-268)/2) UpperLeftY=int((DisplayHeight-230)/2) WindowWidth=268:WindowHeight=230 textbox #icon.Textbox2,21,30,174,24 textbox #icon.Textbox1,21,83,174,24 button #icon.Button4,"...",[get.runtime],UL,216,30,30,24 button #icon.Button3,"...",[get.icon],UL,216,83,30,24 button #icon.Button5,"Change!",[change.it],UL,21,124,69,24 button #icon.Button6,"Exit",[exit.now],UL,176,124,69,24 open "Icon changer V0.90b" for graphics_nsb_nf as #icon print #icon,"trapclose [exiticon]" print #icon,"fill darkcyan;place 21 22" print #icon, "color white;backcolor darkcyan;\Runtime Engine Path" print #icon,"place 21 74;\Icon Path" print #icon,"flush" open "user" for dll as #iconuser open "shell" for dll as #iconshell [mainloop] input loop$ [exiticon] close #iconuser:close #iconshell:close #icon goto [loop] [get.runtime] filedialog "Find Runtime Engine","*.exe",runtime$ print #icon.Textbox2,lower$(runtime$) gosub [ShowBefore] goto [mainloop] [get.icon] if runtime$="" then notice "Icon Changer error"+chr$(13)+_ "Please select the Runtime Engine Path first":goto [mainloop] icopath$=runtime$ while instr(icopath$,"\"):icopath$=mid$(icopath$,instr(icopath$,"\")+1):wend icopath$=left$(runtime$,len(runtime$)-len(icopath$)) icopath$=lower$(icopath$)+"*.ico" filedialog "Icon",icopath$,icon$ print #icon.Textbox1,lower$(icon$) goto [mainloop] [change.it] print #icon.Textbox2,"!contents?" input #icon.Textbox2,runtime$ print #icon.Textbox1,"!contents?" input #icon.Textbox1,icon$ gosub [CheckRuntimeEngine] if error=0 then gosub [CheckIcon] if error=0 then gosub [change] gosub [ShowAfter] end if end if if error=1 then notice "Error changing Runtime Icon" goto [mainloop] [exit.now] goto [exiticon] [change] success=0 ico=hexdec("16") 'I used a hex editor for the offsets, it's easier for me runpos=hexdec("19ff") '' '' open icon$ for input as #1icon 'open up the icon icont$=input$(#1icon,lof(#1icon)) 'read the icon 'skip the header and put all the actual data into icondata$ ' icondata$=mid$(icont$,ico,len(icont$)) 'ERROR? icondata$=mid$(icont$,ico,len(icont$)-ico) 'substitute this close #1icon 'close icon iconlength=len(icondata$) 'improves speed open "kernel" for dll as #kernel 'loads kernel ' Opens up runtime for write & read access and returns the handle into hFile calldll #kernel,"_lopen",runtime$ as ptr,_ _OF_WRITE as short,hFile as word ' Moves the file pointer to the beginning of the file, ' this is why i used apis instead of lb calldll #kernel,"_llseek",hFile as word,_ 0 as long,0 as short,result as long ' Moves to the position of the icon resource calldll #kernel,"_llseek",hFile as word,_ runpos as long,1 as short,result as long calldll #kernel,"_lwrite",hFile as word,icondata$ as ptr,_ iconlength as short,result as short calldll #kernel,"_lclose",hFile as word,result as short close #kernel return [CheckIcon] error=0 if icon$<>"" then open icon$ for input as #1icon icont$=input$(#1icon,lof(#1icon)) close #1icon else error=1 end if ' check to see if the icon is 32 x 32 if mid$(icont$,7,1)<>" " or mid$(icont$,8,1)<>" " then error=1 ' check to see if the icon is 16 colour if mid$(icont$,9,1)<>chr$(16) then error=1 ' ok, that's enough error checking for me :) return [CheckRuntimeEngine] error=0 if runtime$="" then error=1 return [ShowBefore] print #icon,"discard;redraw" szFile$=runtime$+chr$(0):hico=hWnd(#icon):x=120:y=160 calldll #iconuser,"GetDC",hico as word,hicodc as word calldll #iconuser,"GetWindowWord",hico as word,_ _GWL_HINSTANCE as word,hCurrentInst as word calldll #iconshell,"ExtractIcon",hCurrentInst as word,_ szFile$ as ptr,0 as ushort,hicon as word if hicon>1 then print #icon,"place 21 174;\Existing" print #icon,"place 21 190;\Icon >>> " calldll #iconuser,"DrawIcon",hicodc as short,_ x as short,y as short,hicon as word,Ret as short else print #icon,"place 21 190;\Icon - None" end if print #icon,"flush" calldll #iconuser,"ReleaseDC",hico as word,hicodc as word,Ret as ushort return [ShowAfter] print #icon,"discard;redraw" szFile$=runtime$+chr$(0):hico=hWnd(#icon):x=120:y=160 calldll #iconuser,"GetDC",hico as word,hicodc as word calldll #iconuser,"GetWindowWord",hico as word,_ _GWL_HINSTANCE as word,hCurrentInst as word calldll #iconshell,"ExtractIcon",hCurrentInst as word,_ szFile$ as ptr,0 as ushort,hicon as word if hicon>1 then print #icon,"place 21 174;\New " print #icon,"place 21 190;\Icon >>> " calldll #iconuser,"DrawIcon",hicodc as short,_ x as short,y as short,hicon as word,Ret as short end if print #icon,"flush" calldll #iconuser,"ReleaseDC",hico as word,_ hicodc as word,Ret as ushort return
An icon editor is attached to this newsletter. It was written in Liberty BASIC. It will allow you to extract icon files from ICO, EXE and DLL files, or to begin a new icon yourself. You may draw with all 16 colors to make an icon you like, then save it as an ICO file, which you can then use with your runtime engine. It is a simple editor, and does not provide for a transparent color option.
There are many freeware and shareware icon editors available on the internet.
The following program is presented as is, with little explanation. It uses Liberty BASIC string and file functions to obtain the data for the icon drawn by the user, and writes an icon file.
The format for an icon file requires information about the icon, followed by a palette of rgb color values. The data for each pixel of the icon points at one of the 16 palette entries. An icon file also contains mask information, so that desired parts of the icon will be drawn transparent. This author has yet to figure out the proper way to write mask information into the file, so anyone who can add the the knowledge base is encouraged to step forward! The file format reference information for icons follows the program code, for the intrepid.
' This program will open icon files, or DLL's or EXE's and ' display icons for editing. You may alter these, or draw ' icons of your own by choosing a color and drawing with ' the mouse cursor. There is no transparent color function ' in this version of the Icon Machine. Icons will be saved ' in 16-color format, suitable for use with the Liberty ' BASIC runtime engine. ' ' 16-Color Icon Machine (c) Alyce Watson 1999, 2000 ' contact awatson@w... PixColor=256*256*256 + 256*256 + 256 'white cl=256*256*10 + 256*10 + 10 'almost black for grid lines DIM k(15) 'make a palette k(15)=0 'black k(14)=8421504 'darkgray k(13)=12632256 'lightgray k(12)=16777215 'white k(11)=8388608 'darkblue k(10)=16711680 'blue k(9)=32768 'darkgreen k(8)=65280 'green k(7)=8421376 'darkcyan k(6)=16776960 'cyan k(5)=32896 'brown k(4)=65535 'yellow k(3)=128 'darkred k(2)=255 'red k(1)=8388736 'darkpink k(0)=16711935 'pink DIM k$(15) 'set values for palette entries in hex for i = 0 to 9 k$(i)=str$(i) next i k$(10)="A" k$(11)="B" k$(12)="C" k$(13)="D" k$(14)="E" k$(15)="F" 'write the ico file header for 16-color icon, using palette above head$="0 0 1 0 1 0 32 32 16 0 0 0 0 0 232 2 0 0 22 0 0 0 40 0 0 0 32 0 0 0 64 0 0 0 1 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 255 0 128 0 128 0 0 0 255 0 0 0 128 0 0 255 255 0 0 128 128 0 255 255 0 0 128 128 0 0 0 255 0 0 0 128 0 0 255 0 0 0 128 0 0 0 255 255 255 0 192 192 192 0 128 128 128 0 0 0 0 0 0 0 " DIM header(127) for i=1 to 127 header(i)=val(word$(head$,i)) next i head$="" 'free memory WindowWidth = 500 WindowHeight = 400 UpperLeftX=1:UpperLeftY=1 nomainwin menu #main, "&File","&New",[new],"&Open Icon",[open],_ "&Update Icon View",[update],"&Save Icon",[save],"E&xit",[exit] menu #main, "&Help","H&elp",[help],"&About",[about] open "16-Color Icon Machine" for graphics_nsb_nf as #main print #main, "trapclose [exit]" Handle=hwnd(#main) open "user" for dll as #user open "gdi" for dll as #gdi Calldll #user, "GetDC", Handle as word, hdc as word calldll #user, "GetWindowWord",_ Handle as word,_ _GWL_HINSTANCE as word,_ hCurrentInst as word print #main, "down" print #main, "color 1 1 1;backcolor white;place 400 0;boxfilled 500 20" print #main, "backcolor lightgray;place 400 20;boxfilled 500 40" print #main, "backcolor darkgray;place 400 40;boxfilled 500 60" print #main, "backcolor black;place 400 60;boxfilled 500 80" print #main, "backcolor yellow;place 400 80;boxfilled 500 100" print #main, "backcolor brown;place 400 100;boxfilled 500 120" print #main, "backcolor green;place 400 120;boxfilled 500 140" print #main, "backcolor darkgreen;place 400 140;boxfilled 500 160" print #main, "backcolor red;place 400 160;boxfilled 500 180" print #main, "backcolor darkred;place 400 180;boxfilled 500 200" print #main, "backcolor blue;place 400 200;boxfilled 500 220" print #main, "backcolor darkblue;place 400 220;boxfilled 500 240" print #main, "backcolor cyan;place 400 240;boxfilled 500 260" print #main, "backcolor darkcyan;place 400 260;boxfilled 500 280" print #main, "backcolor pink;place 400 280;boxfilled 500 300" print #main, "backcolor darkpink;place 400 300;boxfilled 500 320;flush" gosub [grid] FileName$="UNTITLED.ICO" gosub [print.name] [loop] print #main, "setfocus; when leftButtonDown [mouse.down]" print #main, "when leftButtonMove [mouse.down]" print #main, "place 5 80;boxfilled 45 120" Input a$ [mouse.down] if MouseX<60 OR MouseY<0 OR MouseY>320 then [loop] if MouseX>60 and MouseX<380 then [put.color] if MouseX>400 then [get.color] goto [loop] [get.color] Y=MouseY if Y<20 then print #main, "backcolor white":goto [loop] if Y<40 then print #main, "backcolor lightgray":goto [loop] if Y<60 then print #main, "backcolor darkgray":goto [loop] if Y<80 then print #main, "backcolor black":goto [loop] if Y<100 then print #main, "backcolor yellow":goto [loop] if Y<120 then print #main, "backcolor brown":goto [loop] if Y<140 then print #main, "backcolor green":goto [loop] if Y<160 then print #main, "backcolor darkgreen":goto [loop] if Y<180 then print #main, "backcolor red":goto [loop] if Y<200 then print #main, "backcolor darkred":goto [loop] if Y<220 then print #main, "backcolor blue":goto [loop] if Y<240 then print #main, "backcolor darkblue":goto [loop] if Y<260 then print #main, "backcolor cyan":goto [loop] if Y<280 then print #main, "backcolor darkcyan":goto [loop] if Y<300 then print #main, "backcolor pink":goto [loop] if Y<320 then print #main, "backcolor darkpink":goto [loop] goto [loop] [put.color] 'color working area and preview area if MouseX/10 = int(MouseX/10) then [loop] 'mouse is on grid line if MouseY/10 = int(MouseY/10) then [loop] 'mouse is on grid line filx=MouseX:fily=MouseY calldll #gdi, "FloodFill", _ hdc as word, _ filx as short, _ fily as short, _ cl as long, _ 'boundary color for flood fill results as short iconX=int(((filx-60)/10)+5) iconY=int((fily/10)+200) calldll #gdi, "GetPixel",_ hdc AS short,_ filx AS short,_ fily AS short,_ pixColor AS long calldll#gdi,"SetPixel",_ hdc as word,_ iconX as short,_ iconY as short,_ pixColor as long,_ result as long goto [loop] [open] gosub [clear] filedialog "Choose Icon","*.ico;*.exe;*.dll",FileName$ if FileName$="" then [loop] File$=FileName$+chr$(0) open "shell" for dll as #shell calldll #shell, "ExtractIcon",_ hCurrentInst as word,_ File$ as ptr,_ 0 as ushort,_ hicon as word 'returns icon handle close #shell if hicon>1 then calldll #user, "DrawIcon",_ 'draw icon from file hdc as short,_ 0 as short,_ 0 as short,_ hicon as word,_ Ret as short calldll #user, "DrawIcon",_ 'draw icon to edit hdc as short,_ 5 as short,_ 200 as short,_ hicon as word,_ Ret as short End if calldll #gdi,"StretchBlt",_ 'draw large copy of icon hdc as word,_ 60 as word,_ 0 as word,_ 320 as word, _ 320 as word,_ hdc as word,_ 0 as word,_ 0 as word,_ 32 as word,_ 32 as word,_ _SRCCOPY as long,_ r as ushort gosub [grid] 'draw grid over large copy gosub [print.name] goto [loop] [save] filedialog "Save as...","*.ico",savefile$ if savefile$="" then [loop] cursor hourglass bits$="" 'reset string to hold bit information x2=5:y2=232 'get fresh copy for saving for y1=315 to 5 step -10 for x1=65 to 375 step 10 gosub [get.pixel] gosub [draw.new.icon] gosub [add.to.file] next x1 next y1 gosub [write.file] cursor normal goto [loop] [write.file] saveicon$="" 'reset for i = 1 to 126 saveicon$=saveicon$+chr$(header(i)) next i for i = 1 to 1026 step 2 saveicon$=saveicon$+chr$(hexdec(mid$(bits$,i,1)+mid$(bits$,i+1,1))) next i for i = 1 to 127 saveicon$=saveicon$+chr$(0) next i open savefile$ for output as #sf print #sf, left$(saveicon$,766) close #sf cursor normal notice "File saved as "+lower$(savefile$) goto [loop] [update] cursor hourglass x2=5:y2=200 for y1=315 to 5 step -10 for x1=65 to 375 step 10 gosub [get.pixel] gosub [draw.new.icon] next x1 next y1 cursor normal goto [loop] [draw.new.icon] calldll#gdi,"SetPixel",_ hdc as word,_ x2 as short,_ y2 as short,_ pixColor as long,_ result as long x2=x2+1 if x2>=37 then x2=5:y2=y2-1 RETURN [add.to.file] 'check color and add bit to bit string for j=0 to 15 if pixColor=k(j) then bits$=bits$+k$(j) next j return [get.pixel] calldll #gdi, "GetPixel",_ hdc AS short,_ x1 AS short,_ y1 AS short,_ pixColor AS long RETURN [grid] 'color 10 10 10 is almost black print #main, "down;color 10 10 10;size 1" for x=60 to 380 step 10 print #main, "line ";x;" 0 ";x;" 320" next x for y=0 to 320 step 10 print #main, "line 60 ";y;" 380 ";y next y print #main, "color 10 10 10;place 4 199;box 38 233" print #main, "backcolor white;place 5 254;|view" print #main, "place 5 140;|color" RETURN [print.name] print #main, "backcolor white" print #main, "place 100 340;|";FileName$+space$(100) RETURN [clear] print #main, "place 0 0;color white;backcolor white;boxfilled 381 321" RETURN [new] FileName$="UNTITLED.ICO" gosub [clear] gosub [grid] gosub [print.name] goto [loop] [exit] calldll #user, "ReleaseDC", Handle as word, hdc as word, Ret as ushort close #main close #user Close #gdi end [help] notice "Help"+chr$(13)+"Either choose file/open to open an existing icon, or file/new to begin a new icon. Click on the drawing color desired. Click and drag the mouse in the grid to color the icon. To save the result as a 16-color icon, choose file/save. Only 16 color icons may be saved, and there is no transparent color function in this version." goto [loop] [about] notice "16-Color Icon Machine "+chr$(169)+" Alyce Watson, 1999-2000." goto [loop]
typedef struct tagBITMAPINFOHEADER { /* bmih */ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER;
Each icon-resource file contains one icon image for each image identified in the icon directory. An icon image consists of an icon-image header, a color table, an XOR mask, and an AND mask. The icon image has the following form:
BITMAPINFOHEADER icHeader; RGBQUAD icColors[]; BYTE icXOR[]; BYTE icAND[];
The icon-image header, defined as a BITMAPINFOHEADER structure, specifies the dimensions and color format of the icon bitmap. Only the biSize through biBitCount members and the biSizeImage member are used. All other members (such as biCompression and biClrImportant) must be set to zero.
The color table, defined as an array of RGBQUAD structures, specifies the colors used in the XOR mask. As with the color table in a bitmap file, the biBitCount member in the icon-image header determines the number of elements in the array.
The XOR mask, immediately following the color table, is an array of BYTE values representing consecutive rows of a bitmap. The bitmap defines the basic shape and color of the icon image. As with the bitmap bits in a bitmap file, the bitmap data in an icon-resource file is organized in scan lines, with each byte representing one or more pixels, as defined by the color format.
The AND mask, immediately following the XOR mask, is an array of BYTE values, representing a monochrome bitmap with the same width and height as the XOR mask. The array is organized in scan lines, with each byte representing 8 pixels.
When Windows draws an icon, it uses the AND and XOR masks to combine the icon image with the pixels already on the display surface. Windows first applies the AND mask by using a bitwise AND operation; this preserves or removes existing pixel color. Windows then applies the XOR mask by using a bitwise XOR operation. This sets the final color for each pixel.
Brosco and Alyce have written a Book for Liberty BASIC, which is available in electronic form on a CDROM. For details: http://alyce.50megs.com/sss/cd.htm
Newsletter compiled and edited by: Brosco and Alyce. Comments, requests or corrections: Hit 'REPLY' now! mailto:brosco@o... or mailto:awatson@w...