get the index of the ClistBox item on Mouse over - c++

I have a simple CListBox control. I dynamically add texts in it. Is it possible to get the index of the item over which the mouse is currently hovering on the listbox?
Basically, I want to display a tool tip for each item in the listBox based on the mouse position.
Code samples are really appreciated.

The CListBox::ItemFromPoint member returns the item index of the item nearest to a point.
The point needs to be in client coordinates of the CListBox. If you receive them in screen coordinates (e.g. by calling GetCursorPos), you will have to translate them calling CWnd::ScreenToClient on the CListBox.
The second parameter (bOutside) tells you, whether the position is over an item or not. The member function returns FALSE or TRUE, respectively.

I am writing this answer so that others can get help in case some one else is facing this problem.
First things first; you can't directly handle mouse move messages from Clistbox. So, you create a new class based on ClistBox class and then handle OnMouseMove() in that class.Then, inside that OnMouseMove() function you should get the item in the clistbox based on the mouse coordinates (as mentioned by IInspectable).
For code example; see below.
BOOL b;
int n = ItemFromPoint(point,b);
CString str;
GetText( n,str);
AfxMessageBox(str);

Related

What Function can I use to get the handle of a button?

the situation is as follows:
I have the handle for a window (which i got with the function FindWindowEx() ) and that window has 3 buttons. I would like to know how I can get the handle for 1 of the 3 buttons. I mean I know ppl can use spy++, but I am sure there have to be functions that can do it for me, so my questions are:
Question::
What function or functions can I use to get the handle of a button of a window (already knowing the handle for the window)?
Question2::
How do I get the Button's ID???
You can loop through children of that window with EnumChildWindow.
It lets you define a callback function to be called for every child of the window.
In the callback, you can check if the current child is the button you need.
For example, if you dinamically want to press an OK button, you can check if the window text equals OK. You can get the window text with GetWindowText.
If you know the position in the parent window you can use ChildWindowFromPoint.
For this to work you will probably have to check the windows status first (maximazed or current width-height) to be sure the button is right where you want.
An easy way may also be getting his position relative to another child of the window that's easier to retrieve. For example, if the button is always to the right of a text-box control, you can get coordinates of the text-box and use ChildWindowFromPoint passing those coordinates with something added in the x direction.

Button in MFC CtreeCtrl column

I have a CTreeListCtrl in my MFC application.What I need to do is add a button in a particular column of a node when a particular condition is satisfied(type is changed to reference).
In the image I have edited and added a blue rounded oval to mark the place of desired button.What I want to do is to invoke a dialog on clicking it.But I don't have any clue whether it is possible or not.If yes then pls give me some suggesions.
This is no normal tree control. It is already customized to use multiple columns and I am sure it uses some kid of owner draw. For me it seams more like a list control with tree Features... I know some similar code from Codepproject..
Creating a "real" button (window) isn't wise/good. because it is another window inside the list control...
Change your code to "Draw a button. You can use DrawFrameControl.
Just intercept the left mouse click. Check the range if this area is cliecked. Fire a user defined message to the parent window.

Qt C++ Let multiple QGraphicsItem handle one mouse event

I've created an object Chartblock that implements QGraphicsItem. My goal is to create a grid of these objects, and when the mouse button is pressed (and held) and is drug over each block, perform something on each block as the cursor enters it.
Since a QGraphicsItem grabs the mouse events when it is clicked within it, other Items will not fire for the mouseMoveEvent. I then created an object based on the QGraphicsItemGroup to handle all the mouse events, but then I would need some way to pass mousePressEvent/mouseReleaseEvent as well as mouseMoveEvent to each child that the cursor is over.
Am I overthinking how to do this? It seems like such a simple action shouldn't be that difficult to create, but with QGraphicsItems holding onto the mouse events for itself, I'm not sure how to get around it. I've read similar situations, but nothing seems to give a straightforward answer.
Edit: I suppose a way to do this would keep track of the coordinates/sizes of every single QGraphicsItem I create in an array, then get the position of the cursor in the Group mouseMoveEvent, and see if there's a hit..
I was able to pull together a few similar answers to create a solution; I dropped the idea of placing all my QGraphicItem's in a Group, and placed them directly on a scene. With the scene grabbing all mouse events, I have the mouseMoveEvent check to see if the current position is on top of a QGraphicsItem - if so, perform something.
I still need to try and get itemAt() to work for my own classes that implement QGraphicsItem, as itemAt returns only QGraphicsItem's, but I'm sure some cast should get it working.
void ChartScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QPointF mousePosition = event->scenePos();
QGraphicsItem* pItem = this->itemAt(mousePosition.x(), mousePosition.y());
}

Accessing the the coordinates in a QPushbutton clicked slot

I have a QPushButton with an image that has two areas that I want to handle differently when clicked. Due to the positioning on the image, I cannot really use separate buttons for the two images.
What I'd like to do is, in the slot where I am handling the click, have it check the coordinates of the click to determine which area was clicked.
Is there a way to access this?
This is what first comes to mind. It should work, although there may be a simpler way:
Create your own class that derives from QPushButton.
Override the necessary mouse events (mousePressEvent and mouseReleaseEvent) and, before calling the base class implementation, set a property in your object using setProperty with the position of the mouse click. (The position is available from the event parameter.)
In the slot handling the event, use sender() to get the button, and read the property using property().
If you don't need to treat your object as the base class (QPushButton*) you could just create a new signal that includes the mouse event and attach that to your slot. Then you wouldn't need the property at all.
You can get the current mouse position using QCursor::pos() which returns the position of the cursor (hot spot) in global screen coordinates.
Now screen coordinates are not easy to use, and probably not what you want. Luckily there is a way to transform screen coordinates to coordinates relative to a widget.
QPoint _Position = _Button->mapFromGlobal(QCursor::pos());
This should tell you where on the button the mouse was when the user clicked. And you can take it from there.
Building on #Liz's simple mechanism, here's what I did; this is in a slot method that is called on pressed() but generalizes to other situations. Note that using pushButton->geometry() gives you coordinates that are already in global space so you don't need to mapFromGlobal.
void MainWindow::handlePlanButtonPress()
{
int clickX = QCursor::pos().x();
int middle = m_buttonPlan->geometry().center().x();
if ( clickX < middle ) {
// left half of button was pressed
m_buttonPlan->setStyleSheet(sStyleLargeBlueLeft);
} else {
// right half of button was pressed
m_buttonPlan->setStyleSheet(sStyleLargeBlueRight);
}
}

Get relative X/Y of a mouse-click on a MFC CListBox item

I have a CListBox with custom drawing being used, and need to detect mouse-clicks within each item to perform actions.
I can listen for mouse-clicks on the main control and mess about translating coords into the local space of the RECT for the item under the mouse. But is it possible to register message handlers for clicks on individual list items... are there messages for that?
You can use the LVM_HITTEST message to find out which item was clicked.
Well you could just listen for the LBN_SELCHANGE notification. This will fire every time the user clicks a new item. It won't activate if the already selected item is selected though. This may, or may not, be a problem.
Beyond that I'm pretty sure you'll need to intercept WM_LBUTTONUP messages and transform them to the list box's client space ...
OR You could just use a single columned CListCtrl (ListView) class with headers turned off (LVS_NOCOLUMNHEADER). You can then trap the NM_CLICK message. Personally, I massively prefer CListCtrl to CListBox. It IS a little more complex but way more powerful :)
Edit: Or you could try using http://msdn.microsoft.com/en-us/library/bb761323(VS.85).aspx
I'm not certain I understand why you need to have the XY coordinate inside each item of a Clistbox ?
anyway,
AFAIK, Individual items are not CWnd derived objects.
You could get the mouse position inside the control with OnLButtonDown (or up), it returns a CPoint.
After that, use CListBox::GetItemRect to get the rect of the currently selected item, do a bit of pixel computation and you should be able to get the XY inside the rect of the selected item.
Max.
Use the DPtoLP function to convert device coordinates into logical coordinates.
http://msdn.microsoft.com/en-us/library/dd162474(v=vs.85).aspx