pabs' new website

Pabs' Web page
DEATH TO MORK
Skip [Home][POV][Programming][Tutorials][Opinions][Rantings][Collection][Favourites][Links]
Skip. On this page you will find tutorials on adding a button to the POV-Win 3.1g large toolbar, adding a button to the POV-Win 3.1g auxiliary toolbar, installing the Win32 GIMP on a locked down system, killing the Crosswinds ad window on page loadup & converting CF_DIB to a .bmp file.

To add a button to the large toolbar in POV-Win 3.1g:
This applies only to the official version - I have not tried any others
Remember to mark your changes with a special sequence of characters in comments so that you can find your changes later (esp. in code)(I use "Pabs changed - ...") or simply bookmark them, the former is better so that if you distribute your files others can see your changes. Remember not to delete anything - just comment it out.

  1. Draw your button image X×Y-38×21 16 colours and save it in any directory (povwin_src\windows\bitmaps\toolbar recommended)
    -you should use same palette as rest of toolbar buttons or it may not be visible
    (save palette in one of the other button images and load it in yours)
    -use this yellowish colour RGB (255, 255, 156) as transparent areas
    -other button images (POV-Team ones) are 38×38 and you can use this size but just keep in mind that below and including pixel row 21 should be the above mentioned transparent colour (this is not used)
    e.g.example
  2. Add the image to the pvengine.rc resource file using a resource editor or by hand
     - insert the following line into pvengine.rc after the last bitmap resource (search for "bitmap" and you will see the list)
    "<your ID (see 3)> BITMAP DISCARDABLE "<your directory>"")
    Be sure to replace backslashes with double backslashes or the compiler will produce an incorrect string.
  3. Give your image an ID symbol and number (symbol doesn't matter number does - look in pvengine.rh for an appropriate value) and add " #define <symbol> <number>" to pvengine.rh and ensure the header for the rc script has this symbol and it has the right value (type "= <number>" after the symbol in the ID property of the image in MSVC++)
    -the symbol should begin with "BMP_TOOL" by conventions used (apparently) by the POV-Team
  4. Add an accelerator (or not) and do the same as 3 for it (even if no accelerator is added
    -This will be the ID of your button in code
    -the symbol should begin with "CM_ " by conventions used (apparently) by the POV-Team
  5. If necessary update CM_FIRST
  6. Add a string to the string table with the same symbol as in 4 and this will be the text displayed in a tool-tip when the mouse hovers on your button or on the status bar if you decide to put your button in one of the menus
  7. In pvtext.c Find the definition and initialisation of maintools ( toolbarStruct []) and insert a line as follows before the line that is "0, 0, 0x00, NULL"
    "<symbol defined in 4>, <symbol defined in 3>, <hex number>,<string shown on tool-bar>
    The hex number is a bit field. The first bit is 1 if the button behaves like a check box & the 2nd is 1 if the button is hidden (0x00-0x03) the string should be a literal i.e. "blah blah" and be shorter than the button's image
    -if you put a hidden button last the display f**ks up - tab window & codemax controls not visible
  8. Then in pvtext.c in the body of create_toolbar
    (proto = HWND create_toolbar (HWND hwndParent))
    find the first call of ImageList_Create and add 1 to the 5th (last) parameter
    (it should be 16 in an newly downloaded copy of the POV-Win 3.1g source )
  9. In pvengine.c in handle_main_command (proto = BOOL handle_main_command (WPARAM wParam, LPARAM lParam)) find " switch (LOWORD (wParam))"and add " case < symbol defined in #4> :<yourbody>" below it
    - where yourbody is the code that does what you want the toolbar button to do
    -in the words of the POV-Team "return TRUE if we are to return 0 to Windows, FALSE if we are to continue."
  10. Figure out just how the hell you are going to get it to work and fill out yourbody (from 9)

For the auxiliary tool-bar:
Do everything the same except (note that this may not work - I have not tried it)
In 1 use images of size 14×14
In 7 use auxtools instead
In 8 find the 2nd call to ImageList_Create (5th parameter should be 8 in unchanged source.)

Install the Win32 GIMP on a locked down system:
This is no longer needed since the new GIMP 1.2.3 installer puts all files in the same directory.
This was a quick hack to allow you to install the GIMP on locked down systems.
Locked down systems might include university computer lab machines/work machines/etc
If you can create a directory under C:\Program Files\Common Files\ (or its equivalent) and create files in that dir you don't need this.
You will need a hex editor (try frhed), or a text editor that preserves all bytes (notepad WILL NOT - it removes 0x00 bytes) (try thegun)
Your chosen editor will need to be able to find and (preferably) replace data

  1. Get the zip file from here (or a mirror).
  2. Extract the installer exe from the zip file.
  3. Open it in your chosen editor.
  4. Choose a directory where the dlls normally stored in the common files dir will be installed on your system.
    This needs to be exactly 17 characters or the installer may not work.
  5. Replace all occurrences of "%CommonFiles%\GNU" (minus quotes) with your chosen directory. It appears about 14 times I think.
  6. It might also be "%CommonFilesDir%\GNU" (again minus quotes), which is 20 characters, so try that also.
  7. Save the installer exe.
  8. Execute the installer & install the GIMP.
  9. This last one is optional. If you are installing the GIMP or its dlls on a network server (i.e. your HOME directory), which you access from several machines, you may need to copy the GIMP's dlls to some other dirs.
    This occurs because the GIMP uses HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER in the registry.
    To fix dll not found issues copy all the dlls and minigzip.exe to %GIMP%\bin and copy all the dlls (except minigzip.exe) to the %GIMP%\plug-ins dir, where %GIMP% is the dir you installed the GIMP under.
    There are other issues relating to where the installer installs the uninstaller (only on the machine where the GIMP was originally installed) and the registration of different file types as being associated with the GIMP (HKEY_CLASSES_ROOT (HKLM\Software\Classes) instead of HKCU\Software\Classes) These may not be a problem on Windows 2000 due to merging of HKLM\S\C & HKCU\S\C
  10. Hopefully you can now run the GIMP.

Kill Crosswinds ad window on page loadup
For sites that popup ads from http://www.popuptraffic.com/ this will probably also work if you replace 'jW4Los9wh' with 'cool'
You should use some popup window remover as such a method is more general
Just insert the following script into the <head> of each html file on your site:

<script language="JavaScript" type="text/javascript">
<!--
w = window.open('', 'jW4Los9wh');
w.close();
// -->
</script>

Also if you have a free V3 redirect url (eg http://pabs.zip.to) you can add the following to the end of your favicon url and it will prevent the advert from loading and on CSS capable browsers it will hide the link back to V3.

"><style type='text/css'><!--h1 { display: none !important;}--></style><!--

Also wrt geocities use the following

<script type="text/javascript">
window.document = new Object(); // prevents geocities from having access to the document to write ads
window.onerror = null; // avoids errors
</script>

HOWTO convert CF_DIB to a .bmp file
Simple - paste into M$ Paint & do File\Save
The harder way:
Note: all WORDs & DWORDs are little-endian
According to the M$DN CF_DIB consists of a BITMAPINFO structure followed by the bits
According to the M$DN .bmp files consist of a BITMAPFILEHEADER structure, a BITMAPINFOHEADER structure, a RGBQUAD structure array and a Color-index array
The BITMAPINFO structure consists of a BITMAPINFOHEADER structure plus a RGBQUAD structure array so they are almost equivalent
.'. We only need to add a BITMAPFILEHEADER structure
from the M$DN:

struct BITMAPFILEHEADER{
	WORD bfType; //Specifies the file type. It must be BM.
	DWORD bfSize; //Specifies the size, in bytes, of the bitmap file.
	WORD bfReserved1; //Reserved; must be zero.
	WORD bfReserved2; //Reserved; must be zero.
	DWORD bfOffBits; //Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits.
}

bfType = 'BM' = 0x4d42
bfSize = sizeof(BITMAPFILEHEADER)+sizeof(CF_DIB)= 14+sizeof(CF_DIB)
bfReserved1 = 0x0000
bfReserved2 = 0x0000
bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD array)
this is a bit harder
sizeof(BITMAPFILEHEADER) is 14 always for the current structure
but sizeof(BITMAPINFOHEADER) can differ depending on the version since BITMAPINFOHEADER can be replaced with newer versions, which are longer, but the size is always specified in the 1st DWORD:

struct BITMAPINFOHEADER{
	DWORD biSize; //Specifies the number of bytes required by the structure.
	...
struct BITMAPV4HEADER{
	DWORD bV4Size; //Specifies the number of bytes required by the structure. Applications should use this member to determine which bitmap information header structure is being used.
	...
struct BITMAPV5HEADER{
	DWORD bV5Size; //Specifies the number of bytes required by the structure. Applications should use this member to determine which bitmap information header structure is being used.
	...

So this means we need to read the first DWORD after the BITMAPFILEHEADER or the dword at offset 14 (<DWORD:14>)
and sizeof(RGBQUAD array) differs depending on how many colours are present
the BITMAP<xxx>HEADER:

struct BITMAPINFOHEADER{
	DWORD biSize;
	LONG biWidth;
	LONG biHeight;
	WORD biPlanes;
	WORD biBitCount;
	...

An extract from the BITMAPINFOHEADER documentation:

biBitCount specifies the number of bits per pixel. The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member must be one of the following values.
1 The bitmap is monochrome, and the bmiColors member contains two entries...
4 The bitmap has a maximum of 16 colors, and the bmiColors member contains up to 16 entries...
8 The bitmap has a maximum of 256 colors, and the bmiColors member contains up to 256 entries...
16 The bitmap has a maximum of 2^16 colors...
24 The bitmap has a maximum of 2^24 colors...
32 The bitmap has a maximum of 2^32 colors...

so the number of RGBQUADs in the array = 2^biBitCount = 2^<DWORD:28>
and each RGBQUAD is 4 bytes so sizeof(RGBQUAD array) = 4*2^<DWORD:28>
.'. bfOffBits = 14 + <DWORD:14> + 4*2^<DWORD:28>

To recap:

  1. BITMAPFILEHEADER:insert 14 NIL bytes at the start of the data
  2. bfType:enter "BM" as the first two bytes
  3. bfSize:enter <Size> as a DWORD at offset 0x2
  4. bfOffBits:enter <14 + <DWORD:14> + 4*2^<DWORD:28>> as a DWORD at offset 0xA
    <DWORD:14> is 40 for WinNT3 & Win?.? bitmaps
    <DWORD:14> is 108 for WinNT4 & Win95 bitmaps
    <DWORD:14> is 124 for WinNT5 (Win2000) & Win98 bitmaps
    <DWORD:28> is bits per pixel

If you have M$ Paint you can probably get away with entering anything instead of calculating the correct bfOffBits and then using File\Save As to calculate the correct bfOffBits, but that would be pointless since you could have just pasted into M$ Paint.

More tutorials in the process...

Go to top
Last modified at 11:19 PM GMT on Tuesday 10 December 2002 http http http http http