Link to home
Start Free TrialLog in
Avatar of simongod
simongod

asked on

x and y coordinates of a picture control

How can I use the WM_MOUSEMOVE message so that when I move the mouse over a picture control, that has a picture displayed in it, I can get the pictures x and y coordinates.  What I have so far is, I can get the x and y coordinates of the whole dialog based program that I made, I then found out where the picture control was located and founds it x and y position and then subtracted those dimensions from the WM_MOUSEMOVE to get the x and y coordinates of the picture control.  Well that really is not what I wanted.  I want to wrap the WM_MOUSEMOVE to the picture control and not the Dialog based program, so that I can get the exact x and y coordinates of the picture displayed inside of the picture control.  Any suggestions?
Avatar of migel
migel

Hi!
just deriev your own class from CStatic
and handle WM_MOUSEMOVE message
also you must subclass Picture control by your class (attach class member to the windows Control in the class wizard)
Avatar of simongod

ASKER

i am not really sure how ot do that could you help with that?  I am really a beginning programmer, if you read all the questions i have posted.  But I am a fast learner.
Ok
In the MSVC ide choose New class(in the project classses tree) In the appeared dialog choose  MFC class and select CStatic in the base class Combo.
after that call CLASS Wizard  (Ctrl+W) select this class in the classes combo and add handler for WM_MOUSEMOVE message
implement routines.

in the class wizard (Member variables page) select your dialog where you want this picture control
select picture control ID and  click Add Variable... in the appeared dialog select categoryControl and type: your static derived class
Should I use the same code that I am using to find the x and y coord of the dialog program for the picture?  Would that work?  I am going to try what you said to do.
ok i did what you said and I get an error.  I know why I got the error but I am really not sure how to correct it.

Let me show you the error then the code that I have.

****begin error****
error C2065: 'm_xcord' : undeclared identifier
error C2228: left of '.SetWindowTextA' must have class/struct/union type
error C2065: 'm_ycord' : undeclared identifier
error C2228: left of '.SetWindowTextA' must have class/struct/union type
****end error****

****begin code****
void CMouseMove::OnMouseMove(UINT nFlags, CPoint point)
{
      CString str;
      str.Format("%d", point.x);
      m_xcord.SetWindowText(str);
      str.Format("%d", point.y);
      m_ycord.SetWindowText(str);
                        
      CStatic::OnMouseMove(nFlags, point);
}
****end code****

Now in my dialog based program m_xcord and m_ycord is a member variable for two edit controls that I want the results to be displayed in.  How do I make it so that the results are displayed in the edit controls?
Hi!
code may look like this:
CMyPicture::OnMouseMove(UINT uflags, CPoint pt)
{
GetCursoprPos(&pt);
ScreenToClient(pt);
// now we must say our parent (dialog)
// that we have new cursor coordinates:
CWnd* pParent = GetParent();
if (pParent)
{
// here we can call dialog method to set
// new pos
// i.e. //((CMyDialog*)pParent)->SetCurPos(&pt);

// or another way sent user defined
// message to the parent (I prefer this
// way since it is not depended from
// parent dialog class)
// i.e.
// pParent->SendMessage(WM_SETPICTURECURSORPOS, 0, (LPARAM)&pt);
}
}
i cant seem to get it to work.  I added this code and this is the error that i got -

void CMouseMove::OnMouseMove(UINT nFlags, CPoint point)
{
      GetCursorPos(&point);
      ScreenToClient(point);
      // now we must say our parent (dialog)
      // that we have new cursor coordinates:
      CWnd* pParent = GetParent();
      if (pParent)
      {
            pParent->SendMessage(IDC_PICTURE, 0, (LPARAM)&point);
      }

      CStatic::OnMouseMove(nFlags, point);
}


****error****
error C2664: 'void __thiscall CWnd::ScreenToClient(struct tagPOINT *) const' : cannot convert parameter 1 from 'class CPoint' to 'struct tagPOINT *'

any suggestions?
i added this to what you have and it works -

me - ScreenToClient(&point);
you - ScreenToClient(point);
            
but how do I make the x and y coords of the picture control show up in and edit control?
Adjusted points to 200
ok
1. declare your private message based on the WM_USER
in the picture class header write this:
#define WM_SETPICTURECURSORPOS (WM_USER+0xAA)
and use it the SendMessage;
2. in the parent dialog declare handle for your private message:
class CMyDialog:public CDialog
{
/// something you need
protected:
LRESULT OnSetPictureCoords(WPARAM, LPARAM);
}

in the message map add following:
BEGIN_MESSAGE_MAP(....)
// insert after wizard coments
ON_MESSAGE(WM_SETPICTURECURSORPOS, OnSetPictureCoords)
END_MESSAGE_MAP()

// handler implementation
LRESULT CMyDialog::OnSetPictureCoords(WPARAM, LPARAM lParam)
{
POINT* pt = (POINT*)lParam;
CString str;
str.Format("%d", pt->x);
m_xcord.SetWindowText(str);
str.Format("%d", pt->y);
m_ycord.SetWindowText(str);
}
the x and y coords are not displayed in the edit control and the -

LRESULT CNewDlg::OnMouseMove(WPARAM, LPARAM lParam)

Wants something to be returned.  What should be returned?  I added this to the return -

return pt->x, pt->y;

It seems like something is missing.
Hi simongod
check whether U have done this
1. put a picture control on dialog
2. Go to Properties
3. Give some name to control ID say ID_MYSTATICPICTURE
4. Check Notify property
5. Go to class wizard
6. Add UR own class derived from CStatic
5. Map the handler WM_MOUSEMOVE

but
Whatever function U have mapped is not currect in prototype
what ever migel has written is currect if U want to set text to a edit box then use the following code

CString strX;
CString strY;
strX.Format("%d", pt->x);
strY.Format("%d", pt->y);
strX = "X = " + strX + "Y = " + strY;
m_Edit.SetWindowText(str);


Hope this helps
Hi,

Let me explain it to U.
I assume that U have the dialog box of class say CCustomDialogDlg and U have inserted a picture control into it with ID - ID_MYPICTURE. And there is an edit control with ID - ID_EDIT1. Now follow the following steps(U can test it by creating a sample dialog based application with project name as CustomDialog).

1. Go to class wizard and add the new class called     CMyStaticSubclass derived from CStatic.
2. Using class wizard add the member variable of CStatic to the     ID - ID_MYPICTURE say m_ctrlPicture.
3. Now go to CustomDialogDlg.h and include the
    #include "MyStaticSubclass.h" and replace the line
    CStatic m_ctrlPicture; with
    CMyStaticSubclass      m_ctrlPicture;
    Now u subclassed the picture control.
4. Go to class wizard and map the WM_MOUSEMOVE message to     the dialog and put the following code
    void CCustomDialogDlg::OnMouseMove(UINT nFlags, CPoint      point)
    {
      //Get the Picture Control's Rect To check
      CRect rect;
      m_ctrlPicture.GetWindowRect(rect);      
      ScreenToClient(&rect);
      
      //Store The Cursor Position
      CPoint pt;
      GetCursorPos(&pt);

      //Make it as LPARAM and send it
      LPARAM lp = MAKELPARAM(pt.x, pt.y);
      if(rect.PtInRect(point))
      {      
                                            m_ctrlPicture.SendMessage(WM_MOUSEMOVE, 0 ,lp);
      }
      
      CDialog::OnMouseMove(nFlags, point);
       }
5. Again go to class wizard and map the WM_MOUSEMOVE         message to Ur static class CMyStaticSubclass
6. Modify that function as bellow
    void CMyStaticSubclass::OnMouseMove(UINT nFlags, CPoint     point)
    {
      ScreenToClient(&point);
      CString str;
      str.Format("[%d, %d]", point.x, point.y);
      this->GetParent()->                                           GetDlgItem(IDC_EDIT1)->SetWindowText(str);
      CStatic::OnMouseMove(nFlags, point);
     }

Thats it. It will give u the co-ordinates of picture control in the edit box on the dialog.

If u find any difficulty in following the steps, the sample workspace is with me. I can send it to u.

Hope this helps U.
VinExpert
it works but it only works for the picture control.  What if the picture is larger than the picture control and I am using scrollbars to view the rest of the picture?  How can I get the actual x and y coords of the whole picture?
just add scroll positions to the mouse coords
see GetScrollPos method help in the MSDN
the MSDN does not help.  I have scollbars that move the picture around inside of the picture control (if the picture is to big).  But When I move the mouse over the picture control I want the x and y position of where the mouse is positioned.  Now the code above works but only with the picture control.  What happens if I move the scrollbars to see more of the picture, the x and y coordinates are now wrong.

I am going to ask another question and give more points because I am asking another question.  Now when I move my mouse around on the picture that is displayed inside of my picture control, I would like a little x marker to move with the mouse and when I click on the picture that little x marker will stay where I clicked and I can then record the position of what that x marker is.  Now when I click a second time another x marker will stay where I have clicked.  Can you help me with this?  I added it to this question because it goes along with it.  I will boost the pts to 400, if you can help me make this work.
Where you create scrollbars?
Is it picture control props or standalone dialog control?
If it`s control property you can just get scroll position inside OnMouseMove and add returned values to the mouse pos.
if scrollbars is control the technique will be same but GetScrollPos must be called for scrollbar (i.e c_wndHorzScroll.GetScrollPos())
lets say that the x and y positions of my scrollbars are 0,0.  Then the x and y coordinates of the picture would be normal.  Now if I move the scrollbars say 50% then the x and y coordinates of my picture would be 50% more than what they would normally be.  How might I implement that into my code, IF thats how I might do it.  Also how do I add the code for clicking a marker onto the picture, like I stated above.
hmm, so hard to say :-(
What type your scrollbars? I understand what you want but not what scrollbars you using.
i am using horizontal and vertical scroll bar controls in the VC 6 developer program.  They are on the controls menu.
Wonderfull.
So you have to do next:
1. set proper scrollbars limits (for both: horz and vert) by using SetScrollPos.
    a. To get bitmap size you can ask Picture control about bitmap it dsplayed by calling :
{
HBITMAP hbm =  m_wndMyPictureControl.GetBitmap();
BITMAP bm;
::GetObject(hbm, sizeff(bm), &bm);
// you need bm.bmWidth and bm.bmHeight
}
////////////////////////
  b. you must get scroll range by substraction viewable area dims from owerall bitmap dims.
that is:
{
CRect rc;
m_wndMyPictureControl.GetWindowRect(&rc);
int nVertScrollMax = bm.bmHeight-rc.Height();
int nHorzScrollMax = bm.bmWidth-rc.Width();
}
///////////////////////////////////////////
  c. m_wndVertScrollBar.SetScrollRange(0, nVertScrollMax); // same for horz.
2. When your dialog receive WM_HSCROLL and WM_VSCROLL messages you must ajust picture pos
3. I think that picture control can not show image from desired point so you must override OnPaint in the your derived calss and implement this think manually (by BitBlt operation)
4.In the mouse move you must add scroll pos? as I said in previous somments
the code that VinExpert gave is what I am using in my code.  I am not really sure what you are saying in your example.  Can you tell me how I might use it based on the code that VinExpert gave me?  This is the code that I have so far.

void CMouseMove::OnMouseMove(UINT nFlags, CPoint point)
{
      ScreenToClient(&point);
      CString x, y;
      //x coordinate
      TRACE("\n%d\n", this->GetParent()->GetDlgItem(IDC_XSCROLL)->GetScrollPos(SB_CTL));
      x.Format("%d", point.x);
      this->GetParent()->GetDlgItem(IDC_XCORD)->SetWindowText(x);
      //y coordinate
      y.Format("%d", point.y);
      this->GetParent()->GetDlgItem(IDC_YCORD)->SetWindowText(y);
      CStatic::OnMouseMove(nFlags, point);
}

I derived my own class based on Mouse Movements.  The code works great but I am still have the same problem that I stated above.  The TRACE statment is there just so that I can get the correct numbers from the ScrollBar controls.  The way that I am getting the scrollbar positions, is that an efficent way of doing it?  I know that I need the scrollbar postitions to get the x and y coords of the picture and not of the picture control.
Wonderfull.
So you have to do next:
1. set proper scrollbars limits (for both: horz and vert) by using SetScrollPos.
    a. To get bitmap size you can ask Picture control about bitmap it dsplayed by calling :
{
HBITMAP hbm =  m_wndMyPictureControl.GetBitmap();
BITMAP bm;
::GetObject(hbm, sizeff(bm), &bm);
// you need bm.bmWidth and bm.bmHeight
}
////////////////////////
  b. you must get scroll range by substraction viewable area dims from owerall bitmap dims.
that is:
{
CRect rc;
m_wndMyPictureControl.GetWindowRect(&rc);
int nVertScrollMax = bm.bmHeight-rc.Height();
int nHorzScrollMax = bm.bmWidth-rc.Width();
}
///////////////////////////////////////////
  c. m_wndVertScrollBar.SetScrollRange(0, nVertScrollMax); // same for horz.
2. When your dialog receive WM_HSCROLL and WM_VSCROLL messages you must ajust picture pos
3. I think that picture control can not show image from desired point so you must override OnPaint in the your derived calss and implement this think manually (by BitBlt operation)
4.In the mouse move you must add scroll pos? as I said in previous somments
Adjusted points to 300
what you gave me will not work, I need help based on what VinExpert gave me.
ASKER CERTIFIED SOLUTION
Avatar of migel
migel

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
no its not really that important I can send it to you.  please read the email so that I can show you exactly what I want if you could I would really like for you to make those changes for me.  If you do then I will give you 500 pts.
anyone want to help me?
Hi,

Happy to see so many comments and progress.
Okay, If U want send the sample to me too at k_bbb100@hotmail.com.

Regards,
VinExpert
thanks