Windows SysLink Example

Started by MrBcx, March 13, 2025, 11:42:40 PM

Previous topic - Next topic

MrBcx

Here's how to use a Win32 built-in hyperlink control using BCX. 

It's possible to do more elaborate things with this control but this is my jumping off point.



GUI "Windows SysLink Demonstration"

DIM AS HWND Form1, SysLink
DIM link$

SUB FORMLOAD
    Form1 = BCX_FORM("Windows SysLink Demonstration")

    link$ = "Visit the BCX Basic website <A HREF=" + WRAP$("https://www.BcxBasicCoders.com") + ">click here</A>"
    SysLink = BCX_CONTROL("SysLink", Form1, link$, 9999, 10, 10, 300, 50)
    BCX_SET_FONT(SysLink, "Verdana", 14)

    CENTER(Form1)
    SHOW(Form1)
END SUB


BEGIN EVENTS
    SELECT CASE CBMSG
        CASE WM_NOTIFY
        IF wParam = GetDlgCtrlID(SysLink) THEN
            DIM pnm AS LPNMHDR
            pnm = CAST(LPNMHDR, lParam)
            IF pnm->code = NM_CLICK OR pnm->code = NM_RETURN THEN
                DIM pNMLink AS NMLINK PTR
                pNMLink = CAST(NMLINK PTR, lParam)
                ShellExecute(0, "open", W2A$(pNMLink->item.szUrl), NULL, NULL, SW_SHOWNORMAL)
            END IF
        END IF
    END SELECT
END EVENTS




Quin

Cool trick! It doesn't seem to work here though, my screen reader reads a blank window and when attempting to navigate around with object navigation, I don't even see the link. I'll play around with it once my internet is done being uprooted and let you know if I can make it accessible, then maybe we can have a BCX_Hyperlink function? :D
-Quin.
GitHub

MrBcx

Quote from: Quin on March 14, 2025, 09:11:04 AM
Cool trick! It doesn't seem to work here though, my screen reader reads a blank window and when attempting to navigate around with object navigation, I don't even see the link. I'll play around with it once my internet is done being uprooted and let you know if I can make it accessible, then maybe we can have a BCX_Hyperlink function? :D

It's not a trick ... it's the hoops one must jump through to use this API function.

I particularly don't like needing to rely on WM_NOTIFY for what should be a simple function to use.

WM_NOTIFY messages cannot be reliably forwarded to subclassed windows procedure making it cumbersome to create wrappers.


Vortex

Hi Kevin,

Thanks for the code. Testing the application on Windows 11 2024 H2, I get a blank window wihout hyperlink control. The title of the window is "Windows SysLink Demonstration"

Code built with BCX Version 8.2.5 and PellesC V12


Vortex

During an Ollydbg session to find where is the issue, the status of the stack before calling CreateWindowExA :

00E0FE70   00000000  |ExtStyle = 0
00E0FE74   00408014  |Class = "SysLink"
00E0FE78   0040CEFC  |WindowName = "Visit the BCX Basic website <A HREF="https://www.BcxBasicCoders.com">click here</A>"
00E0FE7C   56000000  |Style = WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE
00E0FE80   00000014  |X = 14 (20.)
00E0FE84   00000014  |Y = 14 (20.)
00E0FE88   00000258  |Width = 258 (600.)
00E0FE8C   00000064  |Height = 64 (100.)
00E0FE90   000803F8  |hParent = 000803F8 ('Windows SysLink Demonstration',class='Windows SysLink Demonstration')
00E0FE94   0000270F  |hMenu = 0000270F
00E0FE98   00400000  |hInst = 00400000
00E0FE9C   00000000  \lParam = NULL


eax returns 0 after calling CreateWindowExA :

LastErr

ERROR_CANNOT_FIND_WND_CLASS (0000057F)

MrBcx

Try this ... It runs fine for me when built using BED and checking the box for BED's DPI /Manifest resource file.

Vortex

Hi Kevin,

Checking the box for BED's DPI /Manifest resource file worked, thanks.

Quin

Ah, that was also my accessibility issue. Checking that box made it all work on Windows 10 21H2 :)
Great work MrBcx!
-Quin.
GitHub

MrBcx

#8
Checking that box causes the following manifest to be embedded in your executable.

Any GUI that you create, whether using BED or not, should include a similar manifest.

When using BED, if you include your own manifest, then you do not need to check that box,
as long as your manifest minimally contains the same sections that are used in BED's manifest.
Note: Windows 11 uses the same supportedOS Id as Windows 10.



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <assemblyIdentity version="1.0.0.0"
         processorArchitecture="*"
         name="Built with BCX BASIC"
         type="win32"/>
  <description>DPI Awareness</description>
  <asmv3:application>
    <asmv3:windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
      <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
    </asmv3:windowsSettings>
  </asmv3:application>
  <!-- Compatibility section -->
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!--The ID below indicates application support for Windows Vista -->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
      <!--The ID below indicates application support for Windows 7 -->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <!--This Id value indicates the application supports Windows 8 functionality-->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
      <!--This Id value indicates the application supports Windows 8.1 functionality-->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
      <!--This Id value indicates the application supports Windows 10 functionality-->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
    </application>
  </compatibility>
  <!-- Trustinfo section -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
                  level="asInvoker"
                  uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
               type="win32"
               name="Microsoft.Windows.Common-Controls"
               version="6.0.0.0"
               processorArchitecture="*"
               publicKeyToken="6595b64144ccf1df"
               language="*" />
    </dependentAssembly>
  </dependency>
</assembly>


Quin

MrBcx,
Thanks for this! Is there Microsoft documentation for me to learn about all the various manifest attributes?
-Quin.
GitHub

MrBcx

Quote from: Quin on March 14, 2025, 06:28:46 PM
MrBcx,
Thanks for this! Is there Microsoft documentation for me to learn about all the various manifest attributes?

Straight from the horse's mouth:

https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests