How do I get the screen or window coordinates of CTreeCtrl node? - winapi

I want to generate a context menu but I need to know where to put it, so I need the coordinates of the node currently selected.

Use CTreeCtrl::GetItemRect(). This will state the rectangle of the tree node.

You can use 'GetCursorPos' and'HitTest method in treeclick event for displaying context menu as below.
//here i am asuming that you want to display menu on mouse rightclick
void MyDialog::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult)
{
CPoint CurPos;
GetCursorPos(&CurPos);
CPoint CurP=CurPos;
m_pwTree.ScreenToClient(&CurPos);// m_pwTree is object of CTreeCtrl class
UINT nFlags;
HTREEITEM htItem = m_pwTree.HitTest(CurPos, &nFlags);
if (htItem != NULL ) {
CMenu menu;
CMenu* pContextMenu;
menu.LoadMenu(IDR_MyMenu)//load appropriate menu
pContextMenu=menu.GetSubMenu(0); pContextMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,CurP.x,CurP.y,this,0);
}
}

Related

How can I add objects to a scene via button click in Unity?

I would like to know how to use a button click to bring objects to the scene.
1) Create a button using Unity GUI system.
2) Create a script:
public GameObject sampleObject;
public void AddObject()
{
Instantiate(sampleObject, Vector3.zero, Quaternion.Identity);
}
3) Attach this script to an object in the scene, and set a prefab to sampleObject.
4) Select your button and in the Inspector add a new OnClick script, and select the object with the new script attached, select AddObject() method.
Now when you click on the button it should instantiate an object at (0.0f, 0.0f, 0.0f).
Hope that helps you.
I think use gameObject z postion value and show or hide when this object allready created
Find current gameObject and set transform.postion.z = -1 or 1
if gameObject z postion set to -1 hideObject else showObject
sampleCode
float yourChose = -1f; // chose object hide or show (-1 or 1 )
foreach (var item in FindObjectsOfType(typeof(GameObject)) as GameObject[])
{
if (item != null && item.name == "CurrentObjectName")
{
item.transform.position = new Vector3(item.transform.position.x, item.transform.position.y, yourChose);
}
}

Forcing a combobox to "dropdown" above instead of below

When you click on the "dropdown" button of a combobox, the dropped down listbox appears below the combobox, unless there is not enough space below, in which case the listbox appears above.
Now I wonder if there is a possibility to force the lisbox to appear above the combobox, even if there is enough space below.
Illustration
When I click on the combo box, I'd like the "drop down" list box appear always above as on the left screen copy.
Everything is possible, and you don't need to implement the control "from scratch".
First, you can subclass the ListBox part of your ComboBox to get complete control over it, as explained in MSDN. You can create a class, derived from CListBox, using the Class Wizard. You only need to implement WM_WINPOSITIONCHANGING handler in it:
void CTopListBox::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
CListBox::OnWindowPosChanging(lpwndpos);
if ((lpwndpos->flags & SWP_NOMOVE) == 0)
{
lpwndpos->y -= lpwndpos->cy + 30;
}
}
Here, for simplicity, I am moving the box up by the (heights+30). You can get the height of your ComboBox instead of my 30.
Then you declare a member variable in your dialog class:
CTopListBox m_listbox;
and subclass it like that:
HBRUSH CMFCDlgDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_LISTBOX)
{
if (m_listbox.GetSafeHwnd() == NULL)
{
m_listbox.SubclassWindow(pWnd->GetSafeHwnd());
CRect r;
m_listbox.GetWindowRect(r);
m_listbox.MoveWindow(r);
}
}
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
Note that I am calling m_listbox.MoveWindow(r) there; it is needed because first WM_CONTROLCOLOR message for that list box comes after it is positioned, so the very first time it would drop down instead of up.
Disclaimer: this is not a very clean solution, as, if you have windows animation enabled, you'd see that the list unrolls from top to bottom.
Alternatively, you should be able to "fool" the combobox that it is too close to the bottom of the screen; then it will drop up by itself. I leave it as an exercise for the readers :)
This would be relatively easy except when combo box has "slide open" effect. If you move the dropdown listbox to the top, and the combo slides open from top-to-bottom, it would look odd. So you have to disable the animation or reverse it.
In this function I call AnimateWindow in OnWindowPosChanging, it doesn't seem to cause any problems but I am not a 100% sure about it!
class CComboBox_ListBox : public CListBox
{
public:
CWnd *comboBox;
void OnWindowPosChanging(WINDOWPOS *wndpos)
{
CListBox::OnWindowPosChanging(wndpos);
if (comboBox && wndpos->cx && wndpos->cy && !(wndpos->flags & SWP_NOMOVE))
{
CRect rc;
comboBox->GetWindowRect(&rc);
//if listbox is at the bottom...
if (wndpos->y > rc.top) {
//if there is enough room for listbox to go on top...
if (rc.top > wndpos->cy) {
wndpos->y = rc.top - wndpos->cy;
BOOL animation;
SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animation, 0);
//if combobox slides open...
if (animation) {
//we have to set the x coordinate otherwise listbox
//is in the wrong place when parent window moves
SetWindowPos(0, wndpos->x, wndpos->y, 0, 0,
SWP_NOSENDCHANGING | SWP_HIDEWINDOW | SWP_NOSIZE);
AnimateWindow(100, AW_VER_NEGATIVE);
}
}
}
}
}
DECLARE_MESSAGE_MAP()
};
Usage:
COMBOBOXINFO ci = { sizeof(COMBOBOXINFO) };
comboBox.GetComboBoxInfo(&ci);
CComboBox_ListBox *listBox = new CComboBox_ListBox;
listBox->comboBox = &comboBox;
listBox->SubclassWindow(ci.hwndList);
Also you can use SetMinVisibleItems to reduce the listbox height and make sure the dropdown list fits on top.

Button Control does not get/forward mouseDown/mouseUp/MouseMove messages

I have title-less MFC Dialog.
So it does not move if you drag it and you need to take care movements yourself.
I do this like this:
bool mbMousedown;
void MyDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
mbMousedown = true;
CDialogEx::OnLButtonDown(nFlags, point);
}
void MyDialog::OnLButtonUp(UINT nFlags, CPoint point)
{
mbMousedown = false;
CDialogEx::OnLButtonUp(nFlags, point);
}
afx_msg LRESULT MyDialog::OnNcHitTest(CPoint point)
{
CRect r;
GetClientRect(&r);
ClientToScreen(&r);
if (r.PtInRect(point))
{
if (mbMousedown)
{
return HTCAPTION;
}
}
return CDialogEx::OnNcHitTest(point);
}
It works - when i drag the dialog it moves.
But when i place button control on the dialog (yes i set notify to true) then the button control forward only click messages to the dialog but not mousedown/mouseup/mousemove.
It just does not have these handlers in class wizard.
So if user press the image inside the button control and drag the dialog like this then nothing happens since dialog did not get any messages from the button control.
I know i can solve this using activeX - i do not want to add activeX.
I know i can derive from button box and do that - but really there is no easiest solution than that to get button to pass the notification or to make my dialog to move when user drag it with the picture control ? I have many button controls on the dialog ...

Javafx - child and parent node mouse event

I have got a larger Pane (Parent) to which I have added another smaller Pane (Child). I would like to drag the child Pane without dragging the parent Pane (i.e. register mouse event only on the child and not on the parent).
How can we best implement it?
I managed to find a work around to my problem.
In the Parent Pane: I used mouseEvent.isControlDown()- So I use crtl+mousebutton down to drag the pane.
In the Child Pane: I used !mouseEvent.isControlDown(). So control keystoke is used to determine which part of the event works.
The parent goes like this:
node.addEventFilter(
MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
if (mouseEvent.isControlDown()) {
// remember initial mouse cursor coordinates
// and node position
dragContext.mouseAnchorX = mouseEvent.getSceneX();
dragContext.mouseAnchorY = mouseEvent.getSceneY();
dragContext.initialTranslateX
= node.getTranslateX();
dragContext.initialTranslateY
= node.getTranslateY();
}
}
});
The Child goes like this:
node.addEventFilter(
MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
if (!mouseEvent.isControlDown()) {
dragContext.mouseAnchorX = mouseEvent.getSceneX();
dragContext.mouseAnchorY = mouseEvent.getSceneY();
dragContext.initialTranslateX
= node.getTranslateX();
dragContext.initialTranslateY
= node.getTranslateY();
}
}
});

Qt- How to Draw Text from a QListWidget

Am Learning to do something with QListWidget. I have a QListWidget, QTextEdit , 2 QPushButtons (Add & Remove Buttons) and a QWidget for drawing the Text in it. When i enter a text in the QTextEdit and Click's the Add Button, the text has to add in the QListWidget. And from that QListWidget, i select any item and click's the Remove Button, the item has to be removed from the QListWidget. Then i want to draw this QListWidget Items in the QWidget and this drawed items has to scroll from Right to left. How can i do this? Plz help me...
//In the constructor
WidgetString = "";
On_add_button_Clicked() //SLOT
{
listwidget->addItem(lineedit->text());
}
On_Remove_Button_clicked() //SLOT
{
listWidget->takeItem(listWidget->currentIndex());
//You may have to delete the the item taken in order to put that change into effect.
//Trigger paintevent
}
on_listWidget_currentTextChanged(QString currentText) //SLOT
{
WidgetString = currentText;
}
paintevent()
{
QPainter painter(Your_Qwidget);
painter.drawText ( int xPos, int YPos, WidgetString )
update();
}
For the Scrollbar thing, you may need to increase the Text size you are going to Draw.

Resources