It is currently Mon Dec 09, 2019 7:00 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 71 posts ]  Go to page Previous  1, 2, 3, 4, 5
Author Message
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 4:02 am 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 8006
Location: Fort Nelson, BC, Canada
Might have happened onto something...
MSDN wrote:
You can use CLSID_ACLMulti if you want AutoComplete to use multiple lists


Code:
DataSection
  CLSID_ACLMulti:
  Data.l $00BB2765
  Data.w $6A77, $11D0
  Data.b $A5, $35, $00, $C0, $4F, $D7, $D0, $62
EndDataSection


Use in place of CLSID_AutoComplete. Since you're still up for working with this, you might give this CLSID a try.

_________________
Veni, vidi, vici.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 4:29 pm 
Offline
Addict
Addict

Joined: Wed Aug 24, 2005 8:39 am
Posts: 2736
Location: Southwest OH - USA
Not sure that solves the updating problem. I haven't been able to get it to work yet, but then, what did you expect :)

The release/rebuild the list approach seems to be unreliable, at least in my testing.

According to this source code, it appears there are ways to add and remove items as part of iautocomplete. Although how to access them remains a mystery to me.

http://www.codeproject.com/kb/wtl/Custo ... e_wtl.aspx

If you decide to cook one of your own, and can understand c++, this might provide a start. Once again, way beyond me. I'll soon be looking for some other alternative. Maybe I can get xombie to update his for lists again :)

http://www.codeproject.com/KB/combobox/ ... plete.aspx

cheers


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 6:10 pm 
Offline
Addict
Addict

Joined: Wed Aug 24, 2005 8:39 am
Posts: 2736
Location: Southwest OH - USA
Mr maestro

Any chance this could be contributing to my unexplained crashes? (which often occur at the procedureReturn)

viewtopic.php?f=4&t=42874&hilit=structure+array+procedure

cheers


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 6:19 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 8006
Location: Fort Nelson, BC, Canada
I doubt it as that fails every time, and that's not what's happening to you. Imho, the IAutoComplete2 object isn't releasing all its resources when the \release() method is called and that's causing a crash on the next run.

_________________
Veni, vidi, vici.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 6:45 pm 
Offline
Addict
Addict

Joined: Wed Aug 24, 2005 8:39 am
Posts: 2736
Location: Southwest OH - USA
Thanks again.

Between perusing codeproject and msdn, I realize I'm in way over my head. I'm moving back to xombies routine, which appears it may satisfy my basic requirements, at least for now. I've spent way too much time on this and it seems I'm no closer to a real solution than I was at the start.

If you decide to roll your own, I'll be happy to lend whatever assistance I can. If you make any progress on this one, please let me know that as well.

Thanks once again for all your assistance.

cheers


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 8:48 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 8006
Location: Fort Nelson, BC, Canada
Here is a solution half-done. That is, the object is working and fully functional, it's just the display presentation isn't done. Results just go to the debug window. Size your debug window narrow and long and pretend it's a menu, then have a play with this and see if you can get it to fail:
Code:
;==================================================================
;
; Library:           AutoComplete v. 0.3 alpha
; Author:            Lloyd Gallant (netmaestro)
; Date:              July 21, 2010
; Target OS:         Microsoft Windows All
; Target Compiler:   PureBasic 4.50 and later
; license:           Free, unrestricted, no warranty whatsoever
;                    credit appreciated but not required
;
;==================================================================

UseSQLiteDatabase()

#DATABASE_OK = ""

Structure AutoCompleteObject
  *vTable
  database.i
  subclass_oldproc.i
  gadget.i
  dynamic.b
EndStructure

Interface iAutoCompleteObject
  Attach    ( gadget, *strings, size )
  AddString ( gadget, *string )
  Release   ()
EndInterface

Procedure AddString(*this.AutoCompleteObject, gadget, *string )
  text$ = PeekS(*string)
  sql$ =  "SELECT promptstring FROM Autocomplete where (promptstring = '"+text$+"' and gadget = '" + Str(gadget) + "')"
  DatabaseQuery(*this\database, sql$)
  recordcount = 0
  While NextDatabaseRow(*this\database)
    recordcount+1
  Wend
  FinishDatabaseQuery(*this\database)
  If recordcount = 0
    sql$ = "insert into Autocomplete (gadget, promptstring) values(" + Str(gadget) + "," + "'"+ PeekS(*string) + "')"
    DatabaseUpdate(*this\database, sql$)
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure _nmAC_StringProc(hwnd, msg, wparam, lparam)
  *this.AutoCompleteObject = GetProp_(hwnd, "acdata")
  oldproc = *this\subclass_oldproc
  gadget = *this\gadget
 
  Select msg
    Case #WM_NCDESTROY
      RemoveProp_(hwnd, "oldproc")
     
    Case #WM_KEYUP
      If GetFocus_() = hwnd
        ClearDebugOutput()
        text$ = GetGadgetText(*this\gadget)
        If text$ <> ""
          sql$ =  "SELECT promptstring FROM Autocomplete where (promptstring like '"+text$+"%' and gadget = '" + Str(gadget) + "')"
          DatabaseQuery(*this\database, sql$)
          While NextDatabaseRow(*this\database)
            Debug GetDatabaseString(*this\database,0)
          Wend
          FinishDatabaseQuery(*this\database)
        EndIf
      EndIf
     
    Case #WM_KILLFOCUS
      If *this\dynamic
        text$ = GetGadgetText(gadget)
        Addstring(*this, gadget, @text$)
      EndIf
     
    Case #WM_SETFOCUS
      SendMessage_(hwnd, #EM_SETSEL, 0, -1)
   
  EndSelect   
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure

Procedure Attach(*this.AutoCompleteObject, gadget, *strings, size )
  Protected fail_status = #False
  *ptr = *strings
  For i=1 To size
    sql$ = "insert into Autocomplete (gadget, promptstring) values(" + Str(gadget) + "," + "'"+ PeekS(PeekL(*ptr)) + "')"
    If DatabaseUpdate(*this\database, sql$)
      *ptr+SizeOf(integer)
    Else
      fail_status = #True
      Break
    EndIf
  Next
  If IsGadget(gadget) And GadgetType(gadget) = #PB_GadgetType_String And fail_status = #False
    *this\gadget = gadget
    *this\subclass_oldproc = SetWindowLongPtr_(GadgetID(gadget), #GWL_WNDPROC, @_nmAC_StringProc())
    SetProp_(GadgetID(gadget), "acdata", *this )
  Else
    fail_status = #True
  EndIf
 
  If fail_status = #False
    ProcedureReturn #True
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure NewObject_Autocomplete(dynamic=0)
  *newobject.AutoCompleteObject = AllocateMemory(SizeOf(AutoCompleteObject))
  With *newobject
    \vTable = ?AutoComplete_Methods
    \dynamic = dynamic
  EndWith
  dbOpenResult = OpenDatabase(#PB_Any, ":memory:", "", "")
  If dbOpenResult
    DatabaseUpdate(dbOpenResult, "CREATE TABLE AutoComplete (gadget VARCHAR, promptstring VARCHAR(255));")       
    If DatabaseError() = #DATABASE_OK
      *newobject\database = dbOpenResult
      ProcedureReturn *newobject
    Else
      ProcedureReturn 0
    EndIf
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure Release(*this.AutoCompleteObject)
  If *this\subclass_oldproc
    SetWindowLongPtr_(GadgetID(*this\gadget),#GWL_WNDPROC, *this\subclass_oldproc)
  EndIf
  If IsDatabase(*this\database)
    CloseDatabase(*this\database)
  EndIf
  FreeMemory(*this)
EndProcedure

DataSection
  AutoComplete_Methods:
  Data.l @Attach(), @AddString(), @Release()
EndDataSection

;=================================================================
;                    END OF INCLUDE CODESECTION
;=================================================================

; Test prog

Dim Strings.s(17)
Strings(0)  = "Else"
Strings(1)  = "ElseIf"
Strings(2)  = "EnableDebugger"
Strings(3)  = "EnableExplicit"
Strings(4)  = "End"
Strings(5)  = "EndDataSection"
Strings(6)  = "EndEnumeration"
Strings(7)  = "EndIf"
Strings(8)  = "EndImport"
Strings(9)  = "EndInterface"
Strings(10) = "EndMacro"
Strings(11) = "EndProcedure"
Strings(12) = "EndSelect"
Strings(13) = "EndStructure"
Strings(14) = "EndStructureUnion"
Strings(15) = "EndWith"
Strings(16) = "Enumeration"


OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
StringGadget(6, 10,10, 300,20,"")
StringGadget(7, 10,50, 300,20,"")
SetActiveGadget(6)


prompts1.iAutoCompleteObject = NewObject_Autocomplete(1) ; Dynamic additions on
prompts1\Attach(6, @strings(), 17 )

prompts2.iAutoCompleteObject = NewObject_Autocomplete() ; Dynamic additions off - list doesn't change
prompts2\Attach(7, @strings(), 17 )

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

prompts1\Release()
prompts2\Release()


_________________
Veni, vidi, vici.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Jul 21, 2010 10:11 pm 
Offline
Addict
Addict

Joined: Wed Aug 24, 2005 8:39 am
Posts: 2736
Location: Southwest OH - USA
Wow, what a novel approach. Brilliant!

At least some of us don't get lost in the forest looking for trees.

This looks very promising. Plus, I know little bit about SQLite, so can understand bits of what's going on.

My hat's of to you, Mr maestro.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Wed Aug 04, 2010 5:16 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jul 01, 2004 2:51 am
Posts: 898
Location: Tacoma, WA
Huh. I haven't messed with my autocomplete stuff for a long time. If I need to change anything, let me know.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Fri May 25, 2012 11:17 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Tue Jun 12, 2007 10:30 am
Posts: 617
Location: not there...
Hi,

I got a problem and I hope someone could help me, please.

Freak`s code runs fine on almost every WinOS, but on some Win7-64bit machines it chrashes when I use ExplorerGadget or Webgadget?!
This is really freaking me out :-)

If I just put one line to the code (ExplorerGadget or WebGadget), the app is freezing, when trying to type something into the StringGadget :-(
No error or something :-(

Has anyone an idea, what`s the reason for this?

** Edit: WebGadget runs fine, when not using it like an Explorer (dir instead or url)...

Many, many Thanks!

_________________
5.70


Top
 Profile  
Reply with quote  
 Post subject: Fixed AutoComplete for StringGadgets in X64 Compiler
PostPosted: Wed Jul 03, 2013 4:55 pm 
Offline
Enthusiast
Enthusiast

Joined: Mon Dec 24, 2007 4:15 pm
Posts: 203
Location: Iran
i changed some lines so now its Compatible with x64 PureBasic compiler.

AutoComplete.pbi
Code:
;
;  Generic Implementation of an IEnumString Interface.
;  New_EnumString(StringArray(), ItemCount) will create a new IEnumString instance
;  with a referencecount of 1. (this means you must call IEnumString\Release()
;  to release this reference once you do not need it anymore.)
;
;
;
EnableExplicit

; To allow for the ::Clone() method without dublicating the buffer,
; the string buffer is kept separate, with its own reference count.
Structure EnumStringBuffer
  RefCount.l
  Strings.l[0]
  ; following is the literal string data
EndStructure

; IEnumString data
Structure EnumString
 *Vtbl
  RefCount.l
  StringCount.l
  Enumerator.l
 *Buffer.EnumStringBuffer
EndStructure


Procedure IEnumString_QueryInterface(*THIS.EnumString, *IID.IID, *Object.Integer)
  If *Object = 0
    ProcedureReturn #E_INVALIDARG
  ElseIf CompareMemory(*IID, ?IID_IUnknown, SizeOf(IID)) Or  CompareMemory(*IID, ?IID_IEnumString, SizeOf(IID))
    *Object\i = *THIS
    *THIS\RefCount + 1
    ProcedureReturn #S_OK
  Else
    *Object\i = 0
    ProcedureReturn #E_NOINTERFACE
  EndIf
EndProcedure


Procedure IEnumString_AddRef(*THIS.EnumString)
  *THIS\RefCount + 1
  ProcedureReturn *THIS\RefCount
EndProcedure


Procedure IEnumString_Release(*THIS.EnumString)
  *THIS\RefCount - 1
 
  If *THIS\RefCount = 0
    *THIS\Buffer\RefCount - 1
    If *THIS\Buffer\RefCount = 0
      FreeMemory(*THIS\Buffer)
    EndIf
   
    FreeMemory(*THIS)
    ProcedureReturn 0
  Else
    ProcedureReturn *THIS\RefCount
  EndIf
EndProcedure


Procedure IEnumString_Next(*THIS.EnumString, celt, *rgelt.Integer, *pceltFetched.Integer)
  Protected count.i, i.i
 
  If *THIS\Enumerator + celt <= *THIS\StringCount
    count = celt
  Else
    count = *THIS\StringCount - *THIS\Enumerator
  EndIf
 
  For i = 0 To count-1
    *rgelt\i = *THIS\Buffer\Strings[*THIS\Enumerator + i]
    *rgelt + 4
  Next i
 
  *THIS\Enumerator + count
 
  If *pceltFetched
    *pceltFetched\i = count
  EndIf
 
  If count = celt
    ProcedureReturn #S_OK
  Else
    ProcedureReturn #S_FALSE
  EndIf
EndProcedure


Procedure IEnumString_Skip(*THIS.EnumString, celt)
  *THIS\Enumerator + celt
  If *THIS\Enumerator <= *THIS\StringCount
    ProcedureReturn #S_OK
  Else
    ProcedureReturn #S_FALSE
  EndIf
EndProcedure


Procedure IEnumString_Reset(*THIS.EnumString)
  *THIS\Enumerator = 0
  ProcedureReturn #S_OK
EndProcedure


Procedure IEnumString_Clone(*THIS.EnumString, *ppenum.Integer)
  Protected *Clone.EnumString
 
  If *ppenum = 0
    ProcedureReturn #E_INVALIDARG
  Else   
    *Clone = AllocateMemory(SizeOf(EnumString))
    If *Clone
      CopyMemory(*THIS, *Clone, SizeOf(EnumString))
      *Clone\RefCount = 1
      *Clone\Buffer\RefCount + 1
      *ppenum\i = *Clone
      ProcedureReturn #S_OK
    Else
      *ppenum\i = 0
      ProcedureReturn #E_OUTOFMEMORY
    EndIf
  EndIf
EndProcedure


Procedure New_EnumString(Array StringArray.s(1))
  Protected *THIS.EnumString = 0, *StringBuffer.EnumStringBuffer
  Protected StringCount.i, Size.i, i.i
  Protected *Pointer
 
  StringCount = ArraySize(StringArray())

  Size = 4 + StringCount * 4
  For i = 0 To StringCount - 1
    Size + Len(StringArray(i)) * 2 + 2
  Next i

  *StringBuffer = AllocateMemory(Size)
  If *StringBuffer
    *StringBuffer\RefCount = 1
    *Pointer = *StringBuffer + 4 + StringCount * 4
   
    For i = 0 To StringCount - 1
      *StringBuffer\Strings[i] = *Pointer
      PokeS(*Pointer, StringArray(i), -1, #PB_Unicode)
      *Pointer + Len(StringArray(i)) * 2 + 2
    Next i
   
    *THIS = AllocateMemory(SizeOf(EnumString))
    If *THIS
      *THIS\Vtbl        = ?IEnumStringVtbl
      *THIS\RefCount    = 1
      *THIS\StringCount = StringCount
      *THIS\Enumerator  = 0
      *THIS\Buffer      = *StringBuffer
    Else
      FreeMemory(*StringBuffer)
    EndIf
  EndIf   

  ProcedureReturn *THIS
EndProcedure


DataSection
  IEnumStringVtbl:
    Data.i @IEnumString_QueryInterface()
    Data.i @IEnumString_AddRef()
    Data.i @IEnumString_Release()
    Data.i @IEnumString_Next()
    Data.i @IEnumString_Skip()
    Data.i @IEnumString_Reset()
    Data.i @IEnumString_Clone()
   
  IID_IUnknown:       ; {00000000-0000-0000-C000-000000000046}
    Data.l $00000000
    Data.w $0000, $0000
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46
   
  IID_IEnumString:    ; {00000101-0000-0000-C000-000000000046}
    Data.l $00000101
    Data.w $0000, $0000
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46
   
  CLSID_AutoComplete: ; {00BB2763-6A77-11D0-A535-00C04FD7D062}
    Data.l $00BB2763
    Data.w $6A77, $11D0
    Data.b $A5, $35, $00, $C0, $4F, $D7, $D0, $62

  IID_IAutoComplete:  ; {00BB2762-6A77-11D0-A535-00C04FD7D062}
    Data.l $00BB2762
    Data.w $6A77, $11D0
    Data.b $A5, $35, $00, $C0, $4F, $D7, $D0, $62

  IID_IAutoComplete2: ; {EAC04BC0-3791-11D2-BB95-0060977B464C}
    Data.l $EAC04BC0
    Data.w $3791, $11D2
    Data.b $BB, $95, $00, $60, $97, $7B, $46, $4C
EndDataSection


#CLSCTX_INPROC_SERVER     = $1
#ACO_NONE                 = 0   ; No autocompletion.
#ACO_AUTOSUGGEST          = $1  ; Enable the autosuggest drop-down list.
#ACO_AUTOAPPEND           = $2  ; Enable autoappend.
#ACO_SEARCH               = $4  ; Add a search item to the dropdown list of completed strings. If this is item is selected, you should launch a search engine to assist the user.
#ACO_FILTERPREFIXES       = $8  ; Don't match common prefixes, such as "www.", "http://", and so on.
#ACO_USETAB               = $10 ; Use the TAB key to select an item from the drop-down list. This flag is disabled by default.
#ACO_UPDOWNKEYDROPSLIST   = $20 ; Use the UP ARROW and DOWN ARROW keys to display the autosuggest drop-down list.
#ACO_RTLREADING           = $40 ; If ACO_RTLREADING is set, the text is read in the opposite direction from the text in the parent window.



main.pb
Code:
IncludeFile "AutoComplete.pbi"

; -----------------------------------------------

#Window_0 = 0
#String_0 = 0

Dim Strings.s(17)
Strings(0)  = "Else"
Strings(1)  = "ElseIf"
Strings(2)  = "EnableDebugger"
Strings(3)  = "EnableExplicit"
Strings(4)  = "End"
Strings(5)  = "EndDataSection"
Strings(6)  = "EndEnumeration"
Strings(7)  = "EndIf"
Strings(8)  = "EndImport"
Strings(9)  = "EndInterface"
Strings(10) = "EndMacro"
Strings(11) = "EndProcedure"
Strings(12) = "EndSelect"
Strings(13) = "EndStructure"
Strings(14) = "EndStructureUnion"
Strings(15) = "EndWith"
Strings(16) = "Enumeration"

; Initialize the COM environment
CoInitialize_(0)

Define *AutoComplete.IAutoComplete2, *Enum.IEnumString

If OpenWindow(#Window_0, 323, 219, 600, 300, "AutoComplete",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    StringGadget(#String_0, 40, 40, 320, 20, "")
    SetActiveGadget(#String_0)
   
    ; This creates the autocomplete object:
    ;
    If CoCreateInstance_(?CLSID_AutoComplete, #Null, 1, ?IID_IAutoComplete2, @*AutoComplete) = #S_OK
   
      ; Lets change the options for autocomplete a bit:
      ; See the constant definitions above for the available options.
      ; There is a dropdown or in-place suggestion mode.
      ;
      *AutoComplete\SetOptions(#ACO_AUTOSUGGEST|#ACO_USETAB)
   
      ; This creates the IEnumString interface from our string array:
      ;
      *Enum = New_EnumString(Strings())
     
      ; This sets the autocomplet with our Enum object.
      ; If you want more info on the last 2 parameters, read here:
      ; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/ifaces/iautocomplete/Init.asp
      ; Note that these must be unicode strings if present!
      ;
      ; This also works for Comboboxes, you just need to get the handle to the edit
      ; control that is contained inside with the GetComboBoxInfo_() function.     
      ;
      *AutoComplete\Init(GadgetID(#String_0), *Enum, 0, 0)
     
      Repeat
      Until WaitWindowEvent() = #PB_Event_CloseWindow
     
      ; Release our own references to the objects to avoid a memory leak
      ;
      *Enum\Release()       
      *AutoComplete\Release()     
    EndIf
EndIf

_________________
Sorry for my bad english.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Windows] AutoComplete for StringGadgets
PostPosted: Thu Apr 11, 2019 6:10 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Jun 23, 2010 5:13 pm
Posts: 206
Autocomplete with using sql select is clear. But how to attach structured or multidimentional array like
1: MyArray(id, string)
2: MyArray\id and MyArray\string
to editable comboboxgadget to autofilter gadget contents.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 71 posts ]  Go to page Previous  1, 2, 3, 4, 5

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye