Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 714
» Latest member: HenryG
» Forum threads: 3,569
» Forum posts: 31,908

Full Statistics

Latest Threads
4x4 Square Elimination Pu...
Forum: bplus
Last Post: bplus
3 hours ago
» Replies: 12
» Views: 405
Container Data Structure
Forum: Utilities
Last Post: bplus
3 hours ago
» Replies: 3
» Views: 112
Accretion Disk
Forum: Programs
Last Post: bplus
3 hours ago
» Replies: 11
» Views: 279
QB64PE v 4.4.0
Forum: Announcements
Last Post: Unseen Machine
11 hours ago
» Replies: 7
» Views: 656
QBJS v0.10.0 - Release
Forum: QBJS, BAM, and Other BASICs
Last Post: Unseen Machine
11 hours ago
» Replies: 13
» Views: 1,289
Arrays inside Types?
Forum: General Discussion
Last Post: hsiangch_ong
Today, 03:24 AM
» Replies: 47
» Views: 1,402
Has anybody experience wi...
Forum: Help Me!
Last Post: Rudy M
Yesterday, 08:47 AM
» Replies: 31
» Views: 1,936
Sorting numbers - FiliSor...
Forum: Utilities
Last Post: PhilOfPerth
03-11-2026, 12:48 AM
» Replies: 11
» Views: 337
Quick Sort for variable l...
Forum: Utilities
Last Post: SMcNeill
03-10-2026, 03:14 PM
» Replies: 3
» Views: 89
Ready for Easter!
Forum: Holiday Code
Last Post: bplus
03-10-2026, 12:15 PM
» Replies: 0
» Views: 58

 
  Arrays as UDTs
Posted by: Pete - 02-01-2026, 11:42 PM - Forum: General Discussion - Replies (26)

@Unseen Machine

So I'm taking a look at John's demo here: https://qb64phoenix.com/forum/showthread...7#pid38857

It took me back to my Atari Basic days. Atari had well supported peek/poke documentation. Couldn't do exactly what you wanted with the keywords? Poke it! So it seems John took a similar approach to pass arrays as _Offset.

It's neat that it didn't require a lot of new stuff under the hood to accomplish this, a little over 3K or is that UK where John hails form? 

I want to take his example and try it out on something SCREEN 0 simple. I think I'm suffering from heat exhaustion today. Played some golf, but should have gone to the beach, instead. Oh well, beats ice fishing.

Anyway, I'll reply back in this thread if I have any questions for John, or form any helpful insights for others. Until then, I suggest we all jut use COMMON SHARED for all variables... mostly because that really pisses off Bill.

Pete

Print this item

  Input Devices Library
Posted by: SMcNeill - 02-01-2026, 09:44 PM - Forum: SMcNeill - Replies (2)

For QB64PE v4.4.0 and up.

Input Devices Library

Unified Joystick and Mouse Handling for QB64

The Input Devices Library provides a clean, reliable, and modernized interface for reading joystick and mouse input in QB64. It wraps QB64’s low‑level device functions into a consistent, high‑level API that delivers stable axis values, normalized directional data, button states, click and hold detection, scroll events, and window‑boundary awareness.

This library is ideal for games, editors, UI systems, and any interactive application that needs precise, real‑time device input.

FEATURES

JOYSTICK SUPPORT
• Automatic detection of joystick hardware
• Reads all axes and buttons from the controller
• Normalizes analog stick values
• Converts analog movement into digital X/Y direction (−1, 0, 1)
• Computes 0–360 degree angle for each stick
• Dead‑zone filtering to eliminate drift
• Supports left stick, right stick, and D‑pad
• Captures Z‑axis triggers and stick‑press buttons

MOUSE SUPPORT
• Full bit‑field mouse event reporting
• Detects button down, click, hold, and scroll wheel movement
• Tracks drag start and drag end coordinates
• Optional automatic _MouseInput clearing
• Works seamlessly inside real‑time loops

WINDOW BOUNDARY DETECTION
• Determines whether the mouse cursor is inside the program window
• Uses Windows API for accurate desktop‑level positioning
• Essential for UI hover logic, pausing input, and preventing off‑window clicks

INCLUDED COMMANDS

ReadJoyStick
Reads all joystick axes and buttons, updates the JoyStick() and Button() shared arrays, applies dead‑zone filtering, computes angles, and normalizes direction values.

MouseButtonStatus
Returns a bit‑field integer describing all mouse events:
1 left down
2 right down
4 middle down
8 left click
16 right click
32 middle click
64 left held
128 right held
256 middle held
512 scroll down
1024 scroll up

Also tracks drag start and end positions.

MBS
Convenience wrapper for MouseButtonStatus.
MBS(1) is identical to MouseButtonStatus(1).

MouseInApp
Returns TRUE if the mouse cursor is inside the program window.
Uses Windows API + GLUT offsets to convert desktop coordinates into app‑relative coordinates.

Axis_Type, JoyStick(), Button()
Internal structures and arrays storing joystick axis data, direction, angle, activity state, and button states.

WHY USE THIS LIBRARY?

QB64’s built‑in device functions are powerful but low‑level.
This library:

• Normalizes inconsistent axis values
• Removes joystick drift
• Converts analog movement into simple digital directions
• Distinguishes click vs. hold events
• Provides a unified bit‑field for mouse input
• Handles drag detection automatically
• Makes joystick and mouse input predictable and easy to use

Instead of wrestling with raw device data, you get clean, ready‑to‑use values ideal for gameplay logic, UI navigation, and interactive tools.

SUMMARY

The Input Devices Library gives QB64 developers a compact but powerful toolkit for real‑time joystick and mouse interaction. It abstracts away hardware quirks, normalizes input, and provides clean, intuitive data structures that make interactive programming dramatically easier.



Attached Files
.7z   Input Devices Library.7z (Size: 7.34 KB / Downloads: 10)
Print this item

  FreeGlut - What do you developers think?
Posted by: Pete - 02-01-2026, 09:29 PM - Forum: General Discussion - Replies (13)

I was reading up on it a bit, since KernelPanic brought it up in another thread. Apparently FreeGlut is compatible with Windows, Apple and Linux. I see it handles key modifies like Ctrl, but I can't find a list of the combos it supports. This could mean it supports all, which sadly GLUT in OpenGL does not. So have any developers looked into this as an alternative? I'm keeping in mind FreeGlut would need to include all GLUT functions. To that end, AI says:

Yes, freeglut is designed to be a full replacement for the original OpenGL Utility Toolkit (GLUT) and does everything that GLUT does, with some enhancements and improvements. It is also more stable and has fewer bugs than the original GLUT. 

Would a change be in order, or would licensing be an issue?

Pete

Print this item

  Don't let INKEY$ byte you in the ASCII
Posted by: Pete - 02-01-2026, 06:36 PM - Forum: General Discussion - Replies (1)

I mostly love INKEY$, but we can't rely on it to accurately report a key was not released. So here are some observations. The last example is a Combined Inkey$ and _Keyhit solution.

Hold down the "A" key and don't release it. See, INKEY$ says it was released!

Code: (Select All)
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If a$ <> b$ Then a$ = b$: Print a$ + " was pressed."
    Else
        If Len(a$) Then Print a$ + " was released.": a$ = ""
    End If
Loop

Now a jerkaround is to add a delay. This works, but sucks...

Code: (Select All)
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If a$ <> b$ Then a$ = b$: Print a$ + " was pressed.": _Delay .5
    Else
        If Len(a$) Then Print a$ + " was released.": a$ = ""
    End If
Loop

That's right. At least in my system anything less than a half-second delay fails! Imagine typing with a half-second delay.

So to ease the delay situation, we create a mock buffer and time it. (This is what I had to do before QB64).

Code: (Select All)
Do
    _Limit 30
    b$ = InKey$
    If Len(b$) Then
        If a$(cnt) <> b$ Then cnt = cnt + 1: a$(cnt) = b$: Print a$(cnt) + " was pressed.": z1 = Timer
    Else
        If Len(a$(cnt)) And Abs(z1 - Timer) > .49 Then
            Print a$(cnt) + " was released.": a$(cnt) = "": cnt = cnt - 1
        End If
    End If
Loop

I know, I know. I didn't bother to dim the array (buffer), so it will fail after 10 here, and I didn't bother to do a complete 24-hour timer, so it would fail once at mid-night, but I'm keeping it as simple coded as possible for this discussion.

Anyway, all this crap can be avoided using the _KeyHit method or by adding _KeyHit to the Inkey$ routine.

_KeyHit Method
Code: (Select All)
Do
    _Limit 30
    k = _KeyHit
    If k > 0 Then
        If j <> k Then j = k: Print j; "was pressed."
    ElseIf k < 0 Then
        If j Then Print j; "was released.": j = 0
    End If
Loop

And finally, our combined INKEY$ with _KEYHIT solution...

_KeyHit used with Inkey$ Method
Code: (Select All)
Do
_Limit 30
b$ = InKey$
k = _KeyHit
If k < 0 Then Print a$ + " was released.": a$ = ""
If Len(b$) And a$ <> b$ Then a$ = b$: Print a$ + " was pressed."
Loop

Just some food for thought for anyone who will need to monitor a key release like a same key tapping routine.

Pete

Print this item

  Demo: Adaptable Hardware Grid
Posted by: Pete - 02-01-2026, 05:20 PM - Forum: Programs - Replies (1)

Okay SCREEN 0 fans, here we go again. Remember back in the Q-Rasic Period when we needed three rows and three columns per element to make things like spreadsheets? Well now thanks to hardware overlays those dinosaur days are over!

PRESS ANY KEY TO EXPAND GRID.

Code: (Select All)
_Title"Adaptable grid. Any key widens."
t1 = _NewImage(1200, 1, 32) ' We make a horizontal and vertical line and copy them to the hardware memory.
_Dest t1
Line (0, 0)-(1200, 0), _RGB32(0, 255, 0), B
Hline& = _CopyImage(t1, 33) ' Horizontal line. Mote: 33 is always the hardware memory number.
_Dest 0
_FreeImage t1
t1 = _NewImage(1, 800, 32)
_Dest t1
Line (0, 0)-(0, 800), _RGB32(0, 255, 0), B
Vline& = _CopyImage(t1, 33) ' Vertical line.
_Dest 0
_FreeImage t1
_KeyClear ' We're using a simple inkey loop, so we clear the keyboard buffer before it begins.
NumberOfCol = 1 ' This will let us start with 2-columns in the loop, instead of just one.
indent = 5 ' This will make us a nice 5 character-length left and right border, and also centers the grid.
Do
    NumberOfCol = NumberOfCol + 1
    fw = _FontWidth: fh = _FontHeight
    i = 0: k = 0: noe = 0: Restore
    Do
        Read a$
        If a$ = "eof" Then Exit Do
        If Len(a$) + 3 > k Then k = Len(a$) + 3
        noe = noe + 1
    Loop
    ElementsPerColumn = noe \ NumberOfCol
    If noe Mod NumberOfCol Then ElementsPerColumn = ElementsPerColumn + 1
    top = 2
    WidthNeeded = k * NumberOfCol + 1: h = top + ElementsPerColumn + 1
    Width WidthNeeded + indent * 2, h: _Font 16
    Restore
    For col = 1 To NumberOfCol
        Locate 1: x = (col - 1) * k + 3
        For j = 0 To ElementsPerColumn - 1
            Locate top + j, x + indent
            Read a$: If a$ = "eof" Then Exit For
            Print a$;
        Next
    Next
    Do
        _Limit 30
        sx1 = 0: sy1 = 0: sy2 = 0 ' sx and sy tell us which part of the line to use. These coordinates tell the routine to use the part of our horizontal line from its top-left start (sx1) and keep its height 0 (1-pixel) with the line top height (sy1) - line bottom height (sy2).
        dx1 = fw / 2 + indent * fw ' dx and dy tell the routine where to place the line segment on our screen. Note that fw (font width) and fh (font height) are needed to convert graphics pixels to text columns and rows. fw / 2 is needed to center our line in the text column and indent will center the grid to the screen.
        dy1 = (top - 1) * fh ' Start the grid at the (top) row. Again, the -1 is needed because columns and rows start at one, but pixels start at zero.
        sx2 = (WidthNeeded - 1) * fw '
        For i = 0 To ElementsPerColumn
            _PutImage (dx1, dy1 + i * fh), Hline&, , (sx1, sy1)-(sx2, sy2)
        Next
        sx1 = 0: sx2 = 0: sy1 = 0
        sy2 = ElementsPerColumn * fh ' Our vertical line segment length. We don't subtract one (-1) here because we want the line to stretch to the bottom of the grid.
        For i = 0 To NumberOfCol ' Again, we don't subtract one (-1) so we can make the final vertical line at the right side of our grid.
            _PutImage (dx1 + (i * k + 0) * fw, dy1), Vline&, , (sx1, sy1)-(sx2, sy2)
        Next
        _Display
    Loop Until Len(InKey$)
    noe = 0
Loop
Data Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware,Florida
Data Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa,Kansas,Kentucky,Louisiana,Maine
Data Maryland,Massachusetts,Michigan,Minnesota,Mississippi,Missouri,Montana,Nebraska
Data Nevada,New Hampshire,New Jersey,New Mexico,New York,North Carolina,North Dakota
Data Ohio,Oklahoma,Oregon,Pennsylvania,Rhode Island,South Carolina,South Dakota,Tennessee
Data Texas,Utah,Vermont,Virginia,Washington,West Virginia,Wisconsin,Wyoming,eof

So I kept this demo as simple as possible jut for illustration purposes. Imagine how cool this stuff could be when you expand it to be used with functions like resizable screens, etc.

Now there is a downside. As in our example here, hardware images are layered over your software screen images. This is important if you want to create a popup effect using another software image. We would want the popup to be 'on top' but the hardware image would still overlay the popup! Now I get around this challenge by coding two _putimage routines. Take our grid example, above. When a popup isn't supposed to be 'over' the hardware lines, it uses the routine in the example above, but when the popup should cover part or all of the grid, the second routine (not shown above) would cut the grid lines up so they would approximate the borders of the popup. This would make it appear the software popup window is over the grid, when the reality is we just poked a hole... or in this case a square, out of the hardware grid so the popup window could fit in it.

Pete

Print this item

  Date Library (v 4.4.0 up)
Posted by: SMcNeill - 02-01-2026, 01:51 PM - Forum: SMcNeill - Replies (4)

QB64PE Date/Time Utility Library – Overview
-------------------------------------------

This library provides a comprehensive suite of date and time utilities designed
to extend and enhance the built‑in DATE$, TIME$, and TIMER functionality in
QB64PE. It offers consistent parsing, formatting, conversion, and timestamp
generation tools that make it easier to work with dates in multiple formats,
produce human‑readable or machine‑sortable output, and perform calendar‑related
calculations.

The library includes the following major capabilities:

1. Date Component Extraction
  --------------------------
  Functions such as Date.Day$, Date.Month$, and Date.Year$ allow you to extract
  individual components from a date string based on a user‑supplied format
  mask. This makes it possible to parse dates in virtually any layout, such as
  MM-DD-YYYY, DD/MM/YY, YYYY.MM.DD, and more.

  Time component extractors (Date.Hour$, Date.Minute$, Date.Second$) perform
  the same role for TIME$-formatted strings.

2. Timestamp Generation
  ---------------------
  Two different timestamp systems are provided:

  • Date.TimeStamp## 
    Produces a Unix‑style timestamp (seconds since Jan 1, 1970). Supports both
    pre‑1970 and post‑1970 dates, including leap‑year corrections and negative
    timestamps for historical dates.

  • Date.TimeStamp.HR$ 
    Generates a human‑readable, sortable timestamp in the form:
        YYYYMMDD.HHMMSS
    Ideal for filenames, logs, and chronological sorting.

  • ExtendedTimer## 
    A lightweight, high‑performance timer based on the current date and TIMER.
    Designed for real‑time measurement rather than historical accuracy.

3. Date Formatting and Conversion
  -------------------------------
  • Date.ToString$ 
    Converts numeric MM/DD/YYYY values into a formatted date string using
    tokens such as YYYY, YY, MM, and DD.

  • Date.ToUniDate$ 
    A powerful universal date formatter that supports:
        - Full month names (January)
        - Abbreviated month names (Jan)
        - Numeric months (01)
        - Ordinal days (01st, 02nd, 03rd)
        - Weekday names (Monday, Mon)
        - 2‑digit or 4‑digit years
    The format language is flexible and forgiving, allowing expressive output
    such as:
        "Tuesday, February 10th, 2026"
        "10.02.2026"
        "Mon 10 Feb 26"

4. Weekday Calculation
  --------------------
  • Date.WeekDay& 
    Returns the weekday number (1–7) using Zeller’s Congruence.

  • Date.WeekDay.Name$ 
    Returns the full weekday name (Sunday–Saturday).

  These functions work with any date format supported by the extraction
  routines.

5. Design Philosophy
  ------------------
  The library is built around flexibility, reliability, and compatibility with
  QB64PE’s native DATE$ and TIME$ formats. It provides:

  • Format‑aware parsing 
  • Consistent output across multiple date styles 
  • Human‑readable and machine‑readable timestamp options 
  • Leap‑year and calendar‑accurate calculations 
  • Tools suitable for logging, sorting, UI display, and timing

In short, this library transforms QB64PE’s basic date/time features into a
complete, modernized toolkit for parsing, formatting, converting, and analyzing
dates and times in any format you need.



NOTE:  This library uses my new *.QLB name extension, rather than *.BI or *.BM.

Since QB64PE v 4.4.0 now allows SUB and FUNCTION to go anywhere in your code, I'm converting all my old libraries into this new format so that all you need to do is include the single file up top in your own projects.  To distinguish between a *.BI (which just goes up top) and a *.BM (which just poops out the bottom), I've decided to go with a *.QLB for a library which holds both sections intact.

Place *.QLB files at the beginning of your program.  One $INCLUDE at the top of your code for one *.QLB library. It can't get much simpler than that.  Wink



EDIT:  Updated to change extension to *.QLB, which is what QB45 used to use for Quick Libraries.  It's nostalgic and doesn't have the same connotations that .lib has with modern extensions.



Attached Files
.7z   Date Library.7z (Size: 8.75 KB / Downloads: 9)
Print this item

  simple 3d starfield & wireframe or vector graphics revisited
Posted by: madscijr - 01-31-2026, 06:04 PM - Forum: Help Me! - Replies (5)

I started thinking again about how you might make a 3d spaceship or car simulator program, with some old PC monitors mounted in a giant cardboard box you can sit in, with a joystick or gaming wheel as the controls, with one monitor mounted in front for the "windshield", and a couple of side "windows" on the right & left, and a PC running a simple 3d program that shows a moving starfield effect (or a road) in front and stars (or terrain) in the side windows also moving past. When you move the joystick in a direction, the stars or terrain would start scrolling in the direction you're moving.

This had been on the backburner for years, but I still would be curious to try making a simple simulation like that, just to see how realistic it would feel. 

We have talked about QB64PE controlling multiple monitors before, where you'd have seperate EXEs each running in its own display, maybe the front window is the master program and the other windows communicate to it through local TCP/IP (I have done this successfully for my multi-mouse program). Vector or wireframe animation should be good enough to start.

The part I would need help with is the 3D graphics, I totally don't know anything about 3D. The main thing I struggle to understand is drawing lines in 3d space from a given camera angle and camera position & distance from the object.

A bonus would be to draw the 3D scene in each monitor from 2 slightly different angles in red and cyan to simulate anaglyphic 3D so that when you wear the red & blue glasses, there would be added realism.

If anyone can share some sample reusable code to do this, I would totally attempt making such a program and share the results here.

Print this item

  I need help
Posted by: Frederick - 01-31-2026, 05:56 PM - Forum: Programs - Replies (8)

This code will not run on my machine. It is a Windows 10 pro system.  The compiler says the code is OK. But error Invalid Handle on line 25 generates.
Does anyone know what is wrong?



Attached Files
.bas   whatswrong.bas (Size: 1.1 KB / Downloads: 12)
Print this item

  InForm Paint by Fellippe Heitor
Posted by: Magdha - 01-31-2026, 10:08 AM - Forum: In-Form - No Replies

   


An early and simple InForm program. 

The program uses the following InForm objects:
Form
PictureBox
Button

Unzip the file and extract the folder into your PEQB64 directory.  In the IDE make sure that you have the Run Option “Save EXE in source folder” checked.

.zip   InForm Paint.zip (Size: 114.18 KB / Downloads: 8)

Code: (Select All)
': This program was created by Fellippe Heitor
': This program uses
': InForm-PE for QB64-PE - v1.5.8 based upon InForm by Fellippe Heitor
': Copyright (c) 2025 QB64 Phoenix Edition Team
': https://github.com/QB64-Phoenix-Edition/InForm-PE
'-----------------------------------------------------------


OPTION _EXPLICIT

': Controls' IDs: ------------------------------------------------------------------
DIM SHARED InFormPaint AS LONG
DIM SHARED PictureBox1 AS LONG
DIM SHARED CircleBT AS LONG
DIM SHARED SquareBT AS LONG
DIM SHARED SquareFilledBT AS LONG
DIM SHARED CopyBT AS LONG

DIM SHARED Drawing AS _BYTE, Tool AS _UNSIGNED _BYTE

': External modules: ---------------------------------------------------------------
'$INCLUDE:'InForm\InForm.bi'
'$INCLUDE:'InForm\xp.uitheme'
'$INCLUDE:'InFormPaint.frm'

': Event procedures: ---------------------------------------------------------------
SUB __UI_BeforeInit
END SUB

SUB __UI_OnLoad
    DIM prevDest AS LONG

    prevDest = _DEST
    Control(CircleBT).HelperCanvas = _NEWIMAGE(30, 30, 32)
    _DEST Control(CircleBT).HelperCanvas
    CIRCLE (_WIDTH / 2, _HEIGHT / 2), 12, _RGB32(0, 0, 0)
    Text(CircleBT) = "."

    Control(SquareBT).HelperCanvas = _NEWIMAGE(30, 30, 32)
    _DEST Control(SquareBT).HelperCanvas
    LINE (3, 3)-STEP(24, 24), _RGB32(0, 0, 0), B
    Text(SquareBT) = "."

    Control(SquareFilledBT).HelperCanvas = _NEWIMAGE(30, 30, 32)
    _DEST Control(SquareFilledBT).HelperCanvas
    LINE (3, 3)-STEP(24, 24), _RGB32(0, 0, 0), BF
    Text(SquareFilledBT) = "."

    Control(CopyBT).HelperCanvas = _NEWIMAGE(30, 30, 32)
    _DEST Control(CopyBT).HelperCanvas
    LINE (3, 3)-STEP(15, 15), _RGB32(0, 0, 0), B
    LINE (7, 7)-STEP(15, 15), _RGB32(0, 0, 0), B
    Text(CopyBT) = "."
    _DEST prevDest

    BeginDraw PictureBox1
    CLS , _RGB32(255, 255, 255)
    EndDraw PictureBox1
END SUB

SUB __UI_BeforeUpdateDisplay
    STATIC TempImage AS LONG
    DIM prevDest AS LONG

    IF TempImage = 0 THEN
        TempImage = _COPYIMAGE(Control(PictureBox1).HelperCanvas)
    END IF

    prevDest = _DEST

    IF Drawing THEN
        _DEST TempImage
        SELECT CASE Tool
            CASE 1
                CIRCLE (__UI_MouseLeft - Control(PictureBox1).Left, __UI_MouseTop - Control(PictureBox1).Top), 30, _RGB32(0, 0, 0)
            CASE 2
                LINE (__UI_MouseLeft - Control(PictureBox1).Left - 10, __UI_MouseTop - Control(PictureBox1).Top - 10)-STEP(20, 20), _RGB32(0, 0, 0), B
            CASE 3
                LINE (__UI_MouseLeft - Control(PictureBox1).Left - 10, __UI_MouseTop - Control(PictureBox1).Top - 10)-STEP(20, 20), _RGB32(0, 0, 0), BF
        END SELECT
        _DEST prevDest
    END IF

    BeginDraw PictureBox1
    _PUTIMAGE (0, 0), TempImage
    IF NOT Drawing THEN
        SELECT CASE Tool
            CASE 1
                CIRCLE (__UI_MouseLeft - Control(PictureBox1).Left, __UI_MouseTop - Control(PictureBox1).Top), 30, _RGB32(0, 0, 0)
            CASE 2
                LINE (__UI_MouseLeft - Control(PictureBox1).Left - 10, __UI_MouseTop - Control(PictureBox1).Top - 10)-STEP(20, 20), _RGB32(0, 0, 0), B
            CASE 3
                LINE (__UI_MouseLeft - Control(PictureBox1).Left - 10, __UI_MouseTop - Control(PictureBox1).Top - 10)-STEP(20, 20), _RGB32(0, 0, 0), BF
        END SELECT
    END IF
    EndDraw PictureBox1
END SUB

SUB __UI_BeforeUnload
END SUB

SUB __UI_Click (id AS LONG)
    SELECT CASE id
        CASE InFormPaint

        CASE PictureBox1

        CASE CircleBT
            Tool = 1
        CASE SquareBT
            Tool = 2
        CASE SquareFilledBT
            Tool = 3
        CASE CopyBT
            _CLIPBOARDIMAGE = Control(PictureBox1).HelperCanvas
    END SELECT
END SUB

SUB __UI_MouseEnter (id AS LONG)
    SELECT CASE id
        CASE InFormPaint

        CASE PictureBox1

        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_MouseLeave (id AS LONG)
    SELECT CASE id
        CASE InFormPaint

        CASE PictureBox1

        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_FocusIn (id AS LONG)
    SELECT CASE id
        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_FocusOut (id AS LONG)
    SELECT CASE id
        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_MouseDown (id AS LONG)
    SELECT CASE id
        CASE InFormPaint

        CASE PictureBox1
            Drawing = True
        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_MouseUp (id AS LONG)
    Drawing = False
    SELECT CASE id
        CASE InFormPaint

        CASE PictureBox1

        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_KeyPress (id AS LONG)
    SELECT CASE id
        CASE CircleBT

        CASE SquareBT

        CASE SquareFilledBT

        CASE CopyBT

    END SELECT
END SUB

SUB __UI_TextChanged (id AS LONG)
    SELECT CASE id
    END SELECT
END SUB

SUB __UI_ValueChanged (id AS LONG)
    SELECT CASE id
    END SELECT
END SUB

SUB __UI_FormResized
END SUB

'$INCLUDE:'InForm\InForm.ui'

Print this item

  Forum Changes to Attachments and Images
Posted by: SMcNeill - 01-31-2026, 02:51 AM - Forum: Announcements - Replies (6)

In the spirit of trying to reduce the scroll as much as possible, I've also enabled the settings which turn attachments into thumbnails instead of full fledged images.   This limits them to a maximum height and width and stops folks from embedding a dozen 8k resolution images into a single post which can destroy displays on phones and other smaller screens.

And, if you look down at the bottom of the screen (scroll ALLLLLLLLLLLLLLL the way to the very bottom of any topic), you'll now see a:  POSSIBLY RELATED TOPIC set of suggestions.  

Please don't fuss at me if these suggestions seem off the wall.  The *FORUM* is generating this also suggested list, not Steve personally, and I have no clue how relevant/insane it's going to be at this point in time.  If it's too insane and can't find anything matching and starts suggesting folks visit posts made by Pete, then we can always remove it later. 

Big Grin

And while you're down there, there's also now a quick jump you can use to speed up forum navigation.  Click it and go to other areas automagically.



All little changes, but hopefully ones which everyone will agree end up making the forums nicer for us in the long run, once we get used to them. 

If not, then they can always be reverted back out again in the future.

Print this item