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?
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
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
ASKER
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.
ASKER
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(UI NT 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(nFlag s, 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?
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(UI
{
CString str;
str.Format("%d", point.x);
m_xcord.SetWindowText(str)
str.Format("%d", point.y);
m_ycord.SetWindowText(str)
CStatic::OnMouseMove(nFlag
}
****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(UI NT 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)->S etCurPos(& 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_SE TPICTURECU RSORPOS, 0, (LPARAM)&pt);
}
}
code may look like this:
CMyPicture::OnMouseMove(UI
{
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)->S
// 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_SE
}
}
ASKER
i cant seem to get it to work. I added this code and this is the error that i got -
void CMouseMove::OnMouseMove(UI NT 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_P ICTURE, 0, (LPARAM)&point);
}
CStatic::OnMouseMove(nFlag s, point);
}
****error****
error C2664: 'void __thiscall CWnd::ScreenToClient(struc t tagPOINT *) const' : cannot convert parameter 1 from 'class CPoint' to 'struct tagPOINT *'
any suggestions?
void CMouseMove::OnMouseMove(UI
{
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_P
}
CStatic::OnMouseMove(nFlag
}
****error****
error C2664: 'void __thiscall CWnd::ScreenToClient(struc
any suggestions?
ASKER
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?
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?
ASKER
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_SETPICTURECU RSORPOS, OnSetPictureCoords)
END_MESSAGE_MAP()
// handler implementation
LRESULT CMyDialog::OnSetPictureCoo rds(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) ;
}
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,
}
in the message map add following:
BEGIN_MESSAGE_MAP(....)
// insert after wizard coments
ON_MESSAGE(WM_SETPICTURECU
END_MESSAGE_MAP()
// handler implementation
LRESULT CMyDialog::OnSetPictureCoo
{
POINT* pt = (POINT*)lParam;
CString str;
str.Format("%d", pt->x);
m_xcord.SetWindowText(str)
str.Format("%d", pt->y);
m_ycord.SetWindowText(str)
}
ASKER
the x and y coords are not displayed in the edit control and the -
LRESULT CNewDlg::OnMouseMove(WPARA M, 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.
LRESULT CNewDlg::OnMouseMove(WPARA
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
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::OnMouseM ove(UINT nFlags, CPoint point)
{
//Get the Picture Control's Rect To check
CRect rect;
m_ctrlPicture.GetWindowRec t(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_MOUSEMO VE, 0 ,lp);
}
CDialog::OnMouseMove(nFlag s, 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::OnMouse Move(UINT nFlags, CPoint point)
{
ScreenToClient(&point);
CString str;
str.Format("[%d, %d]", point.x, point.y);
this->GetParent()-> GetDlgItem(IDC_EDIT1)->Set WindowText (str);
CStatic::OnMouseMove(nFlag s, 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
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::OnMouseM
{
//Get the Picture Control's Rect To check
CRect rect;
m_ctrlPicture.GetWindowRec
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(
}
CDialog::OnMouseMove(nFlag
}
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::OnMouse
{
ScreenToClient(&point);
CString str;
str.Format("[%d, %d]", point.x, point.y);
this->GetParent()-> GetDlgItem(IDC_EDIT1)->Set
CStatic::OnMouseMove(nFlag
}
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
ASKER
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
see GetScrollPos method help in the MSDN
ASKER
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.
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.GetScrollP os())
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.GetScrollP
ASKER
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.
What type your scrollbars? I understand what you want but not what scrollbars you using.
ASKER
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.GetB itmap();
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.GetW indowRect( &rc);
int nVertScrollMax = bm.bmHeight-rc.Height();
int nHorzScrollMax = bm.bmWidth-rc.Width();
}
////////////////////////// ////////// ///////
c. m_wndVertScrollBar.SetScro llRange(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
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.GetB
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.GetW
int nVertScrollMax = bm.bmHeight-rc.Height();
int nHorzScrollMax = bm.bmWidth-rc.Width();
}
//////////////////////////
c. m_wndVertScrollBar.SetScro
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
ASKER
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(UI NT nFlags, CPoint point)
{
ScreenToClient(&point);
CString x, y;
//x coordinate
TRACE("\n%d\n", this->GetParent()->GetDlgI tem(IDC_XS CROLL)->Ge tScrollPos (SB_CTL));
x.Format("%d", point.x);
this->GetParent()->GetDlgI tem(IDC_XC ORD)->SetW indowText( x);
//y coordinate
y.Format("%d", point.y);
this->GetParent()->GetDlgI tem(IDC_YC ORD)->SetW indowText( y);
CStatic::OnMouseMove(nFlag s, 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.
void CMouseMove::OnMouseMove(UI
{
ScreenToClient(&point);
CString x, y;
//x coordinate
TRACE("\n%d\n", this->GetParent()->GetDlgI
x.Format("%d", point.x);
this->GetParent()->GetDlgI
//y coordinate
y.Format("%d", point.y);
this->GetParent()->GetDlgI
CStatic::OnMouseMove(nFlag
}
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.GetB itmap();
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.GetW indowRect( &rc);
int nVertScrollMax = bm.bmHeight-rc.Height();
int nHorzScrollMax = bm.bmWidth-rc.Width();
}
////////////////////////// ////////// ///////
c. m_wndVertScrollBar.SetScro llRange(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
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.GetB
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.GetW
int nVertScrollMax = bm.bmHeight-rc.Height();
int nHorzScrollMax = bm.bmWidth-rc.Width();
}
//////////////////////////
c. m_wndVertScrollBar.SetScro
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
ASKER
Adjusted points to 300
ASKER
what you gave me will not work, I need help based on what VinExpert gave me.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
ASKER
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
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
ASKER
thanks
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)