Main Menu

Recent posts

#21
General Board / New Power Basic Users Forum
Last post by dmontaine - November 03, 2025, 02:03:58 AM
To replace the recently discontinued "official" forum:

https://pbusers.org
#22
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by José Roca - November 02, 2025, 08:19:04 PM
As explained in the documentation ( https://github.com/JoseRoca/AfxNova/blob/main/docs/String%20Management%20/DWSTRING%20Class.md ) DWSTRING works transparently with literals and Free Basic native strings, can be used with Windows API functions and with files, and with arrays. Just as the FreeBasic native string data types.

The Tiko editor allows to use string literals in your language, e.g. DIM dws AS DWSTRING = "a, ā, b, c, č, d, e, ē, f, g, ģ, h, i, ī, j, k, ķ, l, ļ, m, n, ņ, o, p, r, s, š, t, u, ū, v, z, ž", if you select an option other than ansi. You can type them as any other text, without having to use Ctrl+Shift+U, then hold Ctrl and Shift and type the hexadecimal code point for the character you want (as the Geany documentation says).

It is more convenient to work with FreeBasic and AfxNova that Geany.

#23
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by HIGH-Zen - November 02, 2025, 07:42:10 AM
It's 2025 - Unicode should really be the default in FreeBasic by now. The web, browsers, and Windows (e.g., MessageBoxW) have embraced Unicode for decades.
Unfortunately, FreeBasic still lags behind in this area. Even GDB 10.2 (GCC 14.2.0 x64) on Windows 11 Pro doesn't display Unicode characters properly. 😕

On a brighter note - wow, I just discovered the IniFile class! That's a super useful addition. Great job, I'm genuinely impressed.

Thanks for pointing out the DWSTRING type. I didn't realize it integrates so seamlessly with native FreeBasic string functions and operators. The fact that AfxNova is fully Unicode-aware and comes with such extensive documentation is a huge plus.
The string procedures list is amazing - especially with support for VBScript regular expressions. That opens up a lot of possibilities for custom parsing and text handling.

Also, Unicode file management support is a big deal. Even though FreeBasic doesn't support Unicode in file names, having this functionality in AfxNova is a major step forward.

Really appreciate the work that's gone into this framework. It's exciting to see FreeBasic evolve like this!
#24
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by José Roca - November 02, 2025, 05:28:21 AM
For Unicode strings the only thing that you have to do is to declare the variable AS DWSTRING instead of AS STRING. It works transparently with all the native FreeBasic string functions and operators. All he code of AfxNova is Unicode aware, There is much more that AfxNova offers and all is documented. The number of ready to use string procedures is amazing (see: https://github.com/JoseRoca/AfxNova/blob/main/docs/String%20Management%20/String%20Procedures.md ) and includes support for VB Script Regular Expressions, that you can use to build your own procedures.

There is also support for file management in Unicode (FreeBasic supports unicode in files, but not in file names): https://github.com/JoseRoca/AfxNova/tree/main/docs/File%20Management%20
#25
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by HIGH-Zen - November 02, 2025, 03:53:53 AM
Cool!
I'm on a 17.3" laptop with display scaling set to 150%, and now the program looks much better - definitely a noticeable improvement.

Unicode support is also really important to me, especially since Latvian uses accented characters like ā, č, ķ, ī, ē, ū, ļ, and ņ.

The tutorial and templates are fantastic - documentation like this makes a huge difference when getting started.

Thanks again for the detailed explanation and resources. With your guidance, I now have a much clearer understanding of how to work with AfxNova.
#26
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by José Roca - November 02, 2025, 03:14:09 AM
Your example is correct for the times in which all monitors had a DPI of 96, but if you are using a higher DPI, e.g. 175, if you run it virtualized it will look blurry, and if you make it DPI aware, it will look small. CWindow does the scaling for you, so your GUI will be displayed with the same relative size regardless of the DPI settings of your computer.

I have written a tutorial for CWindow: https://github.com/JoseRoca/AfxNova/blob/main/docs/Windows/Windows%20GUI%20/CWindow%20Class.md

I also have written many templates ready to compile and run:
https://github.com/JoseRoca/AfxNova/tree/main/Templates/SDK%20Templates

An small template of a window with a button.

' ########################################################################################
' Microsoft Windows
' File: CW_Button_01.bas
' Contents: CWindow - Button
' Compiler: FreeBasic 32 & 64 bit
' Copyright (c) 2025 José Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#define UNICODE
#INCLUDE ONCE "AfxNova/CWindow.inc"
USING AfxNova

DECLARE FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                           BYVAL hPrevInstance AS HINSTANCE, _
                           BYVAL pwszCmdLine AS WSTRING PTR, _
                           BYVAL nCmdShow AS LONG) AS LONG
   END wWinMain(GetModuleHandleW(NULL), NULL, wCommand(), SW_NORMAL)

' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Main
' ========================================================================================
FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                   BYVAL hPrevInstance AS HINSTANCE, _
                   BYVAL pwszCmdLine AS WSTRING PTR, _
                   BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)
   ' // Enable visual styles without including a manifest file
   AfxEnableVisualStyles

   ' // Creates the main window
   DIM pWindow AS CWindow = "MyClassName"   ' Use the name you wish
   DIM hWin AS HWND = pWindow.Create(NULL, "CWindow - Button", @WndProc)
   ' // Sizes it by setting the wanted width and height of its client area
   pWindow.SetClientSize(400, 220)
   ' // Centers the window
   pWindow.Center

   ' // Adds a button
   pWindow.AddControl("Button", hWin, IDCANCEL, "&Close", 270, 155, 75, 30)
   ' // Anchors the button to the bottom and the right side of the main window
   pWindow.AnchorControl(IDCANCEL, AFX_ANCHOR_BOTTOM_RIGHT)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   SELECT CASE uMsg

      ' // If an application processes this message, it should return zero to continue
      ' // creation of the window. If the application returns –1, the window is destroyed
      ' // and the CreateWindowExW function returns a NULL handle.
      CASE WM_CREATE
         RETURN 0

      ' // Sent when the user selects a command item from a menu, when a control sends a
      ' // notification message to its parent window, or when an accelerator keystroke is translated.
      CASE WM_COMMAND
         SELECT CASE CBCTL(wParam, lParam)
            CASE IDCANCEL
               ' // If ESC key pressed, close the application by sending an WM_CLOSE message
               IF CBCTLMSG(wParam, lParam) = BN_CLICKED THEN SendMessageW(hwnd, WM_CLOSE, 0, 0)
         END SELECT
         RETURN 0

      CASE WM_DESTROY
         ' // End the application by sending an WM_QUIT message
         PostQuitMessage(0)
         RETURN 0

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

When trying the examples, you will see the big difference in sharpness.
#27
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by HIGH-Zen - November 02, 2025, 12:56:48 AM
You guys are absolute coding machines - thank you for the detailed explanation!

I'm now fully convinced to use AfxNova for my future projects. I'll definitely take a closer look at CWindow as well. I'm curious how it compares to raw WinAPI programming. For example, here's how I've been doing things traditionally:
' RAW Windows API version
#Include Once "windows.bi"

Dim Shared hWndMain As HWND
Dim Shared hButton As HWND

Function WindowProc(ByVal hWnd As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As LRESULT
    Select Case uMsg
        Case WM_COMMAND
            If HiWord(wParam) = BN_CLICKED Then
                If Cast(HWND, lParam) = hButton Then
                    MessageBox(hWnd, "Button clicked!", "Info", MB_OK Or MB_ICONINFORMATION)
                End If
            End If
        Case WM_DESTROY
            PostQuitMessage(0)
            Return 0
    End Select
    Return DefWindowProc(hWnd, uMsg, wParam, lParam)
End Function

Sub WinMain()
    Dim wc As WNDCLASS
    Dim msg As MSG
    Dim hInstance As HINSTANCE = GetModuleHandle(NULL)
    Dim className As String = "MyWindowClass"

    With wc
        .style = CS_HREDRAW Or CS_VREDRAW
        .lpfnWndProc = @WindowProc
        .cbClsExtra = 0
        .cbWndExtra = 0
        .hInstance = hInstance
        .hIcon = LoadIcon(NULL, IDI_APPLICATION)
        .hCursor = LoadCursor(NULL, IDC_ARROW)
        .hbrBackground = Cast(HGDIOBJ, COLOR_BTNFACE + 1)
        .lpszMenuName = NULL
        .lpszClassName = StrPtr(className)
    End With
    RegisterClass(@wc)

    hWndMain = CreateWindowEx(0, className, "Pure WinAPI Window", WS_OVERLAPPEDWINDOW, _
                              100, 100, 400, 300, NULL, NULL, hInstance, NULL)

    hButton = CreateWindowEx(0, "BUTTON", "Click Me", WS_CHILD Or WS_VISIBLE Or BS_PUSHBUTTON, _
                             150, 100, 100, 30, hWndMain, Cast(HMENU, 1001), hInstance, NULL)

    ShowWindow(hWndMain, SW_SHOWNORMAL)
    UpdateWindow(hWndMain)

    While GetMessage(@msg, NULL, 0, 0)
        TranslateMessage(@msg)
        DispatchMessage(@msg)
    Wend
End Sub

WinMain()
I'd love to understand how CWindow simplifies or abstracts this kind of setup. Does it handle message loops and control creation internally?
#28
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by José Roca - November 01, 2025, 07:03:56 PM
CWSTR has some quirks for full integration with FreeBasic, like working with bytes instead of characters (WORDs), like DWSTRING does. DWSTRING is more integrated with FreeBasic, behaving as if it was a native data type. It is more suitable to work with Unicode. For those that need it, it also has an option to check and repair broken surrogate pairs.

CWindow has also been improved to allow to make GUIs even more easier than before, with a very easy to use anchoring system that removes the need, in almost all cases, of having to do resizing manually processing WM_SIZE. It also allows to set colors to the main window and to the controls that allow it, automatic scrolling, easy subclassing and much more. The CTabControl class allows to make tabbed interfaces using a tab control and CWindows as pages of the tab control.


I have added to AfxNova a Rich Edit Control that wraps all the windows messages for that control and also all the Text Object Model (TOM) interfaces.


Currently I'm working in GDI+ classes that replicate the C++ ones. They work very well with my graphic control and CWindow, but can be used with SDK windows, dialogs or any device that has an HDC (device context handle), like printers. I have added to them two methods, ScaleTransform and SetResolution to make graphics and images DPI aware.

Next I plan to write a WebView2 control to replace my old WebBrowser control.

That is, I'm modernizing my old framework to work better with the needs of the high resolution monitors. Therefore, for new applications, AfxNova is the way to go.

#29
José Roca Software / Re: GDI+ - SetBrushColor - Get...
Last post by José Roca - November 01, 2025, 04:08:07 PM
Thanks very much for trying. I'm in the process of adding new examples to test all the methods and this leads to some changes. If you forget to upload the file or files changed they're out of sync and causes these errors. GDI+ with about 600 functions is very huge.
#30
General Board / Re: Afx Strings. Afx, Afx2, Af...
Last post by HIGH-Zen - November 01, 2025, 03:21:54 PM
OK, I've decided to go with AfxNova.

For FreeBasic development, I use Geany as my IDE on Windows 11 Pro (version 25H2). It's a simple, minimalist setup with a custom color scheme and personalized build commands - including one for running with GDB.

I've tried VisualFBEditor, WinFBE, and more recently Tiko, but Geany meets my needs just fine. I honestly don't remember why I chose it in the first place - maybe because I've always liked editors like Notepad++ and Emacs too.

Thank You for the explanation.