Main Menu

Recent posts

#1
José Roca Software / Re: GUID's
Last post by Richard Kelly - May 13, 2026, 07:54:42 PM
I knew Jose had something somewhere and, while I looked in a lot of Afx includes, I didn't look in AfxCOM.

The code below works perfectly.

DIM uGUID AS GUID
uGUID = AfxGuid()
print AfxGuidText(@uGUID)
#2
José Roca Software / Re: GUID's
Last post by Paul Squires - May 13, 2026, 07:14:42 PM
Check out AfxCOM.inc

PRIVATE FUNCTION AfxGuid (BYVAL pwszGuidText AS WSTRING PTR = NULL) AS GUID
PRIVATE FUNCTION AfxGuidText OVERLOAD (BYVAL classID AS CLSID PTR) AS STRING
PRIVATE FUNCTION AfxGuidText OVERLOAD (BYVAL classID AS CLSID) AS STRING
PRIVATE FUNCTION AfxGuidText OVERLOAD (BYVAL riid AS REFIID) AS STRING


#3
José Roca Software / GUID's
Last post by Richard Kelly - May 13, 2026, 07:10:48 AM
I had some old code below for creating guid's when I needed them. Is there something in Afx that is equivalent?

#Include once "windows.bi"
#Include once "win/uuids.bi"
#Include once "win/ole2.bi"

Dim guid As GUID
Dim wstrGUID As LPOLESTR
Dim strGUID As ZString * 260

    CoCreateGuid (@guid)
    If(StringFromCLSID (@guid, @wstrGUID) = S_OK) THEN
       WideCharToMultiByte (CP_ACP, 0, Cast(WString Ptr,wstrGUID), -1, strGUID, MAX_PATH, NULL, NULL)
        Print strGUID
     EndIf
    CoTaskMemFree(@wstrGUID)
#4
José Roca Software / Re: DWStrList
Last post by Richard Kelly - May 07, 2026, 01:29:59 AM
Good point guys. As I have already replaced all STRING with DWSTRING I'll just DWSTRING do its thing.
#5
José Roca Software / Re: DWStrList
Last post by José Roca - May 06, 2026, 11:20:43 PM
Even Bjarne Stroustrup, the designer of C++, discourages the use of linked lists. The reason is that they have performance issues like cache misses. Modern CPUs are fast, but memory access is relatively slow. Caches prefer to prefetch contiguous data (like arrays). Linked lists, with their scattered nodes, often cause cache misses. Memory overhead: Each node in a linked list requires extra memory to store pointers, making them less space-efficient than arrays for small data elements. No random access: Accessing the nth element in a linked list takes O(n) time, while arrays do this in O(1). I have added random access by making them indexed, but this adds overhead.

#6
José Roca Software / Re: DWStrList
Last post by Paul Squires - May 06, 2026, 08:07:15 PM
@Richard Kelly just an FYI, DWString and also built-in FB strings are much better at concatenations than PowerBasic's OLE strings. As José has pointed out, FB strings have a built in extra buffer that allows for better concatenation performance. That is why things like PB's StringBuilder is not overly worthwhile. I built a StringBuilder for FB during my early FB days and it essentially turned out to be a waste of time and actually performed slightly worse than simply adding strings together.
#7
José Roca Software / Re: DWStrList
Last post by José Roca - May 06, 2026, 07:42:44 PM
Not sure I fully understand what you intend to do, but here are the key points.

DWSTRING already uses a string‑builder strategy internally, so repeated concatenations like:

sString = sString + sNewString

are not expensive when done through DWSTRING. The class minimizes reallocations: as long as there is enough capacity in the internal buffer, it simply appends using wmemmove, which is extremely fast.

When the buffer runs out of space, DWSTRING allocates a new buffer with double the previous capacity. This amortizes the cost of growth.

If you know the approximate maximum size of the final string, you can eliminate reallocations entirely by setting the Capacity property:

DIM dws AS DWSTRING
dws.Capacity = 100000   ' // Set the initial capacity to 100000 characters
dws += "New string"
dws += "New string 2"
' ...

If your goal is to store strings for later reuse, you don't need DWStrList or linked lists. A simple array of DWSTRING is more efficient and more in line with modern memory behavior:

DIM rg(100) AS DWSTRING
rg(0) = "string 1"
rg(1) = "string 2"
' ...
DIM dws AS DWSTRING
dws += rg(0)
dws += rg(1)
-- or: dws += rg(0) + " " + rg(1)
print dws

Linked lists are a 1950s solution to a 1950s hardware problem. On modern CPUs, with deep caches and wide memory buses, they are usually worse than contiguous arrays because they destroy locality of reference.

Your best options today are:

DSafeArray, which is already optimized for unicode strings and variants.

DSafeArray.CreateVector, which allocates a single contiguous block and is the most efficient when you know the number of elements in advance.

#8
José Roca Software / DWStrList
Last post by Richard Kelly - May 06, 2026, 03:48:01 PM
This old PowerBasic project I'm porting over involves creating a bunch of strings that get added together like:

sString = sString + sNewString

This can happen many times.

Would it be efficient to store each string in DWStrList and, when I need to full string, pull them from DWStrList one at a time and build the final DWSTRING?

My idea was to keep track of the total length of all the strings added and then use:

DWSTRING (BYVAL nChars AS LONG, BYREF wszFill AS CONST WSTRING)

to allocate a buffer one time to hold all the strings in DWStrList.
#9
José Roca Software / Re: CDicObj
Last post by José Roca - May 05, 2026, 10:06:49 AM
I have made mine indexed, allowing to work as if they were arrays.

' // Retrieve and print the results
FOR i AS LONG = 1 TO List->Count
   PRINT List->Item(i)
NEXT

Therefore, First, Last, Next, Previous and For Each aren't needed.

Although DVarList can be used with any data type, because it uses variants, DWStrList is optimized to work with DWSTRING and it is much faster when you only need to use strings.

I also have safe arrays, both dynamic and fixed size (vectors).

https://github.com/JoseRoca/AfxNova/blob/main/docs/COM%20/DSAFEARRAY%20Class.md
#10
José Roca Software / Re: CDicObj
Last post by Richard Kelly - May 05, 2026, 12:52:54 AM
Quote from: José Roca on May 03, 2026, 06:40:57 PMI have DWstrList and DVarList:

https://github.com/JoseRoca/AfxNova/blob/main/docs/String%20Management%20/Linked%20Lists.md



PB supports:

ILinkListCollection.ADD method adds am item to the end of the LinkListCollection.
ILinkListCollection.CLEAR method removes all items from the LinkListCollection.
ILinkListCollection.COUNT method returns the number of items currently in the LinkListCollection.
ILinkListCollection.FIRST method sets the current index for the LinkListCollection to one (1) and returns the previous value.
ILinkListCollection.INDEX method sets the current index for the LinkListCollection to the specified value and returns the previous value.
ILinkListCollection.INSERT method adds the specified item to the specified index position..
ILinkListCollection.ITEM method returns the item from the specified index position.
ILinkListCollection.LAST method sets the index value to the last item and returns the previous value.
ILinkListCollection.NEXT method returns the next item in the LinkListCollection.
ILinkListCollection.PREVIOUS method returns the previous item in the LinkListCollection.
ILinkListCollection.REMOVE method removes the item at the specified position from the LinkListCollection.
ILinkListCollection.REPLACE method replaces the item at the specified position with a new item in the LinkListCollection.

This old PB code I'm looking at uses:

Count, Clear, Item, Replace, Add

I think I'll move forward with DVarList and DWStrList