View Issue Details

IDProjectCategoryView StatusLast Update
0001109NoesisGUIC++ SDKpublic2021-12-01 02:08
Reporternikobarli Assigned Tojsantos  
PriorityhighSeverityfeatureReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.0.2f2 
Target Version3.1.2Fixed in Version3.1.2 
Summary0001109: Custom cursor support
DescriptionIn WPF, we can load and use a custom cursor like this:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <Cursor x:Key="CursorMagnify">C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include\res\magnify.cur</Cursor>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Cursor="{StaticResource CursorMagnify}">
        <TextBlock>test</TextBlock>
    </Grid>
</Window>

Our application uses a lot custom cursors (more than 30). Thus, we need a way to support this in NoesisGUI.

In longer term, you may want to implement the Cursor class with similar capabilities as WPF does. But in shorter term, we only need to designate a custom cursor ID to the FrameworkIElement.

For example, we can write in XAML

<Grid Cursor="Custom_MyCursor"></Grid>

which is the same as below in code behind

Grid::SetCursor(Cursor_Custom /* new enum entry "/, "MyCursor" /* ID string */);

and which causes the cursor callback is called with parameters Cursor_Custom and "MyCursor".

Then inside the client integration code, I can map the tuple {Cursor_Custom, "MyCursor"} to any custom cursor I want.
TagsNo tags attached.
PlatformAny

Activities

nikobarli

nikobarli

2019-03-06 08:51

reporter   ~0005501

Hi, is there any update on this feature ? Is it gonna make it to 2.2.0 maybe ?
jsantos

jsantos

2019-03-06 16:55

manager   ~0005502

Hi Niko, we discussed long time ago and decided to add a char* to our cursors to solve this. But we are almost ready to close 2.2 (RC is happening this week) so I am not sure if we can implement it for this version.

Could you please raise the priority of this ticket and tell me how critical it is for you right now?

Thanks!
nikobarli

nikobarli

2019-03-07 01:23

reporter   ~0005507

Hi Jesus,

I raised the priority to High. I think I can temporarily workaround this issue by providing per-view mapping from the current Cursor enum to the custom cursor inside the Integration layer.
Please consider adding the official support in the near future.
nikobarli

nikobarli

2021-09-16 02:23

reporter   ~0007445

Hi Jesus, is there any update on this issue ?
jsantos

jsantos

2021-09-16 14:28

manager   ~0007446

Last edited: 2021-09-16 14:29

Hi Niko,

Really sorry about this delay. I was talking with @sfernandez and we are going to solve this in 3.1.2. Is that ok for you?

The idea is changing the definition of Cursor in
typedef void (*UpdateCursorCallback)(void* user, IView* view, Cursor cursor);

Cursor will be something like:
struct Cursor
{
   CursorType type;
   String uri;
}

CursorType will be the old enum with a new entry Cursor_Custom indicating that the uri must be read. The uri will containt the .cur file, that must be loaded in each Display.

You only need this for Windows right?

nikobarli

nikobarli

2021-09-16 14:52

reporter   ~0007447

Hi Jesus,

Yes, we only need this for Windows.

So, how can we use it from Xaml? Is it something like:

<Grid Cursor="Custom_MyCursor"></Grid>

in which uri will be set to "MyCursor" ?

As for fix version, 3.1.2 is fine with us.
jsantos

jsantos

2021-09-16 14:57

manager   ~0007448

Last edited: 2021-09-16 14:57

To be compatible with Blend it needs to be
<Grid Cursor="Custom_MyCursor.cur"></Grid>

and you need to have MyCursor.cur in the Blend project.

Our Win32Display implementation will load that .cur file.

Will that work for you?

jsantos

jsantos

2021-09-16 14:58

manager   ~0007449

Last edited: 2021-09-16 14:58

@sfernandez I am not sure if the .cur extension is mandatory

sfernandez

sfernandez

2021-09-16 16:05

manager   ~0007450

Looking at WPF implementation of CursorConverter it seems they only support .cur and .ani files (apart from default known cursors):
https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/CursorConverter.cs,176
nikobarli

nikobarli

2021-09-17 01:49

reporter   ~0007451

> To be compatible with Blend it needs to be
> <Grid Cursor="Custom_MyCursor.cur"></Grid>

And I suppose I can pass uri as part of the string right ?
e.g. <Grid Cursor="Custom_Resources/Cursor/MyCursor.cur"></Grid>

> and you need to have MyCursor.cur in the Blend project.
> Our Win32Display implementation will load that .cur file.
> Will that work for you?

Yes, that will work for us.

Thanks!
jsantos

jsantos

2021-09-17 11:59

manager   ~0007452

Great, thank you. More questions, should our implementation of Win32Display load the cursors? Or that's something you plan to do.

If our implementation does it, we need to load the file using our file providers (we will use the XamlProvider I think, because it provides a IStream interface).
nikobarli

nikobarli

2021-09-17 14:54

reporter   ~0007455

> Great, thank you. More questions, should our implementation of Win32Display load the cursors? Or that's something you plan to do.

We are using our own implementation of Win32Display (because we need to support multiple views inside a process).
But we would appreciate if you can provide the example inside your Win32Display for us to follow.
jsantos

jsantos

2021-09-17 22:06

manager   ~0007457

Last edited: 2021-09-20 10:21

r10741 implemented the core changes. We still need to fix Displays and implement loading .cur files in Win32Display

jsantos

jsantos

2021-12-01 02:05

manager   ~0007626

Last edited: 2021-12-01 02:08

Hi Niko,

I have been testing the implementation for Win32Display and everything is working fine but we are not going to make changes to Win32Display for loading custom cursors because there are many possible approaches to this: loading the cursor for memory, loading the cursor from file, loading the cursor for the resource table of the executable. I think, you are probably going to have an array with all your custom cursors loaded from file (or from the resource table) and then read that table when the request of changing cursor arrives to the Display.

I took your example:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <Cursor x:Key="CursorMagnify">C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include\res\magnify.cur</Cursor>
        </ResourceDictionary>
    </Window.Resources>
    <Grid Cursor="{StaticResource CursorMagnify}">
        <TextBlock>test</TextBlock>
    </Grid>
</Window>

And added the following change to our Win32Display:

        case WM_SETCURSOR:
        {
            if (LOWORD(lParam) == HTCLIENT)
            {
                if (mCursor.type == Cursor::Custom)
                {
                    HCURSOR cur = LoadCursorFromFileA(mCursor.filename.Str());

                    ::SetCursor(cur);
                }
                else
                {

                    if (mCursors[mCursor.type] != 0)
                    {
                        ::SetCursor(mCursors[mCursor.type]);
                        return true;
                    }
                }
            }

            return false;
        }

And it works, the custom cursor changes. This implementation is not efficient because the cursor is loaded per frame, but I just wanted to use it to check everything is working correctly. As said, we are not going to commit any change to Win32Display but if you need more help or have doubts please write us or reopen the ticket.

Thanks for your patience!

jsantos

jsantos

2021-12-01 02:08

manager   ~0007627

I think we finally can close this : )

Issue History

Date Modified Username Field Change
2017-06-14 04:04 nikobarli New Issue
2017-09-27 00:42 jsantos Assigned To => jsantos
2017-09-27 00:42 jsantos Status new => assigned
2018-11-01 02:14 jsantos View Status public => private
2019-03-06 08:51 nikobarli Note Added: 0005501
2019-03-06 16:55 jsantos Status assigned => feedback
2019-03-06 16:55 jsantos Note Added: 0005502
2019-03-06 16:55 jsantos View Status private => public
2019-03-06 16:55 jsantos Platform => Any
2019-03-07 01:23 nikobarli Priority normal => high
2019-03-07 01:23 nikobarli Status feedback => assigned
2019-03-07 01:23 nikobarli Note Added: 0005507
2019-04-08 17:55 sfernandez Target Version => 2.2.2
2019-04-30 10:55 sfernandez Target Version 2.2.2 => 2.2.3
2019-06-18 16:57 sfernandez Target Version 2.2.3 => 2.2.4
2019-08-26 15:26 jsantos Target Version 2.2.4 => 2.2.5
2019-12-30 10:33 sfernandez Target Version 2.2.5 => 3.0.0
2020-05-07 12:53 jsantos Target Version 3.0.0 => 3.0
2021-09-16 02:23 nikobarli Note Added: 0007445
2021-09-16 14:18 jsantos Target Version 3.0 => 3.1.2
2021-09-16 14:28 jsantos Note Added: 0007446
2021-09-16 14:28 jsantos Note Edited: 0007446
2021-09-16 14:28 jsantos Note Edited: 0007446
2021-09-16 14:29 jsantos Note Edited: 0007446
2021-09-16 14:29 jsantos Assigned To jsantos => sfernandez
2021-09-16 14:29 jsantos Status assigned => feedback
2021-09-16 14:52 nikobarli Note Added: 0007447
2021-09-16 14:52 nikobarli Status feedback => assigned
2021-09-16 14:57 jsantos Note Added: 0007448
2021-09-16 14:57 jsantos Status assigned => feedback
2021-09-16 14:57 jsantos Note Edited: 0007448
2021-09-16 14:58 jsantos Note Added: 0007449
2021-09-16 14:58 jsantos Note Edited: 0007449
2021-09-16 16:05 sfernandez Note Added: 0007450
2021-09-17 01:49 nikobarli Note Added: 0007451
2021-09-17 01:49 nikobarli Status feedback => assigned
2021-09-17 11:59 jsantos Note Added: 0007452
2021-09-17 12:00 jsantos Status assigned => feedback
2021-09-17 14:54 nikobarli Note Added: 0007455
2021-09-17 14:54 nikobarli Status feedback => assigned
2021-09-17 22:06 jsantos Note Added: 0007457
2021-09-20 10:21 sfernandez Note Edited: 0007457
2021-11-29 14:26 sfernandez Assigned To sfernandez => jsantos
2021-12-01 02:05 jsantos Note Added: 0007626
2021-12-01 02:06 jsantos Note Edited: 0007626
2021-12-01 02:06 jsantos Note Edited: 0007626
2021-12-01 02:07 jsantos Note Edited: 0007626
2021-12-01 02:08 jsantos Note Edited: 0007626
2021-12-01 02:08 jsantos Status assigned => resolved
2021-12-01 02:08 jsantos Resolution open => fixed
2021-12-01 02:08 jsantos Note Added: 0007627
2021-12-01 02:08 jsantos Fixed in Version => 3.1.2