All pastes #623482 Raw Edit

Untitled

public text v1 · immutable
#623482 ·published 2007-07-17 17:01 UTC
rendered paste body
; 
;  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.) 
; 
; 
; 


; 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.LONG) 
  If *Object = 0 
    ProcedureReturn #E_INVALIDARG 
  ElseIf CompareMemory(*IID, ?IID_IUnknown, SizeOf(IID)) Or  CompareMemory(*IID, ?IID_IEnumString, SizeOf(IID)) 
    *Object\l = *THIS 
    *THIS\RefCount + 1 
    ProcedureReturn #S_OK 
  Else 
    *Object\l = 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.LONG, *pceltFetched.LONG) 
  If *THIS\Enumerator + celt <= *THIS\StringCount 
    count = celt 
  Else 
    count = *THIS\StringCount - *THIS\Enumerator 
  EndIf 
  
  For i = 0 To count-1 
    *rgelt\l = *THIS\Buffer\Strings[*THIS\Enumerator + i] 
    *rgelt + 4 
  Next i 
  
  *THIS\Enumerator + count 
  
  If *pceltFetcted 
    *pceltFetched\l = 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.LONG) 
  If *ppenum = 0 
    ProcedureReturn #E_INVALIDARG 
  Else    
    *Clone.EnumString = AllocateMemory(SizeOf(EnumString)) 
    If *Clone 
      CopyMemory(*THIS, *Clone, SizeOf(EnumString)) 
      *Clone\RefCount = 1 
      *Clone\Buffer\RefCount + 1 
      *ppenum\l = *Clone 
      ProcedureReturn #S_OK 
    Else 
      *ppenum\l = 0 
      ProcedureReturn #E_OUTOFMEMORY 
    EndIf  
  EndIf 
EndProcedure 


Procedure New_EnumString(StringArray$(1), StringCount) 
  *THIS.EnumString = 0 

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

  *StringBuffer.EnumStringBuffer = 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.l @IEnumString_QueryInterface() 
    Data.l @IEnumString_AddRef() 
    Data.l @IEnumString_Release() 
    Data.l @IEnumString_Next() 
    Data.l @IEnumString_Skip() 
    Data.l @IEnumString_Reset() 
    Data.l @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 

EndDataSection


#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 

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) 

If OpenWindow(#Window_0, 323, 219, 600, 300, "AutoComplete",  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered ) 
  If CreateGadgetList(WindowID(#Window_0)) 
    StringGadget(#String_0, 40, 40, 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(), 18) 
      
      ; 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 
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