trying to calc column cell clicked in wxListCtrl

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

trying to calc column cell clicked in wxListCtrl

Post by bsenftner »

I am working in version 3.0.4 on MSW. Working with a wxListCtrl, I understand that getting the column cell clicked in a wxListCtrl is not supported, and one needs to calculate the column receiving the click from the column widths. However, I can't seem to get that working.

I've seen this logic offered to others seeking this, which I put into a function I call from the wxListCtrl's EVT_LIST_ITEM_ACTIVATED event handler. However, it does not work at all:

Code: Select all

int CX_VideoStreamListCtrl::GetColumnClicked( void )
{
	wxPoint click_point = wxGetMousePosition();
	wxPoint listCtrlPosition  = GetScreenPosition();

	int dx = click_point.x - listCtrlPosition.x;

	int column;
	int columnCount = GetColumnCount();

	int x = 0;
	for (column = 0; column <columnCount; column++) {
		x += GetColumnWidth(column);
		if (x >= dx)
			break;
	}

	return column;
}
The issue is simply getting the mouse position in the same coordinate space as the wxListCtrl, but that appears to be harder than it sounds. What is the correct method to get the mouse position relative to a wxControl? The actual wxListCtrl is inside a wxPanel, beneath a wxToolbar, on a wxNotebook. Does the logic need to have knowledge of the window hierarchy to calculate the wxControl relative mouse position?
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: trying to calc column cell clicked in wxListCtrl

Post by doublemax »

Usually when you need this functionality, you already have the mouse coordinates in client space, from the mouse event.

But there is also wxWindow::ScreenToClient(...) that does the conversion for you.

At first glance the code looks ok, as usual: The debugger is your friend. Just single-step through the code and most likely you will see immediately why it doesn't work.
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: trying to calc column cell clicked in wxListCtrl

Post by bsenftner »

After more research and variation trials, the docs seem to indicate this should work but does not:

Code: Select all

int CX_VideoStreamListCtrl::GetColumnClicked(wxListEvent& event)
{
	wxPoint raw_click        = wxGetMousePosition();
	wxPoint listctrl_click    = ClientToScreen(raw_click);
	wxPoint listCtrlPosition = GetScreenPosition();

	int dx = listctrl_click.x - listCtrlPosition.x;

	int column;
	int columnCount = GetColumnCount();

	int x = 0;
	for (column = 0; column <columnCount; column++) {
		x += GetColumnWidth(column);
		if (x >= dx)
			break;
	}

	return column;
}
There seems to be some type of hidden scale factor affecting the coordinates, yet requesting the scaling factor returns 1.0... The column widths returned are the same values I set at wxListCtrl creation. I have 4 columns, with widths of 30, 150, 22, and 300 respectively. The wxListCtrl is right aligned with the border of the window, so I'd expect wxListctrl coordinate mouse positions to be low, within my column widths, but they are not at all.

Clicking within the first column, wxGetMousePosition() returns an x coordinate of something like 820, which after ClientToScreen() has an x coordinate of 4726. Then GetScreenPosition() gives an x coord of 3906, yielding a final mouse dx into the wxListctrl of 820. Much, much larger than my expected value beneath 30.

As I move my window to other monitors, the corresponding values returned make no sense. wxGetMousePosition() seems to be returning x coordinates too high, regardless of where a click takes place. Do I need to be using the toDPI() and FromDPI() routines?
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: trying to calc column cell clicked in wxListCtrl

Post by bsenftner »

wxWindow::ScreenToClient(...) appears to also be affected by this hidden scaling factor. ScreenToClient( wxGetMousePopsition() ) returns an x coord far to high, over 3000 when I'm expecting a value less than 30.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: trying to calc column cell clicked in wxListCtrl

Post by doublemax »

What are the mouse coordinates you get from the click event?
What exactly is your monitor configuration (Position and size) ?
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: trying to calc column cell clicked in wxListCtrl

Post by bsenftner »

This is inside a wxListEvent, the EVT_LIST_ITEM_SELECTED and EVT_LIST_ITEM_ACTIVATED handlers - which do not provide the mouse coordinates.

monitor-wise there is a 2K monitor on the left, a 4K monitor in the center, a 1920x1080 on the right, and a 1920x1080 centered above these three. It's a unified desktop. I'm not sure how to get the window coordinates of each monitor.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: trying to calc column cell clicked in wxListCtrl

Post by doublemax »

I'm not sure how to get the window coordinates of each monitor.
You can using wxDisplay. But you shouldn't have to do this. I'm just trying to narrow down where exactly the error is.

Does this happen on all monitors?

And which call returns wrong values, wxGetMousePosition or GetScreenPosition?

I have a suspicion that wxGetMousePosition doesn't work correctly if there are displays with negative coordinates.
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: trying to calc column cell clicked in wxListCtrl

Post by bsenftner »

I think it is GetScreenPosition() returning unexpected values. Now that I am looking at and using the wxDisplay routines, I am getting a better picture of what is going on.

Image

Using wxDisplay, I am getting these values for the monitor layout shown above:

monitor 1: origin (0,0) size (3840, 2160); client area: (0, 0, -3840, 2122)
monitor 2: origin (4800,0) size (2100,1313); client area: (4800,0, 2100, 1275)
monitor 3: origin (1128,-1350) size (2400,1350); client area: (1128,-1350, 2400, 1313)
monitor 4: origin (-3200,-58) size (3200,1350); client area: (-3200,-58, 3200, 1313)

The monitor sizes returned don't look correct.

Monitor 2 has a resolution set to 1680x1050, (confirmed via VideoModeToText(wxDisplay.GetCurrentMode()) and checking the OS Display Settings), yet the size returned by wxDisplay.GetGeometry() says that display is 2100 x 1313. Ignoring the height, how does the 1680 width become 2100? Checking my Win10 Display settings, that monitor is indeed 1680x1050 and has no display scaling. It is returning values as if that monitor is set for 125% display scaling, but it is not.

Funny thing is, monitor 1 is the only display returning client areas that fit the set display resolution, yet that monitor is set for 125% display scaling - it should be reporting sizes like the other monitors.

I'm still investigating and trying to figure out a solution. Just replying so you know I've not moved on with this issue.
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: trying to calc column cell clicked in wxListCtrl

Post by doublemax »

Is your program marked as DPI aware?

Can you make a test with the latest version from GIT? I think it has a few fixes regarding high DPI support, but AFAIK still no support for per-monitor DPI. That could be the issue.

And if it's not too much hazzle, can you disconnect the one display with 125% scaling or set it to 100%?

Does monitor1 really report a negative width for the client area? That can't be right either.
Use the source, Luke!
User avatar
bsenftner
Experienced Solver
Experienced Solver
Posts: 85
Joined: Thu May 26, 2016 9:19 pm

Re: trying to calc column cell clicked in wxListCtrl

Post by bsenftner »

The program is not marked as DPI Aware.

I could continue here, but I've spent too much time trying to work around this (seemingly odd) limitation of wxListCtrl. I should have used a wxGrid. Rather than start learning about DPI Awareness and pursuing this unsupported feature, I'm just going to bail on wxListCtrl and switch to wxGrid. I'd have had that working by now, but chose wxListCtrl because it looked easier...
Post Reply