After many release candidate versions, I think that it is time to release the first official version.
All the source code, including examples and templates, is hosted in GitHub:
https://github.com/JoseRoca/WinFBX
On-line documentation:
https://github.com/JoseRoca/WinFBX/tree/master/docs
23 Nov 2017
- Bug fix: Changed DIM vArgs(1 TO 15) AS VARIANT to DIM vArgs(1 TO 16) AS VARIANT in the
last overloaded Invoke function of the CDispInvoke class. Thanks to ganlinlao for reporting it.
15 Dec 2017 - Version 1.0.02
- Added the Resize method to the CWSTR class.
- Modified the AfxStrLSet, AfxStrRSet and AfxStCSet functions to work with Unicode.
19 Dec 2017 - Version 1.0.02
- Added the following functions:
AfxGetBrowserHandle
AfxGetInternetExplorerHandle
AfxGetFireFoxHandle
AfxGetGoogleChromeHandle
20 Dec 2017 - Version 1.0.02
- Added the following functions:
AfxCWstrArrayAppend
AfxCWstrArrayInsert
AfxCWstrArrayRemove
AfxCWstrArrayRemoveFirst
AfxCWstrArrayRemoveLast
AfxCWstrArraySort
30 Dec 2017 - Version 1.0.03
- Added two overloaded AfxStrExtract functions.
6 Jan 2018 - Version 1.0.03
- Added two overloaded AfxStrRemove functions.
11 May 2018 - Version 1.0.03
- Modified the AfxStrLSet, AfxStrRset and AfxStrCSet functions because they GPFed with
the 64 bit compiler.
26 May 2018 - Version 1.0.03
- Modified the internal code of several functions that used INSTR with CWSTR variables.
28 May 2018 - Version 1.0.03
- Modified the AfxOpenFileDialog and AfxSaveFileDialog functions because they GPFed with
the 64 bit compiler. Also changed an instruction in AfxOpenFileDialog that prevented to work
with non Latin alphabets.
31 May 2018 - Version 1.0.03
- Modified AfxOpenFileDialog again to check for double double null only if the flag
OFN_ALLOWMULTISELECT is used.
- Modified the FilepPath method of the CFindFile class to use the Root method instead of
the GetFullPathName API function.
16 Jun 2018 - Version 1.0.03
- Typo: LietView_GetTooltipsFont changed to ListView_GetTooltipsFont.
17 Jun 2018 - Version 1.0.03
- Modified CXpButton.inc to allow coloured buttons.
20 Jun 2018 - Version 1.0.03
- AfxGetWindowLocation: Changed parameters from AS LONG PTR to BYREF AS LONG.
22 Jun 2018 - Version 1.0.03
- AfxWin.inc: Added the function AfxCommand.
24 Jun 2018 - Version 1.0.03
- CWSTR.inc and CVAR.inc: Changed the casting from BYREF AS WSTRING to BYREF AS CONST WSTRING.
27 Jun 2018 - Version 1.0.03
- CXpButton: Added DPI awareness to the text and image margins.
29 Jun 2018 - Version 1.0.03
- Removed the 80 characters limitation to the AfxAddTooltip and AfxSetTooltipText functions.
- Added CONST to the string parameters of several procedures.
1 Jul 2018 - Version 1.0.03
- Modified CXpButton.inc to add properties.
2 Jul 2018 - Version 1.0.03
- CTextStream.inc: Added OpenForInputA / W, OpenForOutputA / W and OpenForAppendA / W methods.
4 Jul 2018 - Version 1.0.03
- CWSTR: Changed the [] operator from one-based index to zero-based index.
6 Jul 2018 - Version 1.0.03
- CWSTR: Changed CONSTRUCTOR (BYVAL nChars AS UINT, BYVAL nCodePage AS UINT)
to CONSTRUCTOR (BYVAL nChars AS UINT, BYVAL bClear AS BOOLEAN)
The nCodePage parameter was no longer useful and the new bClear parameter allows to specify
if the memory will be intialized (cleared) or not.
- The default constructor now initializes the memory.
10 Jul 2018 - Version 1.0.03
- CXputton: Added support for the BM_CLICK message.
29 Jul 2018 - Version 1.0.03
- CXputton: Added ButtonBkColorDown and BkBrushDown properties.
Congratulations Jose! all your incredibly hard work has paid off.
I am in the last week of the sale of my house and move into my new condo. I have done a little bit of programming but not much over the past number of weeks. However, this weekend I will at least release a new version of WinFBE to include your Version 1 library code.
Awesome, way to go Jose, your library is the #1 FreeBasic Windows resource by far.
Jose,
Congratulations on the version 1.0 release!!
For new users (and those of us with bad memories) how did you, or better yet, how should we set up our computers (Which Fb downloads,updates,folder structure,etc) to work seamlessly with your massive framework?
James
Well done Jose and thanks for all your efforts.
FYI, I just downloaded the GitHub files and noticed what appears to be a filename conflict between CVAR.inc and CVar.inc in the Afx folder when unzipping the master archive from https://github.com/JoseRoca/WinFBX/archive/master.zip onto my machine.
These files are listed in the following location...
https://github.com/JoseRoca/WinFBX/tree/master/Afx
I have removed CVAR.inc, which is older. Apparently, GitHub is case sensitive and considers that CVAR.inc AND CVar.inc are different files. Thanks very much for reporting it.
hi,jose
Congratulations on the version 1.0 release!!
There is a mistake in the indispinvoke.inc file
Thanks for reporting it.I have modified the file.
FBPiano, based on PBPiano, public domain control originally written by Börje Hagsten in June 2016 for PowerBASIC.
Options:
ComboBox 1 shows available midi devices (usually 1).
ComboBox 2 shows a collection of 16 midi channels, but we usually only use channel 1 for normal play.
Note: Channel 10 is reserved for percussion sets, turning each key from D2# to D7# into an instrument.
Always on top - program stays topmost on screen.
Show Key text - show/hide computer keyboard key text.
Show Note text - show/hide piano key notes.
Effects:
Arrow left - decrease octave
Arrow right - increase octave
Arrow up - pitch bend up
Arrow down - pitch bend down
Sustain on/off, for sustain (reverb) on played keys.
Sustain can cause eternal notes to for example string and brass instruments and should be used with care.
If eternal notes occur, just uncheck this checkbox.
On octave change, pressed notes are repeated for a nice replay effect.
Mouse controls Volume, Balance, Vibrato and Pitch bend.
Remarks: I have had problems to get it working properly. For no apparent reason, the octave setting was being sometimes reset to 0 after changing the instrument or playing notes, but could not be reproduced at will. It was alleatory. I have kept this version as CPiano_v01.inc to demonstrate the problem. In the current CPiano.inc file, I have declared the m_pk and m_hRgn arrays as global instead of as intance variables of the class. This solves the problem. Apparently, the use of arrays as instance variables must be used with caution.
hi,jose
1、 I found cdicobj.inc support newEnum method, maybe we can add a "foreach ... in" statement, only used in the collection class.
I would like to ask, iEnumVariant must manually support next, skip, reset method? Is this the difference between cdicobj and vb's collection?
2、 CDispInvoke.inc, why not increase the property set members, like put? We can use the wstring parameter or any ptr, so that we can use the afxstrsplit function to divide the parameter values into a one-dimensional safeArrary when receiving the parameter values using object.set ("method") = "cArg1, cArg2, cArg3, ..., cArgN" . Because I over-love object.put ("method") = value of this style.
thank you !
Quote
2、 CDispInvoke.inc, why not increase the property set members, like put? We can use the wstring parameter or any ptr, so that we can use the afxstrsplit function to divide the parameter values into a one-dimensional safeArrary when receiving the parameter values using object.set ("method") = "cArg1, cArg2, cArg3, ..., cArgN" . Because I over-love object.put ("method") = value of this style.
Sorry, I don't understand what you mean. How are you going to pass several VARIANT parameters as a string?
Quote
1、 I found cdicobj.inc support newEnum method, maybe we can add a "foreach ... in" statement, only used in the collection class.
I would like to ask, iEnumVariant must manually support next, skip, reset method? Is this the difference between cdicobj and vb's collection?
I have looked at the FreeBasic documentation for implementing iterators, but there is no way to pass a pointer to the enumerator.
However, you can enumerate the collection this way:
DIM pDic AS CDicObj
pDic.Add "a", "Athens"
pDic.Add "b", "Madrid"
pDic.Add "c", "Roma"
DIM cvKeys AS CVAR = pDic.Keys
FOR i AS LONG = cvKeys.GetLBound TO cvKeys.GetUBound
DIM cvKey AS CVAR = cvKeys.GetVariantElem(i)
print cvKey, pDic.Item(cvKey)
NEXT
hi,jose
Please forgive me constantly asking, I would like to ask, winFBX 1.0 help documentation will provide offline chm file? Because I and my friends want to translate help documentation into Chinese. Currently we just translate the help file for cWindowsRC29 into Chinese.
Thanks again for your great sacrifice, for everyone to bring more convenience
I have uploaded a .chm help file in the first post.
hi,jose
In the process of translating winFBX documents, I found that there is a mistake here
Thanks very much for reporting it. I have modified it as follows:
point1
[in] Reference to a GpPoint structure that specifies the starting point of the gradient. The starting boundary line passes through the starting point.
point2
[in] Reference to a GpPoint structure that specifies the ending point of the gradient. The ending boundary line passes through the ending point.
color1
[in] An ARGB value that specifies the color at the starting boundary line of this linear gradient brush.
color2
[in] An ARGB value that specifies the color at the ending boundary line of this linear gradient brush.
rc
[in] Reference to a rectangle that specifies the starting and ending points of the gradient. The upper-left corner of the rectangle is the starting point. The lower-right corner is the ending point.
hi ,jose
I found the UIribbon.inc class in your winapi for powerbasic package and wondered if you plan to provide a freebasic version of the cUIribbon class.
Because from windows vista, win7-win10, the system has brought uiRibbon.dll, for some do not want to use the old menu and want to use ribbon style, the use of cUIribbon class, will bring a lot of convenience.
Thanks!
hi,jose
I found that there is a mistake here
The FreeBasic GDI+ headers are a total mess. The ColorPalette structure is defined twice
In gdiplus-c.bi as:
type ColorPalette
Flags as UINT
Count as UINT
Entries(0 to 0) as ARGB
end type
and in GdiplusPixelFormats.bi as
type ColorPalette
Flags as UINT
Count as UINT
Entries(0 to 1-1) as ARGB
end type
Entries(0 to 0) as ARGB and Entries(0 to 1-1) as ARGB are the same. Anyway, I will change it to Entries(0 to 0).
Quote from: ganlinlao on December 08, 2017, 10:20:33 PM
hi ,jose
I found the UIribbon.inc class in your winapi for powerbasic package and wondered if you plan to provide a freebasic version of the cUIribbon class.
Because from windows vista, win7-win10, the system has brought uiRibbon.dll, for some do not want to use the old menu and want to use ribbon style, the use of cUIribbon class, will bring a lot of convenience.
Thanks!
I will see. Because FB doesn't have support for COM classes, with more than one implemented interface, it will be a bit more difficult. However, if I haven't done it yet it is because, although many people would like to use ribbons, the interest disappears suddenly when they realize that have to learn XAML, install a XAML compiler, etc. Absolutely nobody used it with PowerBasic.
Another problem is that the ribbon api uses propvariants, and although I have done some work with the CPropVar class, it have not yet thoroughly tested it. Also FB does not provide headers and libraries for the UI interfaces and propvariants.
hi,jose
I found that there is a mistake here.
rect and rectF
Changed to
width
Specifies the width of a rectangle.
height
Specifies the height of a rectangle.
Also changed SIZEF to SIZE in the entry for the SIZE structure.
BTW please note that because it is declared as Rect_ in gdiplus-c.bi (to avoid conflicting with GDI's Rect) and as class in GdiPlusTypes.bi, in my headers I'm using the functions GDIP_RECT, GDIP_RECTF, GDIP_POINT, GDIP_POINTF. Otherwise, there is no way to compile the same code to 32 and 64 bit. The FB headers for GDI+ need a complete rewrite.
Thinking about it, I'm going to use the aliases in the documentation, i.e. GpPoint, GpPointF, GpRect, GpRectF, GpSize and GpSizeF.
I'm going to add this method to the CWSTR class.
' ========================================================================================
' Resizes the string to a length of n characters.
' Parameters:
' nSize : New string length, expressed in number of characters.
' ch: Character used to fill the new character space added to the string (in case the
' string is expanded).
' If nSize is smaller than the current string length, the current value is shortened to
' its first nSize characters.
' If nSize is greater than the current string length, the current content is extended by
' inserting at the end as many characters as needed to reach a size of nSize. If ch is
' specified, the new elements are initialized as copies of ch, otherwise, spaces are added.
' ========================================================================================
PRIVATE SUB CWstr.Resize (BYVAL nSize AS UINT, BYREF ch AS WSTRING = "")
CWSTR_DP("CWSTR Resize")
IF m_BufferLen \ 2 = nSize THEN EXIT SUB
IF m_BufferLen \ 2 > nSize THEN
m_BufferLen = nSize * 2
m_Capacity = nSize * 2
m_pBuffer[m_BufferLen] = 0
m_pBuffer[m_BufferLen + 1] = 0
ELSE
DIM cws AS CWSTR
DIM nChars AS UINT = ((nSize * 2) - m_BufferLen) \ 2
IF ch <> "" THEN cws = STRING(nChars, ASC(ch, 1)) ELSE cws = SPACE(nChars)
this.Add(cws)
END IF
END SUB
' ========================================================================================
hi,jose
Thank you, this method is very good, my friend and I a few days ago, just talked about the string and custom structure types of memory self-growth and cleaning problems.
Thank you. I have modified the text to
Returns a GpPoint color value initialized with the specified values for the x and y coordinates.
Returns a GpPointF color value initialized with the specified values for the x and y coordinates.
and also the return types from GpRect/F to GpPoint/F.
Regarding the Resize method, I have changed it to
' ========================================================================================
' Resizes the string to a length of n characters.
' Parameters:
' nSize : New string length, expressed in number of characters.
' ch: Character used to fill the new character space added to the string (in case the
' string is expanded).
' If nSize is smaller than the current string length, the current value is shortened to
' its first nSize characters.
' If nSize is greater than the current string length, the current content is extended by
' inserting at the end as many characters as needed to reach a size of nSize. If ch is
' specified, the new elements are initialized as copies of ch, otherwise, spaces are added.
' ========================================================================================
PRIVATE SUB CWstr.Resize (BYVAL nSize AS UINT, BYREF ch AS WSTRING = "")
CWSTR_DP("CWSTR Resize")
IF m_BufferLen \ 2 = nSize THEN EXIT SUB
IF m_BufferLen \ 2 > nSize THEN
m_BufferLen = nSize * 2
m_Capacity = nSize * 2
m_pBuffer[m_BufferLen] = 0
m_pBuffer[m_BufferLen + 1] = 0
ELSE
IF LEN(ch) > 1 THEN ch = LEFT(ch, 1)
DIM nChars AS UINT = ((nSize * 2) - m_BufferLen) \ 2
DIM cws AS CWSTR = SPACE(nChars)
IF ch <> "" THEN
FOR i AS LONG = 1 TO nChars
MID(**cws, i, 1) = ch
NEXT
END IF
this.Add(cws)
END IF
END SUB
' ========================================================================================
Because the FreeBasic STRING function does not work with Unicode.
Will have to also modify other functions that use STRING. Fortunately they're only three: AfxStrLset, AfxStrRSet and AfxStrCSet.
Done. Changed these functions to:
' ========================================================================================
' Returns a string containing a left-justified (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter
' Example: DIM cws AS CWSTR = AfxStrLSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrLSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
IF LEN(wszPadCharacter) > 1 THEN wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
IF wszPadCharacter <> "" THEN
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
END IF
MID(**cws, 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns a string containing a right-justified (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter.
' Example: DIM cws AS CWSTR = AfxStrRSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrRSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
IF LEN(wszPadCharacter) > 1 THEN wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
IF wszPadCharacter <> "" THEN
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
END IF
MID(**cws, nStringLength - LEN(wszMainStr) + 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns a string containing a centered (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter.
' Example: DIM cws AS CWSTR = AfxStrCSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrCSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
IF LEN(wszPadCharacter) > 1 THEN wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
IF wszPadCharacter <> "" THEN
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
END IF
MID(**cws, (nStringLength - LEN(wszMainStr)) \ 2 + 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
Hi Jose,
Just looking at the new LSet function. Seems like it can be simplified a bit because the PadCharacter will always be at least 1 character (the default if no parameter is passed is a blank character).
PRIVATE FUNCTION AfxStrLSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
MID(**cws, 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
Agree?
Yes. I forgot that the default was " " instead of "".
' ========================================================================================
' Returns a string containing a left-justified (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter
' Example: DIM cws AS CWSTR = AfxStrLSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrLSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
MID(**cws, 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns a string containing a right-justified (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter.
' Example: DIM cws AS CWSTR = AfxStrRSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrRSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
MID(**cws, nStringLength - LEN(wszMainStr) + 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns a string containing a centered (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter.
' Example: DIM cws AS CWSTR = AfxStrCSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrCSet (BYREF wszMainStr AS WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
wszPadCharacter = LEFT(wszPadCharacter, 1)
DIM cws AS CWSTR = SPACE(nStringLength)
FOR i AS LONG = 1 TO LEN(cws)
MID(**cws, i, 1) = wszPadCharacter
NEXT
MID(**cws, (nStringLength - LEN(wszMainStr)) \ 2 + 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
After a discussion in the PowerBasic forum, I have written the following functions to get the handle of the top level window of a web browser. I will incorporate them in AfxWin.inc
' ========================================================================================
' Retrieves the handle of the top level window of the web browser.
' Parameter:
' pwszClassName: The browser class name.
' Return value:
' The handle of the top level window of the browser.
' Thanks to Dominic Mitchell for the information provided in this thread:
' https://forum.powerbasic.com/forum/user-to-user-discussions/powerbasic-for-windows/767812-handle-to-browser-window?p=767896#post767896
' Examples:
' DIM hwndBrowser AS HWND = AfxGetBrowserHandle("IEFrame") ' // Internet Explorer
' DIM hwndBrowser AS HWND = AfxGetBrowserHandle("MozillaWindowClass") ' // Firefox
' DIM hwndBrowser AS HWND = AfxGetBrowserHandle("Chrome_WidgetWin_1") ' // Chrome
' ========================================================================================
FUNCTION AfxEnumThreadWndProc (BYVAL hwnd AS HWND, BYVAL lParam AS LPARAM) AS WINBOOL
DIM dwStyle AS DWORD = GetWindowLongPtr(hwnd, GWL_STYLE)
IF ((dwStyle AND (WS_POPUP OR WS_CHILD)) = 0) AND ((dwStyle AND WS_VISIBLE) <> 0) THEN
DIM phwndTop AS HWND PTR
CAST(LPARAM, phwndTop) = lParam
*phwndTop = hwnd
RETURN FALSE
END IF
RETURN CTRUE
END FUNCTION
' ========================================================================================
' ========================================================================================
FUNCTION AfxGetBrowserHandle (BYVAL pwszClassName AS WSTRING PTR) AS HWND
DIM hwndBrowser AS HWND = FindWindowW(pwszClassName, NULL)
IF hwndBrowser = NULL THEN RETURN NULL
DIM dwThread AS DWORD = GetWindowThreadProcessId(hwndBrowser, NULL)
IF dwThread = 0 THEN RETURN NULL
DIM hwndTop AS HWND
EnumThreadWindows(dwThread, @AfxEnumThreadWndProc, CAST(LPARAM, @hwndTop))
RETURN hwndTop
END FUNCTION
' ========================================================================================
' ========================================================================================
' Retrieves the top level window handle of Intenet Explorer.
' ========================================================================================
FUNCTION AfxGetInternetExplorerHandle () AS HWND
RETURN AfxGetBrowserHandle("IEFrame")
END FUNCTION
' ========================================================================================
' ========================================================================================
' Retrieves the top level window handle of Firefox.
' ========================================================================================
FUNCTION AfxGetFireFoxHandle () AS HWND
RETURN AfxGetBrowserHandle("MozillaWindowClass")
END FUNCTION
' ========================================================================================
' ========================================================================================
' Retrieves the top level window handle of Google Chrome.
' ========================================================================================
FUNCTION AfxGetGoogleChromeHandle () AS HWND
RETURN AfxGetBrowserHandle("Chrome_WidgetWin_1")
END FUNCTION
' ========================================================================================
It would be so incredibly awesome if Dominic Mitchell would convert over to FreeBasic as well. Dominic and Jose are the two smartest PB programmers on the planet.
Quote from: Paul Squires on December 19, 2017, 12:56:24 PM
It would be so incredibly awesome if Dominic Mitchell would convert over to FreeBasic as well. Dominic and Jose are the two smartest PB programmers on the planet.
I may be wrong but I get the impression Dominic is more commercially motivated than is Jose.
James
Since we can use the Free Basic intrinsic array procedures to work with arrays of CWSTR strings, I have added some helper functions to CWSTR.inc.
' ########################################################################################
' *** HELPER FUNCTIONS ***
' ########################################################################################
' ========================================================================================
' qsort CWstr comparison function
' ========================================================================================
PRIVATE FUNCTION AfxCWstrArrayCompare CDECL (BYVAL a AS CWSTR PTR, BYVAL b AS CWSTR PTR) AS LONG
FUNCTION = wcscmp(cast(WSTRING PTR, a->m_pBuffer), cast(WSTRING PTR, b->m_pBuffer))
END FUNCTION
' ========================================================================================
' ========================================================================================
' Reverse qsort CWstr comparison function
' ========================================================================================
PRIVATE FUNCTION AfxCWStrArrayReverseCompare CDECL (BYVAL a AS CWSTR PTR, BYVAL b AS CWSTR PTR) AS LONG
DIM r AS LONG = wcscmp(cast(WSTRING PTR, a->m_pBuffer), cast(WSTRING PTR, b->m_pBuffer))
IF r = 1 THEN r = -1 ELSE IF r = -1 THEN r = 1
RETURN r
END FUNCTION
' ========================================================================================
' ========================================================================================
' Sorts a one-dimensional CWSTR array calling the C qsort function.
' Parameters:
' - rgwstr : Start of target array.
' - numElm : Number of elements in the array.
' - bAscend: TRUE for sorting in ascending order; FALSE for sorting in descending order.
' Example:
' DIM rg(1 TO 10) AS CWSTR
' FOR i AS LONG = 1 TO 10
' rg(i) = "string " & i
' NEXT
' FOR i AS LONG = 1 TO 10
' print rg(i)
' NEXT
' print "---- after sorting ----"
' AfxCWstrSort @rg(1), 10, TRUE
' FOR i AS LONG = 1 TO 10
' print rg(i)
' NEXT
' ========================================================================================
PRIVATE SUB AfxCWstrSort (BYREF rgwstr AS ANY PTR, BYVAL numElm AS LONG, BYVAL bAscend AS BOOLEAN = TRUE)
IF rgwstr = NULL OR numElm < 2 THEN EXIT SUB
IF bAscend THEN
qsort rgwstr, numElm, SIZEOF(CWSTR), CPTR(ANY PTR, @AfxCWstrArrayCompare)
ELSE
qsort rgwstr, numElm, SIZEOF(CWSTR) , CPTR(ANY PTR, @AfxCWStrArrayReverseCompare)
END IF
END SUB
' ========================================================================================
' ========================================================================================
PRIVATE SUB AfxCWstrArraySort (rgwstr() AS CWSTR, BYVAL bAscend AS BOOLEAN = TRUE)
DIM numElm AS LONG = UBOUND(rgwstr) - LBOUND(rgwstr) + 1
AfxCWstrSort @rgwstr(LBOUND(rgwstr)), numElm, bAscend
END SUB
' ========================================================================================
' ========================================================================================
' Appends a CWSTR at the end of a one-dimensional CWSTR array.
' Parameters:
' - rgwstr(): The CWSTR array
' - cws: The CWSTR to append
' Return value:
' TRUE or FALSE
' Example:
' #INCLUDE ONCE "Afx/CWSTR.inc"
' USING Afx
' REDIM rg(1 TO 10) AS CWSTR
' FOR i AS LONG = 1 TO 10
' rg(i) = "string " & i
' NEXT
' AfxCwstrArrayAppend(rg(), "string 11")
' FOR i AS LONG = LBOUND(rg) TO UBOUND(rg)
' print rg(i)
' NEXT
' Note: REDIM PRESERVE cannot be used on fixed-size arrays - i.e. arrays with constant bounds
' made with DIM. If after calling REDIM PRESERVE the upper bound has not changed, it means
' that it is a fixed string.
' ========================================================================================
PRIVATE FUNCTION AfxCWstrArrayAppend (rgwstr() AS CWSTR, BYREF cws AS CWSTR) AS BOOLEAN
DIM upperBound AS LONG = UBOUND(rgwstr)
REDIM PRESERVE rgwstr(LBOUND(rgwstr) TO upperBound + 1) AS CWSTR
IF UBOUND(rgwstr) > upperBound THEN rgwstr(UBOUND(rgwstr)) = cws : RETURN TRUE
RETURN FALSE
END FUNCTION
' ========================================================================================
' ========================================================================================
' Inserts a new CWSTR element before the specified position in a one-dimensional CWSTR array.
' Parameters:
' - rgwstr(): The CWSTR array
' - nPos: The position in the array where the new element will be added.
' This position is relative to the lower bound of the array.
' - cws: The CWSTR to append
' Return value:
' TRUE or FALSE
' Example:
' #INCLUDE ONCE "Afx/CWSTR.inc"
' USING Afx
' REDIM rg(1 TO 10) AS CWSTR
' FOR i AS LONG = 1 TO 10
' rg(i) = "string " & i
' NEXT
' AfxCwstrArrayInsert(rg(), 3, "Inserted element")
' FOR i AS LONG = LBOUND(rg) TO UBOUND(rg)
' print rg(i)
' NEXT
' Note: REDIM PRESERVE cannot be used on fixed-size arrays - i.e. arrays with constant bounds
' made with DIM. If after calling REDIM PRESERVE the upper bound has not changed, it means
' that it is a fixed string.
' ========================================================================================
PRIVATE FUNCTION AfxCWstrArrayInsert (rgwstr() AS CWSTR, BYVAL nPos AS LONG, BYREF cws AS CWSTR) AS BOOLEAN
DIM lowerBound AS LONG = LBOUND(rgwstr)
DIM upperBound AS LONG = UBOUND(rgwstr)
nPos = nPos - 1 + lowerBound
IF nPos < lowerBound OR nPos > upperBound THEN RETURN FALSE
REDIM PRESERVE rgwstr(lowerBound TO upperBound + 1) AS CWSTR
IF UBOUND(rgwstr) = upperBound THEN RETURN FALSE
' // Move all the elements down
FOR i AS LONG = UBOUND(rgwstr) TO nPos + 1 STEP - 1
rgwstr(i) = rgwstr(i - 1)
NEXT
rgwstr(nPos) = cws
RETURN TRUE
END FUNCTION
' ========================================================================================
' ========================================================================================
' Removes the specified element of a one-dimensional CWSTR array.
' Parameters:
' - rgwstr(): The CWSTR array
' - nPos: The position in the array of the element to remove.
' This position is relative to the lower bound of the array.
' - cws: The CWSTR to append
' Return value:
' TRUE or FALSE
' Example:
' #INCLUDE ONCE "Afx/CWSTR.inc"
' USING Afx
' REDIM rg(1 TO 10) AS CWSTR
' FOR i AS LONG = 1 TO 10
' rg(i) = "string " & i
' NEXT
' AfxCwstrArrayRemove(rg(), 3)
' FOR i AS LONG = LBOUND(rg) TO UBOUND(rg)
' print rg(i)
' NEXT
' Note: REDIM PRESERVE cannot be used on fixed-size arrays - i.e. arrays with constant bounds
' made with DIM. If after calling REDIM PRESERVE the upper bound has not changed, it means
' that it is a fixed string.
' ========================================================================================
PRIVATE FUNCTION AfxCWstrArrayRemove (rgwstr() AS CWSTR, BYVAL nPos AS LONG) AS BOOLEAN
DIM lowerBound AS LONG = LBOUND(rgwstr)
DIM upperBound AS LONG = UBOUND(rgwstr)
nPos = nPos - 1 + lowerBound
IF nPos < lowerBound OR nPos > upperBound THEN RETURN FALSE
FOR i AS LONG = nPos TO upperBound - 1
rgwstr(i) = rgwstr(i + 1)
NEXT
REDIM PRESERVE rgwstr(lowerBound TO upperBound - 1) AS CWSTR
IF UBOUND(rgwstr) = upperBound THEN RETURN FALSE
RETURN TRUE
END FUNCTION
' ========================================================================================
' ========================================================================================
' Removes the first element of a one-dimensional CWSTR array.
' ========================================================================================
PRIVATE FUNCTION AfxCWstrArrayRemoveFirst (rgwstr() AS CWSTR) AS BOOLEAN
DIM lowerBound AS LONG = LBOUND(rgwstr)
DIM upperBound AS LONG = UBOUND(rgwstr)
DIM nPos AS LONG = lowerBound
FOR i AS LONG = nPos TO upperBound - 1
rgwstr(i) = rgwstr(i + 1)
NEXT
REDIM PRESERVE rgwstr(lowerBound TO upperBound - 1) AS CWSTR
IF UBOUND(rgwstr) = upperBound THEN RETURN FALSE
RETURN TRUE
END FUNCTION
' ========================================================================================
' ========================================================================================
' Removes the last element of a one-dimensional CWSTR array.
' ========================================================================================
PRIVATE FUNCTION AfxCWstrArrayRemoveLast (rgwstr() AS CWSTR) AS BOOLEAN
DIM lowerBound AS LONG = LBOUND(rgwstr)
DIM upperBound AS LONG = UBOUND(rgwstr)
REDIM PRESERVE rgwstr(lowerBound TO upperBound - 1) AS CWSTR
IF UBOUND(rgwstr) = upperBound THEN RETURN FALSE
RETURN TRUE
END FUNCTION
' ========================================================================================
I wonder if there is a way to detect if an array is fixed other that checking if REDIM PRESERVE has failed.
hi,jose
Happy Christmas, thank you for your hard work, bringing Freebasic an easy-to-use framework.
Thank you for using it. I wish you a Happy New Year.
Removed "Pass -1 to use the default styles." in the documentation of the dwStyle and dwExStyle parameters of the Create method of the CWindow class. This was a leftover of an earlier version.
AfxResizeTabPages function
Changed FUNCTION AfxDestroyAllTabPages (BYVAL hTab AS HWND) AS BOOLEAN to FUNCTION AfxResizeTabPages (BYVAL hTab AS HWND) AS BOOLEAN.
ComboBox_ResetContent
Changed "Limits the length of the text the user may type into the edit control of a combo box." to "Removes all items from the list box and edit control of a combo box."
TOOLINFOW
Changed "Contains information specific to an NM_CUSTOMDRAW notification message sent by a ToolTip control." to "Contains information about a tool in a tooltip control."
AfxSetPrinterCollateStatus
Changed "Switches between color and monochrome on color printers." to "Specifies whether collation should be used when printing multiple copies."
CFileSys
Several methods were documented as returning a CWSTR instead of a CBSTR.
AfxGdiPlus.inc
FUNCTION GDIP_RECT ( _
BYVAL x AS LONG, _
BYVAL y AS LONG, _
BYVAL nWidth AS LONG, _
BYVAL nHeight AS LONG _
) AS GpRect
Returns a GpRect structure initialized with the specified values for the x, y, width, and height components.
FUNCTION GDIP_RECTF ( _
BYVAL x AS SINGLE, _
BYVAL y AS SINGLE, _
BYVAL nWidth AS SINGLE, _
BYVAL nHeight AS SINGLE _
) AS GpRectF
Returns a GpRectF structrure initialized with the specified values for the x, y, width, and height components.
Updated to version 1.0.02.
WinFBX
Windows Framework for FreeBASIC.
20 Dec 2017 - Version 1.0.02
- Added the following functions:
AfxCWstrArrayAppend
AfxCWstrArrayInsert
AfxCWstrArrayRemove
AfxCWstrArrayRemoveFirst
AfxCWstrArrayRemoveLast
AfxCWstrArraySort
19 Dec 2017 - Version 1.0.02
- Added the following functions:
AfxGetBrowserHandle
AfxGetInternetExplorerHandle
AfxGetFireFoxHandle
AfxGetGoogleChromeHandle
15 Dec 2017 - Version 1.0.02
- Added the Resize method to the CWSTR class.
- Modified the AfxStrLSet, AfxStrRSet and AfxStCSet functions to work with Unicode.
23 Nov 2017 - Version 1.0.01
- Bug fix: Changed DIM vArgs(1 TO 15) AS VARIANT to DIM vArgs(1 TO 16) AS VARIANT in the
last overloaded Invoke function of the CDispInvoke.class. Thanks to ganlinlao for reporting it.
21 Nov 2017
- Version 1.0 released
Hi,
I am learning some new stuff from WinFBX framework. Such a giant library and it gives more simplicity to FreeBasic. Especially i love Cwstr library. It is must have for any language. Dynamic unicode string handling is a must have feature. By the way, i got stumbled upon the usage of period in some functions. For example, in DoEvents function.
' // Show the window and update its client area
IF nCmdShow = 0 THEN .ShowWindow m_hwnd, SW_SHOW ELSE .ShowWindow m_hwnd, nCmdShow
.UpdateWindow m_hwnd
See this line ? What is the meaning of that period in the left side of ShowWindow function. I know that ShowWindow is an api function. Then why it is used with a period ?
To avoid possible name conflicts, present or future. It makes sure that it calls that symbol in the global namespace and not a duplicate symbol in another namespace.
If someone else writes a class with a method called ShowWindow, and you use it together with mine, without an "." my code won't know if you intend to call the API function ShowWindow or the ShowWindow method of the other class.
All the code that I have written with FreeBasic is unicode aware. It is unavoidable if one wants to attract international users. And with the WinFBE editor you can use unicode string literals if you save the file with the option UTF-8 BOM. The string literals will be saved in the file as UTF-8, but the CWSTR class will perform the conversion. This way you can work as if dynamic unicode strings were natively supported by FreeBasic.
DIM cws AS CWSTR = "Дмитрий Дмитриевич Шостакович"
WYSIWYG (What you see is what you get), without having to use CHR.
Yeah, Thanks for the reply. Is there any dynamic list or array feature in WinFBX framework ? Does CSafeArray is a dynamic array ?
CSafeArray implements support for safe arrays that are used in COM programming. It works with VARIANTs.
We can use CWSTR as if it was a native data type. Therefore, you can have arrays of CWSTRrings as easily as arrays of FreeBasic ansi strings.
We can use arrays of CWSTR strings transparently, e.g.
DIM rg(1 TO 10) AS CWSTR
FOR i AS LONG = 1 TO 10
rg(i) = "string " & i
NEXT
FOR i AS LONG = 1 TO 10
print rg(i)
NEXT
A two-dimensional array
DIM rg2 (1 TO 2, 1 TO 2) AS CWSTR
rg2(1, 1) = "string 1 1"
rg2(1, 2) = "string 1 2"
rg2(2, 1) = "string 2 1"
rg2(2, 2) = "string 2 2"
print rg2(2, 1)
REDIM PRESERVE / ERASE
REDIM rg(0) AS CWSTR
rg(0) = "string 0"
REDIM PRESERVE rg(0 TO 2) AS CWSTR
rg(1) = "string 1"
rg(2) = "string 2"
print rg(0)
print rg(1)
print rg(2)
ERASE rg
And we can also sort one-dimensional arrays calling the AfxCWstrSort procedure:
DIM rg(1 TO 10) AS CWSTR
FOR i AS LONG = 1 TO 10
rg(i) = "string " & i
NEXT
FOR i AS LONG = 1 TO 10
print rg(i)
NEXT
print "---- after sorting ----"
AfxCWstrSort @rg(1), 10
FOR i AS LONG = 1 TO 10
print rg(i)
NEXT
As noted in the documentation, CWSTR behaves as if it was a native data type, working directly with the intrinsic Free Basic string functions and operators. The only exception is MID when used as a statement: Something like MID(cws, 2, 1) = "x" compiles but does not change the contents of the dynamic unicode string. MID(cws.wstr, 2, 1) = "x" or MID(**cws, 2, 1) = "x" works.
It even works with files, e.g.
#include once "Afx/CWStr.inc"
DIM cws AS CWSTR = "Дмитрий Дмитриевич Шостакович"
DIM f AS LONG = FREEFILE
OPEN "test.txt" FOR OUTPUT ENCODING "utf16" AS #f
PRINT #f, cws
CLOSE #f
There are also wrapper procedures to Append, Insert and Remove elements of the array: AfxCWstrArrayAppend, AfxCWstrArrayInsert, AfxCWstrArrayRemove, AfxCWstrArrayRemoveFirst and AfxCWstrArrayRemoveLast.
New help file uploaded. Corrected some inaccuracies in the documentation.
thank Jose Roca :)
Dear Jose,
I tried to download you .rar files but they seems corrupted.
I use 7-Zip to open them, tied to clear the browser cache, tried to download from different browser but always the same problem.
7-Zip report that "There are some data after the end of the payload data"
I'm the only one having problems?
Thanks a lot
Eros
Paul has moved the forum to another server and some things have become corrupted.
Meanwhile, you can download it from GitHub.
https://github.com/JoseRoca/WinFBX
Thanks Jose.
Yes I got from github.
Hmmm... that's too bad with the corrupted files. Just when I thought everything was moving over okay from the old server. :(
I knew I was having trouble with the avatars but I didn't realize zip files might be affected. It seems you will need to re-upload your personal avatars.
Looks like FileZilla (by default) treats filenames with no extensions as ASCII files rather than binary. Therefore when uploaded to the new forum the line encodings of attachments were affected. I am attempting to redownload from old site and reupload. Hopefully it can be fixed.
You have fallen in the same trap that I did several years ago.
See: http://www.jose.it-berater.org/smfforum/index.php?topic=4183.msg14552#msg14552
I most certainly did! Luckily I have been able to get it all corrected. The only issue is now in posts where your name was (with an accent) it looks like the message got truncated at the accent character.
Modified the AfxStrLSet, AfxStrRset and AfxStrCSet functions because they GPFed with the 64 bit compiler.
' ========================================================================================
' Returns a string containing a left-justified (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter
' Example: DIM cws AS CWSTR = AfxStrLSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrLSet (BYREF wszMainStr AS CONST WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
DIM cws AS CWSTR = WSTRING(nStringLength, wszPadCharacter)
MID(**cws, 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns a string containing a right-justified (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter.
' Example: DIM cws AS CWSTR = AfxStrRSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrRSet (BYREF wszMainStr AS CONST WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
IF LEN(wszMainStr) > nStringLength THEN RETURN LEFT(wszMainStr, nStringLength)
DIM cws AS CWSTR = WSTRING(nStringLength, wszPadCharacter)
MID(**cws, nStringLength - LEN(wszMainStr) + 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns a string containing a centered (padded) string.
' If the optional parameter wszPadCharacter not specified, the function pads the string with
' space characters to the left. Otherwise, the function pads the string with the first
' character of wszPadCharacter.
' Example: DIM cws AS CWSTR = AfxStrCSet("FreeBasic", 20, "*")
' ========================================================================================
PRIVATE FUNCTION AfxStrCSet (BYREF wszMainStr AS CONST WSTRING, BYVAL nStringLength AS LONG, BYREF wszPadCharacter AS WSTRING = " ") AS CWSTR
IF LEN(wszMainStr) > nStringLength THEN RETURN LEFT(wszMainStr, nStringLength)
DIM cws AS CWSTR = WSTRING(nStringLength, wszPadCharacter)
MID(**cws, (nStringLength - LEN(wszMainStr)) \ 2 + 1, LEN(wszMainStr)) = wszMainStr
RETURN cws
END FUNCTION
' ========================================================================================
Modified the internal code of some string functions that worked with INSTR and CWSTR variables without using **.
Modified the AfxOpenFileDialog and AfxSaveFileDialog that GPFed with FB 64 bit.
As always, you can get the most recent code in GitHub: https://github.com/JoseRoca/WinFBX
AfxWin.inc: Added the function AfxCommand. Like FB's COMMAND but Unicode aware.
' ========================================================================================
' Returns command line parameters used to call the program
' Unicode replacement for FreeBasic Command keyword.
' Usage: result = AfxCommand ( [ index ] )
' Parameter:
' - index : Zero-based index for a particular command-line argument.
' Return Value
' Returns the command-line arguments(s).
' Description
' - AfxCommand returns command-line arguments passed to the program upon execution.
' - If index is less than zero (< 0), a space-separated list of all command-line arguments
' is returned, otherwise, a single argument is returned. A value of zero (0) returns the
' name of the executable; and values of one (1) and greater return each command-line argument.
' - If index is greater than the number of arguments passed to the program, a null
' string ("") is returned.
' ========================================================================================
PRIVATE FUNCTION AfxCommand (BYVAL nIndex AS LONG = -1) AS CWSTR
DIM pArgsList AS WSTRING PTR PTR, nArgs AS LONG, cwsArgs AS CWSTR
pArgsList = CAST(WSTRING PTR PTR, CommandLineToArgvW(GetCommandLineW, @nArgs))
IF pArgsList = NULL OR nIndex > nArgs THEN RETURN cwsArgs
IF nIndex < 0 THEN
FOR i AS LONG = 1 TO nArgs - 1
cwsArgs += *pArgsList[i] & " "
NEXT
cwsArgs = RTRIM(**cwsArgs)
ELSE
cwsArgs = *pArgsList[nIndex]
END IF
LocalFree CAST(HLOCAL, pArgsList)
RETURN cwsArgs
END FUNCTION
' ========================================================================================
Added some convenience wrappers to CTextStream.inc: OpenForInputA / W, OpenForOutputA / W and OpenForAppendA / W. This class allows to work easily with sequential files in ansi or unicode, with some advanced methods.
For binary files, the Windows API provides API functions that work perfectly with CWSTR strings, e.g.:
DIM cwsFilename AS CWSTR = "тест.txt"
DIM cwsText AS CWSTR = "Дмитрий Дмитриевич Шостакович"
DIM hFile AS HANDLE = CreateFileW(cwsFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)
WriteFile(hFile, cwsText, LEN(cwsText) * 2, NULL, NULL)
CloseHandle(hFile)
However, in the FB forum prefer to walk in circles:
https://www.freebasic.net/forum/viewtopic.php?f=2&t=26839
thank you José Roca :)
just out curiosity I looked up "Дмитрий Дмитриевич Шостакович" and I got info on Dmitri Dmitriyevich Shostakovich
6 Jul 2018 - Version 1.0.03
- CWSTR: Changed CONSTRUCTOR (BYVAL nChars AS UINT, BYVAL nCodePage AS UINT)
to CONSTRUCTOR (BYVAL nChars AS UINT, BYVAL bClear AS BOOLEAN)
The nCodePage parameter was no longer useful and the new bClear parameter allows to specify
if the memory will be intialized (cleared) or not.
- CWSTR: The default constructor now initializes the memory.
4 Jul 2018 - Version 1.0.03
- CWSTR: Changed the [] operator from one-based index to zero-based index.
Hello all
what is the purpose of WinFBX ? is it something like Jose's includes files for PB?
WinFBX -- where can i get sample codes and applications on how to use it?
Any suggestions? thanks all help appreciated
The WinFBE editor comes with the include fiiles, examples and templates.
On-line help: http://www.jose.it-berater.org/WinFBX/WinFBX.html
Cool, thanks a lot Jose
These examples are so cool !
I have uploaded an updated help file. It is attached to the first post of this thread.
Sorry for the dummy question but which is the correct way to proceed for using WinFBX?
Where do I have to place all files?
I've FreeBasic installed in C:\FreeBasic\
Do I have to copy all WinFBX file inside C:\FreeBasic\inc\ directory?
Thanks a lot
Eros
As long as they're in a folder or subfolder called Afx, you can put them anywhere. When compiling you will need to use the switch -i followed by the path of the include files.
Quote from: Eros Olmi on July 31, 2018, 05:38:43 AM
Do I have to copy all WinFBX file inside C:\FreeBasic\inc\ directory?
That's the way that I have my system setup. I copy all of Jose's WinFBX files into a subfolder called "Afx" and place that subfolder off of the "\inc" folder of the compiler. I do that for both 32 bit and 64 bit compilers.
Ciao José,
link to documentation seems no longer valid: http://www.jose.it-berater.org/WinFBX/WinFBX.html
Eros
Tahnks. I have modified it. The documentation was moved to GitHub:
https://github.com/JoseRoca/WinFBX/tree/master/docs