File: n_svc_resource.sru
Size: 24080
Date: Mon, 07 Apr 2008 21:31:41 +0200
$PBExportHeader$n_svc_resource.sru
$PBExportComments$Resource service
forward
global type n_svc_resource from n_svc_base
end type
type str_images from structure within n_svc_resource
end type
end forward

type str_images from structure
   string      name
   long     handle
   string      appname
   string      images[]
end type

global type n_svc_resource from n_svc_base
boolean #pooled = true
end type
global n_svc_resource n_svc_resource

type prototypes
FUNCTION boolean DestroyWindow( long hWnd ) Library "user32"
end prototypes

type variables
Private:

str_images istr_images[]
w_tmp_resource iw
CONSTANT string DUMMY = "DUMMY"
long il_counter
CONSTANT string SHELL_DLL = "shell32.dll"
end variables

forward prototypes
public function long of_getresourcebitmaphandle (readonly string as_bitmapname)
protected subroutine of_initwindowresource ()
public function long of_getdummyimagelist (ref n_svc_mgr anv_svc)
public function long of_makeresourceimagelist (ref n_svc_mgr anv_svc, readonly string as_imagelistname, readonly string as_imagenames[], readonly integer ai_size)
public function long of_makeresourceimagelist (ref n_svc_mgr anv_svc, readonly string as_imagelistname, readonly string as_imagenames[], readonly integer ai_size, readonly long al_transparentcolor)
public subroutine of_destroyimages ()
public function long of_getstandardimagelist16 (ref n_svc_mgr anv_svc)
public function long of_getstandardimagelist24 (ref n_svc_mgr anv_svc)
public function long of_getdwimagelist (ref n_svc_mgr anv_svc, readonly string as_dwoname, readonly integer ai_size)
public function long of_getstateimagelist (ref n_svc_mgr anv_svc)
public function long of_makeresourceimagelist (ref n_svc_mgr anv_svc, readonly string as_imagelistname, readonly string as_imagenames[], readonly integer ai_width, readonly integer ai_height, readonly long al_transparentcolor)
protected function long of_makeimagelistfromdw (ref n_svc_mgr anv_svc, readonly string as_dwname, readonly integer ai_width, readonly integer ai_height)
public function long of_getdwimagelist (ref n_svc_mgr anv_svc, readonly string as_dwoname, readonly integer ai_width, readonly integer ai_height)
public function long of_getstandardimage16 (ref n_svc_mgr anv_svc, readonly integer ai_index)
public function long of_createimagelistfrombitmap (ref n_svc_mgr anv_svc, string as_filename, string as_resourceid, readonly long al_transparentcolor, readonly integer ai_width, readonly integer ai_height)
public function long of_createimagelistfrombitmap (ref n_svc_mgr anv_svc, string as_filename, string as_resourceid, readonly long al_transparentcolor)
public function long of_getstandardimage24 (ref n_svc_mgr anv_svc, readonly integer ai_index)
protected function long of_createwindowsimagelist (ref n_svc_mgr anv_svc, readonly boolean ab_large)
protected function long of_mergeimagelists (ref n_svc_mgr anv_svc, readonly long al_imagelists[], readonly long al_size)
protected subroutine of_setimagelisthandle (readonly string as_imagelistname, readonly long al_newhiml)
public function integer of_standardimageindexfromstring (string as_resname)
public function string of_createstandardbitmapcache (ref n_svc_mgr anv_svc, readonly string as_appname)
public function integer of_makegradientstrip (ref n_svc_mgr anv_svc, readonly long al_startcolor, readonly long al_endcolor, readonly boolean ab_vertical, readonly integer ai_width, readonly integer ai_height, readonly string as_filename)
public function integer of_makegradientstrip (ref n_svc_mgr anv_svc, readonly long al_startcolor, readonly long al_endcolor, readonly boolean ab_vertical, readonly integer ai_offset, readonly integer ai_width, readonly integer ai_height, readonly string as_filename)
public subroutine of_addimagelist (readonly string as_imagelistname, readonly long al_handle, readonly string as_images[])
public function long of_getimagelist (readonly string as_imagelistname)
public function integer of_getimagelist (readonly string as_imagelistname, readonly string as_images[])
public function integer of_makeheaderline (ref n_svc_mgr anv_svc, readonly long al_color1, readonly long al_color2, readonly long al_color3, readonly string as_filename)
end prototypes

public function long of_getresourcebitmaphandle (readonly string as_bitmapname);long llh
CommandButton lcb

//open bitmap window
of_initwindowresource()

//lcb = iw.of_getbutton()
//lcb.PictureName = as_bitmapname
llh = Handle(lcb)
llh = Send(llh, CWIN32.BM_GETIMAGE, CWIN32.IMAGE_BITMAP, 0)

RETURN llh
end function

protected subroutine of_initwindowresource ();OPEN(iw)
end subroutine

public function long of_getdummyimagelist (ref n_svc_mgr anv_svc);n_svc_imagelist lnv_img
long ll
string ls[]

anv_svc.of_LoadSvc(lnv_img, CSvc.IMAGELIST)
ll = lnv_img.of_create(16, 16, lnv_img.ILC_COLOR16 + lnv_img.ILC_MASK, 0, 1)

of_Addimagelist(DUMMY, ll, ls)

RETURN ll
end function

public function long of_makeresourceimagelist (ref n_svc_mgr anv_svc, readonly string as_imagelistname, readonly string as_imagenames[], readonly integer ai_size);RETURN of_makeresourceimagelist(anv_svc,as_imagelistname,  as_imagenames, ai_size, -1)
end function

public function long of_makeresourceimagelist (ref n_svc_mgr anv_svc, readonly string as_imagelistname, readonly string as_imagenames[], readonly integer ai_size, readonly long al_transparentcolor);RETURN of_makeresourceimagelist(anv_svc,as_imagelistname,  as_imagenames, ai_size, ai_size, -1)
end function

public subroutine of_destroyimages ();long ll_count, n
ll_count = UPPERBOUND(istr_images)
FOR n = 1 to ll_count
   DestroyWindow(istr_images[n].handle)
NEXT
end subroutine

public function long of_getstandardimagelist16 (ref n_svc_mgr anv_svc);long ll_winiml, ll_himl, ll_newhiml
n_svc_win32 lnv_win32

anv_svc.of_LoadSvc(lnv_win32, CSvc.WIN32)

ll_newhiml = of_GetImageList(CResource.IMG_STANDARD16)

IF ll_newhiml = Cret.FAILURE THEN
   ll_himl = of_getdwimagelist(anv_svc, CResource.IMG_STANDARD16, 16)
   ll_winiml = of_CreateWindowsImagelist(anv_svc, FALSE)
   ll_newhiml = of_MergeImageLists(anv_svc, {ll_winiml, ll_himl}, 16)
   
   //update imagelist
   of_Setimagelisthandle(CResource.IMG_STANDARD16, ll_newhiml)
   
   lnv_win32.DestroyWindow(ll_himl)
   lnv_win32.DestroyWindow(ll_winiml)
END IF

RETURN ll_newhiml
end function

public function long of_getstandardimagelist24 (ref n_svc_mgr anv_svc);long ll_winiml, ll_himl, ll_newhiml
n_svc_win32 lnv_win32

anv_svc.of_LoadSvc(lnv_win32, CSvc.WIN32)

ll_newhiml = of_GetImageList(CResource.IMG_STANDARD24)

IF ll_newhiml = Cret.FAILURE THEN
   ll_himl = of_getdwimagelist(anv_svc, CResource.IMG_STANDARD24, 24)
   ll_winiml = of_CreateWindowsImagelist(anv_svc, TRUE)
   ll_newhiml = of_MergeImageLists(anv_svc, {ll_winiml, ll_himl}, 24)
   
   //update imagelist
   of_Setimagelisthandle(CResource.IMG_STANDARD24, ll_newhiml)
   
   lnv_win32.DestroyWindow(ll_himl)
   lnv_win32.DestroyWindow(ll_winiml)
END IF

RETURN ll_newhiml
end function

public function long of_getdwimagelist (ref n_svc_mgr anv_svc, readonly string as_dwoname, readonly integer ai_size);RETURN of_getdwimagelist(anv_svc, as_dwoname, ai_size, ai_size)
end function

public function long of_getstateimagelist (ref n_svc_mgr anv_svc);RETURN of_getdwimagelist(anv_svc, CResource.IMG_STATE, 15, 13)
end function

public function long of_makeresourceimagelist (ref n_svc_mgr anv_svc, readonly string as_imagelistname, readonly string as_imagenames[], readonly integer ai_width, readonly integer ai_height, readonly long al_transparentcolor);n_svc_imagelist lnv_img
n_svc_lv lnv_lv
Listview lv
long ll_himl, ll_newhiml, ll_count, n
w_tmp_resource lw

ll_count = of_GetImageList(as_imagelistname, as_imagenames)

IF ll_count > 0 THEN
   RETURN istr_images[ll_count].handle
END IF

//open tmp window
OPEN(lw)
//use the listview as placeholder
lv = lw.of_getlistview()

lv.LargePictureWidth = ai_width
lv.LargePictureHeight = ai_height
IF al_transparentcolor > 0 THEN
   lv.LargePictureMaskColor = al_transparentcolor
END IF

ll_count = UPPERBOUND(as_imagenames)
FOR n = 1 to ll_count
   lv.AddLargePicture(as_imagenames[n])
NEXT

anv_svc.of_LoadSvc(lnv_lv, CSvc.LV)
//now let's get that imagelist :)
ll_himl = lnv_lv.of_GetLargeImageList(lv)

anv_svc.of_LoadSvc(lnv_img, CSvc.IMAGELIST)

IF ll_himl > 0 THEN
   //let's make a copy and destroy the original
   ll_newhiml = lnv_img.of_Duplicate(ll_himl)
   lnv_img.of_Destroy(ll_himl)
   of_AddImageList(as_imagelistname, ll_newhiml, as_imagenames)
END IF

CLOSE(lw)

RETURN ll_newhiml
end function

protected function long of_makeimagelistfromdw (ref n_svc_mgr anv_svc, readonly string as_dwname, readonly integer ai_width, readonly integer ai_height);long ll_ret, ll_count, n
n_ds lds
string ls_imgs[]

lds = CREATE n_ds

IF lds.of_SetDataObject(as_dwname) = CRet.SUCCESS THEN
   ll_count = lds.RowCount()
   FOR n = ll_count to 1 STEP -1
      ls_imgs[n] = lds.GetItemString(n, 1)      
   NEXT
   
   ll_ret = of_MakeResourceImageList(anv_svc, as_dwname, ls_imgs, ai_width, ai_height, CResource.MASK_COLOR)
END IF

IF ISVALID(lds) THEN DESTROY lds

RETURN ll_ret
end function

public function long of_getdwimagelist (ref n_svc_mgr anv_svc, readonly string as_dwoname, readonly integer ai_width, readonly integer ai_height);long ll_ret

ll_ret = of_GetImageList(as_dwoname)

IF ll_ret = CRet.FAILURE THEN
   ll_ret = of_makeimagelistfromdw(anv_svc, as_dwoname, ai_width, ai_height)
END IF

RETURN ll_ret
end function

public function long of_getstandardimage16 (ref n_svc_mgr anv_svc, readonly integer ai_index);long ll_himl
n_svc_imagelist lnv_img

ll_himl = of_GetStandardImageList16(anv_svc)

anv_svc.of_LoadSvc(lnv_img, CSvc.IMAGELIST)

//uses zero-based index, subtract 1
ll_himl = lnv_img.of_GetIcon(ll_himl, ai_index - 1, 0)

RETURN ll_himl
end function

public function long of_createimagelistfrombitmap (ref n_svc_mgr anv_svc, string as_filename, string as_resourceid, readonly long al_transparentcolor, readonly integer ai_width, readonly integer ai_height);n_svc_win32 lnv_win32
n_svc_isempty lnv_check
n_svc_imagelist lnv_img
long ll_lib, ll_img

anv_svc.of_loadsvc(lnv_win32, CSvc.WIN32)
anv_svc.of_loadsvc(lnv_check, CSvc.ISEMPTY)
anv_svc.of_loadsvc(lnv_img, CSvc.IMAGELIST)
//load library
ll_lib = lnv_win32.LoadLibrary(as_filename)

IF lnv_check.of_isempty(ll_lib) THEN 
   lnv_win32.FreeLibrary(ll_lib)
   RETURN CRet.FAILURE
END IF
   
//insert '#' sign for resource identifier if already a number
IF ISNUMBER(as_resourceid) THEN as_resourceid = "#" + as_resourceid

ll_img = lnv_img.of_loadimage(ll_lib, as_resourceid, ai_width, ai_height, al_transparentcolor, lnv_img.IMAGE_BITMAP, lnv_img.LR_CREATEDIBSECTION)

IF lnv_check.of_isempty(ll_img) THEN 
   lnv_win32.FreeLibrary(ll_lib)
   RETURN CRet.FAILURE
END IF

//free handle and return imagelist handle
lnv_win32.FreeLibrary(ll_lib)
RETURN ll_img
end function

public function long of_createimagelistfrombitmap (ref n_svc_mgr anv_svc, string as_filename, string as_resourceid, readonly long al_transparentcolor);RETURN of_createimagelistfrombitmap( &
               anv_svc, &
               as_filename, &
               as_resourceid, &
               al_transparentcolor, &
               0, 0 /* Setting zero width/height defaults to current size*/)
end function

public function long of_getstandardimage24 (ref n_svc_mgr anv_svc, readonly integer ai_index);long ll_himl
n_svc_imagelist lnv_img

ll_himl = of_GetStandardImageList24(anv_svc)

anv_svc.of_LoadSvc(lnv_img, CSvc.IMAGELIST)

//uses zero-based index, subtract 1
ll_himl = lnv_img.of_GetIcon(ll_himl, ai_index - 1, 0)

RETURN ll_himl


end function

protected function long of_createwindowsimagelist (ref n_svc_mgr anv_svc, readonly boolean ab_large);long ll_newimg, ll_size, ll_img_ie, ll_img_explorer, ll_icon
long ll_count, n
n_svc_imagelist lnv_img
n_svc_win32 lnv_win32
integer li_ie, li_explorer

anv_svc.of_LoadSvc(lnv_img, CSvc.IMAGELIST)
anv_svc.of_LoadSvc(lnv_win32, CSvc.WIN32)

IF ab_large THEN
   ll_size = 24
   li_ie = CResource.IELARGENORMAL
   li_explorer = CResource.EXPLORERLARGENORMAL
ELSE
   ll_size = 16
   li_ie = CResource.IESMALLNORMAL
   li_explorer = CResource.EXPLORERSMALLNORMAL
END IF

//create imagelists
ll_img_ie = this.of_createimagelistfrombitmap(anv_svc, SHELL_DLL, STRING(li_ie), 0)
ll_img_explorer = this.of_createimagelistfrombitmap(anv_svc, SHELL_DLL, STRING(li_explorer), 0)

ll_newimg = of_MergeImageLists(anv_svc, {ll_img_ie, ll_img_explorer}, ll_size)
lnv_win32.DestroyWindow(ll_img_ie)
lnv_win32.DestroyWindow(ll_img_explorer)  

RETURN ll_newimg
end function

protected function long of_mergeimagelists (ref n_svc_mgr anv_svc, readonly long al_imagelists[], readonly long al_size);n_svc_imagelist lnv_img
n_svc_win32 lnv_win32
long ll_newimg, ll_count, n, ll_himlcount, m, ll_icon

ll_himlcount = UPPERBOUND(al_imagelists)
IF ll_himlcount <= 0 THEN RETURN CRet.FAILURE

anv_svc.of_LoadSvc(lnv_img, CSvc.IMAGELIST)
anv_svc.of_LoadSvc(lnv_win32, CSvc.WIN32)

ll_newimg = lnv_img.of_create(al_size, al_size, lnv_img.ILC_COLOR32  + lnv_img.ILC_MASK, 0, 1)  

FOR m = 1 to ll_himlcount
   ll_count = lnv_img.of_getimagecount(al_imagelists[m])
   ll_count --
   FOR n = 0 to ll_count
      ll_icon = lnv_img.of_geticon(al_imagelists[m], n, 0)
      lnv_img.of_addicon(ll_newimg, ll_icon)
      lnv_win32.DestroyIcon(ll_icon)
   NEXT
NEXT

RETURN ll_newimg
end function

protected subroutine of_setimagelisthandle (readonly string as_imagelistname, readonly long al_newhiml);long ll_count, n

ll_count = UPPERBOUND(istr_images)
FOR n = 1 to ll_count
   IF istr_images[n].name = as_imagelistname THEN
      istr_images[n].handle = al_newhiml
      RETURN
   END IF
NEXT
end subroutine

public function integer of_standardimageindexfromstring (string as_resname);integer li_index
long ll_count, n
CResource lnv

lnv = CREATE CResource

ll_count = UPPERBOUND(lnv.BUTTONS)

IF ISNUMBER(as_resname) THEN
   li_index = INTEGER(as_resname)
ELSE
   li_index = CRet.FAILURE
   FOR n = 1 to ll_count
      IF UPPER(TRIM(as_resname)) = lnv.BUTTONS[n] THEN
         li_index = n
         RETURN li_index
      END IF
   NEXT
END IF

DESTROY lnv

RETURN li_index
end function

public function string of_createstandardbitmapcache (ref n_svc_mgr anv_svc, readonly string as_appname);n_svc_files lnv_f
n_svc_imagelist lnv_i
n_svc_win32 lnv_win32
string ls_tmp
CResource res
long ll_wbrush, ll_hbrush
long ll_color, ll_size
ulong ll_himl, ll_himl_large, ll_currenthiml
long ll_count, n, m
string ls_filename

anv_svc.of_LoadSvc(lnv_f, CSvc.FILES)
anv_svc.of_LoadSvc(lnv_win32, CSvc.WIN32)

ls_tmp = lnv_f.of_GetTempPath(anv_svc)
ls_tmp = lnv_f.of_combinepath(ls_tmp, as_appname)
//create tmp dir
CreateDirectory(ls_tmp)


anv_svc.of_LoadSvc(lnv_i, CSvc.IMAGELIST)
res = CREATE CResource

ll_wbrush = lnv_win32.GetSysColor(CWin32.COLOR_WINDOW)
ll_hbrush = lnv_win32.GetSysColor(CWin32.COLOR_HIGHLIGHT)

ll_himl = of_GetStandardImagelist16(anv_svc)
ll_himl_large = of_GetStandardImagelist24(anv_svc)
ll_count = lnv_i.of_GetImageCount(ll_himl)
FOR n = 1 to ll_count
   FOR m = 1 to 4
      CHOOSE CASE m
         CASE 1
            ll_currenthiml = ll_himl
            ll_color = ll_wbrush
            ll_size = 16
            ls_filename = &
               lnv_f.of_combinepath(ls_tmp, "16_" + res.BUTTONS[n]) + "_w.bmp"
         CASE 2
            ll_currenthiml = ll_himl
            ll_color = ll_hbrush
            ll_size = 16
            ls_filename = &
               lnv_f.of_combinepath(ls_tmp, "16_" + res.BUTTONS[n]) + "_s.bmp"
         CASE 3
            ll_currenthiml = ll_himl_large
            ll_color = ll_wbrush
            ll_size = 24
            ls_filename = &
               lnv_f.of_combinepath(ls_tmp, "24_" + res.BUTTONS[n]) + "_w.bmp"
         CASE 4
            ll_currenthiml = ll_himl_large
            ll_color = ll_hbrush
            ll_size = 24
            ls_filename = &
               lnv_f.of_combinepath(ls_tmp, "24_" + res.BUTTONS[n]) + "_s.bmp"
      END CHOOSE
      
      //check for file
      IF NOT FileExists(ls_filename) THEN
         lnv_i.of_icontobitmapfile(anv_svc, &
                     ll_currenthiml, &
                     n - 1, &
                     ll_size, &
                     ll_color, &
                     ls_filename)
      END IF
   NEXT
NEXT

DESTROY res

RETURN ls_tmp
end function

public function integer of_makegradientstrip (ref n_svc_mgr anv_svc, readonly long al_startcolor, readonly long al_endcolor, readonly boolean ab_vertical, readonly integer ai_width, readonly integer ai_height, readonly string as_filename);RETURN of_makegradientstrip(anv_svc, &
                           al_startcolor, &
                           al_endcolor, &
                           ab_vertical, &
                           0, &
                           ai_width, &
                           ai_height, &
                           as_filename)
end function

public function integer of_makegradientstrip (ref n_svc_mgr anv_svc, readonly long al_startcolor, readonly long al_endcolor, readonly boolean ab_vertical, readonly integer ai_offset, readonly integer ai_width, readonly integer ai_height, readonly string as_filename);ulong ll_desktop, ll_dc, ll_mem, ll_bmp, ll_icon, ll_tmpdc
long ll_ret
boolean lbb
n_svc_win32 lnv_win32
blob lb

anv_svc.of_loadsvc(lnv_win32, CSvc.WIN32)

//create compatible DC from desktop
ll_desktop = lnv_win32.GetDesktopWindow()
ll_dc = lnv_win32.GetDC(ll_desktop)
ll_mem = lnv_win32.CreateCompatibleDC(ll_dc)
ll_tmpdc = lnv_win32.CreateCompatibleDC(ll_dc)
ll_bmp = lnv_win32.CreateCompatibleBitmap(ll_dc, ai_width, ai_height)

//draw icon on temp DC
ll_ret = lnv_win32.SelectObject(ll_tmpdc, ll_bmp)

//gradient
n_svc_color lnv_color
rect lrc

lrc.left = 0
lrc.top = 0
lrc.right = ai_width
lrc.bottom = ai_height

IF ab_vertical THEN
   lrc.bottom += ai_offset
ELSE
   lrc.right += ai_offset
END IF

anv_svc.of_LoadSvc(lnv_color, CSvc.COLOR)
lnv_color.of_Drawgradient(ll_tmpdc, lrc, al_startcolor, al_endcolor, ab_vertical)

//copy
ll_ret = lnv_win32.SelectObject(ll_mem, ll_bmp)
ll_ret = lnv_win32.Bitblt(ll_mem, 0, 0, ai_width, ai_height, ll_tmpdc, 0, 0, 13369376)

//create bitmap
long ll_pixels = 1

bitmapinfo lstr_Info
bitmapheader lstr_Header

lstr_Info.bmiheader.bisize=40

IF lnv_win32.GetDIBits(ll_mem, ll_bmp, 0, ai_height, 0, lstr_Info, 0) > 0 THEN
   IF lstr_Info.bmiheader.biBitCount = 16 OR &
         lstr_Info.bmiheader.biBitCount = 32 THEN
         ll_pixels = lstr_info.bmiheader.biwidth * lstr_info.bmiheader.biheight
   END IF
   
   lstr_Info.bmiColor[ll_pixels] = 0
      
   lb = blob(space(lstr_Info.bmiheader.bisizeimage), EncodingANSI!)

   //get the actual bits
   ll_ret = lnv_win32.GetDIBits(ll_mem, ll_bmp, 0, ai_height, lb, lstr_Info, 0) 
   
   // create a bitmap header
   lstr_Header.bfType[1] = CharA("B")
   lstr_Header.bfType[2] = CharA("M")
   lstr_Header.bfSize   = lstr_Info.bmiheader.bisizeimage
   lstr_Header.bfReserved1 = 0
   lstr_Header.bfReserved2 = 0
   lstr_Header.bfOffBits = 54 + (ll_pixels * 4)
   
   // copy the header structure to a blob
   blob lbl_header
   lbl_header = blob(space(14), EncodingANSI!)
   lnv_win32.CopyBitmapFileHeader(lbl_header, lstr_Header, 14 )

   // copy the info structure to a blob
   blob lbl_info
   lbl_Info = blob(space(40  + ll_pixels * 4), EncodingANSI!)
   lnv_win32.CopyBitmapInfo(lbl_Info, lstr_Info, 40 + ll_pixels * 4 )
   
   //add all together and we have a window bitmap in a blob
   lb = lbl_header + lbl_info + lb  
END IF

//clean-up
lnv_win32.DeleteDC(ll_mem)
lnv_win32.DeleteDC(ll_tmpdc)
lnv_win32.ReleaseDC(ll_desktop, ll_dc)
lnv_win32.DeleteObject(ll_bmp)

//write to disk
n_svc_files lnv_files

anv_svc.of_loadsvc(lnv_files, CSvc.FILES)

lnv_files.of_filewrite(anv_svc, as_filename, lb)

RETURN CRet.SUCCESS
end function

public subroutine of_addimagelist (readonly string as_imagelistname, readonly long al_handle, readonly string as_images[]);long ll_count

ll_count = UPPERBOUND(istr_images)
ll_count ++
istr_images[ll_count].name = as_imagelistname
istr_images[ll_count].handle = al_handle
istr_images[ll_count].images = as_images[]
end subroutine

public function long of_getimagelist (readonly string as_imagelistname);long ll_count, n

ll_count = UPPERBOUND(istr_images)
FOR n = 1 to ll_count
   IF istr_images[n].name = as_imagelistname THEN RETURN istr_images[n].handle
NEXT

RETURN CRet.FAILURE
end function

public function integer of_getimagelist (readonly string as_imagelistname, readonly string as_images[]);long ll_count, n

ll_count = UPPERBOUND(istr_images)
FOR n = 1 to ll_count
   IF istr_images[n].name = as_imagelistname THEN
      IF istr_images[n].images = as_images THEN RETURN n
   END IF
NEXT

RETURN CRet.FAILURE
end function

public function integer of_makeheaderline (ref n_svc_mgr anv_svc, readonly long al_color1, readonly long al_color2, readonly long al_color3, readonly string as_filename);ulong ll_desktop, ll_dc, ll_mem, ll_bmp, ll_icon, ll_tmpdc
ulong ll_pen
long ll_ret
boolean lbb
n_svc_win32 lnv_win32
blob lb

anv_svc.of_loadsvc(lnv_win32, CSvc.WIN32)

//create compatible DC from desktop
ll_desktop = lnv_win32.GetDesktopWindow()
ll_dc = lnv_win32.GetDC(ll_desktop)
ll_mem = lnv_win32.CreateCompatibleDC(ll_dc)
ll_tmpdc = lnv_win32.CreateCompatibleDC(ll_dc)
ll_bmp = lnv_win32.CreateCompatibleBitmap(ll_dc, 1, 3)

//draw line on temp DC
ll_ret = lnv_win32.SelectObject(ll_tmpdc, ll_bmp)

point lstrp
rect rc

lnv_win32.SetBkMode(ll_tmpdc, 0)

//rc.right = 2
//rc.bottom = 3
//lnv_win32.FillRect(ll_tmpdc, rc, lnv_win32.CreateSolidBrush(RGB(255,0,0)))

ll_pen = lnv_win32.CreatePen(0, 1, al_color1)
lnv_win32.SelectObject(ll_tmpdc, ll_pen)
lnv_win32.MoveToEx(ll_tmpdc, 0, 0, lstrp)
lnv_win32.LineTo(ll_tmpdc, 3, 0)
lnv_win32.DeleteObject(ll_pen)
lnv_win32.MoveToEx(ll_tmpdc, 0, 1, lstrp)

ll_pen = lnv_win32.CreatePen(0, 1, al_color2)
lnv_win32.SelectObject(ll_tmpdc, ll_pen)
lnv_win32.LineTo(ll_tmpdc, 3, 1)
lnv_win32.DeleteObject(ll_pen)

ll_pen = lnv_win32.CreatePen(0, 1, al_color3)
lnv_win32.SelectObject(ll_tmpdc, ll_pen)
lnv_win32.MoveToEx(ll_tmpdc, 0, 2, lstrp)
lnv_win32.LineTo(ll_tmpdc, 3, 2)
lnv_win32.DeleteObject(ll_pen)

//copy
ll_ret = lnv_win32.SelectObject(ll_mem, ll_bmp)
ll_ret = lnv_win32.Bitblt(ll_mem, 0, 0, 1, 3, ll_tmpdc, 0, 0, 13369376)

//create bitmap
long ll_pixels = 1

bitmapinfo lstr_Info
bitmapheader lstr_Header

lstr_Info.bmiheader.bisize=40

IF lnv_win32.GetDIBits(ll_mem, ll_bmp, 0, 3, 0, lstr_Info, 0) > 0 THEN
   IF lstr_Info.bmiheader.biBitCount = 16 OR &
         lstr_Info.bmiheader.biBitCount = 32 THEN
         ll_pixels = lstr_info.bmiheader.biwidth * lstr_info.bmiheader.biheight
   END IF
   
   lstr_Info.bmiColor[ll_pixels] = 0
      
   lb = blob(space(lstr_Info.bmiheader.bisizeimage), EncodingANSI!)

   //get the actual bits
   ll_ret = lnv_win32.GetDIBits(ll_mem, ll_bmp, 0, 3, lb, lstr_Info, 0) 
   
   // create a bitmap header
   lstr_Header.bfType[1] = CharA("B")
   lstr_Header.bfType[2] = CharA("M")
   lstr_Header.bfSize   = lstr_Info.bmiheader.bisizeimage
   lstr_Header.bfReserved1 = 0
   lstr_Header.bfReserved2 = 0
   lstr_Header.bfOffBits = 54 + (ll_pixels * 4)
   
   // copy the header structure to a blob
   blob lbl_header
   lbl_header = blob(space(14), EncodingANSI!)
   lnv_win32.CopyBitmapFileHeader(lbl_header, lstr_Header, 14 )

   // copy the info structure to a blob
   blob lbl_info
   lbl_Info = blob(space(40  + ll_pixels * 4), EncodingANSI!)
   lnv_win32.CopyBitmapInfo(lbl_Info, lstr_Info, 40 + ll_pixels * 4 )
   
   //add all together and we have a window bitmap in a blob
   lb = lbl_header + lbl_info + lb  
END IF

//clean-up
lnv_win32.DeleteDC(ll_mem)
lnv_win32.DeleteDC(ll_tmpdc)
lnv_win32.ReleaseDC(ll_desktop, ll_dc)
lnv_win32.DeleteObject(ll_bmp)

//write to disk
n_svc_files lnv_files

anv_svc.of_loadsvc(lnv_files, CSvc.FILES)

lnv_files.of_filewrite(anv_svc, as_filename, lb)

RETURN CRet.SUCCESS
end function

on n_svc_resource.create
call super::create
end on

on n_svc_resource.destroy
call super::destroy
end on

event destructor;call super::destructor;IF ISVALID(iw) THEN CLOSE(iw)
of_DestroyImages()
end event