File: u_ddlb_history.sru
Size: 5188
Date: Wed, 18 Jan 2017 04:51:04 +0100
$PBExportHeader$u_ddlb_history.sru
$PBExportComments$Input dropdown listbox with autocomplete history
forward
global type u_ddlb_history from dropdownlistbox
end type
end forward

global type u_ddlb_history from dropdownlistbox
integer width = 1358
integer height = 416
integer taborder = 10
integer textsize = -8
integer weight = 400
fontcharset fontcharset = ansi!
fontpitch fontpitch = variable!
fontfamily fontfamily = swiss!
string facename = "MS Sans Serif"
long textcolor = 33554432
boolean allowedit = true
boolean sorted = false
boolean vscrollbar = true
borderstyle borderstyle = stylelowered!
event editchanged pbm_cbneditchange
end type
global u_ddlb_history u_ddlb_history

type prototypes
Function integer GetClassName ( &
   ulong hWind, &
   ref string name, &
   int cbmax &
   ) Library "user32.dll" Alias For "GetClassNameW"

Function ulong GetWindow ( &
   ulong hWind, &
   uint fuRel &
   ) Library "user32.dll"

Function long GetWindowLong ( &
   long hWindow, &
   integer nIndex &
   ) Library "user32.dll" Alias For "GetWindowLongW"

Function long SetWindowLong ( &
   long hWindow, &
   integer nIndex, &
   long dwNewLong &
   ) Library "user32.dll" Alias For "SetWindowLongW"

end prototypes

type variables
CONSTANT uint ES_UPPERCASE  = 8
CONSTANT uint ES_LOWERCASE  = 16
CONSTANT int GWL_STYLE  = -16
CONSTANT uint GW_CHILD = 5

Window iw_parent

end variables

forward prototypes
public subroutine of_save (string as_section)
public function window of_parentwindow ()
public function string of_getdata ()
public subroutine of_setcase (integer ai_case)
public subroutine of_clear ()
public subroutine of_load (string as_section, boolean ab_preselect)
end prototypes

event editchanged;Integer li_find, li_len
String ls_item

// ignore Delete and Backspace keys
If keyDown(keyDelete!) OR keyDown(keyBack!) Then Return

// search for typed text
li_find = this.FindItem(this.text, 0)
If li_find > 0 Then
   // get length of typed text
   li_len = Len(this.text)
   // set current text to found item
   ls_item = this.Text(li_find)
   this.text = this.text + Mid(ls_item, li_len + 1)
   // select part not typed
   this.SelectText(li_len + 1, 32767)
   // delete found item and reinsert at the top
   this.DeleteItem(li_find)
   this.InsertItem(this.text, 1)
End If

end event

public subroutine of_save (string as_section);// save entries to registry
Integer li_row, li_max
String ls_subkey

// limit saved items to 100
li_max = this.TotalItems()
If li_max > 100 Then
   li_max = 100
End If

ls_subkey = "History\" + as_section

// save items to registry
FOR li_row = 1 TO li_max
   gn_app.of_SetReg(ls_subkey, "row_" + String(li_row), this.Text(li_row))
NEXT
gn_app.of_SetReg(ls_subkey, "max", String(li_max))

end subroutine

public function window of_parentwindow ();PowerObject lpo_parent
Window lw_window

// loop thru parents until a window is found
lpo_parent = this.GetParent()
Do While lpo_parent.TypeOf() <> Window! and IsValid (lpo_parent)
   lpo_parent = lpo_parent.GetParent()
Loop

// set return to the window or null if not found
If IsValid (lpo_parent) Then
   lw_window = lpo_parent
Else
   SetNull(lw_window)
End If

Return lw_window

end function

public function string of_getdata ();// return current value
Return this.text

end function

public subroutine of_setcase (integer ai_case);// set case to upper or lower
//
// This function Copyright © 2000 Philip Salgannik, used with permission

String ls_name
ULong lul_hwnd, lul_style

CHOOSE CASE ai_case
   CASE ES_LOWERCASE, ES_UPPERCASE
      lul_hwnd = GetWindow(Handle(this), GW_CHILD)
      DO UNTIL lul_hwnd = 0
         ls_name = Space(25)
         GetClassName(lul_hwnd, ls_name, Len(ls_name))
         If ls_name = "Edit" Then
            lul_style = GetWindowLong(lul_hwnd, GWL_STYLE)
            IF lul_style > 0 Then
               SetWindowLong(lul_hwnd, GWL_STYLE, lul_style + ai_case)
            End If
            lul_hwnd = 0
         End If
      LOOP
   CASE ELSE
      Return
END CHOOSE

end subroutine

public subroutine of_clear ();// clear all entries
this.Reset()

end subroutine

public subroutine of_load (string as_section, boolean ab_preselect);// load entries from registry
Integer li_row, li_max, li_rc
String ls_subkey, ls_text

ls_subkey = "History\" + as_section

li_max = Integer(gn_app.of_GetReg(ls_subkey, "max", "0"))

// load items from registry
FOR li_row = 1 To li_max
   ls_text = gn_app.of_GetReg(ls_subkey, "row_" + String(li_row), "")
   If Len(ls_text) > 0 Then
      li_rc = this.AddItem(ls_text)
   End If
   If li_row = 1 And ab_preselect Then
      this.text = ls_text
   End If
NEXT

end subroutine

event modified;Integer li_find

// search for current text
li_find = this.FindItem(this.text, 0)
If li_find > 0 Then
   // delete found item and reinsert at the top
   this.DeleteItem(li_find)
   this.InsertItem(this.text, 1)
   this.SelectItem(1)
Else
   // insert item at top
   this.InsertItem(this.text, 1)
End If

end event

event constructor;// get handle to parent window
iw_parent = this.of_ParentWindow()

end event

on u_ddlb_history.create
end on

on u_ddlb_history.destroy
end on