[Windows] AutoComplete for StringGadgets

Share your advanced PureBasic knowledge/code with the community.
Marco2007
Enthusiast
Enthusiast
Posts: 638
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Post by Marco2007 »

Thanx, I didn`t know that (just tried it) :D
PureBasic for Windows
Marco2007
Enthusiast
Enthusiast
Posts: 638
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Re: [Windows] AutoComplete for StringGadgets

Post by Marco2007 »

The code is little too heavy for me, but it`s one of my fav includes.

Does anyone see any problems, when doing this (two arrays for two gadgets):

Code: Select all

  ;{ LinkedList Kundendaten
  If CoCreateInstance_(?CLSID_AutoComplete, 0, 1, ?IID_IAutoComplete2, @AutoComplete.IAutoComplete2) = #S_OK    
    AutoComplete\SetOptions(#ACO_AUTOSUGGEST|#ACO_USETAB)      
    Enum.IEnumString = New_EnumString(kArray(), anzahlelemente) 
    AutoComplete\Init(GadgetID(#kunde), Enum, 0, 0)
  EndIf  
  ;}
  
  ;{ Map Artikel 
  
   If CoCreateInstance_(?CLSID_AutoComplete, 0, 1, ?IID_IAutoComplete2, @AutoComplete.IAutoComplete2) = #S_OK    
    AutoComplete\SetOptions(#ACO_AUTOSUGGEST|#ACO_USETAB)      
    Enum.IEnumString = New_EnumString(ArtikelArray(), anzahlArtikel) 
    AutoComplete\Init(GadgetID(#String_Artikel), Enum, 0, 0)
  EndIf
  ;}
;
;
;Code
;
Enum\Release()        
AutoComplete\Release()
CoUninitialize_()


At least it works without any problems so far....

Would be great, if someone could confirm, that this is okay.

Thank you.


* Edit:
I changed second AutoComplete to:

Code: Select all

;{ Map Artikel 
    Enum2.IEnumString = New_EnumString(ArtikelArray(), anzahlArtikel) 
    AutoComplete\Init(GadgetID(#String_Artikel), Enum2, 0, 0)
  ;}
PureBasic for Windows
Marco2007
Enthusiast
Enthusiast
Posts: 638
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Re: [Windows] AutoComplete for StringGadgets

Post by Marco2007 »

I have no problems on XP, when using:
;{ Map Artikel
Enum2.IEnumString = New_EnumString(ArtikelArray(), anzahlArtikel)
AutoComplete\Init(GadgetID(#String_Artikel), Enum2, 0, 0)
;}
...but it doesn`t work on Windows 7. Has anyone an idea why? thx
PureBasic for Windows
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [Windows] AutoComplete for StringGadgets

Post by netmaestro »

On Win7 using PB 4.40 running the sample prog I get this after I close the program whether I used the autocomplete or not:

Image

Invalid memory access (read error)
BERESHEIT
Marco2007
Enthusiast
Enthusiast
Posts: 638
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Re: [Windows] AutoComplete for StringGadgets

Post by Marco2007 »

Does this work? CloseWindow() after #PB_Event_CloseWindow:
http://www.purebasic.fr/english/viewtop ... 89#p264389
PureBasic for Windows
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [Windows] AutoComplete for StringGadgets

Post by netmaestro »

Yep!
BERESHEIT
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: [Windows] AutoComplete for StringGadgets

Post by rsts »

This routine works nice and would appear to satisfy my autocomplete requirements IF I could figure out some way of updating the commands() array from within the program. All my attempts so far (and there have been many) have resulted in some sort of error (usually memory) upon attempting to use the autocomplete after the addition or upon closing the window.

I've tried updating the commands() array (no good, it's not dynamic) and attempting to release and reinitialize the autocomplete, (eventually results in an error).

Is there something I'm missing (hopefully) or is this implementation of autocomplete static only?

cheers
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: [Windows] AutoComplete for StringGadgets

Post by srod »

Why not just release the objects and then recreate them etc? Worked okay here.
I may look like a mule, but I'm not a complete ass.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: [Windows] AutoComplete for StringGadgets

Post by rsts »

srod wrote:Why not just release the objects and then recreate them etc? Worked okay here.
'cause I can't seem to get it right. :)

That's where I've been spending most of my time, but it always ends in a crash of some sort.

cheers
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [Windows] AutoComplete for StringGadgets

Post by netmaestro »

So far the only way I've found that seems solid is to initialize the array with more items than you should expect to get added in real usage. Then new added items don't seem to cause a problem. In this sample, when you tab away from #string_0, any text that's in the gadget will be added to the autocomplete list for next time. Put some text in, tab away, tab back and fool around with it. So far this code isn't failing here:

Code: Select all

XIncludeFile "IEnumString.pbi"

#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.


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

#Window_0 = 0
#String_0 = 0
#string_1 = 1

Dim Strings.s(100)
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"

Global laststring = 16

; Initialize the COM environment
CoInitialize_(0)

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, "")
  StringGadget(#String_1, 40, 90, 320, 20, "")
  SetActiveGadget(#String_0)
  
  ; This creates the autocomplete object:
  ;
  If CoCreateInstance_(?CLSID_AutoComplete, 0, 1, ?IID_IAutoComplete2, @AutoComplete.IAutoComplete2) = #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.IEnumString = New_EnumString(Strings(), 101)
    
    ; 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
      EventID = WaitWindowEvent()
      Select EventID
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #string_0
              If EventType() = #PB_EventType_LostFocus
                ; Add gadget contents to the array
                tmp$ = GetGadgetText(#string_0)
                FreeGadget(#string_0)
                laststring + 1
                Strings(laststring) = tmp$
                Enum\Release()
                AutoComplete\Release()   
                StringGadget(#String_0, 40, 40, 320, 20, tmp$)
                CoCreateInstance_(?CLSID_AutoComplete, 0, 1, ?IID_IAutoComplete2, @AutoComplete.IAutoComplete2)
                AutoComplete\SetOptions(#ACO_AUTOSUGGEST|#ACO_USETAB) 
                Enum.IEnumString = New_EnumString(Strings(), 101)
                AutoComplete\Init(GadgetID(#String_0), Enum, 0, 0)       
             EndIf
          EndSelect
          
      EndSelect
    Until EventID= #PB_Event_CloseWindow
    CloseWindow(#window_0)
    
    ; Release our own references to the objects to avoid a memory leak
    ;
    Enum\Release()        
    AutoComplete\Release()      
  EndIf
EndIf


CoUninitialize_()

DataSection
  
  
  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
BERESHEIT
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: [Windows] AutoComplete for StringGadgets

Post by rsts »

Actually, one pre-defined array was one of the many approaches I had tried and failed with.

Your fine example allowed me to see the error of my routine. (I was using arraySize as the size passed to New_EnumString(Strings()
where it should be arraySize + 1. Now I remember that discussion from some time back :)

The other problem area I have is related to attempting to proceduralize the routines - that is to have a procedure for the #PB_EventType_LostFocus for #string_0. Each time I've attempted that, the releases and creates have failed at various points.

Many many thanks, Mr netmaestro. I just may get this working yet.

cheers

edit

There also seems to be a recurring problem related to a program crash. It seems that if the program crashes, for whatever reason - maybe an incorrect arraySize parm. Upon re-running the program, all bets are off as to whether it will work or not. It usually needs to be started again and ended cleanly before you can count on anything working. Is there anything that can be done during an initialization to assure a "clean" environment?

Try running your version. add "win" as a new autocomplete entry (via the tab). End the program. restart it and see what entering "w" does. For me, it crashes every time.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [Windows] AutoComplete for StringGadgets

Post by netmaestro »

add "win" as a new autocomplete entry (via the tab). End the program. restart it and see what entering "w" does. For me, it crashes every time
I can't reproduce that. I killed the program many times from the debugger and from Taskmanager but it always works fine next time. I'm running win7 x86 here.
BERESHEIT
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: [Windows] AutoComplete for StringGadgets

Post by rsts »

netmaestro wrote: I'm running win7 x86 here.
Me too.

Must be something screwy here. I can get random crashes in freaks original code too - like if I run it after a crash of your version. It will run fine once or twice and then crash repeatedly. Have re-done the pbi from freaks post, which is where the crashes occur, almost always a memory error on a procedure return #s_OK, usually in Procedure IEnumString_Next(*THIS.EnumString, celt, *rgelt.LONG, *pceltFetched.LONG). I've run it with freaks ValidatePBHeap routine and there's never any stack corruption.

Will keep trying things, but am out of ideas.

Thanks again for your assistance. At least the fact that it won't crash for you gives me some hope.

cheers
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: [Windows] AutoComplete for StringGadgets

Post by netmaestro »

A google search on "IAutocomplete2 Access Violation Refresh List" turns up many many hits, all with random access violations following a refreshing of the list and much discussion as to possible causes and solutions. Unfortunately I didn't find a lot of threads with happy endings and there is a growing consensus that the Microsoft IAutocomplete2 object is bugged. Refreshing the list by all manner of means including those we've tried seems to cause random crashes later, no matter what. I might take a shot at writing a custom one based on an in-memory SQLite database and a popupmenu.
BERESHEIT
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: [Windows] AutoComplete for StringGadgets

Post by rsts »

I'm still working with it (and still getting really random crashes, as in, fine on one run but crashes on the next with nothing having changed).

I'm about ready to abandon it, but am attempting one more approach.

cheers
Post Reply